diff --git a/.agents/skills/dubbo-admin-console-api/SKILL.md b/.agents/skills/dubbo-admin-console-api/SKILL.md new file mode 100644 index 000000000..6468b8fdd --- /dev/null +++ b/.agents/skills/dubbo-admin-console-api/SKILL.md @@ -0,0 +1,60 @@ +--- +name: dubbo-admin-console-api +description: Implements and reviews dubbo-admin Console API changes. Use when the user asks about HTTP endpoints, Gin routes, handlers, request or response models, console services, error handling, API pagination, or the handler to service to manager to store flow under pkg/console/. Do not use for frontend-only, discovery-only, or store-internals tasks unless they affect Console API behavior. +--- + +# dubbo-admin Console API + +## Purpose + +Use this skill to change or explain dubbo-admin Web MVC behavior consistently across router, handler, model, service, manager, and store layers. + +## When to use + +Use for Console API endpoint additions, request binding, response models, service logic, route registration, API error handling, and backend API review. + +Do not use for Vue-only changes, registry discovery internals, or memory store implementation details unless an API contract depends on them. + +## Inputs + +Required: +- Target endpoint, handler, model, or package path. +- Intended API behavior or observed bug. + +Optional: +- Example request or response payload. +- Related frontend API caller. +- Existing route or service function to mirror. + +If missing, inspect `pkg/console/router/router.go` first and ask only for behavior that cannot be inferred from code. + +## Workflow + +1. Locate the route in `pkg/console/router/router.go`. +2. Read the matching handler in `pkg/console/handler/` for binding and response style. +3. Read or update request and response types in `pkg/console/model/`. +4. Put business logic in `pkg/console/service/`; keep handlers focused on HTTP concerns. +5. Use `ctx.ResourceManager()` and helpers in `pkg/core/manager/` for resource access. +6. Return responses with `model.NewSuccessResp`, `util.HandleArgumentError`, or `util.HandleServiceError`. +7. If endpoint behavior is unclear, read `references/web-mvc-flow.md`. + +## Output format + +Return changed files, endpoint behavior, request and response contract, validation performed, and any frontend impact. + +## Validation + +- Confirm the route is registered under `/api/v1`. +- Confirm handler binding matches method semantics: query for reads, JSON body for mutations. +- Confirm service code returns typed models and propagates business errors. +- Run focused Go tests for changed packages; use `make test` for shared API behavior. + +## Edge cases + +- Some handlers include lightweight auth, cookie, or parameter logic; do not force all logic into services. +- If changing response fields, check frontend callers under `ui-vue3/src/api/`. +- If a resource query becomes slow, switch to `dubbo-admin-store`. + +## References + +- Read `references/web-mvc-flow.md` for the current route, handler, service, and response pattern. diff --git a/.agents/skills/dubbo-admin-console-api/evals/evals.json b/.agents/skills/dubbo-admin-console-api/evals/evals.json new file mode 100644 index 000000000..0b64fe7ce --- /dev/null +++ b/.agents/skills/dubbo-admin-console-api/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-console-api", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Add a new GET endpoint under /api/v1/service that returns a typed response from pkg/console/service.", + "expected_behavior": "Use the Console API router, handler, model, service, and manager workflow." + }, + { + "id": "paraphrased-trigger", + "prompt": "The admin backend route binds query parameters incorrectly and returns the wrong CommonResp data.", + "expected_behavior": "Inspect pkg/console handlers, models, services, and response helpers." + }, + { + "id": "file-based-trigger", + "prompt": "Review changes in pkg/console/router/router.go and pkg/console/handler/application.go.", + "expected_behavior": "Use this skill because Console API files are touched." + }, + { + "id": "no-trigger", + "prompt": "Change the Vue sidebar icon for the service page.", + "expected_behavior": "Do not use this skill; use the frontend skill." + }, + { + "id": "conflict-trigger", + "prompt": "A frontend API call fails because the backend response field changed.", + "expected_behavior": "Use this skill for backend contract review and coordinate with frontend skill for caller updates." + } + ] +} diff --git a/.agents/skills/dubbo-admin-console-api/references/web-mvc-flow.md b/.agents/skills/dubbo-admin-console-api/references/web-mvc-flow.md new file mode 100644 index 000000000..367f8552b --- /dev/null +++ b/.agents/skills/dubbo-admin-console-api/references/web-mvc-flow.md @@ -0,0 +1,202 @@ +# Console API Web MVC Implementation + +This reference explains how dubbo-admin exposes backend HTTP APIs through Gin handlers, typed models, console services, resource managers, and stores. + +## End-to-end call chain + +```text +runtime.RegisterComponent(&consoleWebServer{}) + -> Bootstrap initializes consoleWebServer.Init + -> Init creates gin.Engine, middleware, static UI, health route + -> Runtime starts consoleWebServer.Start + -> Start creates consolectx.NewConsoleContext(coreRt) + -> router.InitRouter(c.Engine, c.cs) + -> HTTP request under /api/v1 + -> handler binds query/path/body + -> handler calls service function + -> service uses consolectx.Context and ctx.ResourceManager() + -> manager/store reads or writes resources + -> service returns typed model response + -> handler wraps with model.NewSuccessResp or util.Handle*Error +``` + +## Console component + +Key file: `pkg/console/component.go` + +Console is registered as a runtime component and depends on `runtime.ResourceManager`: + +```go +func init() { + runtime.RegisterComponent(&consoleWebServer{}) +} + +func (c *consoleWebServer) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{runtime.ResourceManager} +} +``` + +`Init` sets up Gin: + +- embedded admin UI mounted at `/admin` +- SPA fallback for `/admin/**` +- `/health` endpoint +- cookie session store +- auth middleware +- zap logging and recovery middleware +- Gin mode from config + +`Start` creates console context and registers `/api/v1` routes: + +```go +c.cs = consolectx.NewConsoleContext(coreRt) +router.InitRouter(c.Engine, c.cs) +httpServer := c.startHttpServer(errChan) +``` + +On stop, the HTTP server shuts down with `Shutdown(context.Background())`. + +## Auth behavior + +`authMiddleware` skips paths ending in `/login`. Other requests require a session value named `user`. Missing user returns HTTP 401 with `model.NewBizErrorResp`. + +This means many API handlers assume authentication already passed. + +## Console context + +Key file: `pkg/console/context/context.go` + +`consolectx.Context` wraps runtime access: + +```go +type Context interface { + ResourceManager() manager.ResourceManager + CounterManager() counter.CounterManager + Config() app.AdminConfig + AppContext() context.Context + LockManager() lock.Lock +} +``` + +`ResourceManager()` retrieves the runtime ResourceManager component and returns its manager: + +```go +rmc, _ := c.coreRt.GetComponent(runtime.ResourceManager) +return rmc.(manager.ResourceManagerComponent).ResourceManager() +``` + +CounterManager and LockManager are optional and may return nil. + +## Route registration + +Key file: `pkg/console/router/router.go` + +All Console API routes are grouped under `/api/v1`: + +```go +router := r.Group("/api/v1") +``` + +Common groups include: + +- `/auth` +- `/instance` +- `/application` +- `/service` +- `/configurator` +- `/condition-rule` +- `/tag-rule` +- global `/search`, `/overview`, `/metadata`, `/meshes` + +When adding an endpoint, register the route in the existing group that matches frontend URL structure. + +## Handler pattern + +Handlers usually close over `consolectx.Context` and return `gin.HandlerFunc`: + +```go +func GetApplicationDetail(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + req := &model.ApplicationDetailReq{} + if err := c.ShouldBindQuery(req); err != nil { + util.HandleArgumentError(c, err) + return + } + resp, err := service.GetApplicationDetail(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + } +} +``` + +Read endpoints commonly use `ShouldBindQuery`. Mutation endpoints commonly use `ShouldBindJSON` or path parameters depending on existing handler style. + +## Error and response model + +Key files: + +- `pkg/console/model/common.go` +- `pkg/console/util/error.go` + +Success response: + +```go +model.NewSuccessResp(data) +``` + +Service errors are normalized to `bizerror.Error` and returned with HTTP 200: + +```go +func HandleServiceError(ctx *gin.Context, err error) { + var e bizerror.Error + if !errors.As(err, &e) { + e = bizerror.New(bizerror.UnknownError, err.Error()) + } + ctx.JSON(http.StatusOK, model.NewBizErrorResp(e)) +} +``` + +Argument errors use `bizerror.InvalidArgument`. Auth middleware is an exception and returns HTTP 401. + +## Service layer + +Key directory: `pkg/console/service/` + +Services receive `consolectx.Context` and typed request models. They usually access resources through generic manager helpers or `ctx.ResourceManager()` directly. + +Typical resource query: + +```go +resources, err := manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + []index.IndexCondition{...}, +) +``` + +Do not put store/index details into handlers. Keep HTTP binding in handlers and resource logic in services. + +## Frontend contract + +Frontend API callers live under `ui-vue3/src/api/`. If a response field, request parameter, or endpoint path changes, check both Console model structs and frontend caller usage. + +## Common failure modes + +- Route registered under wrong group or duplicate service group block. +- Handler binds query when frontend sends JSON, or vice versa. +- Model tags do not match frontend parameter names. +- Service returns raw resource shape not expected by frontend view. +- Error returned directly instead of through `util.HandleServiceError`. +- Optional managers such as CounterManager or LockManager are nil. + +## Review checklist + +- Route path and HTTP method match frontend usage. +- Handler binding matches request source. +- Request/response models have correct tags and JSON field names. +- Service owns business logic and uses ResourceManager/store helpers. +- Response uses `CommonResp` consistently. +- Frontend API client is updated when contract changes. diff --git a/.agents/skills/dubbo-admin-discovery/SKILL.md b/.agents/skills/dubbo-admin-discovery/SKILL.md new file mode 100644 index 000000000..3181e0495 --- /dev/null +++ b/.agents/skills/dubbo-admin-discovery/SKILL.md @@ -0,0 +1,59 @@ +--- +name: dubbo-admin-discovery +description: Implements and reviews dubbo-admin registry discovery changes. Use when the user asks about Zookeeper or Nacos discovery, ListAndWatch, informers, discovery factories, discovery subscribers, ServiceProviderMetadata or ServiceConsumerMetadata processing, or Application, Service, RPCInstance, and Instance derivation under pkg/core/discovery/ and pkg/core/controller/. Do not use for engine-sourced RuntimeInstance behavior. +--- + +# dubbo-admin Discovery + +## Purpose + +Use this skill to trace registry-sourced resources from ListWatcher input through informer events, EventBus dispatch, subscribers, store writes, and derived mesh resources. + +## When to use + +Use for Zookeeper or Nacos registry flow, discovery ListWatchers, discovery subscribers, metadata-derived services, application instance counts, and registry event bugs. + +Do not use for Kubernetes runtime infrastructure engine flow; use `dubbo-admin-engine` for RuntimeInstance behavior. + +## Inputs + +Required: +- Registry type, resource kind, subscriber, or discovery package path. +- The event or resource transition being changed or debugged. + +Optional: +- Example registry metadata. +- Store query or index involved. +- Console API result affected by discovery data. + +If missing, start at `pkg/core/discovery/component.go` and identify the subscriber for the resource kind. + +## Workflow + +1. Read `pkg/core/discovery/component.go` for dependencies, informer creation, subscriber registration, and start behavior. +2. Inspect `pkg/core/controller/listwatcher.go` and `pkg/core/controller/informer.go`. +3. Follow registry-specific ListWatcher creation through `pkg/core/discovery/factory.go`. +4. Read the relevant subscriber under `pkg/core/discovery/subscriber/`. +5. Verify resource writes against store and index behavior. +6. Read `references/discovery-flow.md` for subscriber registration and event flow details. + +## Output format + +Return the resource flow, affected subscriber, store/index interactions, changed files, and validation commands or residual test gaps. + +## Validation + +- Confirm informer events emit the expected `cache.DeltaType`. +- Confirm subscriber `ResourceKind()` matches the event resource kind. +- Confirm derived resources use stable resource keys. +- Run targeted subscriber or controller tests; use `make test` for broad discovery changes. + +## Edge cases + +- Nacos and Zookeeper register extra subscribers conditionally. +- Delete events may need old objects and must not assume `NewObj()` exists. +- If dispatch semantics are the problem, switch to `dubbo-admin-events`. + +## References + +- Read `references/discovery-flow.md` for ListWatcher, informer, and subscriber details. diff --git a/.agents/skills/dubbo-admin-discovery/evals/evals.json b/.agents/skills/dubbo-admin-discovery/evals/evals.json new file mode 100644 index 000000000..1ca8c6894 --- /dev/null +++ b/.agents/skills/dubbo-admin-discovery/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-discovery", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Fix ServiceProviderMetadataEventSubscriber so Service resources update after provider metadata deletion.", + "expected_behavior": "Use discovery subscriber and informer event flow." + }, + { + "id": "paraphrased-trigger", + "prompt": "Nacos registry changes are not reflected in applications shown by dubbo-admin.", + "expected_behavior": "Trace registry ListWatcher, informer events, subscribers, and store writes." + }, + { + "id": "file-based-trigger", + "prompt": "Review pkg/core/discovery/component.go and pkg/core/discovery/subscriber/service_consumer_metadata.go.", + "expected_behavior": "Use this skill because discovery orchestration and subscribers are touched." + }, + { + "id": "no-trigger", + "prompt": "Change how EventBus handles subscriber errors for all domains.", + "expected_behavior": "Do not use this skill as primary; use dubbo-admin-events." + }, + { + "id": "conflict-trigger", + "prompt": "A RuntimeInstance from Kubernetes is not merged into an Instance resource.", + "expected_behavior": "Use dubbo-admin-engine, not discovery, because RuntimeInstance is engine-sourced." + } + ] +} diff --git a/.agents/skills/dubbo-admin-discovery/references/discovery-flow.md b/.agents/skills/dubbo-admin-discovery/references/discovery-flow.md new file mode 100644 index 000000000..c6ea9fc9e --- /dev/null +++ b/.agents/skills/dubbo-admin-discovery/references/discovery-flow.md @@ -0,0 +1,304 @@ +# Discovery Implementation Flow + +This reference explains how registry-sourced discovery is implemented in dubbo-admin. Read it when changing `pkg/core/discovery/`, `pkg/core/controller/`, or discovery subscribers. + +## End-to-end call chain + +```text +runtime.RegisterComponent(newDiscoveryComponent) + -> Bootstrap initializes discoveryComponent.Init + -> Init gets EventBus and ResourceStore from BuilderContext + -> Init loops ctx.Config().Discovery + -> initInformers(cfg, storeRouter, eventBus) + -> initSubscribes(storeRouter, eventBus, ctx.Config().Engine) + -> Start + -> startBusinessLogic + -> EventBus.Subscribe(discovery subscribers) + -> informer.Run(stopCh) + -> cache.Controller ListAndWatch + -> DeltaFIFO Process: informer.HandleDeltas + -> store Add/Update/Delete + -> informer.EmitEvent + -> EventBus.Send + -> subscriber.ProcessEvent + -> derived resources are written and follow-up events may be emitted +``` + +## Component registration and dependencies + +Key file: `pkg/core/discovery/component.go` + +Discovery is registered as a runtime component: + +```go +func init() { + runtime.RegisterComponent(newDiscoveryComponent()) +} +``` + +Its required dependencies are explicit: + +```go +func (d *discoveryComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.EventBus, + runtime.ResourceStore, + } +} +``` + +`Init` retrieves the activated EventBus and ResourceStore, then builds informers and subscribers: + +```go +eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) +eventBus, ok := eventBusComponent.(events.EventBus) +d.subscriptionMgr = eventBus + +storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) +storeRouter, ok := storeComponent.(store.Router) + +d.configs = ctx.Config().Discovery +for _, cfg := range d.configs { + informers, err := d.initInformers(cfg, storeRouter, eventBus) + d.informers[cfg.ID] = informers +} + +err = d.initSubscribes(storeRouter, eventBus, ctx.Config().Engine) +``` + +Memory store skips leader election. Non-memory stores may initialize leader election so only the leader runs discovery business logic. + +## Factory and ListWatcher implementation + +Key files: + +- `pkg/core/discovery/factory.go` +- `pkg/core/controller/listwatcher.go` + +The factory registry chooses an implementation by discovery type: + +```go +type Factory interface { + Support(discovery.Type) bool + NewListWatchers(config *discovery.Config) ([]controller.ResourceListerWatcher, error) +} +``` + +Each discovery ListWatcher must expose the resource kind it produces: + +```go +type ResourceListerWatcher interface { + cache.ListerWatcher + ResourceKind() coremodel.ResourceKind + TransformFunc() cache.TransformFunc +} +``` + +`ResourceKind()` determines the backing store route used by the informer. `TransformFunc()` exists in the interface, but discovery's current `initInformers` does not call `informer.SetTransform(lw.TransformFunc())`; do not rely on discovery transforms without checking or changing that behavior. + +## Informer creation + +Key function: `(*discoveryComponent).initInformers` + +```go +factory, err := ListWatcherFactoryRegistry().GetListWatcherFactory(cfg.Type) +lwList, err := factory.NewListWatchers(cfg) + +for i, lw := range lwList { + resourceStore, err := storeRouter.ResourceKindRoute(lw.ResourceKind()) + informer := controller.NewInformerWithOptions( + lw, + eventBus, + resourceStore, + keyFunc, + controller.Options{ResyncPeriod: 0}, + ) + informers[i] = informer +} +``` + +Discovery uses `keyFunc` from `component.go`, which requires objects to implement `coremodel.Resource` and returns `r.ResourceKey()`. + +## Start and leader election + +Key functions: + +- `(*discoveryComponent).Start` +- `(*discoveryComponent).startBusinessLogic` + +If leader election is not needed, `Start` immediately calls `startBusinessLogic(ch)`. If leader election is needed, business logic runs only inside `onStartLeading`, using a leadership-specific stop channel. `onStopLeading` closes that channel so informer goroutines exit for the lost leadership term. + +Business logic registers subscribers once and starts informers: + +```go +if !d.subscribed.Load() { + for _, sub := range d.subscribers { + err := d.subscriptionMgr.Subscribe(sub) + } + d.subscribed.Store(true) +} + +for name, informers := range d.informers { + for _, informer := range informers { + go informer.Run(stopCh) + } +} +``` + +## Informer DeltaFIFO processing + +Key file: `pkg/core/controller/informer.go` + +`Run` builds a Kubernetes `DeltaFIFO` and `cache.Controller`: + +```go +fifo := cache.NewDeltaFIFOWithOptions(cache.DeltaFIFOOptions{ + KnownObjects: s.indexer, + EmitDeltaTypeReplaced: true, + Transformer: s.transform, + KeyFunction: s.keyFunc, +}) + +cfg := &cache.Config{ + Queue: fifo, + ListerWatcher: s.listerWatcher, + Process: s.HandleDeltas, +} + +s.controller = cache.New(cfg) +s.controller.Run(stopCh) +``` + +`HandleDeltas` updates the store and emits normalized events: + +```go +case cache.Sync, cache.Replaced, cache.Added, cache.Updated: + if old, exists, err := s.indexer.Get(resource); err == nil && exists { + s.indexer.Update(resource) + s.EmitEvent(cache.Updated, old.(model.Resource), resource) + } else { + s.indexer.Add(resource) + s.EmitEvent(cache.Added, nil, resource) + } + +case cache.Deleted: + s.indexer.Delete(resource) + s.EmitEvent(cache.Deleted, resource, nil) +``` + +Subscribers receive event types based on store existence, not only raw watch delta type. Delete handling supports `cache.DeletedFinalStateUnknown` tombstones in `toResource`. + +## Event emission + +Key function: `(*informer).EmitEvent` + +```go +func (s *informer) EmitEvent(typ cache.DeltaType, oldObj model.Resource, newObj model.Resource) { + event := events.NewResourceChangedEvent(typ, oldObj, newObj) + s.emitter.Send(event) +} +``` + +Discovery relies on EventBus dispatch by resource kind. For delete events, `newObj` is nil and EventBus must route by `oldObj`. + +## Subscriber registration + +Key function: `(*discoveryComponent).initSubscribes` + +Base subscribers are always registered: + +```go +rpcInstanceSub := subscriber.NewRPCInstanceEventSubscriber(instanceStore, rtInstanceStore, emitter, engineConfig) +serviceConsumerMetadataSub := subscriber.NewServiceConsumerMetadataEventSubscriber(appStore, emitter) +serviceProviderMetadataSub := subscriber.NewServiceProviderMetadataEventSubscriber( + appStore, serviceStore, serviceProviderMetadataStore, emitter) +instanceSub := subscriber.NewInstanceEventSubscriber(appStore, instanceStore, emitter) +d.subscribers = append(d.subscribers, rpcInstanceSub, serviceConsumerMetadataSub, serviceProviderMetadataSub, instanceSub) +``` + +Conditional subscribers: + +```go +if hasNacosDiscovery { + d.subscribers = append(d.subscribers, subscriber.NewNacosServiceEventSubscriber(emitter, storeRouter)) +} + +if hasZkDiscovery { + d.subscribers = append(d.subscribers, + subscriber.NewZKMetadataEventSubscriber(emitter, storeRouter), + subscriber.NewZKConfigEventSubscriber(emitter, storeRouter)) +} +``` + +## Provider metadata subscriber + +Key file: `pkg/core/discovery/subscriber/service_provider_metadata.go` + +Identity: + +```go +func (s *ServiceProviderMetadataEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.ServiceProviderMetadataKind +} + +func (s *ServiceProviderMetadataEventSubscriber) Name() string { + return "Discovery-" + s.ResourceKind().ToString() +} +``` + +Event handling: + +- Add, replace, sync: require `newObj`, call `processUpsert`. +- Update: require `newObj`, call `processUpdate`. +- Delete: require `oldObj`, call `processDelete`. + +Upsert and update validate `Spec`, ensure the provider application exists, then sync the derived Service resource. Delete validates `Spec` and syncs the derived Service after provider metadata has already been removed from the store. + +`ensureApplication` creates an `ApplicationResource` when `Spec.ProviderAppName` is present and missing, then emits an Application added event. + +`syncService` derives a `ServiceResource` from all provider metadata with the same service identity: + +```go +serviceKey := meshresource.BuildServiceIdentityKey(serviceName, version, group) +resources, err := s.providerStore.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderServiceKey, Value: serviceKey, Operator: index.Equals}, +}) +``` + +Behavior: + +- No providers and no Service: do nothing. +- No providers and Service exists: delete Service and emit Service deleted event. +- Providers remain and Service does not exist: add Service and emit Service added event. +- Providers remain and Service exists: update Service and emit Service updated event. + +`buildServiceSpec` aggregates unique method names, sorts them, and sets language from the first provider where language can be inferred. Language inference priority is explicit `parameters["language"]`, dubbo-go release prefix, then Java type hints in method signatures or exported type definitions. + +## Consumer metadata subscriber + +Key file: `pkg/core/discovery/subscriber/service_consumer_metadata.go` + +Event handling: + +- Add, update, replace, sync: require `newObj`, call `processUpsert`. +- Delete: ignored with a warning. + +`processUpsert` creates an `ApplicationResource` for `Spec.ConsumerAppName` if it is non-blank and missing, then emits an Application added event. + +## Common failure modes + +- Missing EventBus or ResourceStore activated component means runtime dependency setup is wrong. +- Unsupported discovery type means no factory registered with `Support(type) == true`. +- Missing store route for a ListWatcher resource kind prevents informer creation. +- Subscriber type assertions fail if informer emits the wrong resource type. +- Delete logic fails when old object is nil. +- Provider Service derivation depends on `ByMeshIndex` and `ByServiceProviderServiceKey`. + +## Review checklist + +- Confirm the ListWatcher `ResourceKind()` matches the store route and subscriber `ResourceKind()`. +- Confirm informer key function matches transformed resource keys if transforms are introduced. +- Confirm event type semantics after `HandleDeltas`, not just raw watch delta semantics. +- Confirm follow-up events are emitted when subscribers create, update, or delete derived resources. +- Confirm store indexes exist for every `ListByIndexes` query used by subscriber logic. diff --git a/.agents/skills/dubbo-admin-domain/SKILL.md b/.agents/skills/dubbo-admin-domain/SKILL.md new file mode 100644 index 000000000..ff66e6616 --- /dev/null +++ b/.agents/skills/dubbo-admin-domain/SKILL.md @@ -0,0 +1,54 @@ +--- +name: dubbo-admin-domain +description: Routes dubbo-admin architecture questions to the right domain skill. Use for cross-module questions, end-to-end flows, subsystem boundaries, or deciding whether runtime, discovery, engine, events, store, Console API, or frontend guidance applies. Prefer a narrower dubbo-admin-* skill when the request clearly targets one subsystem. +--- + +# dubbo-admin Domain Guide + +## Purpose + +Use this skill to choose the right dubbo-admin domain workflow and avoid mixing registry discovery, runtime engine, EventBus, store, API, and frontend responsibilities. + +## When to use + +Use for cross-module architecture, end-to-end data flow, skill selection, or issue triage that spans multiple subsystems. + +Do not use when a request clearly targets one subsystem; load the narrower skill directly. + +## Inputs + +Required: +- User goal, issue, file path, or subsystem name. + +Optional: +- Stack trace, API path, frontend route, resource kind, or event type. + +If missing, inspect top-level paths and identify the first concrete subsystem before loading a narrower skill. + +## Workflow + +1. Classify the request by primary subsystem. +2. Select one narrow skill when possible. +3. If the request spans multiple domains, order them by data flow: runtime/discovery or engine, events, store, manager, Console API, frontend. +4. Read `references/architecture-map.md` when the boundary is unclear. +5. Avoid loading unrelated domain skills. + +## Output format + +Return selected skill or skills, why they apply, which paths to inspect first, and any boundary assumptions. + +## Validation + +- Confirm selected skill owns the code path being changed. +- Confirm cross-domain changes name both producer and consumer of data. +- If two skills overlap, state which one controls the contract. + +## Edge cases + +- Registry discovery and runtime engine both use informers but source different data. +- EventBus dispatch is shared infrastructure; use `dubbo-admin-events` when dispatch behavior changes. +- Store indexes are shared; use `dubbo-admin-store` when query behavior changes. + +## References + +- Read `references/architecture-map.md` for subsystem ownership and end-to-end flow. diff --git a/.agents/skills/dubbo-admin-domain/evals/evals.json b/.agents/skills/dubbo-admin-domain/evals/evals.json new file mode 100644 index 000000000..47d399f8a --- /dev/null +++ b/.agents/skills/dubbo-admin-domain/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-domain", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Explain the end-to-end dubbo-admin data flow from registry data to Vue pages.", + "expected_behavior": "Use domain routing and name relevant subskills in data-flow order." + }, + { + "id": "paraphrased-trigger", + "prompt": "I am not sure whether this bug belongs to discovery, store, API, or frontend. Help classify it.", + "expected_behavior": "Use this skill to choose subsystem ownership." + }, + { + "id": "file-based-trigger", + "prompt": "A change touches pkg/core/discovery, pkg/core/store, pkg/console, and ui-vue3. How should I review it?", + "expected_behavior": "Use this skill to sequence multiple domain skills." + }, + { + "id": "no-trigger", + "prompt": "Only update pkg/store/memory/store.go prefix lookup logic.", + "expected_behavior": "Do not stay in domain skill; use dubbo-admin-store." + }, + { + "id": "conflict-trigger", + "prompt": "Both discovery and engine use informers. Which skill applies to a Kubernetes RuntimeInstance bug?", + "expected_behavior": "Choose dubbo-admin-engine and explain the boundary." + } + ] +} diff --git a/.agents/skills/dubbo-admin-domain/references/architecture-map.md b/.agents/skills/dubbo-admin-domain/references/architecture-map.md new file mode 100644 index 000000000..c474dfbe0 --- /dev/null +++ b/.agents/skills/dubbo-admin-domain/references/architecture-map.md @@ -0,0 +1,104 @@ +# dubbo-admin Architecture Map + +Use this reference when a task crosses subsystem boundaries or when choosing which narrower `dubbo-admin-*` skill to use. + +## End-to-end runtime flow + +Dubbo Admin is built from runtime components. Startup flows through `pkg/core/bootstrap` and `pkg/core/runtime`: + +```text +main/app -> bootstrap -> runtime builder -> component graph -> Init() -> Start() +``` + +Most backend subsystems register themselves during package init and are then ordered by runtime dependencies. Component-level questions belong to `dubbo-admin-runtime`. + +## Data production paths + +There are two main resource producers: + +```text +Registry metadata + -> discovery component + -> registry ListWatcher (Zookeeper/Nacos) + -> controller Informer + -> ResourceStore write + -> EventBus resource-change event + -> discovery subscribers + -> derived Application/Service/RPCInstance/Instance resources + +Runtime infrastructure + -> engine component + -> engine ListWatcher (Kubernetes/mock) + -> controller Informer + -> ResourceStore write + -> EventBus resource-change event + -> RuntimeInstanceEventSubscriber + -> Instance runtime-source merge +``` + +Use discovery for provider/consumer metadata, registry applications, registry instances, and registry-derived services. Use engine for Kubernetes or other runtime infrastructure, `RuntimeInstance`, leader election in engine sources, and runtime-source merging into `Instance`. + +## Event and storage path + +All informer-produced resource changes are dispatched through `pkg/core/events`: + +```text +Informer.HandleDeltas() + -> ResourceStore.Add/Update/Delete + -> NewResourceChangedEvent(oldObj, newObj) + -> EventBus.Send(event) + -> subscribers for ResourceKind +``` + +Storage is handled through `pkg/core/store` and concrete stores under `pkg/store/`: + +```text +ResourceStore component -> store router -> ResourceKindRoute(kind) -> memory/indexed store +``` + +Use `dubbo-admin-events` for dispatch contract changes. Use `dubbo-admin-store` for `ResourceStore`, index registration, `ListByIndexes`, `PageListByIndexes`, prefix lookup, or persistence behavior. + +## Console API and frontend path + +Console HTTP behavior is layered: + +```text +Gin route -> handler -> console service/manager -> ResourceManager/store -> CommonResp JSON +``` + +Frontend behavior is layered: + +```text +Vue view -> api/service wrapper -> base/http/request.ts -> /api/v1 -> Console API +``` + +Use `dubbo-admin-console-api` when changing routes, handlers, request/response models, service managers, pagination contracts, or error responses. Use `dubbo-admin-frontend` when changing Vue routes, tab metadata, API wrappers, Pinia state, topology rendering, or traffic rule form/YAML behavior. + +## Skill selection table + +| Task | Use skill | +| --- | --- | +| Component lifecycle, dependencies, startup/shutdown | `dubbo-admin-runtime` | +| Zookeeper/Nacos discovery, provider/consumer metadata, derived resources | `dubbo-admin-discovery` | +| Kubernetes/mock runtime discovery, `RuntimeInstance`, runtime-source instance merge | `dubbo-admin-engine` | +| `EventBus`, `Emitter`, `Subscriber`, `Subscribe`, `Send`, dispatch ordering | `dubbo-admin-events` | +| Store APIs, memory store, indexes, pagination, radix prefix lookup | `dubbo-admin-store` | +| Gin routes, handlers, console services, response JSON | `dubbo-admin-console-api` | +| Vue routes, components, API clients, traffic forms, topology tabs | `dubbo-admin-frontend` | + +## Common boundary cases + +- A new backend list endpoint usually needs `console-api` plus `store` if it requires indexes. +- A new graph or topology feature usually needs `console-api`, `store`, and `frontend`; add `discovery` only if new derived resources are needed. +- A registry event subscriber belongs to `discovery` unless it changes EventBus contracts. +- A Kubernetes Pod-to-resource transform belongs to `engine`, not `discovery`. +- If a change introduces a component dependency or startup ordering issue, include `runtime` even when the feature domain is elsewhere. + +## Review sequence for cross-module changes + +1. Identify the source resource kind and producer: discovery, engine, or manual Console API write. +2. Check whether storage needs a new kind, route, or index. +3. Check whether events or subscribers derive additional resources. +4. Verify Console API payloads match frontend expectations. +5. Verify frontend request wrappers, tab routes, and state handling. +6. Run the smallest tests for each touched layer, then broader Go/frontend checks. diff --git a/.agents/skills/dubbo-admin-engine/SKILL.md b/.agents/skills/dubbo-admin-engine/SKILL.md new file mode 100644 index 000000000..8cde1ae18 --- /dev/null +++ b/.agents/skills/dubbo-admin-engine/SKILL.md @@ -0,0 +1,59 @@ +--- +name: dubbo-admin-engine +description: Implements and reviews dubbo-admin resource engine changes. Use when the user asks about runtime infrastructure discovery, engine factories, Kubernetes or mock engine ListWatchers, RuntimeInstance informers, RuntimeInstanceEventSubscriber, engine leader election, or merging RuntimeInstance data into Instance resources under pkg/core/engine/ and pkg/engine/. Do not use for registry discovery unless the task concerns engine-sourced RuntimeInstance resources. +--- + +# dubbo-admin Engine + +## Purpose + +Use this skill to trace runtime infrastructure data from engine ListWatchers through RuntimeInstance events into Instance resource lifecycle changes. + +## When to use + +Use for engine component lifecycle, engine factory support, Kubernetes runtime instance watching, leader election for engine logic, and RuntimeInstance to Instance merge or delete behavior. + +Do not use for registry metadata discovery; use `dubbo-admin-discovery`. + +## Inputs + +Required: +- Engine type, RuntimeInstance behavior, or engine package path. +- Intended runtime to instance transition. + +Optional: +- RuntimeInstance sample. +- Existing Instance resource state. +- Store indexes used to find related instances. + +If missing, inspect `pkg/core/engine/component.go` and then the relevant factory under `pkg/engine/`. + +## Workflow + +1. Read `pkg/core/engine/component.go` for dependencies, config, informers, subscribers, and start behavior. +2. Check `pkg/core/engine/factory.go` before adding or changing engine types. +3. Inspect implementation factories under `pkg/engine/`. +4. Follow RuntimeInstance ListWatcher output into `pkg/core/controller/informer.go`. +5. Read `pkg/core/engine/subscriber/runtime_instance.go` before changing Instance merge or delete behavior. +6. Read `references/runtime-engine-flow.md` for leader election and merge details. + +## Output format + +Return the engine flow, affected RuntimeInstance transition, store/index interactions, changed files, and validation plan. + +## Validation + +- Confirm engine depends on EventBus and ResourceStore. +- Confirm non-memory stores only run business logic under leader election. +- Confirm RuntimeInstance upsert and delete preserve RPC-sourced Instance state correctly. +- Use `make test` for changes touching informer events or Instance lifecycle. + +## Edge cases + +- Runtime-only instances require enough identity fields. +- Runtime delete should update an Instance when RPC source remains, but delete it when no source remains. +- If the EventBus dispatch contract changes, switch to `dubbo-admin-events`. + +## References + +- Read `references/runtime-engine-flow.md` for engine startup and RuntimeInstance handling. diff --git a/.agents/skills/dubbo-admin-engine/evals/evals.json b/.agents/skills/dubbo-admin-engine/evals/evals.json new file mode 100644 index 000000000..c1d71dc33 --- /dev/null +++ b/.agents/skills/dubbo-admin-engine/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-engine", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Update RuntimeInstanceEventSubscriber so runtime-only instances are deleted correctly.", + "expected_behavior": "Use engine subscriber and RuntimeInstance to Instance lifecycle workflow." + }, + { + "id": "paraphrased-trigger", + "prompt": "Kubernetes pod runtime metadata is not being merged into dubbo-admin Instance resources.", + "expected_behavior": "Trace engine ListWatchers, RuntimeInstance events, and merge logic." + }, + { + "id": "file-based-trigger", + "prompt": "Review pkg/core/engine/component.go and pkg/engine/kubernetes/listerwatcher/runtime_instance.go.", + "expected_behavior": "Use this skill because engine component and engine ListWatcher files are touched." + }, + { + "id": "no-trigger", + "prompt": "Provider metadata from Zookeeper is missing method names.", + "expected_behavior": "Do not use this skill; use dubbo-admin-discovery." + }, + { + "id": "conflict-trigger", + "prompt": "An Instance resource is wrong after both registry and Kubernetes events arrive.", + "expected_behavior": "Use engine for RuntimeInstance merge and coordinate with discovery for RPC source state." + } + ] +} diff --git a/.agents/skills/dubbo-admin-engine/references/runtime-engine-flow.md b/.agents/skills/dubbo-admin-engine/references/runtime-engine-flow.md new file mode 100644 index 000000000..51807312e --- /dev/null +++ b/.agents/skills/dubbo-admin-engine/references/runtime-engine-flow.md @@ -0,0 +1,230 @@ +# Resource Engine Implementation Flow + +This reference explains how dubbo-admin watches runtime infrastructure, converts it to RuntimeInstance resources, and merges runtime state into Instance resources. + +## End-to-end call chain + +```text +runtime.RegisterComponent(newEngineComponent) + -> Bootstrap initializes engineComponent.Init + -> Init gets EventBus and ResourceStore + -> initInformers(cfg, eventBus) + -> FactoryRegistry().GetListWatcherFactory(cfg.Type) + -> factory.NewListWatchers(cfg) + -> controller.NewInformerWithOptions(lw, eventBus, store, resolveInformerKeyFunc(lw), ...) + -> initSubscribers(eventBus) + -> Start + -> startBusinessLogic or leader-gated startBusinessLogic + -> EventBus.Subscribe(RuntimeInstanceEventSubscriber) + -> informer.Run(stopCh) + -> RuntimeInstance events + -> RuntimeInstanceEventSubscriber.ProcessEvent + -> Instance resource created, updated, or deleted + -> follow-up Instance event emitted +``` + +## Engine component + +Key file: `pkg/core/engine/component.go` + +The engine component registers itself as `runtime.ResourceEngine` and depends on EventBus and ResourceStore: + +```go +func (e *engineComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{runtime.EventBus, runtime.ResourceStore} +} +``` + +During `Init`, it loads engine config, gets EventBus, casts ResourceStore to `store.Router`, initializes informers, initializes subscribers, and may configure leader election for non-memory stores. + +```go +cfg := ctx.Config().Engine +e.name = cfg.ID + +eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) +eventBus, ok := eventBusComponent.(events.EventBus) +e.subscriptionManager = eventBus + +storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) +storeRouter, ok := storeComponent.(store.Router) +e.storeRouter = storeRouter + +e.initInformers(cfg, eventBus) +e.initSubscribers(eventBus) +``` + +## Factory and Kubernetes ListWatcher + +Key files: + +- `pkg/core/engine/factory.go` +- `pkg/engine/kubernetes/factory.go` +- `pkg/engine/kubernetes/listerwatcher/runtime_instance.go` + +Engine factories create `controller.ResourceListerWatcher` instances from engine config: + +```go +type Factory interface { + Support(enginecfg.Type) bool + NewListWatchers(*enginecfg.Config) ([]controller.ResourceListerWatcher, error) +} +``` + +Kubernetes factory supports `enginecfg.Kubernetes`, builds either kubeconfig or in-cluster config, creates a Kubernetes clientset, then creates a Pod ListWatcher: + +```go +if !strutil.IsBlank(kubeconfigPath) { + config, err = clientcmd.BuildConfigFromFlags("", kubeconfigPath) +} else { + config, err = rest.InClusterConfig() +} +clientset, err := kubernetes.NewForConfig(config) +podListerWatcher, err := listerwatcher.NewPodListWatcher(clientset, cfg) +``` + +## Pod to RuntimeInstance transform + +`PodListerWatcher` produces `meshresource.RuntimeInstanceKind`: + +```go +func (p *PodListerWatcher) ResourceKind() coremodel.ResourceKind { + return meshresource.RuntimeInstanceKind +} +``` + +Its `TransformFunc` converts Kubernetes Pod objects to `RuntimeInstanceResource`. Key extracted fields include: + +- pod name and pod IP +- Dubbo app name from configured annotation or label +- RPC port from configured annotation or label +- mesh/discovery identifier from configured annotation or label +- image, node, workload name and type +- create, start, ready timestamps +- probe ports and pod conditions +- derived phase: starting, running, terminating, crashing, failed, succeeded, unknown + +Important output: + +```go +res := meshresource.NewRuntimeInstanceResourceWithAttributes(pod.Name, p.getDubboMesh(pod)) +res.Spec = &meshproto.RuntimeInstance{ + Name: pod.Name, + Ip: pod.Status.PodIP, + RpcPort: rpcPort, + AppName: appName, + SourceEngine: p.cfg.ID, + SourceEngineType: string(p.cfg.Type), +} +``` + +`PodListerWatcher` also implements `ResourceKeyProvider`. Its `KeyFunc` returns the same key as the transformed RuntimeInstance resource, including tombstone support for delete events. + +## Engine informer creation + +`initInformers` differs from discovery in two important ways: + +1. It uses `resolveInformerKeyFunc(lw)` so a ListWatcher can provide a custom key function. +2. It applies `lw.TransformFunc()` to the informer when present. + +```go +informer := controller.NewInformerWithOptions(lw, emitter, rs, resolveInformerKeyFunc(lw), controller.Options{ResyncPeriod: 0}) +if lw.TransformFunc() != nil { + err = informer.SetTransform(lw.TransformFunc()) +} +``` + +This is necessary for Kubernetes Pods because the raw watch object is a Pod, but the stored resource is RuntimeInstance. + +## Start and leader election + +Memory store starts business logic directly. Non-memory stores may run leader election so only the leader starts informers. On leadership loss, the leader-specific stop channel is closed and informer goroutines exit. + +`startBusinessLogic` subscribes engine subscribers once, then starts informers: + +```go +if !e.subscribed.Load() { + for _, sub := range e.subscribers { + e.subscriptionManager.Subscribe(sub) + } + e.subscribed.Store(true) +} +for _, informer := range e.informers { + go informer.Run(stopCh) +} +``` + +## RuntimeInstance subscriber + +Key file: `pkg/core/engine/subscriber/runtime_instance.go` + +The subscriber listens to `meshresource.RuntimeInstanceKind`: + +```go +func (s *RuntimeInstanceEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.RuntimeInstanceKind +} +``` + +Event handling: + +- Added, updated, replaced, sync: require `newObj`, call `processUpsert`. +- Deleted: require `oldObj`, call `processDelete`. + +### Upsert behavior + +`processUpsert` first finds a related Instance. For Kubernetes runtime instances, lookup prefers full runtime identity, then name, then IP. + +If an Instance exists, runtime fields are merged into it: + +```go +meshresource.MergeRuntimeInstanceIntoInstance(rtInstanceRes, instanceResource) +s.instanceStore.Update(instanceResource) +``` + +If no Instance exists, the subscriber creates a runtime-only Instance only when identity is complete: + +```go +if !checkAttributesEnough(rtInstanceRes) { + return nil +} +instanceRes := meshresource.FromRuntimeInstance(rtInstanceRes) +s.instanceStore.Add(instanceRes) +s.eventEmitter.Send(events.NewResourceChangedEvent(cache.Added, nil, instanceRes)) +``` + +`checkAttributesEnough` requires app name, IP, positive RPC port, non-empty mesh, and mesh not equal to the default mesh. + +### Delete behavior + +`processDelete` clears runtime source from the related Instance: + +- If RPC source remains, update the Instance and emit an Instance updated event. +- If no RPC source remains, delete the Instance and emit an Instance deleted event. + +```go +meshresource.ClearRuntimeInstanceFromInstance(instanceResource) +if meshresource.HasRPCInstanceSource(instanceResource) { + s.instanceStore.Update(instanceResource) + s.eventEmitter.Send(events.NewResourceChangedEvent(cache.Updated, instanceResource, instanceResource)) + return nil +} +s.instanceStore.Delete(instanceResource) +s.eventEmitter.Send(events.NewResourceChangedEvent(cache.Deleted, instanceResource, nil)) +``` + +## Common failure modes + +- Kubernetes config cannot be built from kubeconfig or in-cluster config. +- Pod selector is invalid. +- Pod transform cannot identify app name, RPC port, or mesh. +- RuntimeInstance identity is incomplete, so runtime-only Instance creation is skipped. +- Duplicate Instance matches by name or IP cause subscriber to skip ambiguous merge. +- EventBus dispatch issues should be debugged with `dubbo-admin-events`. + +## Review checklist + +- Confirm ListWatcher `ResourceKind()` is `RuntimeInstanceKind`. +- Confirm raw Pod keys and transformed RuntimeInstance keys are consistent via `KeyFunc`. +- Confirm transform is set before informer starts. +- Confirm runtime-only Instance creation does not happen for default mesh or incomplete identity. +- Confirm delete keeps RPC-sourced Instances and removes only runtime source. diff --git a/.agents/skills/dubbo-admin-events/SKILL.md b/.agents/skills/dubbo-admin-events/SKILL.md new file mode 100644 index 000000000..4dc8352ad --- /dev/null +++ b/.agents/skills/dubbo-admin-events/SKILL.md @@ -0,0 +1,58 @@ +--- +name: dubbo-admin-events +description: Implements and reviews dubbo-admin EventBus dispatching. Use when the user asks about Event, Emitter, Subscriber, SubscriptionManager, EventBus component registration, Subscribe or Unsubscribe behavior, Send dispatch rules, subscriber ProcessEvent flow, resource-kind based routing, or event error handling under pkg/core/events/. Do not use for a domain subscriber unless the task changes the event bus contract or dispatch semantics. +--- + +# dubbo-admin Events + +## Purpose + +Use this skill to modify or explain the shared EventBus contract used by discovery, engine, informers, and subscribers. + +## When to use + +Use for EventBus interfaces, resource-kind dispatching, subscriber registration uniqueness, synchronous processing, and event dispatch error behavior. + +Do not use for business logic inside a single subscriber unless EventBus semantics change. + +## Inputs + +Required: +- EventBus behavior, interface, or dispatch problem. +- Event producer or subscriber involved. + +Optional: +- Event type. +- Old and new resource objects. +- Subscriber names for the same resource kind. + +If missing, inspect `pkg/core/events/eventbus.go` and `pkg/core/events/component.go` first. + +## Workflow + +1. Read `pkg/core/events/eventbus.go` for Event, Emitter, Subscriber, SubscriptionManager, and EventBus interfaces. +2. Read `pkg/core/events/component.go` for the concrete EventBus implementation. +3. Trace producers that call `events.NewResourceChangedEvent` and `Emitter.Send`. +4. Trace consumers implementing `ResourceKind`, `Name`, and `ProcessEvent`. +5. Read `references/eventbus-dispatch.md` before changing dispatch semantics. + +## Output format + +Return event source, resource kind, subscribers called, error behavior, changed files, and validation evidence. + +## Validation + +- Confirm `Send` uses `NewObj()` first and `OldObj()` for delete-like events. +- Confirm subscriber names are unique per resource kind. +- Confirm subscriber errors are logged and do not stop later subscribers. +- Run tests or targeted reasoning for discovery and engine consumers when dispatch changes. + +## Edge cases + +- Events with both old and new nil cannot be routed. +- Dispatch is synchronous; long subscriber work blocks the caller. +- EventBus should stay domain-neutral; put business logic in subscribers. + +## References + +- Read `references/eventbus-dispatch.md` for concrete dispatch rules and failure behavior. diff --git a/.agents/skills/dubbo-admin-events/evals/evals.json b/.agents/skills/dubbo-admin-events/evals/evals.json new file mode 100644 index 000000000..5b5d07ed3 --- /dev/null +++ b/.agents/skills/dubbo-admin-events/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-events", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Change EventBus.Send so subscriber errors stop later subscribers.", + "expected_behavior": "Use EventBus dispatch workflow and validate global impact." + }, + { + "id": "paraphrased-trigger", + "prompt": "Events are routed to the wrong subscribers when NewObj is nil.", + "expected_behavior": "Inspect Send resource-kind routing with OldObj fallback." + }, + { + "id": "file-based-trigger", + "prompt": "Review pkg/core/events/component.go and pkg/core/events/eventbus.go.", + "expected_behavior": "Use this skill because EventBus implementation files are touched." + }, + { + "id": "no-trigger", + "prompt": "Modify only ServiceProviderMetadataEventSubscriber aggregation logic.", + "expected_behavior": "Do not use this skill as primary unless EventBus dispatch changes." + }, + { + "id": "conflict-trigger", + "prompt": "A discovery subscriber does not run after informer emits an event.", + "expected_behavior": "Use this skill if dispatch or subscription is suspect; otherwise use discovery." + } + ] +} diff --git a/.agents/skills/dubbo-admin-events/references/eventbus-dispatch.md b/.agents/skills/dubbo-admin-events/references/eventbus-dispatch.md new file mode 100644 index 000000000..dbd232a35 --- /dev/null +++ b/.agents/skills/dubbo-admin-events/references/eventbus-dispatch.md @@ -0,0 +1,182 @@ +# EventBus Dispatch Implementation + +This reference explains the shared EventBus used by discovery, engine, informers, and subscribers. + +## End-to-end call chain + +```text +runtime.RegisterComponent(&eventBus{}) + -> Bootstrap initializes eventBus.Init + -> eventBus.subscriberDir = map[ResourceKind]Subscribers + -> discovery/engine startBusinessLogic calls Subscribe(subscriber) + -> informer or subscriber creates ResourceChangedEvent + -> Emitter.Send(event) + -> eventBus.Send derives ResourceKind + -> eventBus finds subscribers for that kind + -> each subscriber.ProcessEvent(event) runs synchronously + -> errors are logged and dispatch continues +``` + +## Interfaces + +Key file: `pkg/core/events/eventbus.go` + +```go +type Event interface { + Type() cache.DeltaType + OldObj() model.Resource + NewObj() model.Resource + Context() map[string]string + String() string +} + +type Subscriber interface { + ResourceKind() model.ResourceKind + Name() string + ProcessEvent(event Event) error +} + +type Emitter interface { + Send(event Event) +} + +type SubscriptionManager interface { + Subscribe(subscriber Subscriber) error + Unsubscribe(subscriber Subscriber) error +} + +type EventBus interface { + Emitter + SubscriptionManager +} +``` + +`ResourceChangedEvent` stores delta type, old object, new object, and optional context. Informers usually create it with `events.NewResourceChangedEvent`. + +## Component registration + +Key file: `pkg/core/events/component.go` + +```go +func init() { + runtime.RegisterComponent(&eventBus{}) +} +``` + +`eventBus` is a runtime component of type `runtime.EventBus`. It has no required dependencies and uses max order for runtime start ordering: + +```go +func (b *eventBus) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{} +} + +func (b *eventBus) Type() runtime.ComponentType { + return runtime.EventBus +} + +func (b *eventBus) Order() int { + return math.MaxInt +} +``` + +`Init` creates the subscriber directory: + +```go +func (b *eventBus) Init(_ runtime.BuilderContext) error { + b.subscriberDir = make(map[model.ResourceKind]Subscribers) + return nil +} +``` + +`Start` is a no-op. + +## Subscribe behavior + +Subscribers are grouped by resource kind. Names must be unique within the same resource kind: + +```go +func (b *eventBus) Subscribe(subscriber Subscriber) error { + b.rwMutex.Lock() + defer b.rwMutex.Unlock() + subs, exists := b.subscriberDir[subscriber.ResourceKind()] + if !exists { + subs = make(Subscribers, 0) + } + for _, sub := range subs { + if sub.Name() == subscriber.Name() { + return fmt.Errorf("duplicated subscriber name %s, skipped subscribing", subscriber.Name()) + } + } + b.subscriberDir[subscriber.ResourceKind()] = append(subs, subscriber) + return nil +} +``` + +This means two subscribers may share a name only if they subscribe to different resource kinds. Discovery and engine subscribers typically use prefixes such as `Discovery-` and `Engine-` in `Name()`. + +## Unsubscribe behavior + +`Unsubscribe` removes a subscriber by resource kind and name: + +```go +rk := subscriber.ResourceKind() +name := subscriber.Name() +subs, exists := b.subscriberDir[rk] +... +if sub.Name() == name { + b.subscriberDir[rk] = append(subs[:i], subs[i+1:]...) + return nil +} +``` + +If no subscriber list or no matching name exists, it returns an error. + +## Send dispatch algorithm + +`Send` uses a read lock and derives the dispatch key from event resources: + +```go +var rk model.ResourceKind +if event.NewObj() != nil { + rk = event.NewObj().ResourceKind() +} else if event.OldObj() != nil { + rk = event.OldObj().ResourceKind() +} +``` + +Then it looks up subscribers and calls them synchronously: + +```go +subs, exists := b.subscriberDir[rk] +if !exists { + logger.Infof("no subscriber for resource %s, skipped sending event%v", rk, event) + return +} +for _, sub := range subs { + if err := sub.ProcessEvent(event); err != nil { + logger.Errorf("failed to process event in %s, cause: %s, event: %v", sub.Name(), err.Error(), event) + } +} +``` + +Important semantics: + +- New object wins over old object for routing. +- Delete events rely on old object because new object is nil. +- Events with both old and new nil cannot be routed and will use the zero resource kind. +- Subscriber errors are logged; they do not stop dispatch to later subscribers. +- Dispatch is synchronous; long subscriber work blocks the sender. + +## Common producers + +- `pkg/core/controller/informer.go`: emits events after store add, update, or delete. +- `pkg/core/discovery/subscriber/`: emits follow-up Application, Service, or Instance events after deriving resources. +- `pkg/core/engine/subscriber/`: emits follow-up Instance events after RuntimeInstance merge/delete. + +## Review checklist + +- Confirm delete events provide `OldObj`. +- Confirm subscriber `ResourceKind()` matches the resource being emitted. +- Confirm subscriber `Name()` is unique for that resource kind. +- Do not put business logic in EventBus; keep it in subscribers. +- If changing error behavior, review discovery and engine because both rely on current non-blocking error handling. diff --git a/.agents/skills/dubbo-admin-frontend/SKILL.md b/.agents/skills/dubbo-admin-frontend/SKILL.md new file mode 100644 index 000000000..3178b2a26 --- /dev/null +++ b/.agents/skills/dubbo-admin-frontend/SKILL.md @@ -0,0 +1,60 @@ +--- +name: dubbo-admin-frontend +description: Implements and reviews dubbo-admin Vue 3 frontend changes. Use when the user asks about ui-vue3, Vue views or components, frontend routing, route metadata, API clients, Pinia stores, SearchDomain, i18n, layout tabs, traffic rule form design, frontend tests, or Vite, ESLint, and Prettier configuration. Do not use for Go backend internals unless coordinating an API contract with the frontend. +--- + +# dubbo-admin Frontend + +## Purpose + +Use this skill to change or explain the Vue frontend while preserving routing, API, state, layout, i18n, and traffic-rule form patterns. + +## When to use + +Use for `ui-vue3/` changes, route definitions, views, components, API clients, Pinia stores, tabs, SearchDomain pages, traffic rule forms, and frontend validation. + +Do not use for backend-only logic unless frontend API contracts are affected. + +## Inputs + +Required: +- Frontend route, view, component, or user workflow. +- Intended UI behavior or API contract. + +Optional: +- Backend endpoint or payload. +- Screenshot or user interaction path. +- Existing page to mirror. + +If missing, start from `ui-vue3/src/router/defaultRoutes.ts` and identify the view. + +## Workflow + +1. Locate the route in `ui-vue3/src/router/defaultRoutes.ts`. +2. Read the view under `ui-vue3/src/views/` and nearby components or composables. +3. Check API calls in `ui-vue3/src/api/` and request behavior in `src/base/http/request.ts`. +4. Use shared components and layout patterns before adding new abstractions. +5. Update Pinia state, i18n keys, and tests when user-visible behavior changes. +6. Read `references/traffic-rule-forms.md` for routing, dynamic config, or tag rule forms. + +## Output format + +Return changed UI flow, route or component paths, API contract impact, validation commands, and any screenshot or browser-test gap. + +## Validation + +- Run the smallest relevant command: `yarn lint`, `yarn type-check`, `yarn test:unit`, or `yarn build`. +- Confirm request payloads match backend models. +- Confirm new user-facing text has i18n keys. +- For traffic forms, confirm form and YAML paths round-trip the same data. + +## Edge cases + +- Mesh is injected by the Axios request layer; avoid duplicate mesh handling unless required. +- Tabbed detail pages rely on route metadata and layout state. +- If backend response fields change, check both API client types and view usage. + +## References + +- Read `references/frontend-structure.md` for directory and route patterns. +- Read `references/traffic-rule-forms.md` for traffic form design and round-trip checks. diff --git a/.agents/skills/dubbo-admin-frontend/evals/evals.json b/.agents/skills/dubbo-admin-frontend/evals/evals.json new file mode 100644 index 000000000..be026a6da --- /dev/null +++ b/.agents/skills/dubbo-admin-frontend/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-frontend", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Add a new Vue tab to the service detail page and call an API from ui-vue3/src/api.", + "expected_behavior": "Use frontend routing, layout tab, API client, and view workflow." + }, + { + "id": "paraphrased-trigger", + "prompt": "The traffic rule form and YAML view produce different route conditions.", + "expected_behavior": "Use traffic rule form design and round-trip validation." + }, + { + "id": "file-based-trigger", + "prompt": "Review ui-vue3/src/views/traffic/routingRule/composables/useRoutingRule.ts.", + "expected_behavior": "Use this skill because traffic form composable files are touched." + }, + { + "id": "no-trigger", + "prompt": "Fix ListByIndexes in pkg/store/memory/store.go.", + "expected_behavior": "Do not use this skill; use dubbo-admin-store." + }, + { + "id": "conflict-trigger", + "prompt": "Backend changed a response field and the Vue table no longer renders.", + "expected_behavior": "Use frontend for caller updates and coordinate with Console API contract." + } + ] +} diff --git a/.agents/skills/dubbo-admin-frontend/references/frontend-structure.md b/.agents/skills/dubbo-admin-frontend/references/frontend-structure.md new file mode 100644 index 000000000..df9caa806 --- /dev/null +++ b/.agents/skills/dubbo-admin-frontend/references/frontend-structure.md @@ -0,0 +1,110 @@ +# Frontend Structure and Routing Flow + +Use this reference when changing `ui-vue3/` routes, views, API clients, stores, tab pages, or resource topology UI. + +## Source layout + +- `ui-vue3/src/api/`: typed-by-convention API client wrappers. Most files import `@/base/http/request`. +- `ui-vue3/src/base/http/request.ts`: Axios instance, base URL, response normalization, auth redirect, and mesh injection. +- `ui-vue3/src/router/`: static route tree and `RouterMeta` contract. +- `ui-vue3/src/layout/`: shell and tab layout components. +- `ui-vue3/src/views/`: feature pages, grouped by resource or traffic domain. +- `ui-vue3/src/stores/`: Pinia stores. `stores/mesh.ts` persists the selected mesh. +- `ui-vue3/src/components/`: reusable UI widgets such as `MonacoEditor`. + +## Request chain + +Frontend API calls follow this chain: + +```text +view/component -> src/api/... wrapper -> base/http/request.ts -> /api/v1 backend route +``` + +Key implementation points in `base/http/request.ts`: + +```ts +const service = axios.create({ baseURL: '/api/v1', timeout: 30 * 1000 }) + +request.use((config) => { + config.headers['Content-Type'] ||= 'application/json' + if (!config.params) config.params = {} + const { mesh } = useMeshStore() + config.params['mesh'] = mesh + return config +}) +``` + +Responses are resolved only when `response.status === 200` and `response.data.code === HTTP_STATUS.SUCCESS`. Failed API responses reject with the backend response body and usually show an Ant Design Vue message. `401` clears auth state and redirects to `/login?redirect=...`. + +Do not manually append `mesh` in API wrappers unless the endpoint intentionally needs a different value; the request layer already injects it. + +## Route construction + +Routes are declared in `src/router/defaultRoutes.ts`. `handleRoutes()` mutates each route at startup: + +```text +parent path + child path -> normalized absolute path +route.redirect -> normalized relative target +route.meta._router_key -> unique id +route.meta.parent -> parent route object +route.meta.skip -> explicit true or false +``` + +`RouterMeta` supports: + +```ts +icon, hidden, skip, tab_parent, tab, _router_key, parent, slots, headerParamKey +``` + +Add a new page by extending `defaultRoutes.ts`, adding its view under `src/views/...`, and adding i18n labels for route names used in tabs or menus. + +## Tab page flow + +Tabbed resource and traffic pages use `LayoutTab`: + +```text +route with meta.tab_parent -> component: LayoutTab -> child routes with meta.tab -> a-tabs +``` + +`layout/tab/layout_tab.vue` computes visible tabs from `tabRoute.meta.parent.children.filter(x => x.meta.tab)` and pushes by route `name` while preserving current `params` and `query`. Back navigation uses `tabRoute.meta.back || '../'`. Header slots come from `meta.slots.header`, for example application, service, instance, and traffic rule header slots. + +When adding a new tab, set: + +- `meta.tab: true` +- a stable route `name` used by i18n and tab switching +- `meta.icon` for the tab label +- `meta.back` when the tab needs a deterministic return route +- matching params across sibling tabs, otherwise tab switching loses context + +## Table search flow + +`utils/SearchUtil.ts` defines `SearchDomain` for list pages: + +```text +query config + searchApi + columns -> reactive queryForm -> onSearch() -> API -> result/pageInfo +``` + +`onSearch()` adds `pageSize` and `pageOffset` unless `noPaged` is set, then expects backend data shaped as: + +```json +{ "data": { "list": [], "pageInfo": { "total": 0 } } } +``` + +If changing backend pagination or response fields, update both the API model and the `SearchDomain` consumer. + +## Resource topology pattern + +Topology tabs live at: + +- `views/resources/applications/tabs/topology.vue` +- `views/resources/services/tabs/topology.vue` + +They are wired through child tab routes under `/applications` and `/services`. Keep backend graph fields aligned with frontend expectations: `nodes[]`, `edges[]`, node `id`, `label`, `type`, `rule`, and edge `source`, `target`, `data.type`. + +## Review checklist + +- Confirm the API wrapper path matches the backend route under `/api/v1`. +- Confirm `mesh` is not duplicated in query params. +- For tab pages, check `meta.parent`, `meta.tab`, `meta.back`, route params, header slot, and i18n key. +- For list pages, verify `SearchDomain` still receives `data.list` and `data.pageInfo.total`. +- For topology or charts, verify empty data, loading, and detail-drawer behavior. diff --git a/.agents/skills/dubbo-admin-frontend/references/traffic-rule-forms.md b/.agents/skills/dubbo-admin-frontend/references/traffic-rule-forms.md new file mode 100644 index 000000000..39ef4a8ee --- /dev/null +++ b/.agents/skills/dubbo-admin-frontend/references/traffic-rule-forms.md @@ -0,0 +1,125 @@ +# Traffic Rule Form Design + +Use this reference when changing condition routing, tag routing, dynamic config, YAML views, or traffic rule API payloads under `ui-vue3/src/views/traffic/`. + +## Shared traffic layout + +Traffic pages follow this structure: + +```text +views/traffic//index.vue list page +views/traffic//tabs/*.vue detail, form, YAML, add, update tabs +views/traffic//slots/*.vue tab header slots +api/service/traffic.ts API wrappers +router/defaultRoutes.ts tab routes +``` + +The API wrappers map directly to backend traffic endpoints: + +```text +/condition-rule/search, /condition-rule/{ruleName} +/tag-rule/search, /tag-rule/{ruleName} +/configurator/search, /configurator/{encodedName} +``` + +`configurator` names are encoded with `encodeURIComponent`; keep that behavior for keys containing dots, colons, or other service-name characters. + +## Condition routing implementation chain + +Condition routing form logic is centralized in `routingRule/composables/useRoutingRule.ts`: + +```text +route condition string -> parseCondition...ToArray() -> routeList form state +routeList selected types + values -> mergeConditions() -> API conditions[] +``` + +Supported condition syntax: + +- Single values: `host=1.1.1.1`, `application!=demo`, `method=sayHello` +- Arguments: `arguments[0]=value` +- Attachments: `attachments[key]!=value` +- Custom keys: `region=hangzhou` +- Route target separator: `match & match => target & target` + +Key functions: + +```ts +parseConditionMatchStringToArray(matchStr, routeItemIndex) +parseConditionToStringToArray(toStr, routeItemIndex) +mergeConditions() +mergeConditionItems(selectedTypes, conditionItems) +``` + +`parseConditionString()` also updates selected type arrays on `routeList`: `selectedMatchConditionTypes` for request matching and `selectedRouteDistributeMatchTypes` for target selection. If you add a condition type, update the type options, parser, merge logic, default row creation, delete behavior, description text, and i18n. + +Detail and YAML tabs read from the same backend detail endpoint: + +```text +formView.vue -> getConditionRuleDetailAPI(ruleName) -> parse conditions for display +YAMLView.vue -> getConditionRuleDetailAPI(ruleName) -> yaml.dump(data) +``` + +Add/update tabs must keep form and YAML behavior equivalent; do not add fields to one representation only. + +## Dynamic config implementation chain + +Dynamic config form state lives in `dynamicConfig/model/ConfigModel.ts`: + +```text +backend Configurator detail -> ViewDataModel.fromApiOutput() +configs[] -> ConfigModel.parseMatches() + parseParameters() +form edits -> ViewDataModel.toApiInput(check) -> add/save configurator API +``` + +Important model responsibilities: + +- `ConfigModel.matchesValue` stores match fields such as `address`, `providerAddress`, `service`, `application`, and free `param` matches. +- `ConfigModel.parametersValue` stores common parameter fields such as `retries`, `timeout`, `accesslog`, `weight`, and free `other` keys. +- `parseMatches()` converts backend match maps into UI rows. +- `parseParameters()` maps known parameters to typed rows and unknown keys to `other`. +- `toApiInput(check)` rebuilds the backend payload and performs validation when `check` is true. + +The form tab uses `TAB_LAYOUT_STATE.dynamicConfigForm.data` to preserve edits across sibling tabs. Resetting clears that state and reloads from the API. + +Payload shape produced by `toApiInput()`: + +```json +{ + "ruleName": "service.configurators", + "scope": "service", + "key": "service", + "enabled": true, + "configVersion": "v3.0", + "configs": [ + { "match": {}, "parameters": {}, "enabled": true, "side": "provider" } + ] +} +``` + +When adding new match or parameter fields, update both `parse...` and `toApiInput()` so existing data round-trips. + +## Tag routing implementation chain + +Tag routing pages live in `traffic/tagRule/` and mirror the condition-rule tab structure. Detail view calls `getTagRuleDetailAPI(ruleName)` and displays `tags[].match[]` entries as key/relation/value labels. YAML and add/update views should preserve this backend structure: + +```json +{ + "configVersion": "v3.0", + "scope": "application", + "key": "shop-user", + "enabled": true, + "runtime": true, + "tags": [ + { "name": "gray", "match": [{ "key": "version", "value": { "exact": "v1" } }] } + ] +} +``` + +## Review checklist + +- Keep form view, YAML view, and API payload fields in sync. +- Verify parse/merge round trips for condition strings containing `=>`, `&`, `arguments[]`, `attachments[]`, and custom keys. +- Preserve `TAB_LAYOUT_STATE` when switching dynamic config form/YAML tabs. +- Encode configurator names in API calls. +- Update i18n route labels and tab headers when adding traffic tabs. +- Run `cd ui-vue3 && yarn lint && yarn type-check` for TypeScript or route changes; add `yarn test:unit` when logic is refactored. diff --git a/.agents/skills/dubbo-admin-runtime/SKILL.md b/.agents/skills/dubbo-admin-runtime/SKILL.md new file mode 100644 index 000000000..364d5691e --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/SKILL.md @@ -0,0 +1,60 @@ +--- +name: dubbo-admin-runtime +description: Implements and reviews dubbo-admin runtime component changes. Use when the user asks about component abstraction, component composition, runtime bootstrap, dependency ordering, registration, lifecycle, startup, shutdown, runtime builder behavior, or pkg/core/runtime/ and pkg/core/bootstrap/. Do not use for discovery, engine, store, Console API, or frontend tasks unless component lifecycle or dependencies are affected. +--- + +# dubbo-admin Runtime + +## Purpose + +Use this skill to change or explain component abstraction, dependency composition, bootstrap order, activation, and runtime startup behavior. + +## When to use + +Use for component interfaces, `RequiredDependencies`, `Order`, `RegisterComponent`, `Builder`, dependency graph, bootstrap, start, stop, and core component failure behavior. + +Do not use for domain behavior inside a component unless lifecycle or dependency contracts change. + +## Inputs + +Required: +- Component type, lifecycle method, or runtime package path. +- Dependency or startup behavior being changed. + +Optional: +- Error message from bootstrap or start. +- Existing component to mirror. + +If missing, inspect `pkg/core/runtime/component.go` and `pkg/core/bootstrap/bootstrap.go`. + +## Workflow + +1. Classify the change: component contract, registration, bootstrap, dependency graph, builder activation, or runtime start. +2. Read the matching reference listed below before editing or explaining implementation behavior. +3. Inspect the source files named by that reference and confirm the current code still matches the documented flow. +4. Make the smallest change at the owning layer: component interfaces, registry, bootstrap, dependency graph, builder, or runtime start. +5. Validate the exact lifecycle invariant affected by the change. + +## Output format + +Return component contract impact, dependency order, changed files, startup behavior, and validation performed. + +## Validation + +- Confirm dependencies exist and are initialized before dependents. +- Confirm `Order()` is only used for startup ordering and not dependency correctness. +- Confirm core component startup failures still panic while non-core failures log. +- Run `go test ./pkg/core/runtime ./pkg/core/bootstrap` or `make test`. + +## Edge cases + +- `Order()` is deprecated for dependency management but still used during start. +- Duplicate component registration panics. +- Cycles should fail bootstrap with a clear dependency error. + +## References + +- Read `references/component-contracts.md` when adding or modifying component interfaces, component types, or `RequiredDependencies()`. +- Read `references/bootstrap-flow.md` when changing initialization order, component gathering, `Init`, or activation. +- Read `references/dependency-graph.md` when debugging missing dependencies, ordering, deterministic sort, or cycles. +- Read `references/runtime-start.md` when changing `Start`, `Order()`, goroutine behavior, or startup error handling. diff --git a/.agents/skills/dubbo-admin-runtime/evals/evals.json b/.agents/skills/dubbo-admin-runtime/evals/evals.json new file mode 100644 index 000000000..6785e5634 --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-runtime", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Add a new runtime component with dependencies on EventBus and ResourceStore.", + "expected_behavior": "Use component lifecycle, registration, dependency graph, and bootstrap workflow." + }, + { + "id": "paraphrased-trigger", + "prompt": "Startup order is wrong because one component initializes before its dependency.", + "expected_behavior": "Inspect RequiredDependencies and dependency graph behavior." + }, + { + "id": "file-based-trigger", + "prompt": "Review pkg/core/runtime/dependency_graph.go and pkg/core/bootstrap/bootstrap.go.", + "expected_behavior": "Use this skill because runtime and bootstrap files are touched." + }, + { + "id": "no-trigger", + "prompt": "Change only the Vue route metadata for a tab.", + "expected_behavior": "Do not use this skill; use dubbo-admin-frontend." + }, + { + "id": "conflict-trigger", + "prompt": "The discovery component fails because EventBus is unavailable during Init.", + "expected_behavior": "Use runtime for dependency ordering and discovery for component-specific logic." + } + ] +} diff --git a/.agents/skills/dubbo-admin-runtime/references/bootstrap-flow.md b/.agents/skills/dubbo-admin-runtime/references/bootstrap-flow.md new file mode 100644 index 000000000..28e21a20a --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/references/bootstrap-flow.md @@ -0,0 +1,130 @@ +# Runtime Bootstrap Flow + +This reference explains how dubbo-admin initializes components before building the runtime. + +## End-to-end call chain + +```text +bootstrap.Bootstrap(appCtx, cfg) + -> runtime.BuilderFor(appCtx, cfg) + -> NewSmartBootstrapper(builder) + -> bootstrapper.bootstrapComponents(appCtx, cfg) + -> gatherComponents() + -> sortComponents(components) + -> runtime.NewDependencyGraph(components).TopologicalSort() + -> initAndActivateComponent(builder, comp) + -> comp.Init(builder) + -> builder.ActivateComponent(comp) + -> builder.Build() + -> runtime.Start(stop) +``` + +## Bootstrap entrypoint + +Key file: `pkg/core/bootstrap/bootstrap.go` + +```go +func Bootstrap(appCtx context.Context, cfg app.AdminConfig) (runtime.Runtime, error) { + builder, err := runtime.BuilderFor(appCtx, cfg) + bootstrapper := NewSmartBootstrapper(builder) + if err := bootstrapper.bootstrapComponents(appCtx, cfg); err != nil { + return nil, err + } + rt, err := builder.Build() + return rt, nil +} +``` + +`BuilderFor` creates runtime identity and an initially empty activated component map: + +```go +return &Builder{ + cfg: cfg, + appCtx: appCtx, + runtimeInfo: runtimeInfo{ + instanceId: fmt.Sprintf("%s-%s", hostname, suffix), + clusterId: fmt.Sprintf("%s-%s", hostname, suffix), + startTime: time.Now(), + }, + components: make(map[ComponentType]Component), +}, nil +``` + +## Component gathering + +`gatherComponents` loads required core components from the global registry: + +```go +coreComps := []struct { + name string + getter func() (runtime.Component, error) +}{ + {"EventBus", runtime.ComponentRegistry().EventBus}, + {"ResourceStore", runtime.ComponentRegistry().ResourceStore}, + {"ResourceDiscovery", runtime.ComponentRegistry().ResourceDiscovery}, + {"ResourceEngine", runtime.ComponentRegistry().ResourceEngine}, + {"ResourceManager", runtime.ComponentRegistry().ResourceManager}, + {"Console", runtime.ComponentRegistry().Console}, + {"RuleGovernor", runtime.ComponentRegistry().RuleGovernor}, +} +``` + +If a core component is missing, bootstrap fails. Optional components are checked with `ComponentRegistry().Get`; missing optional components are logged and skipped: + +- CounterManager +- DiagnosticsServer +- DistributedLock + +## Sorting and initialization + +`sortComponents` delegates to the dependency graph: + +```go +graph := runtime.NewDependencyGraph(components) +sorted, err := graph.TopologicalSort() +``` + +`bootstrapComponents` initializes in sorted order: + +```go +for i, comp := range ordered { + if err := initAndActivateComponent(sb.builder, comp); err != nil { + return bizerror.Wrap(err, bizerror.UnknownError, + fmt.Sprintf("failed to initialize component %s", comp.Type())) + } +} +``` + +`initAndActivateComponent` is the critical invariant: + +```go +if err := comp.Init(builder); err != nil { + return err +} +if err := builder.ActivateComponent(comp); err != nil { + return bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to activate %s", comp.Type())) +} +``` + +A component is visible to later components only after successful `Init` and activation. + +## Build validation + +`Builder.Build` requires all core components to be activated: + +```go +for _, typ := range CoreComponentTypes { + if _, exists := b.components[typ]; !exists { + return nil, errors.Errorf("%v has not been configured", typ) + } +} +``` + +It then returns a `runtime` containing runtime info, config, app context, and activated components. + +## Review checks + +- If `GetActivatedComponent` fails inside `Init`, inspect `RequiredDependencies()` and dependency graph order. +- If bootstrap fails while gathering, inspect package imports and `init()` registration. +- Optional components should not be added to `CoreComponentTypes` unless absence should be fatal. +- Do not activate a component before successful `Init`. diff --git a/.agents/skills/dubbo-admin-runtime/references/component-contracts.md b/.agents/skills/dubbo-admin-runtime/references/component-contracts.md new file mode 100644 index 000000000..7dee4ca2a --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/references/component-contracts.md @@ -0,0 +1,139 @@ +# Runtime Component Contracts + +This reference explains the component abstraction used by dubbo-admin runtime. Read it before adding a component, changing component interfaces, or modifying dependency declarations. + +## Key files + +- `pkg/core/runtime/component.go` +- `pkg/core/runtime/registry.go` +- `pkg/core/runtime/builder.go` + +## Component contract + +`pkg/core/runtime/component.go` defines the runtime abstraction: + +```go +type Lifecycle interface { + Init(ctx BuilderContext) error + Start(Runtime, <-chan struct{}) error +} + +type Attribute interface { + Type() ComponentType + Order() int + RequiredDependencies() []ComponentType +} + +type Component interface { + Attribute + Lifecycle +} +``` + +Meaning: + +- `Type()` is the stable identity used by registry, builder, runtime lookup, and dependency graph. +- `Init(ctx BuilderContext)` runs during bootstrap before the component is activated. +- `Start(Runtime, stop)` runs after runtime is built. +- `RequiredDependencies()` controls initialization order. +- `Order()` is deprecated for dependency management but still controls runtime start ordering. + +## Built-in component types + +```go +const ( + Console ComponentType = "console" + ResourceManager ComponentType = "resource manager" + ResourceStore ComponentType = "resource store" + ResourceEngine ComponentType = "resource engine" + ResourceDiscovery ComponentType = "resource discovery" + EventBus ComponentType = "event bus" + RuleGovernor ComponentType = "rule governor" +) +``` + +`CoreComponentTypes` contains `Console`, `ResourceManager`, `ResourceStore`, `ResourceEngine`, `ResourceDiscovery`, and `RuleGovernor`. Runtime start panics when a core component returns an error. + +## Registry implementation + +Key functions in `pkg/core/runtime/registry.go`: + +```go +var registry = NewRegistry() + +func ComponentRegistry() Registry { + return registry +} + +func RegisterComponent(component Component) { + if err := registry.Register(component); err != nil { + panic(err) + } +} +``` + +The registry is global. Packages register components from `init()` functions, for example discovery and engine do this. Duplicate component types fail fast: + +```go +func (r *componentRegistry) Register(component Component) error { + _, ok := r.directory[component.Type()] + if ok { + return componentAlreadyRegisteredError(component.Type()) + } + r.directory[component.Type()] = component + return nil +} +``` + +Lookup is by component type: + +```go +func (r *componentRegistry) Get(typ ComponentType) (Component, error) { + component, ok := r.directory[typ] + if !ok { + return nil, noSuchComponentError(typ) + } + return component, nil +} +``` + +## Builder context contract + +`pkg/core/runtime/builder.go` defines the context available during `Init`: + +```go +type BuilderContext interface { + Config() app.AdminConfig + GetActivatedComponent(typ ComponentType) (Component, error) + ActivateComponent(comp Component) error +} +``` + +A component can only retrieve dependencies that have already been activated by bootstrap. This is why `RequiredDependencies()` must be correct. + +## Implementation example + +A component that needs EventBus and ResourceStore should declare both: + +```go +func (c *myComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{runtime.EventBus, runtime.ResourceStore} +} +``` + +During `Init`, it should retrieve dependencies from `BuilderContext`: + +```go +eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) +storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) +``` + +If the dependency is missing here, the problem is usually dependency declaration or bootstrap ordering, not runtime start order. + +## Review checks + +- New component type is stable and unique. +- New component is registered exactly once. +- `RequiredDependencies()` lists every component used via `GetActivatedComponent` during `Init`. +- `Order()` is not used to compensate for missing `RequiredDependencies()`. +- Core failure semantics are considered if a new component should be fatal during runtime start. diff --git a/.agents/skills/dubbo-admin-runtime/references/dependency-graph.md b/.agents/skills/dubbo-admin-runtime/references/dependency-graph.md new file mode 100644 index 000000000..98776fbd7 --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/references/dependency-graph.md @@ -0,0 +1,106 @@ +# Runtime Dependency Graph + +This reference explains how dubbo-admin sorts runtime components by `RequiredDependencies()`. + +## Key file + +- `pkg/core/runtime/dependency_graph.go` + +## End-to-end algorithm + +```text +NewDependencyGraph(components) + -> map each ComponentType to Component + -> initialize adjacency list for all component types + -> for each component dependency, add edge dependency -> component +TopologicalSort() + -> validate all dependencies exist + -> compute indegree = len(RequiredDependencies()) + -> enqueue components with indegree 0 + -> sort queue alphabetically for deterministic ordering + -> pop current, append component to result + -> decrement indegree for dependents + -> detect cycle if result length is incomplete +``` + +## Graph shape + +`DependencyGraph` stores reverse adjacency: + +```go +type DependencyGraph struct { + components map[ComponentType]Component + adjList map[ComponentType][]ComponentType +} +``` + +When A depends on B, the stored edge is B to A: + +```go +for _, comp := range components { + for _, dependency := range comp.RequiredDependencies() { + dg.adjList[dependency] = append(dg.adjList[dependency], comp.Type()) + } +} +``` + +This makes topological output match initialization order: dependencies appear before dependents. + +## Validation step + +Before sorting, every declared dependency must exist in the component set: + +```go +func (dg *DependencyGraph) validate() error { + for _, comp := range dg.components { + for _, dependency := range comp.RequiredDependencies() { + if _, exists := dg.components[dependency]; !exists { + return bizerror.Wrap( + fmt.Errorf("missing dependency %q", dependency), + bizerror.ConfigError, + fmt.Sprintf("component %q requires missing dependency %q", comp.Type(), dependency), + ) + } + } + } + return nil +} +``` + +A missing dependency is a configuration/registration problem, not a sorting problem. + +## Sorting step + +In-degree is dependency count: + +```go +indegree[comp.Type()] = len(comp.RequiredDependencies()) +``` + +The queue is sorted every iteration: + +```go +sort.Strings(queue) +current := queue[0] +queue = queue[1:] +``` + +This gives deterministic order among otherwise independent components. + +## Cycle detection + +If the sorted result does not include every component, `findCycle` uses DFS through `RequiredDependencies()` to extract a cycle. `newCircularDependencyError` formats it as: + +```text +A -> B -> C -> A +``` + +and returns a `bizerror.ConfigError`. + +## Review checks + +- Add dependencies to `RequiredDependencies()`, not to comments or `Order()`. +- Keep the alphabetic deterministic queue behavior unless there is a strong reason to change reproducibility. +- Missing dependency errors should name both dependent and dependency. +- Cycle errors should remain actionable and point to `RequiredDependencies()`. +- If two components are independent, do not rely on their relative initialization order. diff --git a/.agents/skills/dubbo-admin-runtime/references/runtime-start.md b/.agents/skills/dubbo-admin-runtime/references/runtime-start.md new file mode 100644 index 000000000..bc0f36e23 --- /dev/null +++ b/.agents/skills/dubbo-admin-runtime/references/runtime-start.md @@ -0,0 +1,88 @@ +# Runtime Start Behavior + +This reference explains what happens after bootstrap builds a runtime and `Start(stop)` is called. + +## Key file + +- `pkg/core/runtime/runtime.go` + +## Runtime shape + +`Runtime` combines runtime metadata, runtime context, and component management: + +```go +type Runtime interface { + RuntimeInfo + RuntimeContext + ComponentManager +} +``` + +`runtimeContext` stores config, app context, and activated components. `GetComponent` looks up an activated component by type after runtime build. + +## Start call chain + +```text +runtime.Start(stop) + -> collect activated components from rt.components + -> sort by descending Order() + -> for each component, launch goroutine + -> component.Start(rt, stop) + -> panic on core component error, log on non-core error + -> wait until stop channel closes +``` + +## Key implementation + +```go +func (rt *runtime) Start(stop <-chan struct{}) error { + components := maputil.Values(rt.components) + slice.SortBy(components, func(a, b Component) bool { + return a.Order() > b.Order() + }) + for _, com := range components { + go func() { + err := com.Start(rt, stop) + if err != nil { + if slice.Contain(CoreComponentTypes, com.Type()) { + panic("core component " + com.Type() + " running failed with error: " + err.Error()) + } else { + logger.Errorf("component %s running failed with error: %s", com.Type(), err.Error()) + } + } else { + logger.Infof("component %s started successfully", com.Type()) + } + }() + } + logger.Info("Admin started successfully") + select { + case <-stop: + return nil + } +} +``` + +## Important distinction + +`RequiredDependencies()` controls bootstrap initialization order. `Order()` controls runtime start order only. If a component needs another component during `Init`, declare it in `RequiredDependencies()`. + +## Concurrency caveat + +The goroutine closes over the loop variable `com`. If changing this code, consider capturing the loop variable explicitly to avoid accidental closure bugs in Go versions or refactors where loop variable semantics matter: + +```go +for _, com := range components { + com := com + go func() { _ = com.Start(rt, stop) }() +} +``` + +Do not change this casually without tests, because startup failure behavior is important for core components. + +## Review checks + +- New `Start` implementations should respect the stop channel. +- Long-running work belongs in `Start`; runtime already starts components in goroutines. +- Core component failure should remain fatal unless product behavior intentionally changes. +- Non-core component failure should not stop the whole runtime unless promoted to core semantics. +- Startup ordering must not be used as a substitute for initialization dependencies. diff --git a/.agents/skills/dubbo-admin-store/SKILL.md b/.agents/skills/dubbo-admin-store/SKILL.md new file mode 100644 index 000000000..87306d453 --- /dev/null +++ b/.agents/skills/dubbo-admin-store/SKILL.md @@ -0,0 +1,58 @@ +--- +name: dubbo-admin-store +description: Implements and reviews dubbo-admin resource storage and indexing changes. Use when the user asks about ResourceStore APIs, store routing, memory store behavior, index registration, IndexCondition, ListByIndexes, PageListByIndexes, ByMeshIndex, radix-tree prefix lookup, or pkg/core/store/, pkg/core/store/index/, and pkg/store/. Do not use for frontend, Console API, discovery, or engine tasks unless they require store or index changes. +--- + +# dubbo-admin Store + +## Purpose + +Use this skill to change or explain resource storage, indexes, query semantics, pagination, and prefix matching without breaking callers. + +## When to use + +Use for `ResourceStore`, store routing, memory store internals, index definitions, equality or prefix query behavior, pagination, and query performance. + +Do not use for a domain feature unless the feature requires store or index changes. + +## Inputs + +Required: +- Resource kind, index name, query path, or store package path. +- Desired query behavior or bug. + +Optional: +- Caller in Console API, discovery, or engine. +- Example resource keys and index values. + +If missing, inspect the caller first, then follow into `pkg/core/store/` or `pkg/store/memory/`. + +## Workflow + +1. Read `pkg/core/store/store.go` for the ResourceStore contract. +2. Check store routing and lifecycle in `pkg/core/store/component.go`. +3. Inspect memory behavior in `pkg/store/memory/store.go`. +4. Check index registration in `pkg/core/store/index/`. +5. Prefer existing `IndexCondition` operators before adding new APIs. +6. Read `references/indexing-and-query.md` before changing query semantics. + +## Output format + +Return resource kind, index conditions, expected keys or resources, caller impact, changed files, and validation commands. + +## Validation + +- Confirm `ByMeshIndex` is included when mesh scoping is required. +- Confirm multiple index conditions intersect key sets. +- Confirm prefix queries update radix trees on add, update, delete, and dynamic index additions. +- Run `go test ./pkg/store/memory ./pkg/core/store/...` or `make test`. + +## Edge cases + +- Empty index conditions return no keys in memory store. +- Missing indexes should return a clear error rather than silently scanning. +- Store contract changes can affect Console API, discovery, and engine callers. + +## References + +- Read `references/indexing-and-query.md` for index registration and memory query behavior. diff --git a/.agents/skills/dubbo-admin-store/evals/evals.json b/.agents/skills/dubbo-admin-store/evals/evals.json new file mode 100644 index 000000000..0fa0bb1ed --- /dev/null +++ b/.agents/skills/dubbo-admin-store/evals/evals.json @@ -0,0 +1,30 @@ +{ + "skill_name": "dubbo-admin-store", + "evals": [ + { + "id": "obvious-trigger", + "prompt": "Add a new index for ServiceKind and query it with ListByIndexes.", + "expected_behavior": "Use store index registration and query validation workflow." + }, + { + "id": "paraphrased-trigger", + "prompt": "Prefix search in the memory resource store returns missing keys.", + "expected_behavior": "Inspect HasPrefix handling and radix tree maintenance." + }, + { + "id": "file-based-trigger", + "prompt": "Review pkg/store/memory/store.go and pkg/core/store/index/service.go.", + "expected_behavior": "Use this skill because store implementation and index files are touched." + }, + { + "id": "no-trigger", + "prompt": "Add a frontend filter input to the service page.", + "expected_behavior": "Do not use this skill unless backend store query behavior changes." + }, + { + "id": "conflict-trigger", + "prompt": "A Console API search endpoint is slow because it scans resources.", + "expected_behavior": "Use Console API for endpoint contract and store for index/query design." + } + ] +} diff --git a/.agents/skills/dubbo-admin-store/references/indexing-and-query.md b/.agents/skills/dubbo-admin-store/references/indexing-and-query.md new file mode 100644 index 000000000..6741ba828 --- /dev/null +++ b/.agents/skills/dubbo-admin-store/references/indexing-and-query.md @@ -0,0 +1,215 @@ +# Store Indexing and Query Implementation + +This reference explains how dubbo-admin routes resources to stores, registers indexes, and executes indexed queries in the memory store. + +## End-to-end call chain + +```text +runtime.RegisterComponent(newStoreComponent) + -> Bootstrap initializes storeComponent.Init + -> Init gets store config + -> FactoryRegistry().GetStoreFactory(cfg.Type) + -> ResourceSchemaRegistry().AllResourceKinds() + -> factory.New(kind, cfg) + -> store.Init(ctx) + -> storeComponent.ResourceKindRoute(kind) + -> caller invokes ResourceStore Add/Update/Delete/ListByIndexes/PageListByIndexes + -> memory resourceStore delegates exact indexes to cache.Indexer + -> memory resourceStore delegates prefix indexes to radix trees +``` + +## Store component routing + +Key file: `pkg/core/store/component.go` + +The store component is registered as `runtime.ResourceStore` and depends on EventBus: + +```go +func init() { + runtime.RegisterComponent(newStoreComponent()) +} + +func (sc *storeComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{runtime.EventBus} +} +``` + +During `Init`, it creates one managed store per registered resource kind: + +```go +cfg := ctx.Config().Store +factory, err := FactoryRegistry().GetStoreFactory(cfg.Type) +for _, kind := range coremodel.ResourceSchemaRegistry().AllResourceKinds() { + store, err := factory.New(kind, cfg) + sc.stores[kind] = store + err = store.Init(ctx) +} +``` + +Routing is by resource kind: + +```go +func (sc *storeComponent) ResourceKindRoute(k coremodel.ResourceKind) (ResourceStore, error) { + if store, exists := sc.stores[k]; exists { + return store, nil + } + return nil, fmt.Errorf("%s is not supported by store yet", k) +} +``` + +## ResourceStore contract + +Key file: `pkg/core/store/store.go` + +```go +type ResourceStore interface { + Indexer + GetByKeys(keys []string) ([]model.Resource, error) + ListByIndexes(indexes []index.IndexCondition) ([]model.Resource, error) + PageListByIndexes(indexes []index.IndexCondition, pq model.PageReq) (*model.PageData[model.Resource], error) +} +``` + +`ManagedResourceStore` adds runtime lifecycle to `ResourceStore`, so each concrete store participates in bootstrap and start. + +## Index registration + +Key directory: `pkg/core/store/index/` + +Indexers register during package initialization with `RegisterIndexers`: + +```go +func RegisterIndexers(rk model.ResourceKind, indexers cache.Indexers) { + indexRegistry.Register(rk, indexers) +} +``` + +`ByMeshIndex` is registered for mesh resources in `common.go`. Resource-specific files register indexes such as service name, provider service key, consumer service key, instance IP, and runtime instance IP. + +When adding a query, verify that the target resource kind has a registered index for every `IndexCondition` used. + +## Memory store initialization + +Key file: `pkg/store/memory/store.go` + +Memory store wraps a Kubernetes `cache.Indexer` and maintains radix trees for prefix lookups: + +```go +type resourceStore struct { + rk coremodel.ResourceKind + storeProxy cache.Indexer + prefixTrees map[string]*radix.Tree + treesMu sync.RWMutex +} +``` + +`Init` loads registered indexers for the resource kind and initializes one radix tree per index: + +```go +indexers := index.IndexersRegistry().Indexers(rs.rk) +rs.storeProxy = cache.NewIndexer(keyFunc, indexers) +rs.prefixTrees = make(map[string]*radix.Tree) +for indexName := range indexers { + rs.prefixTrees[indexName] = radix.New() +} +``` + +## Write path and prefix tree maintenance + +`Add`, `Update`, `Delete`, and `Replace` keep radix trees in sync with the underlying indexer. + +Add: + +```go +rs.storeProxy.Add(obj) +rs.addToTrees(resource) +``` + +Update removes old index values and adds new ones only after successful store update: + +```go +oldObj, exists, err := rs.storeProxy.Get(r) +rs.storeProxy.Update(obj) +if oldRes != nil { rs.removeFromTrees(oldRes) } +rs.addToTrees(r) +``` + +Delete: + +```go +rs.storeProxy.Delete(obj) +rs.removeFromTrees(resource) +``` + +Dynamic indexes are supported through `AddIndexers`; it adds missing radix trees for new indexers. + +## Query path + +`ListByIndexes` and `PageListByIndexes` both start with `getKeysByIndexes`. + +```go +func (rs *resourceStore) getKeysByIndexes(indexes []index.IndexCondition) ([]string, error) { + if len(indexes) == 0 { + return []string{}, nil + } + keySet := set.New[string]() + first := true + for _, condition := range indexes { + switch condition.Operator { + case index.Equals: + keys, err = rs.storeProxy.IndexKeys(condition.IndexName, condition.Value) + case index.HasPrefix: + keys, err = rs.getKeysByPrefix(condition.IndexName, condition.Value) + default: + return nil, bizerror.New(bizerror.InvalidArgument, "operator not yet supported: "+string(condition.Operator)) + } + if first { keySet = set.FromSlice(keys) } else { keySet = keySet.Intersection(set.FromSlice(keys)) } + } + return keySet.ToSlice(), nil +} +``` + +Important semantics: + +- Empty conditions return no keys, not all resources. +- Multiple conditions are AND semantics through intersection. +- Unsupported operators return invalid argument errors. + +`ListByIndexes` loads resources by keys and sorts resources by `ResourceKey()`. `PageListByIndexes` sorts keys, applies offset and page size, loads resources, and returns `coremodel.PageData`. + +## Prefix lookup implementation + +Radix keys are stored as: + +```text +indexValue/resourceKey +``` + +`resourceKey` itself contains `/` as `mesh/name`, so prefix extraction uses the first slash: + +```go +idx := strings.Index(k, "/") +keys = append(keys, k[idx+1:]) +``` + +Review prefix queries carefully because a wrong separator assumption can corrupt keys. + +## DB-backed store and leader election support + +`storeComponent` implements `leader.DBSource` by reflectively finding a store pool with `GetDB`. Discovery and engine use this to decide whether leader election is available for non-memory stores. + +## Common failure modes + +- Query uses an index name that was never registered for the resource kind. +- Mesh-scoped query forgets `ByMeshIndex` and returns cross-mesh data. +- Prefix tree is not updated after update/delete/dynamic index addition. +- Empty index conditions are expected to return no results. +- Multiple conditions unexpectedly narrow results because they are intersections. + +## Review checklist + +- Confirm every `IndexCondition` has a registered index for the resource kind. +- Confirm mesh scoping is explicit where required. +- Confirm write paths maintain both `storeProxy` and `prefixTrees`. +- Confirm pagination uses stable key ordering. +- Confirm caller expectations match empty-condition behavior. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d28ce592e..a63ffe385 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,6 @@ **Please provide a description of this PR:** + **To help us figure out who should review this PR, please put an X in all the areas that this PR affects.** - [ ] Docs @@ -7,6 +8,8 @@ - [ ] User Experience - [ ] Dubboctl - [ ] Console -- +- [ ] Core Component + + **Please check any characteristics that apply to this pull request.** diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a4c10aa6..4065f4254 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,70 +13,80 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Continues Integration +name: dubbo-admin ci on: push: branches: - - master + - develop pull_request: branches: - - master + - develop jobs: - unit-test: - name: Go Test - runs-on: ubuntu-latest - if: github.repository == 'apache/dubbo-admin' - steps: - - uses: actions/checkout@v4 - - name: Set up Go 1.x - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Download dependencies - run: | - go mod download - - name: Go Test - run: | - go test ./... -gcflags=-l -coverprofile=coverage.txt -covermode=atomic - - name: "Upload test result" - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-coverage - path: "**/coverage.txt" - - name: Coverage - run: bash <(curl -s https://codecov.io/bash) - license-check: - name: License Check - Go + name: License Check runs-on: ubuntu-latest if: github.repository == 'apache/dubbo-admin' steps: - uses: actions/checkout@v4 - - name: Set up Go 1.x - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Check License Header uses: apache/skywalking-eyes/header@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + config: .licenserc.yaml + mode: check - go-fmt: - name: Go fmt - runs-on: ubuntu-latest + CI: + name: CI (${{ matrix.os }} - Go ${{ matrix.go_version }}) + runs-on: ${{ matrix.os }} + strategy: + # If you want to matrix build , you can append the following list. + matrix: + go_version: + - "1.24" + - "1.23" + os: + - ubuntu-latest if: github.repository == 'apache/dubbo-admin' steps: - uses: actions/checkout@v4 - - name: Set up Go 1.x + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + cache-dependency-path: ui-vue3/yarn.lock + - name: Build Frontend (Vue3) + working-directory: ui-vue3 + run: | + yarn install --frozen-lockfile + yarn build + - name: Copy Dist Directory + run: cp -r ui-vue3/dist/ app/dubbo-ui/ + - name: Setup Go ${{ matrix.go_version }} uses: actions/setup-go@v5 with: go-version-file: go.mod - - name: Download dependencies - run: | - go mod download - - name: Go Fmt - run: | - go fmt ./... && git status && [[ -z `git status -s` ]] - # diff -u <(echo -n) <(gofmt -d -s .) + - name: Cache dependencies + # ref: https://github.com/actions/cache/blob/main/examples.md#go---module + uses: actions/cache@v4 + with: + # Cache, works only on Linux + path: | + ~/.cache/go-build + ~/go/pkg/mod + # Cache key + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + # An ordered list of keys to use for restoring the cache if no cache hit occurred for key + restore-keys: | + ${{ runner.os }}-go- + - name: Check Code Format + run: make fmt && git status && [[ -z `git status -s` ]] + - name: Run Unit Test + run: make test + # TODO(marsevilspirit): add lint + - name: Coverage + # TODO(marsevilspirit): fix coverage + run: bash <(curl -s https://codecov.io/bash) diff --git a/.gitignore b/.gitignore index 21d960b7b..b41087695 100644 --- a/.gitignore +++ b/.gitignore @@ -45,11 +45,4 @@ bin/ build/ vendor/ -# dubbo cp cache -app/dubbo-cp/cache - -# environment files -.env -.env.local -.env.*.local -AI_CHANGES_SUMMARY.md +app/dubbo-ui/dist/ diff --git a/.licenserc.yaml b/.licenserc.yaml index 3de0b608f..7bbbde883 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -20,6 +20,7 @@ header: paths-ignore: - '**/*.versionsBackup' - '**/.idea/**' + - '**/.agents/**' - '**/*.iml' - '**/.settings/*' - '**/.classpath' @@ -83,6 +84,7 @@ header: - '**/docs/**' - '**/.husky/pre-commit' - '**/.nvmrc' + - '**/public/mockServiceWorker.js' - '**/**.txtar' - '**/**gen.go' - '**/api/**' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..8d04ee5ff --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ +# 0.7.0 [Milestone] +## Summary +This release is a milestone version. The entire backend system is completely rewritten using Go, meanwhile, +the frontend ui is redesigned and completely rewritten using Vue3. +The whole refactor extends the base functions of past system and introduces many new features including the native support of kubernetes, +deep integration of observability system and form-based traffic rule publishing. + + +## New Features +- Support resource-level isolation of store. [#1310](https://github.com/apache/dubbo-admin/pull/1310) +- Introduce informer framework to support discovery and engine. [#1314](https://github.com/apache/dubbo-admin/pull/1314) +- Support memory type of store based on cache in client-go. [#1332](https://github.com/apache/dubbo-admin/pull/1332) +- Kubernetes implemention of Engine. [#1340](https://github.com/apache/dubbo-admin/pull/1340) +- Implement Counter in local cache. [#1345](https://github.com/apache/dubbo-admin/pull/1345) +- Introduce a unified error and display error in a better way. [#1353](https://github.com/apache/dubbo-admin/pull/1353), [#1355](https://github.com/apache/dubbo-admin/pull/1355) +- Support multiple registries in console. [#1356](https://github.com/apache/dubbo-admin/pull/1356) +- Nacos Implemention of Discovery. [#1367](https://github.com/apache/dubbo-admin/pull/1367) +- Support components to start in dependency order. [#1370](https://github.com/apache/dubbo-admin/pull/1370) +- Zookeeper Implemention of Discovery. [#1371](https://github.com/apache/dubbo-admin/pull/1371) + +## Bug Fixes +- Fix compile error. [#1325](https://github.com/apache/dubbo-admin/pull/1325) +- Fix counter registration bug. [#1369](https://github.com/apache/dubbo-admin/pull/1369) +- Fix npe caused by incorrect indexer initiation order. [#1372](https://github.com/apache/dubbo-admin/pull/1372) +- Redirect to login page when user is not logged in. [#1373](https://github.com/apache/dubbo-admin/pull/1373) + +## Enhancements +- Migrate the base project from [dubbo-kubernetes](https://github.com/apache/dubbo-kubernetes) to this repository. [#1302](https://github.com/apache/dubbo-admin/pull/1302) +- Reorganize the project structure and tidy up the legacy code. [#1304](https://github.com/apache/dubbo-admin/pull/1304), [#1307](https://github.com/apache/dubbo-admin/pull/1307), [#1311](https://github.com/apache/dubbo-admin/pull/1311) + +## Documentation & CI +- Fix ci problems. [#1320](https://github.com/apache/dubbo-admin/pull/1320), [#1322](https://github.com/apache/dubbo-admin/pull/1322), [#1326](https://github.com/apache/dubbo-admin/pull/1326) + +## Contributors +Thanks to all contributors for their efforts in this release: + +[AlexStocks](https://github.com/AlexStocks), [ikun-Lg](https://github.com/ikun-Lg),[everfid-ever](https://github.com/everfid-ever), +[WyRainBow](https://github.com/WyRainBow), [Helltab](https://github.com/Helltab),[stringl1l1l1l](https://github.com/stringl1l1l1l), +[marseilspirit](https://github.com/marsevilspirit), [mfordjody](https://github.com/mfordjody), [tew-axiom](https://github.com/tew-axiom), +[robocanic](https://github.com/robocanic) + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b138c44e3..d66c819ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,4 +14,4 @@ The mailing list is the recommended way of pursuing a discussion on almost anyth ## Reporting issue -Please create an issue [here](https://github.com/apache/dubbo-kubernetes) \ No newline at end of file +Please create an issue [here](https://github.com/apache/dubbo-admin) \ No newline at end of file diff --git a/DISCLAIMER b/DISCLAIMER deleted file mode 100644 index e69787d3b..000000000 --- a/DISCLAIMER +++ /dev/null @@ -1 +0,0 @@ -Apache Dubbo Admin is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..688cef37e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Build frontend +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:18-alpine AS frontend-builder + +WORKDIR /ui-vue3 + +COPY ui-vue3/package.json ui-vue3/yarn.lock ./ +RUN yarn install --frozen-lockfile +COPY ui-vue3/ ./ +RUN yarn build + + +# Build backend +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:1.24 AS builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /app +ENV GOPROXY=https://goproxy.cn,direct + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +COPY --from=frontend-builder /ui-vue3/dist app/dubbo-ui/dist + + +RUN CGO_ENABLED=0 \ + GOOS=${TARGETOS:-linux} \ + GOARCH=${TARGETARCH:-amd64} \ + go build -a -o dubbo-admin ./app/dubbo-admin/main.go + + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.20 +RUN addgroup -g 65532 app \ + && adduser -D -u 65532 -G app app + +WORKDIR /app +COPY --from=builder /app/dubbo-admin /app/dubbo-admin +USER 65532:65532 + +ENTRYPOINT ["./dubbo-admin"] \ No newline at end of file diff --git a/Makefile b/Makefile index 0086a92e6..7db582a09 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,38 @@ # See the License for the specific language governing permissions and # limitations under the License. -SHELL := /usr/bin/env bash +SHELL := bash +.DELETE_ON_ERROR: +.DEFAULT_GOAL := help +.SHELLFLAGS := -eu -o pipefail -c +MAKEFLAGS += --warn-undefined-variables +MAKEFLAGS += --no-builtin-rules +MAKEFLAGS += --no-print-directory -.PHONY: build-dubbo-admin -build-dubbo-cp: - CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build \ - -ldflags "-X github.com/apache/dubbo-admin/pkg/version.gitTag=$(GIT_VERSION)" \ - -o bin/dubbo-cp app/dubbo-main/main.go && cp app/dubbo-admin/dubbo-admin.yaml bin/ \ No newline at end of file +.PHONY: help test fmt clean lint + +help: + @echo "Available commands:" + @echo " test - Run unit tests" + @echo " clean - Clean test generate files" + @echo " fmt - Format code" + @echo " lint - Run golangci-lint" + +# Run unit tests +test: clean + go test ./... -gcflags=-l -coverprofile=coverage.txt -covermode=atomic + +fmt: + go fmt ./... + +# Clean test generate files +clean: + rm -rf coverage.txt + +# Run golangci-lint +lint: install-golangci-lint + go vet ./... + golangci-lint run ./... --timeout=10m + +install-golangci-lint: + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0 diff --git a/README.md b/README.md index 3b7ed2de3..236414659 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ Dubbo Admin -[![Build](https://github.com/apache/dubbo-kubernetes/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/dubbo-kubernetes/actions/workflows/ci.yml) -[![codecov](https://codecov.io/gh/apache/dubbo-kubernetes/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/dubbo-kubernetes) +[![Build](https://github.com/apache/dubbo-admin/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/dubbo-admin/actions/workflows/ci.yml/badge.svg) +[![codecov](https://codecov.io/gh/apache/dubbo-admin/branch/develop/graph/badge.svg)](https://codecov.io/gh/apache/dubbo-admin) ![license](https://img.shields.io/badge/license-Apache--2.0-green.svg) -Dubbo Admin is the console designed for better visualization of Dubbo services. +Dubbo Admin is the console designed for better visualization of Dubbo applications. ## Repositories The main code repositories of Dubbo Admin include: @@ -33,7 +33,7 @@ Please refer to [RoadMap](https://github.com/apache/dubbo-admin/discussions/1300 - [docs/server-develop](https://github.com/apache/dubbo-admin/docs/server-develop/README.md) for more detail ### Other Information -Refer to [CONTRIBUTING.md](https://github.com/apache/dubbo-kubernetes/blob/master/CONTRIBUTING.md) +Refer to [CONTRIBUTING.md](https://github.com/apache/dubbo-admin/blob/develop/CONTRIBUTING.md) ## License -Apache License 2.0, see [LICENSE](https://github.com/apache/dubbo-kubernetes/blob/master/LICENSE). \ No newline at end of file +Apache License 2.0, see [LICENSE](https://github.com/apache/dubbo-admin/blob/develop/LICENSE). \ No newline at end of file diff --git a/api/mesh/options.pb.go b/api/mesh/options.pb.go index da895ec26..13d9ed064 100644 --- a/api/mesh/options.pb.go +++ b/api/mesh/options.pb.go @@ -1,22 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.0 +// protoc-gen-go v1.35.1 +// protoc v3.12.4 // source: api/mesh/options.proto package mesh import ( - reflect "reflect" - sync "sync" -) - -import ( + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - - descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" ) const ( @@ -31,46 +26,21 @@ type DubboResourceOptions struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Name of the Dubbo resource struct. + // Name and type of the dubbo resource struct. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Name and value of the modelResourceType constant. - Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` - // True if this resource has global scope. Otherwise it will be mesh scope. - Global bool `protobuf:"varint,3,opt,name=global,proto3" json:"global,omitempty"` + // The name of the resource showed as plural + PluralName string `protobuf:"bytes,2,opt,name=plural_name,json=pluralName,proto3" json:"plural_name,omitempty"` // Name of the resource's Go package. - Package string `protobuf:"bytes,4,opt,name=package,proto3" json:"package,omitempty"` - // Whether to skip type registration for this resource. - SkipRegistration bool `protobuf:"varint,6,opt,name=skip_registration,json=skipRegistration,proto3" json:"skip_registration,omitempty"` - Dds *DubboDdsOptions `protobuf:"bytes,10,opt,name=dds,proto3" json:"dds,omitempty"` - Ws *DubboWsOptions `protobuf:"bytes,7,opt,name=ws,proto3" json:"ws,omitempty"` - // Whether scope is "Namespace"; Otherwise to "Cluster". - ScopeNamespace bool `protobuf:"varint,11,opt,name=scope_namespace,json=scopeNamespace,proto3" json:"scope_namespace,omitempty"` - // Whether to skip generation of native API helper functions. - SkipKubernetesWrappers bool `protobuf:"varint,12,opt,name=skip_kubernetes_wrappers,json=skipKubernetesWrappers,proto3" json:"skip_kubernetes_wrappers,omitempty"` - // Whether to generate Inspect API endpoint - AllowToInspect bool `protobuf:"varint,13,opt,name=allow_to_inspect,json=allowToInspect,proto3" json:"allow_to_inspect,omitempty"` - // If resource has more than one version, then the flag defines which version - // is used in the storage. All other versions must be convertible to it. - StorageVersion bool `protobuf:"varint,14,opt,name=storage_version,json=storageVersion,proto3" json:"storage_version,omitempty"` - // The name of the policy showed as plural to be displayed in the UI and maybe - // CLI - PluralDisplayName string `protobuf:"bytes,15,opt,name=plural_display_name,json=pluralDisplayName,proto3" json:"plural_display_name,omitempty"` - // Is Experimental indicates if a policy is in experimental state (might not - // be production ready). - IsExperimental bool `protobuf:"varint,16,opt,name=is_experimental,json=isExperimental,proto3" json:"is_experimental,omitempty"` - // Columns to set using `+kubebuilder::printcolumns` - AdditionalPrinterColumns []string `protobuf:"bytes,17,rep,name=additional_printer_columns,json=additionalPrinterColumns,proto3" json:"additional_printer_columns,omitempty"` - // Whether the resource has a matching insight type - HasInsights bool `protobuf:"varint,18,opt,name=has_insights,json=hasInsights,proto3" json:"has_insights,omitempty"` + Package string `protobuf:"bytes,3,opt,name=package,proto3" json:"package,omitempty"` + // Is Experimental indicates if a resource is in experimental state. + IsExperimental bool `protobuf:"varint,4,opt,name=is_experimental,json=isExperimental,proto3" json:"is_experimental,omitempty"` } func (x *DubboResourceOptions) Reset() { *x = DubboResourceOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_api_mesh_options_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_mesh_options_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DubboResourceOptions) String() string { @@ -81,7 +51,7 @@ func (*DubboResourceOptions) ProtoMessage() {} func (x *DubboResourceOptions) ProtoReflect() protoreflect.Message { mi := &file_api_mesh_options_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -103,20 +73,13 @@ func (x *DubboResourceOptions) GetName() string { return "" } -func (x *DubboResourceOptions) GetType() string { +func (x *DubboResourceOptions) GetPluralName() string { if x != nil { - return x.Type + return x.PluralName } return "" } -func (x *DubboResourceOptions) GetGlobal() bool { - if x != nil { - return x.Global - } - return false -} - func (x *DubboResourceOptions) GetPackage() string { if x != nil { return x.Package @@ -124,62 +87,6 @@ func (x *DubboResourceOptions) GetPackage() string { return "" } -func (x *DubboResourceOptions) GetSkipRegistration() bool { - if x != nil { - return x.SkipRegistration - } - return false -} - -func (x *DubboResourceOptions) GetDds() *DubboDdsOptions { - if x != nil { - return x.Dds - } - return nil -} - -func (x *DubboResourceOptions) GetWs() *DubboWsOptions { - if x != nil { - return x.Ws - } - return nil -} - -func (x *DubboResourceOptions) GetScopeNamespace() bool { - if x != nil { - return x.ScopeNamespace - } - return false -} - -func (x *DubboResourceOptions) GetSkipKubernetesWrappers() bool { - if x != nil { - return x.SkipKubernetesWrappers - } - return false -} - -func (x *DubboResourceOptions) GetAllowToInspect() bool { - if x != nil { - return x.AllowToInspect - } - return false -} - -func (x *DubboResourceOptions) GetStorageVersion() bool { - if x != nil { - return x.StorageVersion - } - return false -} - -func (x *DubboResourceOptions) GetPluralDisplayName() string { - if x != nil { - return x.PluralDisplayName - } - return "" -} - func (x *DubboResourceOptions) GetIsExperimental() bool { if x != nil { return x.IsExperimental @@ -187,237 +94,21 @@ func (x *DubboResourceOptions) GetIsExperimental() bool { return false } -func (x *DubboResourceOptions) GetAdditionalPrinterColumns() []string { - if x != nil { - return x.AdditionalPrinterColumns - } - return nil -} - -func (x *DubboResourceOptions) GetHasInsights() bool { - if x != nil { - return x.HasInsights - } - return false -} - -type DubboWsOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Name is the name of the policy for resource name usage in path. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Plural is only to be set if the plural of the resource is irregular (not - // just adding a 's' at the end). - Plural string `protobuf:"bytes,2,opt,name=plural,proto3" json:"plural,omitempty"` - // ReadOnly if the resource is read only. - ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"` - // AdminOnly whether this entity requires admin auth to access these - // endpoints. - AdminOnly bool `protobuf:"varint,4,opt,name=admin_only,json=adminOnly,proto3" json:"admin_only,omitempty"` -} - -func (x *DubboWsOptions) Reset() { - *x = DubboWsOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_api_mesh_options_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DubboWsOptions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DubboWsOptions) ProtoMessage() {} - -func (x *DubboWsOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_options_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DubboWsOptions.ProtoReflect.Descriptor instead. -func (*DubboWsOptions) Descriptor() ([]byte, []int) { - return file_api_mesh_options_proto_rawDescGZIP(), []int{1} -} - -func (x *DubboWsOptions) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *DubboWsOptions) GetPlural() string { - if x != nil { - return x.Plural - } - return "" -} - -func (x *DubboWsOptions) GetReadOnly() bool { - if x != nil { - return x.ReadOnly - } - return false -} - -func (x *DubboWsOptions) GetAdminOnly() bool { - if x != nil { - return x.AdminOnly - } - return false -} - -type DubboDdsOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // SendToGlobal whether this entity will be sent from zone cp to global cp - SendToGlobal bool `protobuf:"varint,1,opt,name=send_to_global,json=sendToGlobal,proto3" json:"send_to_global,omitempty"` - // SendToZone whether this entity will be sent from global cp to zone cp - SendToZone bool `protobuf:"varint,2,opt,name=send_to_zone,json=sendToZone,proto3" json:"send_to_zone,omitempty"` -} - -func (x *DubboDdsOptions) Reset() { - *x = DubboDdsOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_api_mesh_options_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DubboDdsOptions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DubboDdsOptions) ProtoMessage() {} - -func (x *DubboDdsOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_options_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DubboDdsOptions.ProtoReflect.Descriptor instead. -func (*DubboDdsOptions) Descriptor() ([]byte, []int) { - return file_api_mesh_options_proto_rawDescGZIP(), []int{2} -} - -func (x *DubboDdsOptions) GetSendToGlobal() bool { - if x != nil { - return x.SendToGlobal - } - return false -} - -func (x *DubboDdsOptions) GetSendToZone() bool { - if x != nil { - return x.SendToZone - } - return false -} - -type DubboPolicyOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Whether to skip type registration for this resource. - SkipRegistration bool `protobuf:"varint,1,opt,name=skip_registration,json=skipRegistration,proto3" json:"skip_registration,omitempty"` - // An optional alternative plural form if this is unset default to a standard - // derivation of the name - Plural string `protobuf:"bytes,2,opt,name=plural,proto3" json:"plural,omitempty"` -} - -func (x *DubboPolicyOptions) Reset() { - *x = DubboPolicyOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_api_mesh_options_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DubboPolicyOptions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DubboPolicyOptions) ProtoMessage() {} - -func (x *DubboPolicyOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_options_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DubboPolicyOptions.ProtoReflect.Descriptor instead. -func (*DubboPolicyOptions) Descriptor() ([]byte, []int) { - return file_api_mesh_options_proto_rawDescGZIP(), []int{3} -} - -func (x *DubboPolicyOptions) GetSkipRegistration() bool { - if x != nil { - return x.SkipRegistration - } - return false -} - -func (x *DubboPolicyOptions) GetPlural() string { - if x != nil { - return x.Plural - } - return "" -} - var file_api_mesh_options_proto_extTypes = []protoimpl.ExtensionInfo{ { - ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtendedType: (*descriptor.MessageOptions)(nil), ExtensionType: (*DubboResourceOptions)(nil), Field: 43534533, Name: "dubbo.mesh.resource", Tag: "bytes,43534533,opt,name=resource", Filename: "api/mesh/options.proto", }, - { - ExtendedType: (*descriptorpb.MessageOptions)(nil), - ExtensionType: (*DubboPolicyOptions)(nil), - Field: 43534534, - Name: "dubbo.mesh.policy", - Tag: "bytes,43534534,opt,name=policy", - Filename: "api/mesh/options.proto", - }, } -// Extension fields to descriptorpb.MessageOptions. +// Extension fields to descriptor.MessageOptions. var ( // optional dubbo.mesh.DubboResourceOptions resource = 43534533; E_Resource = &file_api_mesh_options_proto_extTypes[0] // 'dubbo' - // optional dubbo.mesh.DubboPolicyOptions policy = 43534534; - E_Policy = &file_api_mesh_options_proto_extTypes[1] // 'dubbo' ) var File_api_mesh_options_proto protoreflect.FileDescriptor @@ -427,80 +118,25 @@ var file_api_mesh_options_proto_rawDesc = []byte{ 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x04, 0x0a, 0x14, 0x44, 0x75, 0x62, 0x62, 0x6f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x01, 0x0a, 0x14, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6b, 0x69, - 0x70, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x03, 0x64, 0x64, 0x73, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x44, 0x64, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x03, 0x64, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x02, 0x77, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x44, - 0x75, 0x62, 0x62, 0x6f, 0x57, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x02, 0x77, - 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x6b, - 0x69, 0x70, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x6f, - 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x54, 0x6f, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x27, - 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x6c, 0x75, 0x72, 0x61, - 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x44, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x65, 0x78, - 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0e, 0x69, 0x73, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, - 0x12, 0x3c, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x11, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x21, - 0x0a, 0x0c, 0x68, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x68, 0x61, 0x73, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, - 0x73, 0x22, 0x78, 0x0a, 0x0e, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x57, 0x73, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x72, 0x61, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x12, - 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x59, 0x0a, 0x0f, 0x44, - 0x75, 0x62, 0x62, 0x6f, 0x44, 0x64, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, - 0x0a, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x47, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x6f, 0x5f, - 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x65, 0x6e, 0x64, - 0x54, 0x6f, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, - 0x72, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x72, 0x61, - 0x6c, 0x3a, 0x60, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xc5, - 0x91, 0xe1, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x3a, 0x5a, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1f, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xc6, - 0x91, 0xe1, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x44, 0x75, 0x62, 0x62, 0x6f, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, - 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x6b, 0x75, 0x62, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x65, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x27, + 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x45, 0x78, 0x70, 0x65, 0x72, + 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x3a, 0x60, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xc5, 0x91, 0xe1, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x44, 0x75, 0x62, 0x62, 0x6f, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, + 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, + 0x65, 0x73, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -515,26 +151,19 @@ func file_api_mesh_options_proto_rawDescGZIP() []byte { return file_api_mesh_options_proto_rawDescData } -var file_api_mesh_options_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_api_mesh_options_proto_goTypes = []interface{}{ - (*DubboResourceOptions)(nil), // 0: dubbo.mesh.DubboResourceOptions - (*DubboWsOptions)(nil), // 1: dubbo.mesh.DubboWsOptions - (*DubboDdsOptions)(nil), // 2: dubbo.mesh.DubboDdsOptions - (*DubboPolicyOptions)(nil), // 3: dubbo.mesh.DubboPolicyOptions - (*descriptorpb.MessageOptions)(nil), // 4: google.protobuf.MessageOptions +var file_api_mesh_options_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_mesh_options_proto_goTypes = []any{ + (*DubboResourceOptions)(nil), // 0: dubbo.mesh.DubboResourceOptions + (*descriptor.MessageOptions)(nil), // 1: google.protobuf.MessageOptions } var file_api_mesh_options_proto_depIdxs = []int32{ - 2, // 0: dubbo.mesh.DubboResourceOptions.dds:type_name -> dubbo.mesh.DubboDdsOptions - 1, // 1: dubbo.mesh.DubboResourceOptions.ws:type_name -> dubbo.mesh.DubboWsOptions - 4, // 2: dubbo.mesh.resource:extendee -> google.protobuf.MessageOptions - 4, // 3: dubbo.mesh.policy:extendee -> google.protobuf.MessageOptions - 0, // 4: dubbo.mesh.resource:type_name -> dubbo.mesh.DubboResourceOptions - 3, // 5: dubbo.mesh.policy:type_name -> dubbo.mesh.DubboPolicyOptions - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 4, // [4:6] is the sub-list for extension type_name - 2, // [2:4] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 0: dubbo.mesh.resource:extendee -> google.protobuf.MessageOptions + 0, // 1: dubbo.mesh.resource:type_name -> dubbo.mesh.DubboResourceOptions + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 1, // [1:2] is the sub-list for extension type_name + 0, // [0:1] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_api_mesh_options_proto_init() } @@ -542,64 +171,14 @@ func file_api_mesh_options_proto_init() { if File_api_mesh_options_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_api_mesh_options_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DubboResourceOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_mesh_options_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DubboWsOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_mesh_options_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DubboDdsOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_mesh_options_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DubboPolicyOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_mesh_options_proto_rawDesc, NumEnums: 0, - NumMessages: 4, - NumExtensions: 2, + NumMessages: 1, + NumExtensions: 1, NumServices: 0, }, GoTypes: file_api_mesh_options_proto_goTypes, diff --git a/api/mesh/options.proto b/api/mesh/options.proto index 02dfe2f8e..840b36a70 100644 --- a/api/mesh/options.proto +++ b/api/mesh/options.proto @@ -7,81 +7,19 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh"; import "google/protobuf/descriptor.proto"; message DubboResourceOptions { - // Name of the Dubbo resource struct. + // Name and type of the dubbo resource struct. string name = 1; - // Name and value of the modelResourceType constant. - string type = 2; - - // True if this resource has global scope. Otherwise it will be mesh scope. - bool global = 3; + // The name of the resource showed as plural + string plural_name = 2; // Name of the resource's Go package. - string package = 4; - - // Whether to skip type registration for this resource. - bool skip_registration = 6; - - DubboDdsOptions dds = 10; - DubboWsOptions ws = 7; - - // Whether scope is "Namespace"; Otherwise to "Cluster". - bool scope_namespace = 11; - - // Whether to skip generation of native API helper functions. - bool skip_kubernetes_wrappers = 12; - - // Whether to generate Inspect API endpoint - bool allow_to_inspect = 13; - - // If resource has more than one version, then the flag defines which version - // is used in the storage. All other versions must be convertible to it. - bool storage_version = 14; - - // The name of the policy showed as plural to be displayed in the UI and maybe - // CLI - string plural_display_name = 15; - - // Is Experimental indicates if a policy is in experimental state (might not - // be production ready). - bool is_experimental = 16; - - // Columns to set using `+kubebuilder::printcolumns` - repeated string additional_printer_columns = 17; - - // Whether the resource has a matching insight type - bool has_insights = 18; -} - -message DubboWsOptions { - // Name is the name of the policy for resource name usage in path. - string name = 1; - // Plural is only to be set if the plural of the resource is irregular (not - // just adding a 's' at the end). - string plural = 2; - // ReadOnly if the resource is read only. - bool read_only = 3; - // AdminOnly whether this entity requires admin auth to access these - // endpoints. - bool admin_only = 4; -} - -message DubboDdsOptions { - // SendToGlobal whether this entity will be sent from zone cp to global cp - bool send_to_global = 1; - // SendToZone whether this entity will be sent from global cp to zone cp - bool send_to_zone = 2; -} + string package = 3; -message DubboPolicyOptions { - // Whether to skip type registration for this resource. - bool skip_registration = 1; - // An optional alternative plural form if this is unset default to a standard - // derivation of the name - string plural = 2; + // Is Experimental indicates if a resource is in experimental state. + bool is_experimental = 4; } extend google.protobuf.MessageOptions { DubboResourceOptions resource = 43534533; // 'dubbo' - DubboPolicyOptions policy = 43534534; // 'dubbo' } diff --git a/api/mesh/v1alpha1/affinity_route.pb.go b/api/mesh/v1alpha1/affinity_route.pb.go index 0fcda9c5e..f02703e36 100644 --- a/api/mesh/v1alpha1/affinity_route.pb.go +++ b/api/mesh/v1alpha1/affinity_route.pb.go @@ -26,12 +26,14 @@ type AffinityRoute struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ConfigVersion string `protobuf:"bytes,1,opt,name=configVersion,proto3" json:"configVersion,omitempty"` - Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` // must be chosen from `service` and `application` - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // specifies which service or application the rule body acts on - Runtime bool `protobuf:"varint,4,opt,name=runtime,proto3" json:"runtime,omitempty"` - Enabled bool `protobuf:"varint,5,opt,name=enabled,proto3" json:"enabled,omitempty"` - Affinity *AffinityAware `protobuf:"bytes,6,opt,name=affinity,proto3" json:"affinity,omitempty"` + ConfigVersion string `protobuf:"bytes,1,opt,name=configVersion,proto3" json:"configVersion,omitempty"` + // scope must be chosen from `service` and `application` + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` + // key specifies which service or application the rule body acts on + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + Runtime bool `protobuf:"varint,4,opt,name=runtime,proto3" json:"runtime,omitempty"` + Enabled bool `protobuf:"varint,5,opt,name=enabled,proto3" json:"enabled,omitempty"` + Affinity *AffinityAware `protobuf:"bytes,6,opt,name=affinity,proto3" json:"affinity,omitempty"` } func (x *AffinityRoute) Reset() { @@ -167,7 +169,7 @@ var file_api_mesh_v1alpha1_affinity_route_proto_rawDesc = []byte{ 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x02, 0x0a, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x01, 0x0a, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, @@ -180,20 +182,17 @@ var file_api_mesh_v1alpha1_affinity_route_proto_rawDesc = []byte{ 0x69, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x41, 0x77, 0x61, 0x72, 0x65, 0x52, - 0x08, 0x61, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x3a, 0x59, 0xaa, 0x8c, 0x89, 0xa6, 0x01, - 0x53, 0x0a, 0x15, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x22, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x3a, 0x1f, 0x0a, - 0x0d, 0x61, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0e, - 0x61, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x02, - 0x10, 0x01, 0x68, 0x01, 0x22, 0x37, 0x0a, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, - 0x41, 0x77, 0x61, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x42, 0x31, 0x5a, - 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, - 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x08, 0x61, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x3a, 0x2b, 0xaa, 0x8c, 0x89, 0xa6, 0x01, + 0x25, 0x0a, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x12, 0x0e, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x37, 0x0a, 0x0d, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x79, 0x41, 0x77, 0x61, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x42, + 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/mesh/v1alpha1/affinity_route.proto b/api/mesh/v1alpha1/affinity_route.proto index 7bc699867..96751ff78 100644 --- a/api/mesh/v1alpha1/affinity_route.proto +++ b/api/mesh/v1alpha1/affinity_route.proto @@ -7,17 +7,16 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; import "api/mesh/options.proto"; message AffinityRoute { - option (dubbo.mesh.resource).name = "AffinityRouteResource"; - option (dubbo.mesh.resource).type = "AffinityRoute"; + option (dubbo.mesh.resource).name = "AffinityRoute"; + option (dubbo.mesh.resource).plural_name = "AffinityRoutes"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).dds.send_to_zone = true; - option (dubbo.mesh.resource).ws.name = "affinityroute"; - option (dubbo.mesh.resource).ws.plural = "affinityroutes"; - option (dubbo.mesh.resource).allow_to_inspect = true; + option (dubbo.mesh.resource).is_experimental = false; string configVersion = 1; - string scope = 2; // must be chosen from `service` and `application` - string key = 3; // specifies which service or application the rule body acts on + // scope must be chosen from `service` and `application` + string scope = 2; + // key specifies which service or application the rule body acts on + string key = 3; bool runtime = 4; bool enabled = 5; AffinityAware affinity = 6; diff --git a/api/mesh/v1alpha1/application.pb.go b/api/mesh/v1alpha1/application.pb.go index 59777adb3..2a3b74858 100644 --- a/api/mesh/v1alpha1/application.pb.go +++ b/api/mesh/v1alpha1/application.pb.go @@ -26,8 +26,8 @@ type Application struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Features map[string]string `protobuf:"bytes,99,rep,name=features,proto3" json:"features,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + InstanceCount int64 `protobuf:"varint,2,opt,name=instanceCount,proto3" json:"instanceCount,omitempty"` } func (x *Application) Reset() { @@ -67,11 +67,11 @@ func (x *Application) GetName() string { return "" } -func (x *Application) GetFeatures() map[string]string { +func (x *Application) GetInstanceCount() int64 { if x != nil { - return x.Features + return x.InstanceCount } - return nil + return 0 } var File_api_mesh_v1alpha1_application_proto protoreflect.FileDescriptor @@ -82,26 +82,18 @@ var file_api_mesh_v1alpha1_application_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xfd, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x18, 0x63, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, - 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, - 0x51, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x4b, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b, 0x41, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x3a, - 0x1d, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0c, - 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x58, 0x01, - 0x68, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x22, 0x72, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x29, 0xaa, 0x8c, 0x89, + 0xa6, 0x01, 0x23, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x04, + 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, + 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -116,18 +108,16 @@ func file_api_mesh_v1alpha1_application_proto_rawDescGZIP() []byte { return file_api_mesh_v1alpha1_application_proto_rawDescData } -var file_api_mesh_v1alpha1_application_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_api_mesh_v1alpha1_application_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_api_mesh_v1alpha1_application_proto_goTypes = []any{ (*Application)(nil), // 0: dubbo.mesh.v1alpha1.Application - nil, // 1: dubbo.mesh.v1alpha1.Application.FeaturesEntry } var file_api_mesh_v1alpha1_application_proto_depIdxs = []int32{ - 1, // 0: dubbo.mesh.v1alpha1.Application.features:type_name -> dubbo.mesh.v1alpha1.Application.FeaturesEntry - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_api_mesh_v1alpha1_application_proto_init() } @@ -141,7 +131,7 @@ func file_api_mesh_v1alpha1_application_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_mesh_v1alpha1_application_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/api/mesh/v1alpha1/application.proto b/api/mesh/v1alpha1/application.proto index 325054d5e..f56b41873 100644 --- a/api/mesh/v1alpha1/application.proto +++ b/api/mesh/v1alpha1/application.proto @@ -8,17 +8,13 @@ import "api/mesh/options.proto"; message Application { - option (dubbo.mesh.resource).name = "ApplicationResource"; - option (dubbo.mesh.resource).type = "Application"; + option (dubbo.mesh.resource).name = "Application"; + option (dubbo.mesh.resource).plural_name = "Applications"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).ws.name = "application"; - option (dubbo.mesh.resource).ws.plural = "applications"; - option (dubbo.mesh.resource).ws.read_only = true; - option (dubbo.mesh.resource).scope_namespace = true; - option (dubbo.mesh.resource).allow_to_inspect = true; + option (dubbo.mesh.resource).is_experimental = true; string name = 1; - map features = 99; + int64 instanceCount = 2; } \ No newline at end of file diff --git a/api/mesh/v1alpha1/condition_route.pb.go b/api/mesh/v1alpha1/condition_route.pb.go index d935c579f..f9cbb44e9 100644 --- a/api/mesh/v1alpha1/condition_route.pb.go +++ b/api/mesh/v1alpha1/condition_route.pb.go @@ -26,11 +26,14 @@ type ConditionRoute struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Types that are assignable to Conditions: - // - // *ConditionRoute_ConditionsV3 - // *ConditionRoute_ConditionsV3X1 - Conditions isConditionRoute_Conditions `protobuf_oneof:"conditions"` + ConfigVersion string `protobuf:"bytes,1,opt,name=configVersion,proto3" json:"configVersion,omitempty"` + Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"` + Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"` + Force bool `protobuf:"varint,4,opt,name=force,proto3" json:"force,omitempty"` + Runtime bool `protobuf:"varint,5,opt,name=runtime,proto3" json:"runtime,omitempty"` + Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"` + Scope string `protobuf:"bytes,7,opt,name=scope,proto3" json:"scope,omitempty"` + Conditions []string `protobuf:"bytes,8,rep,name=conditions,proto3" json:"conditions,omitempty"` } func (x *ConditionRoute) Reset() { @@ -63,42 +66,61 @@ func (*ConditionRoute) Descriptor() ([]byte, []int) { return file_api_mesh_v1alpha1_condition_route_proto_rawDescGZIP(), []int{0} } -func (m *ConditionRoute) GetConditions() isConditionRoute_Conditions { - if m != nil { - return m.Conditions +func (x *ConditionRoute) GetConfigVersion() string { + if x != nil { + return x.ConfigVersion } - return nil + return "" } -func (x *ConditionRoute) GetConditionsV3() *ConditionRouteV3 { - if x, ok := x.GetConditions().(*ConditionRoute_ConditionsV3); ok { - return x.ConditionsV3 +func (x *ConditionRoute) GetPriority() int32 { + if x != nil { + return x.Priority } - return nil + return 0 } -func (x *ConditionRoute) GetConditionsV3X1() *ConditionRouteV3X1 { - if x, ok := x.GetConditions().(*ConditionRoute_ConditionsV3X1); ok { - return x.ConditionsV3X1 +func (x *ConditionRoute) GetEnabled() bool { + if x != nil { + return x.Enabled } - return nil + return false } -type isConditionRoute_Conditions interface { - isConditionRoute_Conditions() +func (x *ConditionRoute) GetForce() bool { + if x != nil { + return x.Force + } + return false } -type ConditionRoute_ConditionsV3 struct { - ConditionsV3 *ConditionRouteV3 `protobuf:"bytes,1,opt,name=conditionsV3,proto3,oneof"` +func (x *ConditionRoute) GetRuntime() bool { + if x != nil { + return x.Runtime + } + return false } -type ConditionRoute_ConditionsV3X1 struct { - ConditionsV3X1 *ConditionRouteV3X1 `protobuf:"bytes,2,opt,name=conditionsV3x1,proto3,oneof"` +func (x *ConditionRoute) GetKey() string { + if x != nil { + return x.Key + } + return "" } -func (*ConditionRoute_ConditionsV3) isConditionRoute_Conditions() {} +func (x *ConditionRoute) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} -func (*ConditionRoute_ConditionsV3X1) isConditionRoute_Conditions() {} +func (x *ConditionRoute) GetConditions() []string { + if x != nil { + return x.Conditions + } + return nil +} type ConditionRule struct { state protoimpl.MessageState @@ -251,200 +273,6 @@ func (x *ConditionRuleTo) GetWeight() int32 { return 0 } -type ConditionRouteV3 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ConfigVersion string `protobuf:"bytes,1,opt,name=configVersion,proto3" json:"configVersion,omitempty"` - Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"` - Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"` - Force bool `protobuf:"varint,4,opt,name=force,proto3" json:"force,omitempty"` - Runtime bool `protobuf:"varint,5,opt,name=runtime,proto3" json:"runtime,omitempty"` - Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"` - Scope string `protobuf:"bytes,7,opt,name=scope,proto3" json:"scope,omitempty"` - Conditions []string `protobuf:"bytes,8,rep,name=conditions,proto3" json:"conditions,omitempty"` -} - -func (x *ConditionRouteV3) Reset() { - *x = ConditionRouteV3{} - mi := &file_api_mesh_v1alpha1_condition_route_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConditionRouteV3) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConditionRouteV3) ProtoMessage() {} - -func (x *ConditionRouteV3) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_v1alpha1_condition_route_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConditionRouteV3.ProtoReflect.Descriptor instead. -func (*ConditionRouteV3) Descriptor() ([]byte, []int) { - return file_api_mesh_v1alpha1_condition_route_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *ConditionRouteV3) GetConfigVersion() string { - if x != nil { - return x.ConfigVersion - } - return "" -} - -func (x *ConditionRouteV3) GetPriority() int32 { - if x != nil { - return x.Priority - } - return 0 -} - -func (x *ConditionRouteV3) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *ConditionRouteV3) GetForce() bool { - if x != nil { - return x.Force - } - return false -} - -func (x *ConditionRouteV3) GetRuntime() bool { - if x != nil { - return x.Runtime - } - return false -} - -func (x *ConditionRouteV3) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *ConditionRouteV3) GetScope() string { - if x != nil { - return x.Scope - } - return "" -} - -func (x *ConditionRouteV3) GetConditions() []string { - if x != nil { - return x.Conditions - } - return nil -} - -type ConditionRouteV3X1 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ConfigVersion string `protobuf:"bytes,1,opt,name=configVersion,proto3" json:"configVersion,omitempty"` - Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` // must be chosen from `service` and `application` - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // specifies which service or application the rule body acts on - Force bool `protobuf:"varint,4,opt,name=force,proto3" json:"force,omitempty"` - Runtime bool `protobuf:"varint,5,opt,name=runtime,proto3" json:"runtime,omitempty"` - Enabled bool `protobuf:"varint,6,opt,name=enabled,proto3" json:"enabled,omitempty"` - Conditions []*ConditionRule `protobuf:"bytes,8,rep,name=conditions,proto3" json:"conditions,omitempty"` -} - -func (x *ConditionRouteV3X1) Reset() { - *x = ConditionRouteV3X1{} - mi := &file_api_mesh_v1alpha1_condition_route_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConditionRouteV3X1) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConditionRouteV3X1) ProtoMessage() {} - -func (x *ConditionRouteV3X1) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_v1alpha1_condition_route_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConditionRouteV3X1.ProtoReflect.Descriptor instead. -func (*ConditionRouteV3X1) Descriptor() ([]byte, []int) { - return file_api_mesh_v1alpha1_condition_route_proto_rawDescGZIP(), []int{0, 1} -} - -func (x *ConditionRouteV3X1) GetConfigVersion() string { - if x != nil { - return x.ConfigVersion - } - return "" -} - -func (x *ConditionRouteV3X1) GetScope() string { - if x != nil { - return x.Scope - } - return "" -} - -func (x *ConditionRouteV3X1) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *ConditionRouteV3X1) GetForce() bool { - if x != nil { - return x.Force - } - return false -} - -func (x *ConditionRouteV3X1) GetRuntime() bool { - if x != nil { - return x.Runtime - } - return false -} - -func (x *ConditionRouteV3X1) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *ConditionRouteV3X1) GetConditions() []*ConditionRule { - if x != nil { - return x.Conditions - } - return nil -} - var File_api_mesh_v1alpha1_condition_route_proto protoreflect.FileDescriptor var file_api_mesh_v1alpha1_condition_route_proto_rawDesc = []byte{ @@ -453,72 +281,43 @@ var file_api_mesh_v1alpha1_condition_route_proto_rawDesc = []byte{ 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdf, 0x05, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x33, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x76, 0x33, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x33, 0x12, 0x52, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x33, 0x78, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x76, 0x33, 0x78, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x33, 0x78, 0x31, 0x1a, 0xd8, 0x01, 0x0a, 0x02, - 0x76, 0x33, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xe2, 0x01, 0x0a, 0x04, 0x76, 0x33, 0x78, 0x31, 0x12, - 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x75, - 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x5d, 0xaa, 0x8c, 0x89, - 0xa6, 0x01, 0x57, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x22, 0x04, 0x6d, 0x65, 0x73, - 0x68, 0x3a, 0x21, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x73, 0x52, 0x02, 0x10, 0x01, 0x68, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x3a, 0x0a, 0x04, 0x66, 0x72, - 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x46, 0x72, 0x6f, 0x6d, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x34, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x6f, 0x52, 0x02, 0x74, 0x6f, 0x22, 0x29, 0x0a, 0x11, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x46, 0x72, 0x6f, - 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x3f, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, - 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, - 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x93, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x2d, 0xaa, + 0x8c, 0x89, 0xa6, 0x01, 0x27, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0f, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x81, 0x01, 0x0a, + 0x0d, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x3a, + 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x64, + 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, + 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x34, 0x0a, 0x02, 0x74, 0x6f, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x6f, 0x52, 0x02, 0x74, 0x6f, + 0x22, 0x29, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, + 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x3f, 0x0a, 0x0f, 0x43, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x42, 0x31, 0x5a, 0x2f, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, + 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -533,26 +332,21 @@ func file_api_mesh_v1alpha1_condition_route_proto_rawDescGZIP() []byte { return file_api_mesh_v1alpha1_condition_route_proto_rawDescData } -var file_api_mesh_v1alpha1_condition_route_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_api_mesh_v1alpha1_condition_route_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_api_mesh_v1alpha1_condition_route_proto_goTypes = []any{ - (*ConditionRoute)(nil), // 0: dubbo.mesh.v1alpha1.ConditionRoute - (*ConditionRule)(nil), // 1: dubbo.mesh.v1alpha1.ConditionRule - (*ConditionRuleFrom)(nil), // 2: dubbo.mesh.v1alpha1.ConditionRuleFrom - (*ConditionRuleTo)(nil), // 3: dubbo.mesh.v1alpha1.ConditionRuleTo - (*ConditionRouteV3)(nil), // 4: dubbo.mesh.v1alpha1.ConditionRoute.v3 - (*ConditionRouteV3X1)(nil), // 5: dubbo.mesh.v1alpha1.ConditionRoute.v3x1 + (*ConditionRoute)(nil), // 0: dubbo.mesh.v1alpha1.ConditionRoute + (*ConditionRule)(nil), // 1: dubbo.mesh.v1alpha1.ConditionRule + (*ConditionRuleFrom)(nil), // 2: dubbo.mesh.v1alpha1.ConditionRuleFrom + (*ConditionRuleTo)(nil), // 3: dubbo.mesh.v1alpha1.ConditionRuleTo } var file_api_mesh_v1alpha1_condition_route_proto_depIdxs = []int32{ - 4, // 0: dubbo.mesh.v1alpha1.ConditionRoute.conditionsV3:type_name -> dubbo.mesh.v1alpha1.ConditionRoute.v3 - 5, // 1: dubbo.mesh.v1alpha1.ConditionRoute.conditionsV3x1:type_name -> dubbo.mesh.v1alpha1.ConditionRoute.v3x1 - 2, // 2: dubbo.mesh.v1alpha1.ConditionRule.from:type_name -> dubbo.mesh.v1alpha1.ConditionRuleFrom - 3, // 3: dubbo.mesh.v1alpha1.ConditionRule.to:type_name -> dubbo.mesh.v1alpha1.ConditionRuleTo - 1, // 4: dubbo.mesh.v1alpha1.ConditionRoute.v3x1.conditions:type_name -> dubbo.mesh.v1alpha1.ConditionRule - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 2, // 0: dubbo.mesh.v1alpha1.ConditionRule.from:type_name -> dubbo.mesh.v1alpha1.ConditionRuleFrom + 3, // 1: dubbo.mesh.v1alpha1.ConditionRule.to:type_name -> dubbo.mesh.v1alpha1.ConditionRuleTo + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_api_mesh_v1alpha1_condition_route_proto_init() } @@ -560,17 +354,13 @@ func file_api_mesh_v1alpha1_condition_route_proto_init() { if File_api_mesh_v1alpha1_condition_route_proto != nil { return } - file_api_mesh_v1alpha1_condition_route_proto_msgTypes[0].OneofWrappers = []any{ - (*ConditionRoute_ConditionsV3)(nil), - (*ConditionRoute_ConditionsV3X1)(nil), - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_mesh_v1alpha1_condition_route_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/api/mesh/v1alpha1/condition_route.proto b/api/mesh/v1alpha1/condition_route.proto index 797d94707..b2a9870ba 100644 --- a/api/mesh/v1alpha1/condition_route.proto +++ b/api/mesh/v1alpha1/condition_route.proto @@ -7,15 +7,11 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; import "api/mesh/options.proto"; message ConditionRoute { - option (dubbo.mesh.resource).name = "ConditionRouteResource"; - option (dubbo.mesh.resource).type = "ConditionRoute"; + option (dubbo.mesh.resource).name = "ConditionRoute"; + option (dubbo.mesh.resource).plural_name = "ConditionRoutes"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).dds.send_to_zone = true; - option (dubbo.mesh.resource).ws.name = "conditionroute"; - option (dubbo.mesh.resource).ws.plural = "conditionroutes"; - option (dubbo.mesh.resource).allow_to_inspect = true; + option (dubbo.mesh.resource).is_experimental = false; - message v3 { string configVersion = 1; int32 priority = 2; bool enabled = 3; @@ -24,22 +20,6 @@ message ConditionRoute { string key = 6; string scope = 7; repeated string conditions = 8; - } - - message v3x1 { - string configVersion = 1; - string scope = 2; // must be chosen from `service` and `application` - string key = 3; // specifies which service or application the rule body acts on - bool force = 4; - bool runtime = 5; - bool enabled = 6; - repeated ConditionRule conditions = 8; - } - - oneof conditions { - v3 conditionsV3 = 1; - v3x1 conditionsV3x1 = 2; - } } message ConditionRule { diff --git a/api/mesh/v1alpha1/condition_route_helper.go b/api/mesh/v1alpha1/condition_route_helper.go index 7fb21235b..169ac422b 100644 --- a/api/mesh/v1alpha1/condition_route_helper.go +++ b/api/mesh/v1alpha1/condition_route_helper.go @@ -20,120 +20,14 @@ package v1alpha1 import ( "strings" - "github.com/pkg/errors" - "sigs.k8s.io/yaml" - - "github.com/apache/dubbo-admin/pkg/common/util/proto" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/common/constants" ) -func (x *ConditionRoute) GetVersion() string { - if x.ToConditionRouteV3() != nil { - return consts.ConfiguratorVersionV3 - } else { - return consts.ConfiguratorVersionV3x1 - } -} - -func (x *ConditionRoute) ToYAML() ([]byte, error) { - if msg := x.ToConditionRouteV3x1(); msg != nil { - return proto.ToYAML(msg) - } else if msg := x.ToConditionRouteV3(); msg != nil { - return proto.ToYAML(msg) - } - return nil, errors.New(`ConditionRoute validation failed`) -} - -func ConditionRouteDecodeFromYAML(content []byte) (*ConditionRoute, error) { - _map := map[string]interface{}{} - err := yaml.Unmarshal(content, &_map) - if err != nil { - return nil, err - } - - version, ok := _map[consts.ConfigVersionKey].(string) - if !ok { - return nil, errors.New("invalid condition route format") - } - if version == consts.ConfiguratorVersionV3 { - v3 := new(ConditionRouteV3) - if err = proto.FromYAML(content, v3); err != nil { - return nil, err - } - return v3.ToConditionRoute(), nil - } else if version == consts.ConfiguratorVersionV3x1 { - v3x1 := new(ConditionRouteV3X1) - if err = proto.FromYAML(content, v3x1); err != nil { - return nil, err - } - return v3x1.ToConditionRoute(), nil - } else { - return nil, errors.New("invalid condition route format") - } -} - -func (x *ConditionRouteV3) ToConditionRoute() *ConditionRoute { - return &ConditionRoute{Conditions: &ConditionRoute_ConditionsV3{ConditionsV3: x}} -} - -func (x *ConditionRouteV3X1) ToConditionRoute() *ConditionRoute { - return &ConditionRoute{Conditions: &ConditionRoute_ConditionsV3X1{ConditionsV3X1: x}} -} - -func (x *ConditionRoute) ToConditionRouteV3() *ConditionRouteV3 { - if v, ok := x.Conditions.(*ConditionRoute_ConditionsV3); ok { - return v.ConditionsV3 - } - return nil -} - -func (x *ConditionRoute) ToConditionRouteV3x1() *ConditionRouteV3X1 { - if v, ok := x.Conditions.(*ConditionRoute_ConditionsV3X1); ok { - return v.ConditionsV3X1 - } - return nil -} - -func (x *ConditionRouteV3X1) RangeConditions(f func(r *ConditionRule) (isStop bool)) { - if f == nil { - return - } - for _, condition := range x.Conditions { - if condition != nil && f(condition) { - break - } - } -} - -func (x *ConditionRouteV3) RangeConditions(f func(condition string) (isStop bool)) { - if f == nil { - return - } - for _, condition := range x.Conditions { - if f(condition) { - break - } - } -} - -func (x *ConditionRouteV3X1) RangeConditionsToRemove(f func(r *ConditionRule) (isRemove bool)) { - if f == nil { - return - } - res := make([]*ConditionRule, 0, len(x.Conditions)/2+1) - for _, condition := range x.Conditions { - if condition != nil && !f(condition) { - res = append(res, condition) - } - } - x.Conditions = res -} - func (x *ConditionRule) IsMatchMethod() (string, bool) { conditions := strings.Split(x.From.Match, "&") for _, condition := range conditions { if idx := strings.Index(condition, "method"); idx != -1 { - args := strings.Split(condition, consts.Equal) + args := strings.Split(condition, constants.Equal) if len(args) == 2 { return strings.TrimSpace(args[1]), true } diff --git a/api/mesh/v1alpha1/dynamic_config.pb.go b/api/mesh/v1alpha1/dynamic_config.pb.go index 0d7e04e91..a5bbf5d18 100644 --- a/api/mesh/v1alpha1/dynamic_config.pb.go +++ b/api/mesh/v1alpha1/dynamic_config.pb.go @@ -409,7 +409,7 @@ var file_api_mesh_v1alpha1_dynamic_config_proto_rawDesc = []byte{ 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x61, 0x67, 0x5f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, 0x02, 0x0a, 0x0d, 0x44, 0x79, 0x6e, + 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe3, 0x01, 0x0a, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, @@ -421,77 +421,74 @@ var file_api_mesh_v1alpha1_dynamic_config_proto_rawDesc = []byte{ 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x3a, 0x59, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x53, 0x0a, 0x15, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, - 0x04, 0x6d, 0x65, 0x73, 0x68, 0x3a, 0x1f, 0x0a, 0x0d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x02, 0x10, 0x01, 0x68, 0x01, 0x22, 0xd5, 0x03, 0x0a, - 0x0e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x12, 0x0a, 0x04, 0x73, 0x69, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, - 0x69, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, - 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, - 0x53, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x26, 0x0a, - 0x10, 0x5f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x79, 0x5f, 0x63, - 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x42, 0x79, 0x43, 0x70, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd9, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0b, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x22, 0x54, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x63, 0x69, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x72, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x22, 0x49, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x05, 0x6f, 0x6e, 0x65, - 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6f, 0x6e, 0x65, 0x6f, - 0x66, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x3a, 0x2b, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x25, 0x0a, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0xd5, + 0x03, 0x0a, 0x0e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x73, 0x69, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x12, 0x53, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x26, 0x0a, 0x10, 0x5f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x79, + 0x5f, 0x63, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x42, 0x79, 0x43, 0x70, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd9, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, + 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0b, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x22, 0x54, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x69, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, + 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x22, 0x49, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x05, 0x6f, + 0x6e, 0x65, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6f, 0x6e, + 0x65, 0x6f, 0x66, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/mesh/v1alpha1/dynamic_config.proto b/api/mesh/v1alpha1/dynamic_config.proto index 7ebd20909..7521494a8 100644 --- a/api/mesh/v1alpha1/dynamic_config.proto +++ b/api/mesh/v1alpha1/dynamic_config.proto @@ -8,14 +8,10 @@ import "api/mesh/options.proto"; import "api/mesh/v1alpha1/tag_route.proto"; message DynamicConfig { - option (dubbo.mesh.resource).name = "DynamicConfigResource"; - option (dubbo.mesh.resource).type = "DynamicConfig"; + option (dubbo.mesh.resource).name = "DynamicConfig"; + option (dubbo.mesh.resource).plural_name = "DynamicConfigs"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).dds.send_to_zone = true; - option (dubbo.mesh.resource).ws.name = "dynamicconfig"; - option (dubbo.mesh.resource).ws.plural = "dynamicconfigs"; - option (dubbo.mesh.resource).allow_to_inspect = true; - + option (dubbo.mesh.resource).is_experimental = false; string key = 1; string scope = 2; string configVersion = 3; diff --git a/api/mesh/v1alpha1/dynamic_config_helper.go b/api/mesh/v1alpha1/dynamic_config_helper.go index 26d666a02..631c2cb2a 100644 --- a/api/mesh/v1alpha1/dynamic_config_helper.go +++ b/api/mesh/v1alpha1/dynamic_config_helper.go @@ -20,12 +20,12 @@ package v1alpha1 import ( "strings" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/common/constants" ) func GetOverridePath(key string) string { key = strings.Replace(key, "/", "*", -1) - return key + consts.ConfiguratorRuleSuffix + return key + constants.ConfiguratorRuleDotSuffix } func (d *DynamicConfig) ListUnGenConfigs() []*OverrideConfig { diff --git a/api/mesh/v1alpha1/instance.pb.go b/api/mesh/v1alpha1/instance.pb.go index 38ab8a4a0..25bcfc4d0 100644 --- a/api/mesh/v1alpha1/instance.pb.go +++ b/api/mesh/v1alpha1/instance.pb.go @@ -21,21 +21,35 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Instance is merged from RuntimeInstance and RPCInstance, indicates a runtime entity of a specific dubbo application type Instance struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` - Port string `protobuf:"bytes,3,opt,name=port,proto3" json:"port,omitempty"` - Image string `protobuf:"bytes,4,opt,name=image,proto3" json:"image,omitempty"` - AppName string `protobuf:"bytes,5,opt,name=appName,proto3" json:"appName,omitempty"` - CreateTime string `protobuf:"bytes,6,opt,name=createTime,proto3" json:"createTime,omitempty"` - StartTime string `protobuf:"bytes,7,opt,name=startTime,proto3" json:"startTime,omitempty"` - ReadyTime string `protobuf:"bytes,8,opt,name=readyTime,proto3" json:"readyTime,omitempty"` - RegisterTime string `protobuf:"bytes,9,opt,name=registerTime,proto3" json:"registerTime,omitempty"` - Features map[string]string `protobuf:"bytes,99,rep,name=features,proto3" json:"features,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AppName string `protobuf:"bytes,2,opt,name=appName,proto3" json:"appName,omitempty"` + Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` + RpcPort int64 `protobuf:"varint,4,opt,name=rpcPort,proto3" json:"rpcPort,omitempty"` + QosPort int64 `protobuf:"varint,5,opt,name=qosPort,proto3" json:"qosPort,omitempty"` + ReleaseVersion string `protobuf:"bytes,6,opt,name=releaseVersion,proto3" json:"releaseVersion,omitempty"` + RegisterTime string `protobuf:"bytes,7,opt,name=registerTime,proto3" json:"registerTime,omitempty"` + UnregisterTime string `protobuf:"bytes,8,opt,name=unregisterTime,proto3" json:"unregisterTime,omitempty"` + Protocol string `protobuf:"bytes,9,opt,name=protocol,proto3" json:"protocol,omitempty"` + Serialization string `protobuf:"bytes,10,opt,name=serialization,proto3" json:"serialization,omitempty"` + PreferSerialization string `protobuf:"bytes,11,opt,name=preferSerialization,proto3" json:"preferSerialization,omitempty"` + Tags map[string]string `protobuf:"bytes,50,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Image string `protobuf:"bytes,51,opt,name=image,proto3" json:"image,omitempty"` + CreateTime string `protobuf:"bytes,52,opt,name=createTime,proto3" json:"createTime,omitempty"` + StartTime string `protobuf:"bytes,53,opt,name=startTime,proto3" json:"startTime,omitempty"` + ReadyTime string `protobuf:"bytes,54,opt,name=readyTime,proto3" json:"readyTime,omitempty"` + DeployState string `protobuf:"bytes,55,opt,name=deployState,proto3" json:"deployState,omitempty"` + WorkloadType string `protobuf:"bytes,56,opt,name=workloadType,proto3" json:"workloadType,omitempty"` + WorkloadName string `protobuf:"bytes,57,opt,name=workloadName,proto3" json:"workloadName,omitempty"` + Node string `protobuf:"bytes,58,opt,name=node,proto3" json:"node,omitempty"` + SourceEngine string `protobuf:"bytes,59,opt,name=sourceEngine,proto3" json:"sourceEngine,omitempty"` + Probes []*Probe `protobuf:"bytes,99,rep,name=probes,proto3" json:"probes,omitempty"` + Conditions []*Condition `protobuf:"bytes,100,rep,name=conditions,proto3" json:"conditions,omitempty"` } func (x *Instance) Reset() { @@ -75,6 +89,13 @@ func (x *Instance) GetName() string { return "" } +func (x *Instance) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + func (x *Instance) GetIp() string { if x != nil { return x.Ip @@ -82,23 +103,72 @@ func (x *Instance) GetIp() string { return "" } -func (x *Instance) GetPort() string { +func (x *Instance) GetRpcPort() int64 { if x != nil { - return x.Port + return x.RpcPort + } + return 0 +} + +func (x *Instance) GetQosPort() int64 { + if x != nil { + return x.QosPort + } + return 0 +} + +func (x *Instance) GetReleaseVersion() string { + if x != nil { + return x.ReleaseVersion } return "" } -func (x *Instance) GetImage() string { +func (x *Instance) GetRegisterTime() string { if x != nil { - return x.Image + return x.RegisterTime } return "" } -func (x *Instance) GetAppName() string { +func (x *Instance) GetUnregisterTime() string { if x != nil { - return x.AppName + return x.UnregisterTime + } + return "" +} + +func (x *Instance) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *Instance) GetSerialization() string { + if x != nil { + return x.Serialization + } + return "" +} + +func (x *Instance) GetPreferSerialization() string { + if x != nil { + return x.PreferSerialization + } + return "" +} + +func (x *Instance) GetTags() map[string]string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Instance) GetImage() string { + if x != nil { + return x.Image } return "" } @@ -124,16 +194,51 @@ func (x *Instance) GetReadyTime() string { return "" } -func (x *Instance) GetRegisterTime() string { +func (x *Instance) GetDeployState() string { if x != nil { - return x.RegisterTime + return x.DeployState } return "" } -func (x *Instance) GetFeatures() map[string]string { +func (x *Instance) GetWorkloadType() string { + if x != nil { + return x.WorkloadType + } + return "" +} + +func (x *Instance) GetWorkloadName() string { + if x != nil { + return x.WorkloadName + } + return "" +} + +func (x *Instance) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *Instance) GetSourceEngine() string { + if x != nil { + return x.SourceEngine + } + return "" +} + +func (x *Instance) GetProbes() []*Probe { + if x != nil { + return x.Probes + } + return nil +} + +func (x *Instance) GetConditions() []*Condition { if x != nil { - return x.Features + return x.Conditions } return nil } @@ -145,39 +250,71 @@ var file_api_mesh_v1alpha1_instance_proto_rawDesc = []byte{ 0x68, 0x61, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xbf, 0x03, 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, - 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, + 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x28, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x93, 0x07, 0x0a, 0x08, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, + 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x71, 0x6f, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x71, 0x6f, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x18, 0x63, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x3b, 0x0a, - 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x45, 0xaa, 0x8c, 0x89, 0xa6, - 0x01, 0x3f, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x04, - 0x6d, 0x65, 0x73, 0x68, 0x3a, 0x17, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x12, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x58, 0x01, 0x68, - 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x75, 0x6e, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, + 0x0a, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x32, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x54, 0x61, + 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x33, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x18, 0x35, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x36, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x37, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x38, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x39, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, + 0x65, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x0a, + 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x3b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x12, 0x32, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x18, 0x63, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x06, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x64, 0x75, 0x62, 0x62, + 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x23, + 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x1d, 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x12, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, + 0x68, 0x20, 0x01, 0x4a, 0x04, 0x08, 0x0c, 0x10, 0x32, 0x4a, 0x04, 0x08, 0x3c, 0x10, 0x63, 0x42, + 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -194,16 +331,20 @@ func file_api_mesh_v1alpha1_instance_proto_rawDescGZIP() []byte { var file_api_mesh_v1alpha1_instance_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_api_mesh_v1alpha1_instance_proto_goTypes = []any{ - (*Instance)(nil), // 0: dubbo.mesh.v1alpha1.Instance - nil, // 1: dubbo.mesh.v1alpha1.Instance.FeaturesEntry + (*Instance)(nil), // 0: dubbo.mesh.v1alpha1.Instance + nil, // 1: dubbo.mesh.v1alpha1.Instance.TagsEntry + (*Probe)(nil), // 2: dubbo.mesh.v1alpha1.Probe + (*Condition)(nil), // 3: dubbo.mesh.v1alpha1.Condition } var file_api_mesh_v1alpha1_instance_proto_depIdxs = []int32{ - 1, // 0: dubbo.mesh.v1alpha1.Instance.features:type_name -> dubbo.mesh.v1alpha1.Instance.FeaturesEntry - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 1, // 0: dubbo.mesh.v1alpha1.Instance.tags:type_name -> dubbo.mesh.v1alpha1.Instance.TagsEntry + 2, // 1: dubbo.mesh.v1alpha1.Instance.probes:type_name -> dubbo.mesh.v1alpha1.Probe + 3, // 2: dubbo.mesh.v1alpha1.Instance.conditions:type_name -> dubbo.mesh.v1alpha1.Condition + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_api_mesh_v1alpha1_instance_proto_init() } @@ -211,6 +352,7 @@ func file_api_mesh_v1alpha1_instance_proto_init() { if File_api_mesh_v1alpha1_instance_proto != nil { return } + file_api_mesh_v1alpha1_runtime_instance_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/mesh/v1alpha1/instance.proto b/api/mesh/v1alpha1/instance.proto index 02f5acf91..f9bf9375f 100644 --- a/api/mesh/v1alpha1/instance.proto +++ b/api/mesh/v1alpha1/instance.proto @@ -5,35 +5,69 @@ package dubbo.mesh.v1alpha1; option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; import "api/mesh/options.proto"; +import "api/mesh/v1alpha1/runtime_instance.proto"; - +// Instance is merged from RuntimeInstance and RPCInstance, indicates a runtime entity of a specific dubbo application message Instance { - option (dubbo.mesh.resource).name = "InstanceResource"; - option (dubbo.mesh.resource).type = "Instance"; + option (dubbo.mesh.resource).name = "Instance"; + option (dubbo.mesh.resource).plural_name = "Instances"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).ws.name = "instance"; - option (dubbo.mesh.resource).ws.plural = "instances"; - option (dubbo.mesh.resource).ws.read_only = true; - option (dubbo.mesh.resource).scope_namespace = true; - option (dubbo.mesh.resource).allow_to_inspect = true; + option (dubbo.mesh.resource).is_experimental = true; string name = 1; - string ip = 2; + string appName = 2; + + string ip = 3; + + int64 rpcPort = 4; + /* + FROM RPCInstance + */ + + int64 qosPort = 5; + + string releaseVersion = 6; + + string registerTime = 7; + + string unregisterTime = 8; + + string protocol = 9; + + string serialization = 10; + + string preferSerialization = 11; + + map tags = 50; + + reserved 12 to 49; + + /* + FROM RuntimeInstance + */ + + string image = 51; + + string createTime = 52; + + string startTime = 53; + + string readyTime = 54; - string port = 3; + string deployState = 55; - string image = 4; + string workloadType = 56; - string appName = 5; + string workloadName = 57; - string createTime = 6; + string node = 58; - string startTime = 7; + string sourceEngine = 59; - string readyTime = 8; + repeated Probe probes = 99; - string registerTime = 9; + repeated Condition conditions = 100; - map features = 99; + reserved 60 to 98; } \ No newline at end of file diff --git a/api/mesh/v1alpha1/known_backends.go b/api/mesh/v1alpha1/known_backends.go deleted file mode 100644 index 54cd87ecc..000000000 --- a/api/mesh/v1alpha1/known_backends.go +++ /dev/null @@ -1,11 +0,0 @@ -package v1alpha1 - -const ( - LoggingTcpType = "tcp" - LoggingFileType = "file" - - TracingZipkinType = "zipkin" - TracingDatadogType = "datadog" - - MetricsPrometheusType = "prometheus" -) diff --git a/api/mesh/v1alpha1/mapping.pb.go b/api/mesh/v1alpha1/mapping.pb.go deleted file mode 100644 index 45cc9eb3e..000000000 --- a/api/mesh/v1alpha1/mapping.pb.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/mesh/v1alpha1/mapping.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Mapping struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Zone string `protobuf:"bytes,1,opt,name=zone,proto3" json:"zone,omitempty"` - InterfaceName string `protobuf:"bytes,2,opt,name=interfaceName,proto3" json:"interfaceName,omitempty"` - ApplicationNames []string `protobuf:"bytes,3,rep,name=applicationNames,proto3" json:"applicationNames,omitempty"` -} - -func (x *Mapping) Reset() { - *x = Mapping{} - mi := &file_api_mesh_v1alpha1_mapping_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Mapping) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Mapping) ProtoMessage() {} - -func (x *Mapping) ProtoReflect() protoreflect.Message { - mi := &file_api_mesh_v1alpha1_mapping_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Mapping.ProtoReflect.Descriptor instead. -func (*Mapping) Descriptor() ([]byte, []int) { - return file_api_mesh_v1alpha1_mapping_proto_rawDescGZIP(), []int{0} -} - -func (x *Mapping) GetZone() string { - if x != nil { - return x.Zone - } - return "" -} - -func (x *Mapping) GetInterfaceName() string { - if x != nil { - return x.InterfaceName - } - return "" -} - -func (x *Mapping) GetApplicationNames() []string { - if x != nil { - return x.ApplicationNames - } - return nil -} - -var File_api_mesh_v1alpha1_mapping_proto protoreflect.FileDescriptor - -var file_api_mesh_v1alpha1_mapping_proto_rawDesc = []byte{ - 0x0a, 0x1f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, - 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, - 0x01, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, - 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x24, - 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, - 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x3a, 0x45, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x3f, 0x0a, 0x0f, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x07, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x22, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x3a, 0x13, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x12, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x08, - 0x01, 0x10, 0x01, 0x58, 0x01, 0x68, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, - 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_api_mesh_v1alpha1_mapping_proto_rawDescOnce sync.Once - file_api_mesh_v1alpha1_mapping_proto_rawDescData = file_api_mesh_v1alpha1_mapping_proto_rawDesc -) - -func file_api_mesh_v1alpha1_mapping_proto_rawDescGZIP() []byte { - file_api_mesh_v1alpha1_mapping_proto_rawDescOnce.Do(func() { - file_api_mesh_v1alpha1_mapping_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_mapping_proto_rawDescData) - }) - return file_api_mesh_v1alpha1_mapping_proto_rawDescData -} - -var file_api_mesh_v1alpha1_mapping_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_api_mesh_v1alpha1_mapping_proto_goTypes = []any{ - (*Mapping)(nil), // 0: dubbo.mesh.v1alpha1.Mapping -} -var file_api_mesh_v1alpha1_mapping_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_api_mesh_v1alpha1_mapping_proto_init() } -func file_api_mesh_v1alpha1_mapping_proto_init() { - if File_api_mesh_v1alpha1_mapping_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_mesh_v1alpha1_mapping_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_mesh_v1alpha1_mapping_proto_goTypes, - DependencyIndexes: file_api_mesh_v1alpha1_mapping_proto_depIdxs, - MessageInfos: file_api_mesh_v1alpha1_mapping_proto_msgTypes, - }.Build() - File_api_mesh_v1alpha1_mapping_proto = out.File - file_api_mesh_v1alpha1_mapping_proto_rawDesc = nil - file_api_mesh_v1alpha1_mapping_proto_goTypes = nil - file_api_mesh_v1alpha1_mapping_proto_depIdxs = nil -} diff --git a/api/mesh/v1alpha1/mapping.proto b/api/mesh/v1alpha1/mapping.proto deleted file mode 100644 index 6c617b556..000000000 --- a/api/mesh/v1alpha1/mapping.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -package dubbo.mesh.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; - -import "api/mesh/options.proto"; - -message Mapping { - option (dubbo.mesh.resource).name = "MappingResource"; - option (dubbo.mesh.resource).type = "Mapping"; - option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).dds.send_to_global = true; - option (dubbo.mesh.resource).dds.send_to_zone = true; - option (dubbo.mesh.resource).ws.name = "mapping"; - option (dubbo.mesh.resource).ws.plural = "mappings"; - option (dubbo.mesh.resource).scope_namespace = true; - option (dubbo.mesh.resource).allow_to_inspect = true; - - string zone = 1; - string interfaceName = 2; - repeated string applicationNames = 3; -} diff --git a/api/mesh/v1alpha1/nacos_config.pb.go b/api/mesh/v1alpha1/nacos_config.pb.go new file mode 100644 index 000000000..c1a01c060 --- /dev/null +++ b/api/mesh/v1alpha1/nacos_config.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/nacos_config.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Nacos config is the raw data of nacos configuration +type NacosConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DataId string `protobuf:"bytes,1,opt,name=dataId,proto3" json:"dataId,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *NacosConfig) Reset() { + *x = NacosConfig{} + mi := &file_api_mesh_v1alpha1_nacos_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NacosConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NacosConfig) ProtoMessage() {} + +func (x *NacosConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_nacos_config_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NacosConfig.ProtoReflect.Descriptor instead. +func (*NacosConfig) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_nacos_config_proto_rawDescGZIP(), []int{0} +} + +func (x *NacosConfig) GetDataId() string { + if x != nil { + return x.DataId + } + return "" +} + +func (x *NacosConfig) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +var File_api_mesh_v1alpha1_nacos_config_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_nacos_config_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, + 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x0b, 0x4e, 0x61, 0x63, 0x6f, 0x73, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x74, 0x61, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x64, 0x61, 0x74, 0x61, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x29, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x23, 0x0a, 0x0b, 0x4e, 0x61, + 0x63, 0x6f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0c, 0x4e, 0x61, 0x63, 0x6f, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, 0x42, + 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_nacos_config_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_nacos_config_proto_rawDescData = file_api_mesh_v1alpha1_nacos_config_proto_rawDesc +) + +func file_api_mesh_v1alpha1_nacos_config_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_nacos_config_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_nacos_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_nacos_config_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_nacos_config_proto_rawDescData +} + +var file_api_mesh_v1alpha1_nacos_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_mesh_v1alpha1_nacos_config_proto_goTypes = []any{ + (*NacosConfig)(nil), // 0: dubbo.mesh.v1alpha1.NacosConfig +} +var file_api_mesh_v1alpha1_nacos_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_nacos_config_proto_init() } +func file_api_mesh_v1alpha1_nacos_config_proto_init() { + if File_api_mesh_v1alpha1_nacos_config_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_nacos_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_nacos_config_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_nacos_config_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_nacos_config_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_nacos_config_proto = out.File + file_api_mesh_v1alpha1_nacos_config_proto_rawDesc = nil + file_api_mesh_v1alpha1_nacos_config_proto_goTypes = nil + file_api_mesh_v1alpha1_nacos_config_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/nacos_config.proto b/api/mesh/v1alpha1/nacos_config.proto new file mode 100644 index 000000000..81b19e019 --- /dev/null +++ b/api/mesh/v1alpha1/nacos_config.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +// Nacos config is the raw data of nacos configuration +message NacosConfig { + option (dubbo.mesh.resource).name = "NacosConfig"; + option (dubbo.mesh.resource).plural_name = "NacosConfigs"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string dataId = 1; + + string content = 2; +} \ No newline at end of file diff --git a/api/mesh/v1alpha1/nacos_service.pb.go b/api/mesh/v1alpha1/nacos_service.pb.go new file mode 100644 index 000000000..40a44d2d2 --- /dev/null +++ b/api/mesh/v1alpha1/nacos_service.pb.go @@ -0,0 +1,226 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/nacos_service.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Nacos Service is the raw data of nacos service +type NacosService struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceKey string `protobuf:"bytes,1,opt,name=serviceKey,proto3" json:"serviceKey,omitempty"` + Instances []*NacosInstance `protobuf:"bytes,3,rep,name=instances,proto3" json:"instances,omitempty"` +} + +func (x *NacosService) Reset() { + *x = NacosService{} + mi := &file_api_mesh_v1alpha1_nacos_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NacosService) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NacosService) ProtoMessage() {} + +func (x *NacosService) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_nacos_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NacosService.ProtoReflect.Descriptor instead. +func (*NacosService) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_nacos_service_proto_rawDescGZIP(), []int{0} +} + +func (x *NacosService) GetServiceKey() string { + if x != nil { + return x.ServiceKey + } + return "" +} + +func (x *NacosService) GetInstances() []*NacosInstance { + if x != nil { + return x.Instances + } + return nil +} + +type NacosInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + Port int64 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *NacosInstance) Reset() { + *x = NacosInstance{} + mi := &file_api_mesh_v1alpha1_nacos_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NacosInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NacosInstance) ProtoMessage() {} + +func (x *NacosInstance) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_nacos_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NacosInstance.ProtoReflect.Descriptor instead. +func (*NacosInstance) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_nacos_service_proto_rawDescGZIP(), []int{1} +} + +func (x *NacosInstance) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *NacosInstance) GetPort() int64 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *NacosInstance) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +var File_api_mesh_v1alpha1_nacos_service_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_nacos_service_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, + 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x4e, 0x61, 0x63, 0x6f, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x40, 0x0a, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, + 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, + 0x61, 0x63, 0x6f, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x3a, 0x2a, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x24, 0x0a, + 0x0c, 0x4e, 0x61, 0x63, 0x6f, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0c, 0x4e, + 0x61, 0x63, 0x6f, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x04, 0x6d, 0x65, 0x73, + 0x68, 0x20, 0x01, 0x22, 0xbe, 0x01, 0x0a, 0x0d, 0x4e, 0x61, 0x63, 0x6f, 0x73, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4c, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x64, 0x75, + 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4e, 0x61, 0x63, 0x6f, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_nacos_service_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_nacos_service_proto_rawDescData = file_api_mesh_v1alpha1_nacos_service_proto_rawDesc +) + +func file_api_mesh_v1alpha1_nacos_service_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_nacos_service_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_nacos_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_nacos_service_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_nacos_service_proto_rawDescData +} + +var file_api_mesh_v1alpha1_nacos_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_api_mesh_v1alpha1_nacos_service_proto_goTypes = []any{ + (*NacosService)(nil), // 0: dubbo.mesh.v1alpha1.NacosService + (*NacosInstance)(nil), // 1: dubbo.mesh.v1alpha1.NacosInstance + nil, // 2: dubbo.mesh.v1alpha1.NacosInstance.MetadataEntry +} +var file_api_mesh_v1alpha1_nacos_service_proto_depIdxs = []int32{ + 1, // 0: dubbo.mesh.v1alpha1.NacosService.instances:type_name -> dubbo.mesh.v1alpha1.NacosInstance + 2, // 1: dubbo.mesh.v1alpha1.NacosInstance.metadata:type_name -> dubbo.mesh.v1alpha1.NacosInstance.MetadataEntry + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_nacos_service_proto_init() } +func file_api_mesh_v1alpha1_nacos_service_proto_init() { + if File_api_mesh_v1alpha1_nacos_service_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_nacos_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_nacos_service_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_nacos_service_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_nacos_service_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_nacos_service_proto = out.File + file_api_mesh_v1alpha1_nacos_service_proto_rawDesc = nil + file_api_mesh_v1alpha1_nacos_service_proto_goTypes = nil + file_api_mesh_v1alpha1_nacos_service_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/nacos_service.proto b/api/mesh/v1alpha1/nacos_service.proto new file mode 100644 index 000000000..71316ba18 --- /dev/null +++ b/api/mesh/v1alpha1/nacos_service.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +// Nacos Service is the raw data of nacos service +message NacosService { + option (dubbo.mesh.resource).name = "NacosService"; + option (dubbo.mesh.resource).plural_name = "NacosService"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string serviceKey = 1; + + repeated NacosInstance instances = 3; +} + +message NacosInstance{ + + string ip = 1; + + int64 port = 2; + + map metadata = 3; +} \ No newline at end of file diff --git a/api/mesh/v1alpha1/rpc_instance.pb.go b/api/mesh/v1alpha1/rpc_instance.pb.go new file mode 100644 index 000000000..b36b39db3 --- /dev/null +++ b/api/mesh/v1alpha1/rpc_instance.pb.go @@ -0,0 +1,356 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/rpc_instance.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// RPCInstance is retrieved from Discovery, defines the attributes of instance during service discovery and rpc call +type RPCInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + Port int64 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"` + AppName string `protobuf:"bytes,5,opt,name=appName,proto3" json:"appName,omitempty"` + RegisterTime string `protobuf:"bytes,6,opt,name=registerTime,proto3" json:"registerTime,omitempty"` + // TODO, we need to sort out the status of an instance + UnregisterTime string `protobuf:"bytes,7,opt,name=unregisterTime,proto3" json:"unregisterTime,omitempty"` + Revision string `protobuf:"bytes,8,opt,name=revision,proto3" json:"revision,omitempty"` + MetadataStorageType string `protobuf:"bytes,9,opt,name=metadataStorageType,proto3" json:"metadataStorageType,omitempty"` + ReleaseVersion string `protobuf:"bytes,10,opt,name=releaseVersion,proto3" json:"releaseVersion,omitempty"` + Protocol string `protobuf:"bytes,11,opt,name=protocol,proto3" json:"protocol,omitempty"` + Serialization string `protobuf:"bytes,12,opt,name=serialization,proto3" json:"serialization,omitempty"` + PreferSerialization string `protobuf:"bytes,13,opt,name=preferSerialization,proto3" json:"preferSerialization,omitempty"` + Tags map[string]string `protobuf:"bytes,51,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Endpoints []*Endpoint `protobuf:"bytes,52,rep,name=endpoints,proto3" json:"endpoints,omitempty"` + Metadata map[string]string `protobuf:"bytes,53,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *RPCInstance) Reset() { + *x = RPCInstance{} + mi := &file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RPCInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RPCInstance) ProtoMessage() {} + +func (x *RPCInstance) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RPCInstance.ProtoReflect.Descriptor instead. +func (*RPCInstance) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_rpc_instance_proto_rawDescGZIP(), []int{0} +} + +func (x *RPCInstance) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RPCInstance) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *RPCInstance) GetPort() int64 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *RPCInstance) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + +func (x *RPCInstance) GetRegisterTime() string { + if x != nil { + return x.RegisterTime + } + return "" +} + +func (x *RPCInstance) GetUnregisterTime() string { + if x != nil { + return x.UnregisterTime + } + return "" +} + +func (x *RPCInstance) GetRevision() string { + if x != nil { + return x.Revision + } + return "" +} + +func (x *RPCInstance) GetMetadataStorageType() string { + if x != nil { + return x.MetadataStorageType + } + return "" +} + +func (x *RPCInstance) GetReleaseVersion() string { + if x != nil { + return x.ReleaseVersion + } + return "" +} + +func (x *RPCInstance) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *RPCInstance) GetSerialization() string { + if x != nil { + return x.Serialization + } + return "" +} + +func (x *RPCInstance) GetPreferSerialization() string { + if x != nil { + return x.PreferSerialization + } + return "" +} + +func (x *RPCInstance) GetTags() map[string]string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *RPCInstance) GetEndpoints() []*Endpoint { + if x != nil { + return x.Endpoints + } + return nil +} + +func (x *RPCInstance) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type Endpoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Port int64 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` +} + +func (x *Endpoint) Reset() { + *x = Endpoint{} + mi := &file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Endpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Endpoint) ProtoMessage() {} + +func (x *Endpoint) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Endpoint.ProtoReflect.Descriptor instead. +func (*Endpoint) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_rpc_instance_proto_rawDescGZIP(), []int{1} +} + +func (x *Endpoint) GetPort() int64 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *Endpoint) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +var File_api_mesh_v1alpha1_rpc_instance_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_rpc_instance_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, + 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x85, 0x06, 0x0a, 0x0b, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, + 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, + 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x6e, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x75, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, + 0x13, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x04, 0x74, + 0x61, 0x67, 0x73, 0x18, 0x33, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x64, 0x75, 0x62, 0x62, + 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x3b, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x34, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x35, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xaa, 0x8c, 0x89, 0xa6, + 0x01, 0x23, 0x0a, 0x0b, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, + 0x0c, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x04, 0x6d, + 0x65, 0x73, 0x68, 0x20, 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x33, 0x22, 0x3a, 0x0a, 0x08, 0x45, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_rpc_instance_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_rpc_instance_proto_rawDescData = file_api_mesh_v1alpha1_rpc_instance_proto_rawDesc +) + +func file_api_mesh_v1alpha1_rpc_instance_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_rpc_instance_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_rpc_instance_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_rpc_instance_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_rpc_instance_proto_rawDescData +} + +var file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_api_mesh_v1alpha1_rpc_instance_proto_goTypes = []any{ + (*RPCInstance)(nil), // 0: dubbo.mesh.v1alpha1.RPCInstance + (*Endpoint)(nil), // 1: dubbo.mesh.v1alpha1.Endpoint + nil, // 2: dubbo.mesh.v1alpha1.RPCInstance.TagsEntry + nil, // 3: dubbo.mesh.v1alpha1.RPCInstance.MetadataEntry +} +var file_api_mesh_v1alpha1_rpc_instance_proto_depIdxs = []int32{ + 2, // 0: dubbo.mesh.v1alpha1.RPCInstance.tags:type_name -> dubbo.mesh.v1alpha1.RPCInstance.TagsEntry + 1, // 1: dubbo.mesh.v1alpha1.RPCInstance.endpoints:type_name -> dubbo.mesh.v1alpha1.Endpoint + 3, // 2: dubbo.mesh.v1alpha1.RPCInstance.metadata:type_name -> dubbo.mesh.v1alpha1.RPCInstance.MetadataEntry + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_rpc_instance_proto_init() } +func file_api_mesh_v1alpha1_rpc_instance_proto_init() { + if File_api_mesh_v1alpha1_rpc_instance_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_rpc_instance_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_rpc_instance_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_rpc_instance_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_rpc_instance_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_rpc_instance_proto = out.File + file_api_mesh_v1alpha1_rpc_instance_proto_rawDesc = nil + file_api_mesh_v1alpha1_rpc_instance_proto_goTypes = nil + file_api_mesh_v1alpha1_rpc_instance_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/rpc_instance.proto b/api/mesh/v1alpha1/rpc_instance.proto new file mode 100644 index 000000000..151f6153f --- /dev/null +++ b/api/mesh/v1alpha1/rpc_instance.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +// RPCInstance is retrieved from Discovery, defines the attributes of instance during service discovery and rpc call +message RPCInstance { + option (dubbo.mesh.resource).name = "RPCInstance"; + option (dubbo.mesh.resource).plural_name = "RPCInstances"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string name = 1; + + string ip = 2; + + int64 port = 3; + + string appName = 5; + + string registerTime = 6; + + // TODO, we need to sort out the status of an instance + string unregisterTime = 7; + + string revision = 8; + + string metadataStorageType = 9; + + string releaseVersion = 10; + + string protocol = 11; + + string serialization = 12; + + string preferSerialization = 13; + + map tags = 51; + + repeated Endpoint endpoints = 52; + + map metadata = 53; + + reserved 15 to 50; +} + +message Endpoint{ + int64 port = 1; + + string protocol= 2; +} \ No newline at end of file diff --git a/api/mesh/v1alpha1/rpc_instance_metadata.pb.go b/api/mesh/v1alpha1/rpc_instance_metadata.pb.go new file mode 100644 index 000000000..117f4ede5 --- /dev/null +++ b/api/mesh/v1alpha1/rpc_instance_metadata.pb.go @@ -0,0 +1,284 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/rpc_instance_metadata.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RPCInstanceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + App string `protobuf:"bytes,1,opt,name=app,proto3" json:"app,omitempty"` + Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // key format is '{group}/{interface name}:{version}:{protocol}' + Services map[string]*ServiceInfo `protobuf:"bytes,4,rep,name=services,proto3" json:"services,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *RPCInstanceMetadata) Reset() { + *x = RPCInstanceMetadata{} + mi := &file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RPCInstanceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RPCInstanceMetadata) ProtoMessage() {} + +func (x *RPCInstanceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RPCInstanceMetadata.ProtoReflect.Descriptor instead. +func (*RPCInstanceMetadata) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *RPCInstanceMetadata) GetApp() string { + if x != nil { + return x.App + } + return "" +} + +func (x *RPCInstanceMetadata) GetRevision() string { + if x != nil { + return x.Revision + } + return "" +} + +func (x *RPCInstanceMetadata) GetServices() map[string]*ServiceInfo { + if x != nil { + return x.Services + } + return nil +} + +type ServiceInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Protocol string `protobuf:"bytes,4,opt,name=protocol,proto3" json:"protocol,omitempty"` + Port int64 `protobuf:"varint,5,opt,name=port,proto3" json:"port,omitempty"` + Path string `protobuf:"bytes,6,opt,name=path,proto3" json:"path,omitempty"` + Params map[string]string `protobuf:"bytes,7,rep,name=params,proto3" json:"params,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ServiceInfo) Reset() { + *x = ServiceInfo{} + mi := &file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceInfo) ProtoMessage() {} + +func (x *ServiceInfo) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceInfo.ProtoReflect.Descriptor instead. +func (*ServiceInfo) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescGZIP(), []int{1} +} + +func (x *ServiceInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ServiceInfo) GetGroup() string { + if x != nil { + return x.Group + } + return "" +} + +func (x *ServiceInfo) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ServiceInfo) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *ServiceInfo) GetPort() int64 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *ServiceInfo) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ServiceInfo) GetParams() map[string]string { + if x != nil { + return x.Params + } + return nil +} + +var File_api_mesh_v1alpha1_rpc_instance_metadata_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x02, 0x0a, + 0x13, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x50, 0x43, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x5d, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, + 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x37, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x31, 0x0a, 0x13, 0x52, + 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x14, 0x52, 0x50, 0x43, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x96, + 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x39, 0x0a, 0x0b, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescData = file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDesc +) + +func file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDescData +} + +var file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_api_mesh_v1alpha1_rpc_instance_metadata_proto_goTypes = []any{ + (*RPCInstanceMetadata)(nil), // 0: dubbo.mesh.v1alpha1.RPCInstanceMetadata + (*ServiceInfo)(nil), // 1: dubbo.mesh.v1alpha1.ServiceInfo + nil, // 2: dubbo.mesh.v1alpha1.RPCInstanceMetadata.ServicesEntry + nil, // 3: dubbo.mesh.v1alpha1.ServiceInfo.ParamsEntry +} +var file_api_mesh_v1alpha1_rpc_instance_metadata_proto_depIdxs = []int32{ + 2, // 0: dubbo.mesh.v1alpha1.RPCInstanceMetadata.services:type_name -> dubbo.mesh.v1alpha1.RPCInstanceMetadata.ServicesEntry + 3, // 1: dubbo.mesh.v1alpha1.ServiceInfo.params:type_name -> dubbo.mesh.v1alpha1.ServiceInfo.ParamsEntry + 1, // 2: dubbo.mesh.v1alpha1.RPCInstanceMetadata.ServicesEntry.value:type_name -> dubbo.mesh.v1alpha1.ServiceInfo + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_rpc_instance_metadata_proto_init() } +func file_api_mesh_v1alpha1_rpc_instance_metadata_proto_init() { + if File_api_mesh_v1alpha1_rpc_instance_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_rpc_instance_metadata_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_rpc_instance_metadata_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_rpc_instance_metadata_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_rpc_instance_metadata_proto = out.File + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_rawDesc = nil + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_goTypes = nil + file_api_mesh_v1alpha1_rpc_instance_metadata_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/rpc_instance_metadata.proto b/api/mesh/v1alpha1/rpc_instance_metadata.proto new file mode 100644 index 000000000..045b6f71b --- /dev/null +++ b/api/mesh/v1alpha1/rpc_instance_metadata.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message RPCInstanceMetadata { + option (dubbo.mesh.resource).name = "RPCInstanceMetadata"; + option (dubbo.mesh.resource).plural_name = "RPCInstanceMetaDatas"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = false; + + string app = 1; + string revision = 2; + // key format is '{group}/{interface name}:{version}:{protocol}' + map services = 4; +} + +message ServiceInfo { + string name = 1; + string group = 2; + string version = 3; + string protocol = 4; + int64 port = 5; + string path = 6; + map params = 7; +} \ No newline at end of file diff --git a/api/mesh/v1alpha1/runtime_instance.pb.go b/api/mesh/v1alpha1/runtime_instance.pb.go new file mode 100644 index 000000000..4946d511d --- /dev/null +++ b/api/mesh/v1alpha1/runtime_instance.pb.go @@ -0,0 +1,439 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/runtime_instance.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// RuntimeInstance is retrieved from Engine, defines the attributes of instance in runtime environments +type RuntimeInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + RpcPort int64 `protobuf:"varint,3,opt,name=rpcPort,proto3" json:"rpcPort,omitempty"` + Image string `protobuf:"bytes,4,opt,name=image,proto3" json:"image,omitempty"` + AppName string `protobuf:"bytes,5,opt,name=appName,proto3" json:"appName,omitempty"` + CreateTime string `protobuf:"bytes,6,opt,name=createTime,proto3" json:"createTime,omitempty"` + StartTime string `protobuf:"bytes,7,opt,name=startTime,proto3" json:"startTime,omitempty"` + ReadyTime string `protobuf:"bytes,8,opt,name=readyTime,proto3" json:"readyTime,omitempty"` + Phase string `protobuf:"bytes,9,opt,name=phase,proto3" json:"phase,omitempty"` + WorkloadName string `protobuf:"bytes,10,opt,name=workloadName,proto3" json:"workloadName,omitempty"` + WorkloadType string `protobuf:"bytes,11,opt,name=workloadType,proto3" json:"workloadType,omitempty"` + Node string `protobuf:"bytes,12,opt,name=node,proto3" json:"node,omitempty"` + Probes []*Probe `protobuf:"bytes,13,rep,name=probes,proto3" json:"probes,omitempty"` + Conditions []*Condition `protobuf:"bytes,14,rep,name=conditions,proto3" json:"conditions,omitempty"` + // start from 50 for extra fields which is added by components in admin + // sourceEngine is the engine name of runtime instance running on + SourceEngine string `protobuf:"bytes,51,opt,name=sourceEngine,proto3" json:"sourceEngine,omitempty"` + // sourceEngineType is the engine type of runtime instance running on + SourceEngineType string `protobuf:"bytes,52,opt,name=sourceEngineType,proto3" json:"sourceEngineType,omitempty"` +} + +func (x *RuntimeInstance) Reset() { + *x = RuntimeInstance{} + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RuntimeInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeInstance) ProtoMessage() {} + +func (x *RuntimeInstance) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeInstance.ProtoReflect.Descriptor instead. +func (*RuntimeInstance) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_runtime_instance_proto_rawDescGZIP(), []int{0} +} + +func (x *RuntimeInstance) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RuntimeInstance) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *RuntimeInstance) GetRpcPort() int64 { + if x != nil { + return x.RpcPort + } + return 0 +} + +func (x *RuntimeInstance) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *RuntimeInstance) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + +func (x *RuntimeInstance) GetCreateTime() string { + if x != nil { + return x.CreateTime + } + return "" +} + +func (x *RuntimeInstance) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *RuntimeInstance) GetReadyTime() string { + if x != nil { + return x.ReadyTime + } + return "" +} + +func (x *RuntimeInstance) GetPhase() string { + if x != nil { + return x.Phase + } + return "" +} + +func (x *RuntimeInstance) GetWorkloadName() string { + if x != nil { + return x.WorkloadName + } + return "" +} + +func (x *RuntimeInstance) GetWorkloadType() string { + if x != nil { + return x.WorkloadType + } + return "" +} + +func (x *RuntimeInstance) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *RuntimeInstance) GetProbes() []*Probe { + if x != nil { + return x.Probes + } + return nil +} + +func (x *RuntimeInstance) GetConditions() []*Condition { + if x != nil { + return x.Conditions + } + return nil +} + +func (x *RuntimeInstance) GetSourceEngine() string { + if x != nil { + return x.SourceEngine + } + return "" +} + +func (x *RuntimeInstance) GetSourceEngineType() string { + if x != nil { + return x.SourceEngineType + } + return "" +} + +type Probe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` +} + +func (x *Probe) Reset() { + *x = Probe{} + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Probe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Probe) ProtoMessage() {} + +func (x *Probe) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Probe.ProtoReflect.Descriptor instead. +func (*Probe) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_runtime_instance_proto_rawDescGZIP(), []int{1} +} + +func (x *Probe) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Probe) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +// reference: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions +type Condition struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + LastTransitionTime string `protobuf:"bytes,3,opt,name=lastTransitionTime,proto3" json:"lastTransitionTime,omitempty"` + Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"` + Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *Condition) Reset() { + *x = Condition{} + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Condition) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Condition) ProtoMessage() {} + +func (x *Condition) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Condition.ProtoReflect.Descriptor instead. +func (*Condition) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_runtime_instance_proto_rawDescGZIP(), []int{2} +} + +func (x *Condition) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Condition) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *Condition) GetLastTransitionTime() string { + if x != nil { + return x.LastTransitionTime + } + return "" +} + +func (x *Condition) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Condition) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +var File_api_mesh_v1alpha1_runtime_instance_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_runtime_instance_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, + 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, + 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x04, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x07, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x61, 0x64, + 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x22, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x62, 0x65, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x33, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x12, + 0x2a, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x31, 0xaa, 0x8c, 0x89, + 0xa6, 0x01, 0x2b, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, 0x4a, 0x04, + 0x08, 0x0f, 0x10, 0x33, 0x22, 0x2f, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x2e, 0x0a, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x61, 0x73, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_runtime_instance_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_runtime_instance_proto_rawDescData = file_api_mesh_v1alpha1_runtime_instance_proto_rawDesc +) + +func file_api_mesh_v1alpha1_runtime_instance_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_runtime_instance_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_runtime_instance_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_runtime_instance_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_runtime_instance_proto_rawDescData +} + +var file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_api_mesh_v1alpha1_runtime_instance_proto_goTypes = []any{ + (*RuntimeInstance)(nil), // 0: dubbo.mesh.v1alpha1.RuntimeInstance + (*Probe)(nil), // 1: dubbo.mesh.v1alpha1.Probe + (*Condition)(nil), // 2: dubbo.mesh.v1alpha1.Condition +} +var file_api_mesh_v1alpha1_runtime_instance_proto_depIdxs = []int32{ + 1, // 0: dubbo.mesh.v1alpha1.RuntimeInstance.probes:type_name -> dubbo.mesh.v1alpha1.Probe + 2, // 1: dubbo.mesh.v1alpha1.RuntimeInstance.conditions:type_name -> dubbo.mesh.v1alpha1.Condition + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_runtime_instance_proto_init() } +func file_api_mesh_v1alpha1_runtime_instance_proto_init() { + if File_api_mesh_v1alpha1_runtime_instance_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_runtime_instance_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_runtime_instance_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_runtime_instance_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_runtime_instance_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_runtime_instance_proto = out.File + file_api_mesh_v1alpha1_runtime_instance_proto_rawDesc = nil + file_api_mesh_v1alpha1_runtime_instance_proto_goTypes = nil + file_api_mesh_v1alpha1_runtime_instance_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/runtime_instance.proto b/api/mesh/v1alpha1/runtime_instance.proto new file mode 100644 index 000000000..9a59ea2e2 --- /dev/null +++ b/api/mesh/v1alpha1/runtime_instance.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +// RuntimeInstance is retrieved from Engine, defines the attributes of instance in runtime environments +message RuntimeInstance { + option (dubbo.mesh.resource).name = "RuntimeInstance"; + option (dubbo.mesh.resource).plural_name = "RuntimeInstances"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string name = 1; + + string ip = 2; + + int64 rpcPort = 3; + + string image = 4; + + string appName = 5; + + string createTime = 6; + + string startTime = 7; + + string readyTime = 8; + + string phase = 9; + + string workloadName = 10; + + string workloadType = 11; + + string node = 12; + + repeated Probe probes = 13; + + repeated Condition conditions = 14; + + // reserved for future use + reserved 15 to 50; + + // start from 50 for extra fields which is added by components in admin + // sourceEngine is the engine name of runtime instance running on + string sourceEngine = 51; + + // sourceEngineType is the engine type of runtime instance running on + string sourceEngineType = 52; + +} + +message Probe { + string type = 1; + int32 port = 2; +} + +// reference: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions +message Condition{ + + string type = 1; + + string status = 2; + + string lastTransitionTime = 3; + + string reason = 4; + + string message = 5; +} \ No newline at end of file diff --git a/api/system/v1alpha1/zone_insight_helpers.go b/api/mesh/v1alpha1/runtime_instance_helper.go similarity index 79% rename from api/system/v1alpha1/zone_insight_helpers.go rename to api/mesh/v1alpha1/runtime_instance_helper.go index 9aa529bee..3bffb4cf6 100644 --- a/api/system/v1alpha1/zone_insight_helpers.go +++ b/api/mesh/v1alpha1/runtime_instance_helper.go @@ -17,11 +17,14 @@ package v1alpha1 -func (x *ZoneInsight) IsOnline() bool { - for _, s := range x.GetSubscriptions() { - if s.ConnectTime != nil && s.DisconnectTime == nil { - return true - } - } - return false -} +const ( + LivenessProbe = "liveness" + ReadinessProbe = "readiness" + StartupProbe = "startup" +) + +const ( + InstanceStarting = "Starting" + InstanceCrashing = "Crashing" + InstanceTerminating = "Terminating" +) diff --git a/api/mesh/v1alpha1/service.pb.go b/api/mesh/v1alpha1/service.pb.go index 6d7b92611..10723e7a3 100644 --- a/api/mesh/v1alpha1/service.pb.go +++ b/api/mesh/v1alpha1/service.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.35.1 -// protoc v3.12.4 +// protoc v7.34.1 // source: api/mesh/v1alpha1/service.proto package v1alpha1 @@ -26,13 +26,11 @@ type Service struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"` - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - Language string `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"` - Providers []string `protobuf:"bytes,5,rep,name=providers,proto3" json:"providers,omitempty"` - Consumers []string `protobuf:"bytes,6,rep,name=consumers,proto3" json:"consumers,omitempty"` - Features map[string]string `protobuf:"bytes,99,rep,name=features,proto3" json:"features,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Language string `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"` + Methods []string `protobuf:"bytes,5,rep,name=methods,proto3" json:"methods,omitempty"` } func (x *Service) Reset() { @@ -93,23 +91,9 @@ func (x *Service) GetLanguage() string { return "" } -func (x *Service) GetProviders() []string { +func (x *Service) GetMethods() []string { if x != nil { - return x.Providers - } - return nil -} - -func (x *Service) GetConsumers() []string { - if x != nil { - return x.Consumers - } - return nil -} - -func (x *Service) GetFeatures() map[string]string { - if x != nil { - return x.Features + return x.Methods } return nil } @@ -121,34 +105,22 @@ var file_api_mesh_v1alpha1_service_proto_rawDesc = []byte{ 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, - 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xed, - 0x02, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa6, + 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x12, 0x46, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x18, 0x63, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x3b, - 0x0a, 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x41, 0xaa, 0x8c, 0x89, - 0xa6, 0x01, 0x3b, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x04, 0x6d, - 0x65, 0x73, 0x68, 0x3a, 0x15, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x08, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x58, 0x01, 0x68, 0x01, 0x42, 0x31, - 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, - 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x3a, 0x21, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x1b, 0x0a, 0x07, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, + 0x04, 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -163,18 +135,16 @@ func file_api_mesh_v1alpha1_service_proto_rawDescGZIP() []byte { return file_api_mesh_v1alpha1_service_proto_rawDescData } -var file_api_mesh_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_api_mesh_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_api_mesh_v1alpha1_service_proto_goTypes = []any{ (*Service)(nil), // 0: dubbo.mesh.v1alpha1.Service - nil, // 1: dubbo.mesh.v1alpha1.Service.FeaturesEntry } var file_api_mesh_v1alpha1_service_proto_depIdxs = []int32{ - 1, // 0: dubbo.mesh.v1alpha1.Service.features:type_name -> dubbo.mesh.v1alpha1.Service.FeaturesEntry - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_api_mesh_v1alpha1_service_proto_init() } @@ -188,7 +158,7 @@ func file_api_mesh_v1alpha1_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_mesh_v1alpha1_service_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/api/mesh/v1alpha1/service.proto b/api/mesh/v1alpha1/service.proto index 010821f9d..4a2ea1cbd 100644 --- a/api/mesh/v1alpha1/service.proto +++ b/api/mesh/v1alpha1/service.proto @@ -7,27 +7,19 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; import "api/mesh/options.proto"; -message Service{ - option (dubbo.mesh.resource).name = "ServiceResource"; - option (dubbo.mesh.resource).type = "Service"; - option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).ws.name = "service"; - option (dubbo.mesh.resource).ws.plural = "services"; - option (dubbo.mesh.resource).ws.read_only = true; - option (dubbo.mesh.resource).scope_namespace = true; - option (dubbo.mesh.resource).allow_to_inspect = true; +message Service{ + option (dubbo.mesh.resource).name = "Service"; + option (dubbo.mesh.resource).plural_name = "Services"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; string name = 1; string group = 2; - string version = 3; - - string language = 4; - - repeated string providers = 5; - - repeated string consumers = 6; - - map features = 99; -} \ No newline at end of file + string version = 3; + + string language = 4; + + repeated string methods = 5; +} diff --git a/api/mesh/v1alpha1/service_consumer_metadata.pb.go b/api/mesh/v1alpha1/service_consumer_metadata.pb.go new file mode 100644 index 000000000..c25f3a64d --- /dev/null +++ b/api/mesh/v1alpha1/service_consumer_metadata.pb.go @@ -0,0 +1,188 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/service_consumer_metadata.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServiceConsumerMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=serviceName,proto3" json:"serviceName,omitempty"` + ConsumerAppName string `protobuf:"bytes,2,opt,name=consumerAppName,proto3" json:"consumerAppName,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Group string `protobuf:"bytes,4,opt,name=group,proto3" json:"group,omitempty"` + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ServiceConsumerMetadata) Reset() { + *x = ServiceConsumerMetadata{} + mi := &file_api_mesh_v1alpha1_service_consumer_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceConsumerMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceConsumerMetadata) ProtoMessage() {} + +func (x *ServiceConsumerMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_consumer_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceConsumerMetadata.ProtoReflect.Descriptor instead. +func (*ServiceConsumerMetadata) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceConsumerMetadata) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *ServiceConsumerMetadata) GetConsumerAppName() string { + if x != nil { + return x.ConsumerAppName + } + return "" +} + +func (x *ServiceConsumerMetadata) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ServiceConsumerMetadata) GetGroup() string { + if x != nil { + return x.Group + } + return "" +} + +func (x *ServiceConsumerMetadata) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +var File_api_mesh_v1alpha1_service_consumer_metadata_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, + 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xeb, 0x02, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, + 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, + 0x72, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x56, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x3f, 0xaa, + 0x8c, 0x89, 0xa6, 0x01, 0x39, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x18, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x4d, + 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x42, 0x31, + 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, + 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescData = file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDesc +) + +func file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDescData +} + +var file_api_mesh_v1alpha1_service_consumer_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_api_mesh_v1alpha1_service_consumer_metadata_proto_goTypes = []any{ + (*ServiceConsumerMetadata)(nil), // 0: dubbo.mesh.v1alpha1.ServiceConsumerMetadata + nil, // 1: dubbo.mesh.v1alpha1.ServiceConsumerMetadata.MetadataEntry +} +var file_api_mesh_v1alpha1_service_consumer_metadata_proto_depIdxs = []int32{ + 1, // 0: dubbo.mesh.v1alpha1.ServiceConsumerMetadata.metadata:type_name -> dubbo.mesh.v1alpha1.ServiceConsumerMetadata.MetadataEntry + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_service_consumer_metadata_proto_init() } +func file_api_mesh_v1alpha1_service_consumer_metadata_proto_init() { + if File_api_mesh_v1alpha1_service_consumer_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_service_consumer_metadata_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_service_consumer_metadata_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_service_consumer_metadata_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_service_consumer_metadata_proto = out.File + file_api_mesh_v1alpha1_service_consumer_metadata_proto_rawDesc = nil + file_api_mesh_v1alpha1_service_consumer_metadata_proto_goTypes = nil + file_api_mesh_v1alpha1_service_consumer_metadata_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/service_consumer_metadata.proto b/api/mesh/v1alpha1/service_consumer_metadata.proto new file mode 100644 index 000000000..f2a185e37 --- /dev/null +++ b/api/mesh/v1alpha1/service_consumer_metadata.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message ServiceConsumerMetadata { + option (dubbo.mesh.resource).name = "ServiceConsumerMetadata"; + option (dubbo.mesh.resource).plural_name = "ServiceConsumerMetaDatas"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = false; + + string serviceName = 1; + + string consumerAppName = 2; + + string version = 3; + + string group = 4; + + map metadata = 5; +} + diff --git a/api/mesh/v1alpha1/service_provider_mapping.pb.go b/api/mesh/v1alpha1/service_provider_mapping.pb.go new file mode 100644 index 000000000..44ce1cf14 --- /dev/null +++ b/api/mesh/v1alpha1/service_provider_mapping.pb.go @@ -0,0 +1,149 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/service_provider_mapping.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServiceProviderMapping struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=serviceName,proto3" json:"serviceName,omitempty"` + AppNames []string `protobuf:"bytes,2,rep,name=appNames,proto3" json:"appNames,omitempty"` +} + +func (x *ServiceProviderMapping) Reset() { + *x = ServiceProviderMapping{} + mi := &file_api_mesh_v1alpha1_service_provider_mapping_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceProviderMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceProviderMapping) ProtoMessage() {} + +func (x *ServiceProviderMapping) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_provider_mapping_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceProviderMapping.ProtoReflect.Descriptor instead. +func (*ServiceProviderMapping) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceProviderMapping) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *ServiceProviderMapping) GetAppNames() []string { + if x != nil { + return x.AppNames + } + return nil +} + +var File_api_mesh_v1alpha1_service_provider_mapping_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x95, 0x01, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x3a, 0x3d, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x37, + 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, + 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescData = file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDesc +) + +func file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDescData +} + +var file_api_mesh_v1alpha1_service_provider_mapping_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_mesh_v1alpha1_service_provider_mapping_proto_goTypes = []any{ + (*ServiceProviderMapping)(nil), // 0: dubbo.mesh.v1alpha1.ServiceProviderMapping +} +var file_api_mesh_v1alpha1_service_provider_mapping_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_service_provider_mapping_proto_init() } +func file_api_mesh_v1alpha1_service_provider_mapping_proto_init() { + if File_api_mesh_v1alpha1_service_provider_mapping_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_service_provider_mapping_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_service_provider_mapping_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_service_provider_mapping_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_service_provider_mapping_proto = out.File + file_api_mesh_v1alpha1_service_provider_mapping_proto_rawDesc = nil + file_api_mesh_v1alpha1_service_provider_mapping_proto_goTypes = nil + file_api_mesh_v1alpha1_service_provider_mapping_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/service_provider_mapping.proto b/api/mesh/v1alpha1/service_provider_mapping.proto new file mode 100644 index 000000000..c96e5fcaa --- /dev/null +++ b/api/mesh/v1alpha1/service_provider_mapping.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message ServiceProviderMapping { + option (dubbo.mesh.resource).name = "ServiceProviderMapping"; + option (dubbo.mesh.resource).plural_name = "ServiceProviderMappings"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = false; + + string serviceName = 1; + repeated string appNames = 2; +} diff --git a/api/mesh/v1alpha1/service_provider_metadata.pb.go b/api/mesh/v1alpha1/service_provider_metadata.pb.go new file mode 100644 index 000000000..8900a8b6b --- /dev/null +++ b/api/mesh/v1alpha1/service_provider_metadata.pb.go @@ -0,0 +1,457 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/service_provider_metadata.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServiceProviderMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=serviceName,proto3" json:"serviceName,omitempty"` + ProviderAppName string `protobuf:"bytes,2,opt,name=providerAppName,proto3" json:"providerAppName,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Group string `protobuf:"bytes,4,opt,name=group,proto3" json:"group,omitempty"` + CanonicalName string `protobuf:"bytes,5,opt,name=canonicalName,proto3" json:"canonicalName,omitempty"` + Methods []*Method `protobuf:"bytes,6,rep,name=methods,proto3" json:"methods,omitempty"` + Parameters map[string]string `protobuf:"bytes,7,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Types []*Type `protobuf:"bytes,8,rep,name=types,proto3" json:"types,omitempty"` +} + +func (x *ServiceProviderMetadata) Reset() { + *x = ServiceProviderMetadata{} + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceProviderMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceProviderMetadata) ProtoMessage() {} + +func (x *ServiceProviderMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceProviderMetadata.ProtoReflect.Descriptor instead. +func (*ServiceProviderMetadata) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceProviderMetadata) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *ServiceProviderMetadata) GetProviderAppName() string { + if x != nil { + return x.ProviderAppName + } + return "" +} + +func (x *ServiceProviderMetadata) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ServiceProviderMetadata) GetGroup() string { + if x != nil { + return x.Group + } + return "" +} + +func (x *ServiceProviderMetadata) GetCanonicalName() string { + if x != nil { + return x.CanonicalName + } + return "" +} + +func (x *ServiceProviderMetadata) GetMethods() []*Method { + if x != nil { + return x.Methods + } + return nil +} + +func (x *ServiceProviderMetadata) GetParameters() map[string]string { + if x != nil { + return x.Parameters + } + return nil +} + +func (x *ServiceProviderMetadata) GetTypes() []*Type { + if x != nil { + return x.Types + } + return nil +} + +type Method struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Annotations []string `protobuf:"bytes,1,rep,name=annotations,proto3" json:"annotations,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + ParameterTypes []string `protobuf:"bytes,3,rep,name=parameterTypes,proto3" json:"parameterTypes,omitempty"` + Parameters []*Parameter `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty"` + ReturnType string `protobuf:"bytes,5,opt,name=returnType,proto3" json:"returnType,omitempty"` +} + +func (x *Method) Reset() { + *x = Method{} + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Method) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Method) ProtoMessage() {} + +func (x *Method) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Method.ProtoReflect.Descriptor instead. +func (*Method) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescGZIP(), []int{1} +} + +func (x *Method) GetAnnotations() []string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Method) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Method) GetParameterTypes() []string { + if x != nil { + return x.ParameterTypes + } + return nil +} + +func (x *Method) GetParameters() []*Parameter { + if x != nil { + return x.Parameters + } + return nil +} + +func (x *Method) GetReturnType() string { + if x != nil { + return x.ReturnType + } + return "" +} + +type Parameter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` +} + +func (x *Parameter) Reset() { + *x = Parameter{} + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Parameter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Parameter) ProtoMessage() {} + +func (x *Parameter) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Parameter.ProtoReflect.Descriptor instead. +func (*Parameter) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescGZIP(), []int{2} +} + +func (x *Parameter) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Parameter) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +type Type struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enums []string `protobuf:"bytes,1,rep,name=enums,proto3" json:"enums,omitempty"` + Items []string `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` + Properties map[string]string `protobuf:"bytes,3,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` +} + +func (x *Type) Reset() { + *x = Type{} + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Type) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Type) ProtoMessage() {} + +func (x *Type) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Type.ProtoReflect.Descriptor instead. +func (*Type) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescGZIP(), []int{3} +} + +func (x *Type) GetEnums() []string { + if x != nil { + return x.Enums + } + return nil +} + +func (x *Type) GetItems() []string { + if x != nil { + return x.Items + } + return nil +} + +func (x *Type) GetProperties() map[string]string { + if x != nil { + return x.Properties + } + return nil +} + +func (x *Type) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +var File_api_mesh_v1alpha1_service_provider_metadata_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, + 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x81, 0x04, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, + 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x61, 0x6e, 0x6f, + 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, + 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x07, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x5c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x64, 0x75, 0x62, 0x62, + 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x3a, 0x3f, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x39, 0x0a, 0x17, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x18, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x73, 0x1a, 0x04, + 0x6d, 0x65, 0x73, 0x68, 0x22, 0xc6, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x20, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x3e, 0x0a, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x33, 0x0a, + 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x75, + 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, + 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescData = file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDesc +) + +func file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDescData +} + +var file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_api_mesh_v1alpha1_service_provider_metadata_proto_goTypes = []any{ + (*ServiceProviderMetadata)(nil), // 0: dubbo.mesh.v1alpha1.ServiceProviderMetadata + (*Method)(nil), // 1: dubbo.mesh.v1alpha1.Method + (*Parameter)(nil), // 2: dubbo.mesh.v1alpha1.Parameter + (*Type)(nil), // 3: dubbo.mesh.v1alpha1.Type + nil, // 4: dubbo.mesh.v1alpha1.ServiceProviderMetadata.ParametersEntry + nil, // 5: dubbo.mesh.v1alpha1.Type.PropertiesEntry +} +var file_api_mesh_v1alpha1_service_provider_metadata_proto_depIdxs = []int32{ + 1, // 0: dubbo.mesh.v1alpha1.ServiceProviderMetadata.methods:type_name -> dubbo.mesh.v1alpha1.Method + 4, // 1: dubbo.mesh.v1alpha1.ServiceProviderMetadata.parameters:type_name -> dubbo.mesh.v1alpha1.ServiceProviderMetadata.ParametersEntry + 3, // 2: dubbo.mesh.v1alpha1.ServiceProviderMetadata.types:type_name -> dubbo.mesh.v1alpha1.Type + 2, // 3: dubbo.mesh.v1alpha1.Method.parameters:type_name -> dubbo.mesh.v1alpha1.Parameter + 5, // 4: dubbo.mesh.v1alpha1.Type.properties:type_name -> dubbo.mesh.v1alpha1.Type.PropertiesEntry + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_service_provider_metadata_proto_init() } +func file_api_mesh_v1alpha1_service_provider_metadata_proto_init() { + if File_api_mesh_v1alpha1_service_provider_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_service_provider_metadata_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_service_provider_metadata_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_service_provider_metadata_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_service_provider_metadata_proto = out.File + file_api_mesh_v1alpha1_service_provider_metadata_proto_rawDesc = nil + file_api_mesh_v1alpha1_service_provider_metadata_proto_goTypes = nil + file_api_mesh_v1alpha1_service_provider_metadata_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/service_provider_metadata.proto b/api/mesh/v1alpha1/service_provider_metadata.proto new file mode 100644 index 000000000..b167269b3 --- /dev/null +++ b/api/mesh/v1alpha1/service_provider_metadata.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message ServiceProviderMetadata { + option (dubbo.mesh.resource).name = "ServiceProviderMetadata"; + option (dubbo.mesh.resource).plural_name = "ServiceProviderMetaDatas"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = false; + + string serviceName = 1; + + string providerAppName = 2; + + string version = 3; + + string group = 4; + + string canonicalName = 5; + + repeated Method methods = 6; + + map parameters = 7; + + repeated Type types = 8; +} + +message Method { + repeated string annotations = 1; + + string name = 2; + + repeated string parameterTypes = 3; + + repeated Parameter parameters = 4; + + string returnType = 5; +} + +message Parameter { + string name = 1; + + string type = 2; +} + +message Type { + repeated string enums = 1; + + repeated string items = 2; + + map properties = 3; + + string type = 4; +} diff --git a/api/mesh/v1alpha1/tag_route.pb.go b/api/mesh/v1alpha1/tag_route.pb.go index ef472b5fb..37b6b8f74 100644 --- a/api/mesh/v1alpha1/tag_route.pb.go +++ b/api/mesh/v1alpha1/tag_route.pb.go @@ -330,7 +330,7 @@ var file_api_mesh_v1alpha1_tag_route_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x9d, 0x02, 0x0a, 0x08, 0x54, 0x61, 0x67, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1a, 0x0a, + 0x22, 0xf9, 0x01, 0x0a, 0x08, 0x54, 0x61, 0x67, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, @@ -343,40 +343,38 @@ var file_api_mesh_v1alpha1_tag_route_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x45, 0xaa, 0x8c, 0x89, 0xa6, 0x01, - 0x3f, 0x0a, 0x10, 0x54, 0x61, 0x67, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x08, 0x54, 0x61, 0x67, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x22, 0x04, 0x6d, - 0x65, 0x73, 0x68, 0x3a, 0x15, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, - 0x09, 0x74, 0x61, 0x67, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x02, 0x10, 0x01, 0x68, 0x01, - 0x22, 0x96, 0x01, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x75, 0x62, 0x62, - 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x12, 0x26, 0x0a, 0x10, 0x5f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, - 0x62, 0x79, 0x5f, 0x63, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x42, 0x79, 0x43, 0x70, 0x22, 0x9d, 0x01, 0x0a, 0x0b, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, - 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, - 0x07, 0x6e, 0x6f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6e, 0x6f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1a, 0x0a, - 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x22, 0x56, 0x0a, 0x0a, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x21, 0xaa, 0x8c, 0x89, 0xa6, 0x01, + 0x1b, 0x0a, 0x08, 0x54, 0x61, 0x67, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x09, 0x54, 0x61, 0x67, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x96, 0x01, 0x0a, + 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x26, 0x0a, + 0x10, 0x5f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x79, 0x5f, 0x63, + 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x42, 0x79, 0x43, 0x70, 0x22, 0x9d, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x6f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x6c, + 0x64, 0x63, 0x61, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x69, 0x6c, + 0x64, 0x63, 0x61, 0x72, 0x64, 0x22, 0x56, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x31, 0x5a, + 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, + 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/mesh/v1alpha1/tag_route.proto b/api/mesh/v1alpha1/tag_route.proto index eef63c818..0edcf9858 100644 --- a/api/mesh/v1alpha1/tag_route.proto +++ b/api/mesh/v1alpha1/tag_route.proto @@ -7,13 +7,11 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; import "api/mesh/options.proto"; message TagRoute { - option (dubbo.mesh.resource).name = "TagRouteResource"; - option (dubbo.mesh.resource).type = "TagRoute"; + option (dubbo.mesh.resource).name = "TagRoute"; + option (dubbo.mesh.resource).plural_name = "TagRoutes"; option (dubbo.mesh.resource).package = "mesh"; - option (dubbo.mesh.resource).dds.send_to_zone = true; - option (dubbo.mesh.resource).ws.name = "tagroute"; - option (dubbo.mesh.resource).ws.plural = "tagroutes"; - option (dubbo.mesh.resource).allow_to_inspect = true; + option (dubbo.mesh.resource).is_experimental = false; + int32 priority = 1; bool enabled = 2; diff --git a/api/mesh/v1alpha1/traffic_helper.go b/api/mesh/v1alpha1/traffic_helper.go deleted file mode 100644 index 903b6671f..000000000 --- a/api/mesh/v1alpha1/traffic_helper.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v1alpha1 - -import ( - "strings" - - "github.com/apache/dubbo-admin/pkg/core/consts" - "github.com/dubbogo/gost/encoding/yaml" -) - -// Application 流量管控相关的基础label -const ( - ApplicationLabel = "dubbo.io/application" - ServiceLabel = "dubbo.io/service" - IDLabel = "dubbo.io/id" - ServiceVersionLabel = "dubbo.io/serviceVersion" - ServiceGroupLabel = "dubbo.io/serviceGroup" - RevisionLabel = "dubbo.io/revision" -) - -type Base struct { - Application string `json:"application" yaml:"application"` - Service string `json:"service" yaml:"service"` - ID string `json:"id" yaml:"id"` - ServiceVersion string `json:"serviceVersion" yaml:"serviceVersion"` - ServiceGroup string `json:"serviceGroup" yaml:"serviceGroup"` -} - -func BuildServiceKey(baseDto Base) string { - if baseDto.Application != "" { - return baseDto.Application - } - // id format: "${class}:${version}:${group}" - return baseDto.Service + consts.Colon + baseDto.ServiceVersion + consts.Colon + baseDto.ServiceGroup -} - -func GetRoutePath(key string, routeType string) string { - key = strings.ReplaceAll(key, "/", "*") - switch routeType { - case consts.ConditionRoute: - return key + consts.ConditionRuleSuffix - case consts.TagRoute: - return key + consts.TagRuleSuffix - case consts.AffinityRoute: - return key + consts.AffinityRuleSuffix - } - return key + "." + routeType + "-router" -} - -func LoadObject(content string, obj interface{}) error { - return yaml.UnmarshalYML([]byte(content), obj) -} diff --git a/api/mesh/v1alpha1/zk_config.pb.go b/api/mesh/v1alpha1/zk_config.pb.go new file mode 100644 index 000000000..01a9565c8 --- /dev/null +++ b/api/mesh/v1alpha1/zk_config.pb.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/zk_config.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ZKConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeName string `protobuf:"bytes,1,opt,name=nodeName,proto3" json:"nodeName,omitempty"` + NodeData string `protobuf:"bytes,2,opt,name=nodeData,proto3" json:"nodeData,omitempty"` +} + +func (x *ZKConfig) Reset() { + *x = ZKConfig{} + mi := &file_api_mesh_v1alpha1_zk_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ZKConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ZKConfig) ProtoMessage() {} + +func (x *ZKConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_zk_config_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ZKConfig.ProtoReflect.Descriptor instead. +func (*ZKConfig) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_zk_config_proto_rawDescGZIP(), []int{0} +} + +func (x *ZKConfig) GetNodeName() string { + if x != nil { + return x.NodeName + } + return "" +} + +func (x *ZKConfig) GetNodeData() string { + if x != nil { + return x.NodeData + } + return "" +} + +var File_api_mesh_v1alpha1_zk_config_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_zk_config_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x7a, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, + 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x66, 0x0a, 0x08, 0x5a, 0x4b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, + 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x3a, 0x22, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x1c, 0x0a, 0x08, 0x5a, 0x4b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x08, 0x5a, 0x4b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, + 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, + 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_zk_config_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_zk_config_proto_rawDescData = file_api_mesh_v1alpha1_zk_config_proto_rawDesc +) + +func file_api_mesh_v1alpha1_zk_config_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_zk_config_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_zk_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_zk_config_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_zk_config_proto_rawDescData +} + +var file_api_mesh_v1alpha1_zk_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_mesh_v1alpha1_zk_config_proto_goTypes = []any{ + (*ZKConfig)(nil), // 0: dubbo.mesh.v1alpha1.ZKConfig +} +var file_api_mesh_v1alpha1_zk_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_zk_config_proto_init() } +func file_api_mesh_v1alpha1_zk_config_proto_init() { + if File_api_mesh_v1alpha1_zk_config_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_zk_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_zk_config_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_zk_config_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_zk_config_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_zk_config_proto = out.File + file_api_mesh_v1alpha1_zk_config_proto_rawDesc = nil + file_api_mesh_v1alpha1_zk_config_proto_goTypes = nil + file_api_mesh_v1alpha1_zk_config_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/zk_config.proto b/api/mesh/v1alpha1/zk_config.proto new file mode 100644 index 000000000..6b7dd2272 --- /dev/null +++ b/api/mesh/v1alpha1/zk_config.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message ZKConfig { + option (dubbo.mesh.resource).name = "ZKConfig"; + option (dubbo.mesh.resource).plural_name = "ZKConfig"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string nodeName = 1; + + string nodeData = 2; +} \ No newline at end of file diff --git a/api/mesh/v1alpha1/zk_metadata.pb.go b/api/mesh/v1alpha1/zk_metadata.pb.go new file mode 100644 index 000000000..97d95b2a0 --- /dev/null +++ b/api/mesh/v1alpha1/zk_metadata.pb.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.12.4 +// source: api/mesh/v1alpha1/zk_metadata.proto + +package v1alpha1 + +import ( + _ "github.com/apache/dubbo-admin/api/mesh" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ZKMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodePath string `protobuf:"bytes,1,opt,name=nodePath,proto3" json:"nodePath,omitempty"` + NodeData string `protobuf:"bytes,2,opt,name=nodeData,proto3" json:"nodeData,omitempty"` +} + +func (x *ZKMetadata) Reset() { + *x = ZKMetadata{} + mi := &file_api_mesh_v1alpha1_zk_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ZKMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ZKMetadata) ProtoMessage() {} + +func (x *ZKMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_mesh_v1alpha1_zk_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ZKMetadata.ProtoReflect.Descriptor instead. +func (*ZKMetadata) Descriptor() ([]byte, []int) { + return file_api_mesh_v1alpha1_zk_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *ZKMetadata) GetNodePath() string { + if x != nil { + return x.NodePath + } + return "" +} + +func (x *ZKMetadata) GetNodeData() string { + if x != nil { + return x.NodeData + } + return "" +} + +var File_api_mesh_v1alpha1_zk_metadata_proto protoreflect.FileDescriptor + +var file_api_mesh_v1alpha1_zk_metadata_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x7a, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, + 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x6c, 0x0a, 0x0a, 0x5a, 0x4b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, + 0x6e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6e, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x26, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x20, + 0x0a, 0x0a, 0x5a, 0x4b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0a, 0x5a, 0x4b, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x20, 0x01, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_mesh_v1alpha1_zk_metadata_proto_rawDescOnce sync.Once + file_api_mesh_v1alpha1_zk_metadata_proto_rawDescData = file_api_mesh_v1alpha1_zk_metadata_proto_rawDesc +) + +func file_api_mesh_v1alpha1_zk_metadata_proto_rawDescGZIP() []byte { + file_api_mesh_v1alpha1_zk_metadata_proto_rawDescOnce.Do(func() { + file_api_mesh_v1alpha1_zk_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_mesh_v1alpha1_zk_metadata_proto_rawDescData) + }) + return file_api_mesh_v1alpha1_zk_metadata_proto_rawDescData +} + +var file_api_mesh_v1alpha1_zk_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_mesh_v1alpha1_zk_metadata_proto_goTypes = []any{ + (*ZKMetadata)(nil), // 0: dubbo.mesh.v1alpha1.ZKMetadata +} +var file_api_mesh_v1alpha1_zk_metadata_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_mesh_v1alpha1_zk_metadata_proto_init() } +func file_api_mesh_v1alpha1_zk_metadata_proto_init() { + if File_api_mesh_v1alpha1_zk_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_mesh_v1alpha1_zk_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_mesh_v1alpha1_zk_metadata_proto_goTypes, + DependencyIndexes: file_api_mesh_v1alpha1_zk_metadata_proto_depIdxs, + MessageInfos: file_api_mesh_v1alpha1_zk_metadata_proto_msgTypes, + }.Build() + File_api_mesh_v1alpha1_zk_metadata_proto = out.File + file_api_mesh_v1alpha1_zk_metadata_proto_rawDesc = nil + file_api_mesh_v1alpha1_zk_metadata_proto_goTypes = nil + file_api_mesh_v1alpha1_zk_metadata_proto_depIdxs = nil +} diff --git a/api/mesh/v1alpha1/zk_metadata.proto b/api/mesh/v1alpha1/zk_metadata.proto new file mode 100644 index 000000000..d25d900a0 --- /dev/null +++ b/api/mesh/v1alpha1/zk_metadata.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package dubbo.mesh.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1"; + +import "api/mesh/options.proto"; + +message ZKMetadata { + option (dubbo.mesh.resource).name = "ZKMetadata"; + option (dubbo.mesh.resource).plural_name = "ZKMetadata"; + option (dubbo.mesh.resource).package = "mesh"; + option (dubbo.mesh.resource).is_experimental = true; + + string nodePath = 1; + + string nodeData = 2; +} \ No newline at end of file diff --git a/api/system/v1alpha1/config.pb.go b/api/system/v1alpha1/config.pb.go deleted file mode 100644 index d1af2c7fb..000000000 --- a/api/system/v1alpha1/config.pb.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/config.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Config is a entity that represents dynamic configuration that is stored in -// underlying storage. For now it's used only for internal mechanisms. -type Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // configuration that is stored (ex. in JSON) - Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` -} - -func (x *Config) Reset() { - *x = Config{} - mi := &file_api_system_v1alpha1_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Config) ProtoMessage() {} - -func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_config_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Config.ProtoReflect.Descriptor instead. -func (*Config) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_config_proto_rawDescGZIP(), []int{0} -} - -func (x *Config) GetConfig() string { - if x != nil { - return x.Config - } - return "" -} - -var File_api_system_v1alpha1_config_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_config_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x50, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x3a, 0x2e, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x28, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x06, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x01, 0x22, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x02, 0x10, - 0x01, 0x60, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_system_v1alpha1_config_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_config_proto_rawDescData = file_api_system_v1alpha1_config_proto_rawDesc -) - -func file_api_system_v1alpha1_config_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_config_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_config_proto_rawDescData) - }) - return file_api_system_v1alpha1_config_proto_rawDescData -} - -var file_api_system_v1alpha1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_api_system_v1alpha1_config_proto_goTypes = []any{ - (*Config)(nil), // 0: dubbo.system.v1alpha1.Config -} -var file_api_system_v1alpha1_config_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_config_proto_init() } -func file_api_system_v1alpha1_config_proto_init() { - if File_api_system_v1alpha1_config_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_config_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_system_v1alpha1_config_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_config_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_config_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_config_proto = out.File - file_api_system_v1alpha1_config_proto_rawDesc = nil - file_api_system_v1alpha1_config_proto_goTypes = nil - file_api_system_v1alpha1_config_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/config.proto b/api/system/v1alpha1/config.proto deleted file mode 100644 index b631b18dd..000000000 --- a/api/system/v1alpha1/config.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -import "api/mesh/options.proto"; - -// Config is a entity that represents dynamic configuration that is stored in -// underlying storage. For now it's used only for internal mechanisms. -message Config { - - option (dubbo.mesh.resource).name = "ConfigResource"; - option (dubbo.mesh.resource).type = "Config"; - option (dubbo.mesh.resource).package = "system"; - option (dubbo.mesh.resource).global = true; - option (dubbo.mesh.resource).skip_kubernetes_wrappers = true; - option (dubbo.mesh.resource).dds.send_to_zone = true; - - // configuration that is stored (ex. in JSON) - string config = 1; -} diff --git a/api/system/v1alpha1/datasource.pb.go b/api/system/v1alpha1/datasource.pb.go deleted file mode 100644 index d40e44848..000000000 --- a/api/system/v1alpha1/datasource.pb.go +++ /dev/null @@ -1,224 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/datasource.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - wrappers "github.com/golang/protobuf/ptypes/wrappers" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// DataSource defines the source of bytes to use. -type DataSource struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Type: - // - // *DataSource_Secret - // *DataSource_File - // *DataSource_Inline - // *DataSource_InlineString - Type isDataSource_Type `protobuf_oneof:"type"` -} - -func (x *DataSource) Reset() { - *x = DataSource{} - mi := &file_api_system_v1alpha1_datasource_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataSource) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataSource) ProtoMessage() {} - -func (x *DataSource) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_datasource_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataSource.ProtoReflect.Descriptor instead. -func (*DataSource) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_datasource_proto_rawDescGZIP(), []int{0} -} - -func (m *DataSource) GetType() isDataSource_Type { - if m != nil { - return m.Type - } - return nil -} - -func (x *DataSource) GetSecret() string { - if x, ok := x.GetType().(*DataSource_Secret); ok { - return x.Secret - } - return "" -} - -func (x *DataSource) GetFile() string { - if x, ok := x.GetType().(*DataSource_File); ok { - return x.File - } - return "" -} - -func (x *DataSource) GetInline() *wrappers.BytesValue { - if x, ok := x.GetType().(*DataSource_Inline); ok { - return x.Inline - } - return nil -} - -func (x *DataSource) GetInlineString() string { - if x, ok := x.GetType().(*DataSource_InlineString); ok { - return x.InlineString - } - return "" -} - -type isDataSource_Type interface { - isDataSource_Type() -} - -type DataSource_Secret struct { - // Data source is a secret with given Secret key. - Secret string `protobuf:"bytes,1,opt,name=secret,proto3,oneof"` -} - -type DataSource_File struct { - // Data source is a path to a file. - // Deprecated, use other sources of a data. - File string `protobuf:"bytes,2,opt,name=file,proto3,oneof"` -} - -type DataSource_Inline struct { - // Data source is inline bytes. - Inline *wrappers.BytesValue `protobuf:"bytes,3,opt,name=inline,proto3,oneof"` -} - -type DataSource_InlineString struct { - // Data source is inline string - InlineString string `protobuf:"bytes,4,opt,name=inlineString,proto3,oneof"` -} - -func (*DataSource_Secret) isDataSource_Type() {} - -func (*DataSource_File) isDataSource_Type() {} - -func (*DataSource_Inline) isDataSource_Type() {} - -func (*DataSource_InlineString) isDataSource_Type() {} - -var File_api_system_v1alpha1_datasource_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_datasource_proto_rawDesc = []byte{ - 0x0a, 0x24, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, - 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe4, 0x01, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x24, 0x0a, 0x0c, 0x69, - 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x3a, 0x41, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x3b, 0x0a, 0x12, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0a, 0x44, - 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x22, 0x06, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x3a, 0x0c, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x90, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x42, 0x33, 0x5a, 0x31, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, - 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_system_v1alpha1_datasource_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_datasource_proto_rawDescData = file_api_system_v1alpha1_datasource_proto_rawDesc -) - -func file_api_system_v1alpha1_datasource_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_datasource_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_datasource_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_datasource_proto_rawDescData) - }) - return file_api_system_v1alpha1_datasource_proto_rawDescData -} - -var file_api_system_v1alpha1_datasource_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_api_system_v1alpha1_datasource_proto_goTypes = []any{ - (*DataSource)(nil), // 0: dubbo.system.v1alpha1.DataSource - (*wrappers.BytesValue)(nil), // 1: google.protobuf.BytesValue -} -var file_api_system_v1alpha1_datasource_proto_depIdxs = []int32{ - 1, // 0: dubbo.system.v1alpha1.DataSource.inline:type_name -> google.protobuf.BytesValue - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_datasource_proto_init() } -func file_api_system_v1alpha1_datasource_proto_init() { - if File_api_system_v1alpha1_datasource_proto != nil { - return - } - file_api_system_v1alpha1_datasource_proto_msgTypes[0].OneofWrappers = []any{ - (*DataSource_Secret)(nil), - (*DataSource_File)(nil), - (*DataSource_Inline)(nil), - (*DataSource_InlineString)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_datasource_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_system_v1alpha1_datasource_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_datasource_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_datasource_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_datasource_proto = out.File - file_api_system_v1alpha1_datasource_proto_rawDesc = nil - file_api_system_v1alpha1_datasource_proto_goTypes = nil - file_api_system_v1alpha1_datasource_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/datasource.proto b/api/system/v1alpha1/datasource.proto deleted file mode 100644 index 76917988a..000000000 --- a/api/system/v1alpha1/datasource.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -import "api/mesh/options.proto"; -import "google/protobuf/wrappers.proto"; - -// DataSource defines the source of bytes to use. -message DataSource { - option (dubbo.mesh.resource).name = "DataSourceResource"; - option (dubbo.mesh.resource).type = "DataSource"; - option (dubbo.mesh.resource).package = "system"; - option (dubbo.mesh.resource).global = true; - option (dubbo.mesh.resource).ws.name = "datasource"; - option (dubbo.mesh.resource).has_insights = true; - - oneof type { - // Data source is a secret with given Secret key. - string secret = 1; - // Data source is a path to a file. - // Deprecated, use other sources of a data. - string file = 2; - // Data source is inline bytes. - google.protobuf.BytesValue inline = 3; - // Data source is inline string - string inlineString = 4; - } -} diff --git a/api/system/v1alpha1/inter_cp_ping.pb.go b/api/system/v1alpha1/inter_cp_ping.pb.go deleted file mode 100644 index 3a2017b61..000000000 --- a/api/system/v1alpha1/inter_cp_ping.pb.go +++ /dev/null @@ -1,218 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/inter_cp_ping.proto - -package v1alpha1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PingRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - InterCpPort uint32 `protobuf:"varint,3,opt,name=inter_cp_port,json=interCpPort,proto3" json:"inter_cp_port,omitempty"` - Ready bool `protobuf:"varint,4,opt,name=ready,proto3" json:"ready,omitempty"` -} - -func (x *PingRequest) Reset() { - *x = PingRequest{} - mi := &file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *PingRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingRequest) ProtoMessage() {} - -func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. -func (*PingRequest) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_inter_cp_ping_proto_rawDescGZIP(), []int{0} -} - -func (x *PingRequest) GetInstanceId() string { - if x != nil { - return x.InstanceId - } - return "" -} - -func (x *PingRequest) GetAddress() string { - if x != nil { - return x.Address - } - return "" -} - -func (x *PingRequest) GetInterCpPort() uint32 { - if x != nil { - return x.InterCpPort - } - return 0 -} - -func (x *PingRequest) GetReady() bool { - if x != nil { - return x.Ready - } - return false -} - -type PingResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Leader bool `protobuf:"varint,1,opt,name=leader,proto3" json:"leader,omitempty"` -} - -func (x *PingResponse) Reset() { - *x = PingResponse{} - mi := &file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *PingResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingResponse) ProtoMessage() {} - -func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. -func (*PingResponse) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_inter_cp_ping_proto_rawDescGZIP(), []int{1} -} - -func (x *PingResponse) GetLeader() bool { - if x != nil { - return x.Leader - } - return false -} - -var File_api_system_v1alpha1_inter_cp_ping_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_inter_cp_ping_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x70, 0x5f, 0x70, - 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, - 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x22, 0x82, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x72, 0x65, 0x61, 0x64, 0x79, 0x22, 0x26, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x32, 0x65, 0x0a, - 0x12, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x70, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x2e, 0x64, 0x75, - 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_api_system_v1alpha1_inter_cp_ping_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_inter_cp_ping_proto_rawDescData = file_api_system_v1alpha1_inter_cp_ping_proto_rawDesc -) - -func file_api_system_v1alpha1_inter_cp_ping_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_inter_cp_ping_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_inter_cp_ping_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_inter_cp_ping_proto_rawDescData) - }) - return file_api_system_v1alpha1_inter_cp_ping_proto_rawDescData -} - -var file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_api_system_v1alpha1_inter_cp_ping_proto_goTypes = []any{ - (*PingRequest)(nil), // 0: dubbo.system.v1alpha1.PingRequest - (*PingResponse)(nil), // 1: dubbo.system.v1alpha1.PingResponse -} -var file_api_system_v1alpha1_inter_cp_ping_proto_depIdxs = []int32{ - 0, // 0: dubbo.system.v1alpha1.InterCpPingService.Ping:input_type -> dubbo.system.v1alpha1.PingRequest - 1, // 1: dubbo.system.v1alpha1.InterCpPingService.Ping:output_type -> dubbo.system.v1alpha1.PingResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_inter_cp_ping_proto_init() } -func file_api_system_v1alpha1_inter_cp_ping_proto_init() { - if File_api_system_v1alpha1_inter_cp_ping_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_inter_cp_ping_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_api_system_v1alpha1_inter_cp_ping_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_inter_cp_ping_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_inter_cp_ping_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_inter_cp_ping_proto = out.File - file_api_system_v1alpha1_inter_cp_ping_proto_rawDesc = nil - file_api_system_v1alpha1_inter_cp_ping_proto_goTypes = nil - file_api_system_v1alpha1_inter_cp_ping_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/inter_cp_ping.proto b/api/system/v1alpha1/inter_cp_ping.proto deleted file mode 100644 index 9c9ae4f32..000000000 --- a/api/system/v1alpha1/inter_cp_ping.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -message PingRequest { - string instance_id = 1; - string address = 2; - uint32 inter_cp_port = 3; - bool ready = 4; -} - -message PingResponse { bool leader = 1; } - -service InterCpPingService { rpc Ping(PingRequest) returns (PingResponse); } diff --git a/api/system/v1alpha1/inter_cp_ping_grpc.pb.go b/api/system/v1alpha1/inter_cp_ping_grpc.pb.go deleted file mode 100644 index c671e1f8d..000000000 --- a/api/system/v1alpha1/inter_cp_ping_grpc.pb.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v3.12.4 -// source: api/system/v1alpha1/inter_cp_ping.proto - -package v1alpha1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - InterCpPingService_Ping_FullMethodName = "/dubbo.system.v1alpha1.InterCpPingService/Ping" -) - -// InterCpPingServiceClient is the client API for InterCpPingService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type InterCpPingServiceClient interface { - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) -} - -type interCpPingServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewInterCpPingServiceClient(cc grpc.ClientConnInterface) InterCpPingServiceClient { - return &interCpPingServiceClient{cc} -} - -func (c *interCpPingServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(PingResponse) - err := c.cc.Invoke(ctx, InterCpPingService_Ping_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// InterCpPingServiceServer is the server API for InterCpPingService service. -// All implementations must embed UnimplementedInterCpPingServiceServer -// for forward compatibility. -type InterCpPingServiceServer interface { - Ping(context.Context, *PingRequest) (*PingResponse, error) - mustEmbedUnimplementedInterCpPingServiceServer() -} - -// UnimplementedInterCpPingServiceServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedInterCpPingServiceServer struct{} - -func (UnimplementedInterCpPingServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedInterCpPingServiceServer) mustEmbedUnimplementedInterCpPingServiceServer() {} -func (UnimplementedInterCpPingServiceServer) testEmbeddedByValue() {} - -// UnsafeInterCpPingServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to InterCpPingServiceServer will -// result in compilation errors. -type UnsafeInterCpPingServiceServer interface { - mustEmbedUnimplementedInterCpPingServiceServer() -} - -func RegisterInterCpPingServiceServer(s grpc.ServiceRegistrar, srv InterCpPingServiceServer) { - // If the following call pancis, it indicates UnimplementedInterCpPingServiceServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&InterCpPingService_ServiceDesc, srv) -} - -func _InterCpPingService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(InterCpPingServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: InterCpPingService_Ping_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(InterCpPingServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// InterCpPingService_ServiceDesc is the grpc.ServiceDesc for InterCpPingService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var InterCpPingService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "dubbo.system.v1alpha1.InterCpPingService", - HandlerType: (*InterCpPingServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _InterCpPingService_Ping_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "api/system/v1alpha1/inter_cp_ping.proto", -} diff --git a/api/system/v1alpha1/secret.pb.go b/api/system/v1alpha1/secret.pb.go deleted file mode 100644 index 0cebf9d78..000000000 --- a/api/system/v1alpha1/secret.pb.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/secret.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - wrappers "github.com/golang/protobuf/ptypes/wrappers" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Secret defines an encrypted value in Dubbo. -type Secret struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Value of the secret - Data *wrappers.BytesValue `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` -} - -func (x *Secret) Reset() { - *x = Secret{} - mi := &file_api_system_v1alpha1_secret_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Secret) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Secret) ProtoMessage() {} - -func (x *Secret) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_secret_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Secret.ProtoReflect.Descriptor instead. -func (*Secret) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_secret_proto_rawDescGZIP(), []int{0} -} - -func (x *Secret) GetData() *wrappers.BytesValue { - if x != nil { - return x.Data - } - return nil -} - -var File_api_system_v1alpha1_secret_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_secret_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x70, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x35, 0xaa, 0x8c, - 0x89, 0xa6, 0x01, 0x2f, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x22, 0x06, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x08, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x90, 0x01, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_system_v1alpha1_secret_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_secret_proto_rawDescData = file_api_system_v1alpha1_secret_proto_rawDesc -) - -func file_api_system_v1alpha1_secret_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_secret_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_secret_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_secret_proto_rawDescData) - }) - return file_api_system_v1alpha1_secret_proto_rawDescData -} - -var file_api_system_v1alpha1_secret_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_api_system_v1alpha1_secret_proto_goTypes = []any{ - (*Secret)(nil), // 0: dubbo.system.v1alpha1.Secret - (*wrappers.BytesValue)(nil), // 1: google.protobuf.BytesValue -} -var file_api_system_v1alpha1_secret_proto_depIdxs = []int32{ - 1, // 0: dubbo.system.v1alpha1.Secret.data:type_name -> google.protobuf.BytesValue - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_secret_proto_init() } -func file_api_system_v1alpha1_secret_proto_init() { - if File_api_system_v1alpha1_secret_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_secret_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_system_v1alpha1_secret_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_secret_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_secret_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_secret_proto = out.File - file_api_system_v1alpha1_secret_proto_rawDesc = nil - file_api_system_v1alpha1_secret_proto_goTypes = nil - file_api_system_v1alpha1_secret_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/secret.proto b/api/system/v1alpha1/secret.proto deleted file mode 100644 index 9cd67da78..000000000 --- a/api/system/v1alpha1/secret.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -import "api/mesh/options.proto"; -import "google/protobuf/wrappers.proto"; - -// Secret defines an encrypted value in Dubbo. -message Secret { - - option (dubbo.mesh.resource).name = "SecretResource"; - option (dubbo.mesh.resource).type = "Secret"; - option (dubbo.mesh.resource).package = "system"; - option (dubbo.mesh.resource).global = true; - option (dubbo.mesh.resource).ws.name = "secret"; - option (dubbo.mesh.resource).has_insights = true; - - // Value of the secret - google.protobuf.BytesValue data = 1; -} diff --git a/api/system/v1alpha1/zone.pb.go b/api/system/v1alpha1/zone.pb.go deleted file mode 100644 index e12f50a51..000000000 --- a/api/system/v1alpha1/zone.pb.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/zone.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - wrappers "github.com/golang/protobuf/ptypes/wrappers" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Zone defines the Zone configuration used at the Global Control Plane -// within a distributed deployment -type Zone struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // enable allows to turn the zone on/off and exclude the whole zone from - // balancing traffic on it - Enabled *wrappers.BoolValue `protobuf:"bytes,1,opt,name=enabled,proto3" json:"enabled,omitempty"` -} - -func (x *Zone) Reset() { - *x = Zone{} - mi := &file_api_system_v1alpha1_zone_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Zone) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Zone) ProtoMessage() {} - -func (x *Zone) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Zone.ProtoReflect.Descriptor instead. -func (*Zone) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_proto_rawDescGZIP(), []int{0} -} - -func (x *Zone) GetEnabled() *wrappers.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -var File_api_system_v1alpha1_zone_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_zone_proto_rawDesc = []byte{ - 0x0a, 0x1e, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x7a, 0x6f, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x6d, 0x0a, 0x04, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x2f, 0xaa, - 0x8c, 0x89, 0xa6, 0x01, 0x29, 0x0a, 0x0c, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x04, 0x5a, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x22, 0x06, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x3a, 0x06, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x90, 0x01, 0x01, 0x42, 0x33, - 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, - 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_system_v1alpha1_zone_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_zone_proto_rawDescData = file_api_system_v1alpha1_zone_proto_rawDesc -) - -func file_api_system_v1alpha1_zone_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_zone_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_zone_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_zone_proto_rawDescData) - }) - return file_api_system_v1alpha1_zone_proto_rawDescData -} - -var file_api_system_v1alpha1_zone_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_api_system_v1alpha1_zone_proto_goTypes = []any{ - (*Zone)(nil), // 0: dubbo.system.v1alpha1.Zone - (*wrappers.BoolValue)(nil), // 1: google.protobuf.BoolValue -} -var file_api_system_v1alpha1_zone_proto_depIdxs = []int32{ - 1, // 0: dubbo.system.v1alpha1.Zone.enabled:type_name -> google.protobuf.BoolValue - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_zone_proto_init() } -func file_api_system_v1alpha1_zone_proto_init() { - if File_api_system_v1alpha1_zone_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_zone_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_system_v1alpha1_zone_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_zone_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_zone_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_zone_proto = out.File - file_api_system_v1alpha1_zone_proto_rawDesc = nil - file_api_system_v1alpha1_zone_proto_goTypes = nil - file_api_system_v1alpha1_zone_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/zone.proto b/api/system/v1alpha1/zone.proto deleted file mode 100644 index 618bc9d04..000000000 --- a/api/system/v1alpha1/zone.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -import "api/mesh/options.proto"; -import "google/protobuf/wrappers.proto"; - -// Zone defines the Zone configuration used at the Global Control Plane -// within a distributed deployment -message Zone { - - option (dubbo.mesh.resource).name = "ZoneResource"; - option (dubbo.mesh.resource).type = "Zone"; - option (dubbo.mesh.resource).package = "system"; - option (dubbo.mesh.resource).global = true; - option (dubbo.mesh.resource).ws.name = "zone"; - option (dubbo.mesh.resource).has_insights = true; - - // enable allows to turn the zone on/off and exclude the whole zone from - // balancing traffic on it - google.protobuf.BoolValue enabled = 1; -} diff --git a/api/system/v1alpha1/zone_insight.pb.go b/api/system/v1alpha1/zone_insight.pb.go deleted file mode 100644 index 889811115..000000000 --- a/api/system/v1alpha1/zone_insight.pb.go +++ /dev/null @@ -1,635 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.35.1 -// protoc v3.12.4 -// source: api/system/v1alpha1/zone_insight.proto - -package v1alpha1 - -import ( - _ "github.com/apache/dubbo-admin/api/mesh" - timestamp "github.com/golang/protobuf/ptypes/timestamp" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ZoneInsight struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // List of DDS subscriptions created by a given Zone Dubbo CP. - Subscriptions []*DDSSubscription `protobuf:"bytes,1,rep,name=subscriptions,proto3" json:"subscriptions,omitempty"` - // Statistics about Envoy Admin Streams - EnvoyAdminStreams *EnvoyAdminStreams `protobuf:"bytes,2,opt,name=envoy_admin_streams,json=envoyAdminStreams,proto3" json:"envoy_admin_streams,omitempty"` - HealthCheck *HealthCheck `protobuf:"bytes,3,opt,name=health_check,json=healthCheck,proto3" json:"health_check,omitempty"` -} - -func (x *ZoneInsight) Reset() { - *x = ZoneInsight{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ZoneInsight) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ZoneInsight) ProtoMessage() {} - -func (x *ZoneInsight) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ZoneInsight.ProtoReflect.Descriptor instead. -func (*ZoneInsight) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{0} -} - -func (x *ZoneInsight) GetSubscriptions() []*DDSSubscription { - if x != nil { - return x.Subscriptions - } - return nil -} - -func (x *ZoneInsight) GetEnvoyAdminStreams() *EnvoyAdminStreams { - if x != nil { - return x.EnvoyAdminStreams - } - return nil -} - -func (x *ZoneInsight) GetHealthCheck() *HealthCheck { - if x != nil { - return x.HealthCheck - } - return nil -} - -type EnvoyAdminStreams struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Global instance ID that handles XDS Config Dump streams. - ConfigDumpGlobalInstanceId string `protobuf:"bytes,1,opt,name=config_dump_global_instance_id,json=configDumpGlobalInstanceId,proto3" json:"config_dump_global_instance_id,omitempty"` - // Global instance ID that handles Stats streams. - StatsGlobalInstanceId string `protobuf:"bytes,2,opt,name=stats_global_instance_id,json=statsGlobalInstanceId,proto3" json:"stats_global_instance_id,omitempty"` - // Global instance ID that handles Clusters streams. - ClustersGlobalInstanceId string `protobuf:"bytes,3,opt,name=clusters_global_instance_id,json=clustersGlobalInstanceId,proto3" json:"clusters_global_instance_id,omitempty"` -} - -func (x *EnvoyAdminStreams) Reset() { - *x = EnvoyAdminStreams{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EnvoyAdminStreams) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EnvoyAdminStreams) ProtoMessage() {} - -func (x *EnvoyAdminStreams) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EnvoyAdminStreams.ProtoReflect.Descriptor instead. -func (*EnvoyAdminStreams) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{1} -} - -func (x *EnvoyAdminStreams) GetConfigDumpGlobalInstanceId() string { - if x != nil { - return x.ConfigDumpGlobalInstanceId - } - return "" -} - -func (x *EnvoyAdminStreams) GetStatsGlobalInstanceId() string { - if x != nil { - return x.StatsGlobalInstanceId - } - return "" -} - -func (x *EnvoyAdminStreams) GetClustersGlobalInstanceId() string { - if x != nil { - return x.ClustersGlobalInstanceId - } - return "" -} - -// DDSSubscription describes a single DDS subscription -// created by a Zone to the Global. -// Ideally, there should be only one such subscription per Zone lifecycle. -// Presence of multiple subscriptions might indicate one of the following -// events: -// - transient loss of network connection between Zone and Global Control -// Planes -// - Zone Dubbo CP restarts (i.e. hot restart or crash) -// - Global Dubbo CP restarts (i.e. rolling update or crash) -// - etc -type DDSSubscription struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Unique id per DDS subscription. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Global CP instance that handled given subscription. - GlobalInstanceId string `protobuf:"bytes,2,opt,name=global_instance_id,json=globalInstanceId,proto3" json:"global_instance_id,omitempty"` - // Time when a given Zone connected to the Global. - ConnectTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=connect_time,json=connectTime,proto3" json:"connect_time,omitempty"` - // Time when a given Zone disconnected from the Global. - DisconnectTime *timestamp.Timestamp `protobuf:"bytes,4,opt,name=disconnect_time,json=disconnectTime,proto3" json:"disconnect_time,omitempty"` - // Status of the DDS subscription. - Status *DDSSubscriptionStatus `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"` - // Generation is an integer number which is periodically increased by the - // status sink - Generation uint32 `protobuf:"varint,7,opt,name=generation,proto3" json:"generation,omitempty"` - // Config of Zone Dubbo CP - Config string `protobuf:"bytes,8,opt,name=config,proto3" json:"config,omitempty"` - // Indicates if subscription provided auth token - AuthTokenProvided bool `protobuf:"varint,9,opt,name=auth_token_provided,json=authTokenProvided,proto3" json:"auth_token_provided,omitempty"` - // Zone CP instance that handled the given subscription (This is the leader at - // time of connection). - ZoneInstanceId string `protobuf:"bytes,10,opt,name=zone_instance_id,json=zoneInstanceId,proto3" json:"zone_instance_id,omitempty"` -} - -func (x *DDSSubscription) Reset() { - *x = DDSSubscription{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DDSSubscription) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DDSSubscription) ProtoMessage() {} - -func (x *DDSSubscription) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DDSSubscription.ProtoReflect.Descriptor instead. -func (*DDSSubscription) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{2} -} - -func (x *DDSSubscription) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *DDSSubscription) GetGlobalInstanceId() string { - if x != nil { - return x.GlobalInstanceId - } - return "" -} - -func (x *DDSSubscription) GetConnectTime() *timestamp.Timestamp { - if x != nil { - return x.ConnectTime - } - return nil -} - -func (x *DDSSubscription) GetDisconnectTime() *timestamp.Timestamp { - if x != nil { - return x.DisconnectTime - } - return nil -} - -func (x *DDSSubscription) GetStatus() *DDSSubscriptionStatus { - if x != nil { - return x.Status - } - return nil -} - -func (x *DDSSubscription) GetGeneration() uint32 { - if x != nil { - return x.Generation - } - return 0 -} - -func (x *DDSSubscription) GetConfig() string { - if x != nil { - return x.Config - } - return "" -} - -func (x *DDSSubscription) GetAuthTokenProvided() bool { - if x != nil { - return x.AuthTokenProvided - } - return false -} - -func (x *DDSSubscription) GetZoneInstanceId() string { - if x != nil { - return x.ZoneInstanceId - } - return "" -} - -// DDSSubscriptionStatus defines status of an DDS subscription. -type DDSSubscriptionStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Time when status of a given DDS subscription was most recently updated. - LastUpdateTime *timestamp.Timestamp `protobuf:"bytes,1,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` - // Total defines an aggregate over individual DDS stats. - Total *DDSServiceStats `protobuf:"bytes,2,opt,name=total,proto3" json:"total,omitempty"` - Stat map[string]*DDSServiceStats `protobuf:"bytes,3,rep,name=stat,proto3" json:"stat,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *DDSSubscriptionStatus) Reset() { - *x = DDSSubscriptionStatus{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DDSSubscriptionStatus) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DDSSubscriptionStatus) ProtoMessage() {} - -func (x *DDSSubscriptionStatus) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DDSSubscriptionStatus.ProtoReflect.Descriptor instead. -func (*DDSSubscriptionStatus) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{3} -} - -func (x *DDSSubscriptionStatus) GetLastUpdateTime() *timestamp.Timestamp { - if x != nil { - return x.LastUpdateTime - } - return nil -} - -func (x *DDSSubscriptionStatus) GetTotal() *DDSServiceStats { - if x != nil { - return x.Total - } - return nil -} - -func (x *DDSSubscriptionStatus) GetStat() map[string]*DDSServiceStats { - if x != nil { - return x.Stat - } - return nil -} - -// DiscoveryServiceStats defines all stats over a single xDS service. -type DDSServiceStats struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Number of xDS responses sent to the Dataplane. - ResponsesSent uint64 `protobuf:"varint,1,opt,name=responses_sent,json=responsesSent,proto3" json:"responses_sent,omitempty"` - // Number of xDS responses ACKed by the Dataplane. - ResponsesAcknowledged uint64 `protobuf:"varint,2,opt,name=responses_acknowledged,json=responsesAcknowledged,proto3" json:"responses_acknowledged,omitempty"` - // Number of xDS responses NACKed by the Dataplane. - ResponsesRejected uint64 `protobuf:"varint,3,opt,name=responses_rejected,json=responsesRejected,proto3" json:"responses_rejected,omitempty"` -} - -func (x *DDSServiceStats) Reset() { - *x = DDSServiceStats{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DDSServiceStats) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DDSServiceStats) ProtoMessage() {} - -func (x *DDSServiceStats) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DDSServiceStats.ProtoReflect.Descriptor instead. -func (*DDSServiceStats) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{4} -} - -func (x *DDSServiceStats) GetResponsesSent() uint64 { - if x != nil { - return x.ResponsesSent - } - return 0 -} - -func (x *DDSServiceStats) GetResponsesAcknowledged() uint64 { - if x != nil { - return x.ResponsesAcknowledged - } - return 0 -} - -func (x *DDSServiceStats) GetResponsesRejected() uint64 { - if x != nil { - return x.ResponsesRejected - } - return 0 -} - -// HealthCheck holds information about the received zone health check -type HealthCheck struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Time last health check received - Time *timestamp.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` -} - -func (x *HealthCheck) Reset() { - *x = HealthCheck{} - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *HealthCheck) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HealthCheck) ProtoMessage() {} - -func (x *HealthCheck) ProtoReflect() protoreflect.Message { - mi := &file_api_system_v1alpha1_zone_insight_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HealthCheck.ProtoReflect.Descriptor instead. -func (*HealthCheck) Descriptor() ([]byte, []int) { - return file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP(), []int{5} -} - -func (x *HealthCheck) GetTime() *timestamp.Timestamp { - if x != nil { - return x.Time - } - return nil -} - -var File_api_system_v1alpha1_zone_insight_proto protoreflect.FileDescriptor - -var file_api_system_v1alpha1_zone_insight_proto_rawDesc = []byte{ - 0x0a, 0x26, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x69, 0x67, - 0x68, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, - 0x16, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc2, 0x02, 0x0a, 0x0b, 0x5a, 0x6f, 0x6e, - 0x65, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x44, 0x53, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x13, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x5f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x6f, - 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x11, 0x65, - 0x6e, 0x76, 0x6f, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x12, 0x45, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x3a, 0x44, 0xaa, 0x8c, 0x89, 0xa6, 0x01, 0x3e, 0x0a, - 0x13, 0x5a, 0x6f, 0x6e, 0x65, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b, 0x5a, 0x6f, 0x6e, 0x65, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x01, 0x22, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x10, 0x0a, 0x0c, 0x7a, - 0x6f, 0x6e, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x22, 0xcf, 0x01, - 0x0a, 0x11, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x75, - 0x6d, 0x70, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x67, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, - 0xab, 0x03, 0x0a, 0x0f, 0x44, 0x44, 0x53, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x43, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x44, - 0x53, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x11, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x7a, - 0x6f, 0x6e, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xc8, 0x02, - 0x0a, 0x15, 0x44, 0x44, 0x53, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, - 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, - 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x64, - 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x44, 0x53, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x04, 0x73, - 0x74, 0x61, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x64, 0x75, 0x62, 0x62, - 0x6f, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x44, 0x44, 0x53, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x04, 0x73, 0x74, 0x61, 0x74, 0x1a, 0x5f, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x44, - 0x53, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9e, 0x01, 0x0a, 0x0f, 0x44, 0x44, 0x53, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x53, - 0x65, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x16, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, - 0x5f, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x15, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x41, 0x63, - 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x73, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x3d, 0x0a, 0x0b, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, - 0x62, 0x62, 0x6f, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_system_v1alpha1_zone_insight_proto_rawDescOnce sync.Once - file_api_system_v1alpha1_zone_insight_proto_rawDescData = file_api_system_v1alpha1_zone_insight_proto_rawDesc -) - -func file_api_system_v1alpha1_zone_insight_proto_rawDescGZIP() []byte { - file_api_system_v1alpha1_zone_insight_proto_rawDescOnce.Do(func() { - file_api_system_v1alpha1_zone_insight_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_system_v1alpha1_zone_insight_proto_rawDescData) - }) - return file_api_system_v1alpha1_zone_insight_proto_rawDescData -} - -var file_api_system_v1alpha1_zone_insight_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_api_system_v1alpha1_zone_insight_proto_goTypes = []any{ - (*ZoneInsight)(nil), // 0: dubbo.system.v1alpha1.ZoneInsight - (*EnvoyAdminStreams)(nil), // 1: dubbo.system.v1alpha1.EnvoyAdminStreams - (*DDSSubscription)(nil), // 2: dubbo.system.v1alpha1.DDSSubscription - (*DDSSubscriptionStatus)(nil), // 3: dubbo.system.v1alpha1.DDSSubscriptionStatus - (*DDSServiceStats)(nil), // 4: dubbo.system.v1alpha1.DDSServiceStats - (*HealthCheck)(nil), // 5: dubbo.system.v1alpha1.HealthCheck - nil, // 6: dubbo.system.v1alpha1.DDSSubscriptionStatus.StatEntry - (*timestamp.Timestamp)(nil), // 7: google.protobuf.Timestamp -} -var file_api_system_v1alpha1_zone_insight_proto_depIdxs = []int32{ - 2, // 0: dubbo.system.v1alpha1.ZoneInsight.subscriptions:type_name -> dubbo.system.v1alpha1.DDSSubscription - 1, // 1: dubbo.system.v1alpha1.ZoneInsight.envoy_admin_streams:type_name -> dubbo.system.v1alpha1.EnvoyAdminStreams - 5, // 2: dubbo.system.v1alpha1.ZoneInsight.health_check:type_name -> dubbo.system.v1alpha1.HealthCheck - 7, // 3: dubbo.system.v1alpha1.DDSSubscription.connect_time:type_name -> google.protobuf.Timestamp - 7, // 4: dubbo.system.v1alpha1.DDSSubscription.disconnect_time:type_name -> google.protobuf.Timestamp - 3, // 5: dubbo.system.v1alpha1.DDSSubscription.status:type_name -> dubbo.system.v1alpha1.DDSSubscriptionStatus - 7, // 6: dubbo.system.v1alpha1.DDSSubscriptionStatus.last_update_time:type_name -> google.protobuf.Timestamp - 4, // 7: dubbo.system.v1alpha1.DDSSubscriptionStatus.total:type_name -> dubbo.system.v1alpha1.DDSServiceStats - 6, // 8: dubbo.system.v1alpha1.DDSSubscriptionStatus.stat:type_name -> dubbo.system.v1alpha1.DDSSubscriptionStatus.StatEntry - 7, // 9: dubbo.system.v1alpha1.HealthCheck.time:type_name -> google.protobuf.Timestamp - 4, // 10: dubbo.system.v1alpha1.DDSSubscriptionStatus.StatEntry.value:type_name -> dubbo.system.v1alpha1.DDSServiceStats - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name -} - -func init() { file_api_system_v1alpha1_zone_insight_proto_init() } -func file_api_system_v1alpha1_zone_insight_proto_init() { - if File_api_system_v1alpha1_zone_insight_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_system_v1alpha1_zone_insight_proto_rawDesc, - NumEnums: 0, - NumMessages: 7, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_api_system_v1alpha1_zone_insight_proto_goTypes, - DependencyIndexes: file_api_system_v1alpha1_zone_insight_proto_depIdxs, - MessageInfos: file_api_system_v1alpha1_zone_insight_proto_msgTypes, - }.Build() - File_api_system_v1alpha1_zone_insight_proto = out.File - file_api_system_v1alpha1_zone_insight_proto_rawDesc = nil - file_api_system_v1alpha1_zone_insight_proto_goTypes = nil - file_api_system_v1alpha1_zone_insight_proto_depIdxs = nil -} diff --git a/api/system/v1alpha1/zone_insight.proto b/api/system/v1alpha1/zone_insight.proto deleted file mode 100644 index 3c4e7d998..000000000 --- a/api/system/v1alpha1/zone_insight.proto +++ /dev/null @@ -1,108 +0,0 @@ -syntax = "proto3"; - -package dubbo.system.v1alpha1; - -option go_package = "github.com/apache/dubbo-admin/api/system/v1alpha1"; - -import "api/mesh/options.proto"; -import "google/protobuf/timestamp.proto"; - -message ZoneInsight { - - option (dubbo.mesh.resource).name = "ZoneInsightResource"; - option (dubbo.mesh.resource).type = "ZoneInsight"; - option (dubbo.mesh.resource).package = "system"; - option (dubbo.mesh.resource).global = true; - option (dubbo.mesh.resource).ws.name = "zone-insight"; - option (dubbo.mesh.resource).ws.read_only = true; - - // List of DDS subscriptions created by a given Zone Dubbo CP. - repeated DDSSubscription subscriptions = 1; - - // Statistics about Envoy Admin Streams - EnvoyAdminStreams envoy_admin_streams = 2; - - HealthCheck health_check = 3; -} - -message EnvoyAdminStreams { - // Global instance ID that handles XDS Config Dump streams. - string config_dump_global_instance_id = 1; - // Global instance ID that handles Stats streams. - string stats_global_instance_id = 2; - // Global instance ID that handles Clusters streams. - string clusters_global_instance_id = 3; -} - -// DDSSubscription describes a single DDS subscription -// created by a Zone to the Global. -// Ideally, there should be only one such subscription per Zone lifecycle. -// Presence of multiple subscriptions might indicate one of the following -// events: -// - transient loss of network connection between Zone and Global Control -// Planes -// - Zone Dubbo CP restarts (i.e. hot restart or crash) -// - Global Dubbo CP restarts (i.e. rolling update or crash) -// - etc -message DDSSubscription { - - // Unique id per DDS subscription. - string id = 1; - - // Global CP instance that handled given subscription. - string global_instance_id = 2; - - // Time when a given Zone connected to the Global. - google.protobuf.Timestamp connect_time = 3; - - // Time when a given Zone disconnected from the Global. - google.protobuf.Timestamp disconnect_time = 4; - - // Status of the DDS subscription. - DDSSubscriptionStatus status = 5; - - // Generation is an integer number which is periodically increased by the - // status sink - uint32 generation = 7; - - // Config of Zone Dubbo CP - string config = 8; - - // Indicates if subscription provided auth token - bool auth_token_provided = 9; - - // Zone CP instance that handled the given subscription (This is the leader at - // time of connection). - string zone_instance_id = 10; -} - -// DDSSubscriptionStatus defines status of an DDS subscription. -message DDSSubscriptionStatus { - - // Time when status of a given DDS subscription was most recently updated. - google.protobuf.Timestamp last_update_time = 1; - - // Total defines an aggregate over individual DDS stats. - DDSServiceStats total = 2; - - map stat = 3; -} - -// DiscoveryServiceStats defines all stats over a single xDS service. -message DDSServiceStats { - - // Number of xDS responses sent to the Dataplane. - uint64 responses_sent = 1; - - // Number of xDS responses ACKed by the Dataplane. - uint64 responses_acknowledged = 2; - - // Number of xDS responses NACKed by the Dataplane. - uint64 responses_rejected = 3; -} - -// HealthCheck holds information about the received zone health check -message HealthCheck { - // Time last health check received - google.protobuf.Timestamp time = 1; -} diff --git a/app/dubbo-admin/cmd/root.go b/app/dubbo-admin/cmd/root.go index 363d1c775..0a88ffd35 100644 --- a/app/dubbo-admin/cmd/root.go +++ b/app/dubbo-admin/cmd/root.go @@ -18,70 +18,24 @@ package cmd import ( - "fmt" "os" - "path/filepath" "github.com/spf13/cobra" - dubbolog "github.com/apache/dubbo-admin/pkg/common/log" - "github.com/apache/dubbo-admin/pkg/core" - cmd2 "github.com/apache/dubbo-admin/pkg/core/cmd" "github.com/apache/dubbo-admin/pkg/core/cmd/version" ) -var adminLog = core.Log.WithName("admin") - // newRootCmd represents the base command when called without any subcommands. func newRootCmd() *cobra.Command { - args := struct { - logLevel string - outputPath string - maxSize int - maxBackups int - maxAge int - }{} cmd := &cobra.Command{ Use: "dubbo-admin", Short: "Universal Admin for Dubbo Application", Long: `Universal Admin for Dubbo Application`, - PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { - level, err := dubbolog.ParseLogLevel(args.logLevel) - if err != nil { - return err - } - - if args.outputPath != "" { - output, err := filepath.Abs(args.outputPath) - if err != nil { - return err - } - - fmt.Printf("%s: logs will be stored in %q\n", "dubbo-cp", output) - core.SetLogger(core.NewLoggerWithRotation(level, output, args.maxSize, args.maxBackups, args.maxAge)) - } else { - core.SetLogger(core.NewLogger(level)) - } - - // once command line flags have been parsed, - // avoid printing usage instructions - cmd.SilenceUsage = true - - return nil - }, } cmd.SetOut(os.Stdout) - - // root flags - cmd.PersistentFlags().StringVar(&args.logLevel, "log-level", dubbolog.InfoLevel.String(), cmd2.UsageOptions("log level", dubbolog.OffLevel, dubbolog.InfoLevel, dubbolog.DebugLevel)) - cmd.PersistentFlags().StringVar(&args.outputPath, "log-output-path", args.outputPath, "path to the file that will be filled with logs. Example: if we set it to /tmp/dubbo.log then after the file is rotated we will have /tmp/dubbo-2021-06-07T09-15-18.265.log") - cmd.PersistentFlags().IntVar(&args.maxBackups, "log-max-retained-files", 1000, "maximum number of the old log files to retain") - cmd.PersistentFlags().IntVar(&args.maxSize, "log-max-size", 100, "maximum size in megabytes of a log file before it gets rotated") - cmd.PersistentFlags().IntVar(&args.maxAge, "log-max-age", 30, "maximum number of days to retain old log files based on the timestamp encoded in their filename") - // sub-commands - cmd.AddCommand(newRunCmdWithOpts(cmd2.DefaultRunCmdOpts)) + cmd.AddCommand(newRunCmdWithOpts()) cmd.AddCommand(version.NewVersionCmd()) return cmd diff --git a/app/dubbo-admin/cmd/run.go b/app/dubbo-admin/cmd/run.go index 6bd94b9c9..a6bd5acb8 100644 --- a/app/dubbo-admin/cmd/run.go +++ b/app/dubbo-admin/cmd/run.go @@ -18,7 +18,10 @@ package cmd import ( - "fmt" + "context" + "os" + "os/signal" + "syscall" "time" "github.com/spf13/cobra" @@ -26,19 +29,14 @@ import ( "github.com/apache/dubbo-admin/pkg/config" "github.com/apache/dubbo-admin/pkg/config/app" "github.com/apache/dubbo-admin/pkg/core/bootstrap" - dubbocmd "github.com/apache/dubbo-admin/pkg/core/cmd" + "github.com/apache/dubbo-admin/pkg/core/logger" + _ "github.com/apache/dubbo-admin/pkg/lock/gorm" dubboversion "github.com/apache/dubbo-admin/pkg/version" ) -var runLog = adminLog.WithName("run") - const gracefullyShutdownDuration = 3 * time.Second -// This is the open file limit below which the control plane may not -// reasonably have enough descriptors to accept all its clients. -const minOpenFileLimit = 4096 - -func newRunCmdWithOpts(opts dubbocmd.RunCmdOpts) *cobra.Command { +func newRunCmdWithOpts() *cobra.Command { args := struct { configPath string }{} @@ -51,49 +49,66 @@ func newRunCmdWithOpts(opts dubbocmd.RunCmdOpts) *cobra.Command { cfg := app.DefaultAdminConfig() err := config.Load(args.configPath, &cfg) if err != nil { - runLog.Error(err, "could not load the configuration") return err - } + // 2. configure logger + logger.Init(cfg.Log) cfgForDisplay, err := config.ConfigForDisplay(&cfg) if err != nil { - runLog.Error(err, "unable to prepare config for display") + logger.Errorf("unable to prepare config for display, cause: %s", err.Error()) return err } cfgBytes, err := config.ToJson(cfgForDisplay) if err != nil { - runLog.Error(err, "unable to convert config to json") + logger.Errorf("unable to convert config to json, cause: %s", err.Error()) return err } - runLog.Info(fmt.Sprintf("Current config %s", cfgBytes)) - runLog.Info(fmt.Sprintf("Running in mode `%s`", cfg.Mode)) + logger.Infof("current config:\n %s", cfgBytes) // 2. build components - gracefulCtx, ctx := opts.SetupSignalHandler() + gracefulCtx, ctx := setupSignalHandler() rt, err := bootstrap.Bootstrap(gracefulCtx, cfg) if err != nil { - runLog.Error(err, "unable to bootstrap") + logger.Errorf("unable to bootstrap, cause: %s", err.Error()) return err } // 3. start components - runLog.Info("starting Admin......", "version", dubboversion.Build.Version) + logger.Infof("starting Admin......, version: %s", dubboversion.Build.Version) if err := rt.Start(gracefulCtx.Done()); err != nil { - runLog.Error(err, "problem running Admin") + logger.Errorf("problem running Admin, cause: %s", err.Error()) return err } - - runLog.Info("stop signal received. Waiting 3 seconds for components to stop gracefully...") + logger.Info("stop signal received. Waiting 3 seconds for components to stop gracefully...") select { case <-ctx.Done(): - runLog.Info("all components have stopped") + logger.Info("all components have stopped") case <-time.After(gracefullyShutdownDuration): - runLog.Info("forcefully stopped") + logger.Info("forcefully stopped") } return nil }, } // flags - cmd.PersistentFlags().StringVarP(&args.configPath, "config-file", "c", "", "configuration file") + cmd.PersistentFlags().StringVarP(&args.configPath, "config-file", "c", "./dubbo-admin.yaml", "configuration file") return cmd } + +func setupSignalHandler() (context.Context, context.Context) { + gracefulCtx, gracefulCancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(context.Background()) + c := make(chan os.Signal, 3) + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) + go func() { + s := <-c + logger.Warnf("received signal %s, stopping instance gracefully", s.String()) + gracefulCancel() + s = <-c + logger.Warnf("received second signal %s, stopping instance", s.String()) + cancel() + s = <-c + logger.Warnf("received third signal %s, force exit", s.String()) + os.Exit(1) + }() + return gracefulCtx, ctx +} diff --git a/app/dubbo-admin/dubbo-admin-legacy.yaml b/app/dubbo-admin/dubbo-admin-legacy.yaml deleted file mode 100644 index 5123ea4b4..000000000 --- a/app/dubbo-admin/dubbo-admin-legacy.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Support multi deploy status, see https://github.com/apache/dubbo-kubernetes/blob/master/README.md -# Available options: k8s(not supported yet), half, universal -deployMode: half -# Support multi-cluster -# Available options: zone, global(not supported yet) -mode: zone -store: - # Traditional Store support nacos and zookeeper - traditional: - registry: - address: nacos://47.76.94.134:8848?username=nacos&password=nacos - configCenter: - address: nacos://47.76.94.134:8848?username=nacos&password=nacos - metadataReport: - address: nacos://47.76.94.134:8848?username=nacos&password=nacos -admin: - # metric and trace grafana dashboards - metricDashboards: - application: - baseURL: http://47.76.81.123:3000/d/a0b114ca-edf7-4dfe-ac2c-34a4fc545fed/application - instance: - baseURL: http://47.76.81.123:3000/d/dcf5defe-d198-4704-9edf-6520838880e9/instance - service: - baseURL: http://47.76.81.123:3000/d/ec689613-b4a1-45b1-b8bd-9d557059f970/service/ - traceDashboards: - application: - baseURL: http://47.76.81.123:3000/d/e968a89b-f03d-42e3-8ad3-930ae815cb0f/application - instance: - baseURL: http://47.76.81.123:3000/d/f5f48f75-13ec-489b-88ae-635ae38d8618/instance - service: - baseURL: http://47.76.81.123:3000/d/b2e178fb-ada3-4d5e-9f54-de99e7f07662/service - prometheus: http://8.218.148.84:9090 - # grafana should custom configs below: - # [server] - # root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana - # allowed_origins = * - # serve_from_sub_path = true - # [security] - # allow_embedding = true - # [auth.anonymous] - # enabled = true - grafana: http://47.76.81.123:3000/ - auth: - user: admin - password: Dubbo@2025 - expirationTime: 7200 diff --git a/app/dubbo-admin/dubbo-admin.yaml b/app/dubbo-admin/dubbo-admin.yaml index 5cd21bce6..1e74b47ea 100644 --- a/app/dubbo-admin/dubbo-admin.yaml +++ b/app/dubbo-admin/dubbo-admin.yaml @@ -13,40 +13,161 @@ # See the License for the specific language governing permissions and # limitations under the License. -mode: zone +# [Optional] Config for log. +log: + # [Optional] log level, options are debug, info, warn, error. Optional, default is info. + level: info + # [Optional] log file output path, default is ./logs/dubbo-admin.log. + outputPath: logs/dubbo-admin.log + # [Optional] max size for a single log file, default is 100, unit is `M`. [Optional] + maxSize: 100 + # [Optional] max number of old log files to retain, default is 5. [Optional] + maxBackups: 5 + # [Optional] max age for a log file, default is 3, unit is `day`. [Optional] + maxAge: 3 + +# [Optional] config for observability. +observability: + # [Optional] config for grafana and prometheus. + grafana: http://101.34.253.152:30300 + # [Optional] config for prometheus. + prometheus: http://101.34.253.152:30900/ + +# [Optional] config for console. console: - observability: - grafana: xx - prometheus: xx - jaeger: xx - dashboards: - metric: - application: xx - instance: xx - service: xx - trace: - application: xx - instance: xx - service: xx - log: - application: xx - instance: xx - service: xx + # [Optional] port of http server, default is 8888. + port: 8888 + # [Optional] running mode of Gin, options are debug, release, test, default is release. + ginMode: release + # [Optional] dashboard for metrics. + metricDashboards: + application: http://101.34.253.152:30300/d/a0b114ca-edf7-4dfe-ac2c-34a4fc545fed?kiosk=1&theme=light + instance: http://101.34.253.152:30300/d/dcf5defe-d198-4704-9edf-6520838880e9?kiosk=1&theme=light + service: http://101.34.253.152:30300/d/ec689613-b4a1-45b1-b8bd-9d557059f970?kiosk=1&theme=light + # [Optional] dashboard for traces. + traceDashboards: + application: http://101.34.253.152:30300/d/e968a89b-f03d-42e3-8ad3-930ae815cb0f?kiosk=1&theme=light + instance: http://101.34.253.152:30300/d/f5f48f75-13ec-489b-88ae-635ae38d8618?kiosk=1&theme=light + service: http://101.34.253.152:30300/d/b2e178fb-ada3-4d5e-9f54-de99e7f07662?kiosk=1&theme=light + # [Optional] typical user-pwd authentication, default user-pwd is admin-admin. auth: - type: oath2 - oauth2: - clientId: xx + user: admin + password: dubbo@2025 + expirationTime: 3600 + +# [Optional] config for data storage, default is memory store: - type: mysql - address: xx + # [Optional] store data in memory + type: memory + # [Optional, Beta] store data in mysql +# type: mysql +# address: root:123456@tcp(127.0.0.1:23306)/dubbo-admin?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai + +# [Necessary] configs for service discovery discovery: - - type: nacos - id: nacos-44.33 + # [Necessary] discovery type, options are nacos2, zookeeper, mock(only for dev) + - type: nacos2 + # [Necessary] discovery name, will be displayed in the web ui + name: nacos2.5-standalone + # [Necessary] a unique id for this discovery + id: nacos2.5 + # [Necessary] address config address: - registry: nacos://47.76.94.134:8848?username=nacos&password=nacos - configCenter: nacos://47.76.94.134:8848?username=nacos&password=nacos - metadataReport: nacos://47.76.94.134:8848?username=nacos&password=nacos - - type: istio + # [Necessary] registry address + registry: nacos://101.34.253.152:30848?username=nacos&password=nacos + # [Optional] config center address, if not set, will use registry address + configCenter: nacos://101.34.253.152:30848?username=nacos&password=nacos + # [Optional] metadata report address, if not set, will use registry address + metadataReport: nacos://101.34.253.152:30848?username=nacos&password=nacos + # [Optional] extra properties + properties: + # [Nacos2, Optional] Adjust the interval(time unit is `s`) to adjust the frequency of list-all configs in nacos. + # Default period is 30s + configWatchPeriod: 30 + # [Nacos2, Optional] Adjust the interval(time unit is `s`) to adjust the frequency of list-all services in nacos. + # Default period is 30s + serviceWatchPeriod: 30 +# - type: zookeeper +# name: localhost-zookeeper +# id: zk3.6 +# address: +# registry: zookeeper://127.0.0.1:2181 +# configCenter: zookeeper://127.0.0.1:2181 +# metadataReport: zookeeper://127.0.0.1:2181 +# mock discovery is only for development +# - type: mock +# id: mock +# name: mockRegistry + +# [Optional] config for runtime engine, default is mock, as well as no engine. engine: - type: k8s -controlPlane: \ No newline at end of file +# id: mock +# name: mock +# type: mock + id: default + name: k8s1.28.6 + type: kubernetes + properties: + # [Kubernetes, Optional] kubeConfigPath: Path to kubernetes config file, if not set, will use in cluster config + # e.g. + kubeConfigPath: /root/.kube/config + + # [Kubernetes, Optional] podWatchSelector: Watch pods with specified labels, if not set, will watch all pods + # e.g. + # podWatchSelector: org.apache.dubbo/dubbo-apps=true + + # [Kubernetes, Optional] dubboAppIdentifier: Identify which Dubbo app the pod belongs to, if not set, pod will not be seen as a dubbo instance at first + # 1. ByLabels: Use the label value corresponding to the labelKey as the dubbo app name + # e.g. + # dubboAppIdentifier: + # type: ByLabel + # labelKey: org.apache.dubbo/dubbo-app-name + # 2. ByAnnotation: Use the annotation value corresponding to the annotationKey as the dubbo app name + # e.g. + # dubboAppIdentifier: + # type: ByAnnotation + # annotationKey: org.apache.dubbo/dubbo-app-name + + # [Kubernetes, Optional] dubboRPCPortIdentifier: Identify the rpc port of a dubbo application, if not set, pod will not be seen as a dubbo instance at first + # 1. ByLabels: Use the label value corresponding to the labelKey as the dubbo rpc port + # e.g. + # dubboRPCPortIdentifier: + # type: ByLabel + # labelKey: org.apache.dubbo/dubbo-rpc-port + # 2. ByAnnotation: Use the annotation value corresponding to the annotationKey as the dubbo rpc port + # e.g. + # dubboRPCPortIdentifier: + # type: ByAnnotation + # annotationKey: org.apache.dubbo/dubbo-rpc-port + + # [Kubernetes, Optional] dubboDiscoveryIdentifier: Identify the registry(discovery) which the dubbo instance belongs to, if not set, pod will not be seen as a dubbo instance at first + # 1. ByLabels: Use the label value corresponding to the labelKey as the dubbo registry name + # e.g. + # dubboDiscoveryIdentifier: + # type: ByLabel + # labelKey: org.apache.dubbo/registry + # 2. ByAnnotation: Use the annotation value corresponding to the annotationKey as the dubbo registry name + # e.g. + # dubboDiscoveryIdentifier: + # type: ByAnnotation + # annotationKey: org.apache.dubbo/registry + + # [Kubernetes, Optional] mainContainerChooseStrategy: Strategy of choosing the main container, if not set, [type = ByIndex] and [index = 0] will be used + # 1. ByLast: choose the last container as the main container + # e.g. + # mainContainerChooseStrategy: + # type: ByLast + # 2. ByIndex(default): choose the container at the specified index location as the main container + # e.g. + # type: ByIndex + # index: 0 + # 3. ByName: choose the container with the specified name + # e.g. + # mainContainerChooseStrategy: + # type: ByName + # name: main + # 4. ByAnnotation: choose the container with the annotation key, specified annotation value will be used as the container name + # e.g. + # mainContainerChooseStrategy: + # type: ByAnnotation + # annotationKey: org.apache.dubbo/main-container-name=${app-name} diff --git a/app/dubbo-ui/dist/admin/assets/ByteUtil-YdHlSEeW.js b/app/dubbo-ui/dist/admin/assets/ByteUtil-YdHlSEeW.js deleted file mode 100644 index 193c1c68e..000000000 --- a/app/dubbo-ui/dist/admin/assets/ByteUtil-YdHlSEeW.js +++ /dev/null @@ -1 +0,0 @@ -function u(n=0){const o=["B","KB","MB","GB","TB"];let t=0;for(;n>=1024&&te in u?h(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var o=(u,e,t)=>(p(u,typeof e!="symbol"?e+"":e,t),t);import{i as c}from"./index-hmLAZQYT.js";class m{constructor(e){o(this,"enabled",!0);o(this,"hasMatch",!1);o(this,"side","provider");o(this,"matches",[]);o(this,"parameters",[]);o(this,"matchesKeys",[]);o(this,"parametersKeys",[]);o(this,"parametersValue",{retries:{type:"obj",relation:"=",value:""},timeout:{type:"obj",relation:"=",value:""},accesslog:{type:"obj",relation:"=",value:""},weight:{type:"obj",relation:"=",value:""},other:{type:"free",arr:[{key:"",relation:"=",value:""}]}});o(this,"matchesValue",{address:{type:"obj",relation:"",value:""},providerAddress:{type:"obj",relation:"",value:""},service:{type:"arr",arr:[{key:"oneof",relation:"",value:""}]},application:{type:"arr",arr:[{key:"oneof",relation:"",value:""}]},param:{type:"free",arr:[{key:"",relation:"",value:""}]}});if(e){for(let t of Object.keys(this))e[t]&&(this[t]=e[t]);this.hasMatch=this.matchesKeys.length>0}}descMatches(){let e=[];for(let t in this.matchesValue){let a=this.matchesValue[t];if(this.matchesKeys.includes(t))if(a.type==="obj")e.push(`${t} ${a.relation} ${a.value}`);else if(a.type==="arr"){let s=a.arr.map(r=>`${r.relation} ${r.value}`).join(", ");e.push(`${t} oneof [${s}]`)}else{let s=a.arr.map(r=>`${r.key} ${r.relation} ${r.value}`).join(", ");e.push(`${t} allof [${s}]`)}}return e}descParameters(){let e=[];for(let t in this.parametersValue){let a=this.parametersValue[t];this.parametersKeys.includes(t)&&(a.type==="obj"?e.push(`${t} = ${a.value}`):e.push(...a.arr.map(s=>`${s.key} ${s.relation} ${s.value}`)))}return e}delArrConfig(e,t,a){e[t].arr.splice(a,1)}addArrConfig(e,t,a,s){e[t].arr.splice(a+1,0,{key:"",relation:(s==null?void 0:s.relation)||"",value:""})}parseMatches(e){let t=this.matchesValue;for(let a in e){this.matchesKeys.push(a),this.hasMatch=!0;let s=e[a];if(t[a])if(t[a].type==="obj")for(let r in s)t[a].relation=r,t[a].value=s[r];else if(t[a].type==="arr"){t[a].arr=[];for(let r in s)for(let i of s[r])for(let l in i)t[a].arr.push({key:r,relation:l,value:i[l]})}else{t[a].arr=[];for(let r of s)for(let i in r.value)t[a].arr.push({key:r.key,relation:i,value:r.value[i]})}}}parseParameters(e){let t=this.parametersValue;for(let a in e){let s=e[a];if(this.parametersValue[a])this.parametersKeys.push(a),t[a].relation="=",t[a].value=s;else{let r="other";this.parametersKeys.push(r),t[r].arr=[],t[r].arr.push({key:a,relation:"=",value:s})}}}checkArrConfig(e,t,a,s){for(let r of t){let i=a[r];if(i.type==="obj"){if(i.relation===null||i.relation==="")return s.push(`${e}: ${r} 条件为空`),console.log(`${e}: ${r} 条件为空`),!1;if(i.value===null)return s.push(`${e}: ${r} 值为空`),console.log(`${e}: ${r} 值为空`),!1}if(i.type==="arr")for(let l of i.arr){if(l.relation===null||l.relation==="")return s.push(`${e}: ${r} 条件为空`),console.log(`${e}: ${r} 条件为空`),!1;if(l.value===null)return s.push(`${e}: ${r} 值为空`),console.log(`${e}: ${r} 值为空`),!1}else{let l=1;if(!i.arr)continue;for(let n of i.arr){if(n.relation===null||n.relation==="")return s.push(`${e}: ${r} 下第${l}条记录key为空`),console.log(`${e}: ${r} 下第${l}条记录key为空`),!1;if(n.relation===null||n.relation==="")return s.push(`${e}: ${r} 下第${l}条记录条件为空`),console.log(`${e}: ${r} 下第${l}条记录条件为空`),!1;if(n.value===null)return s.push(`${e}: ${r} 第${l}条记录值为空`),console.log(`${e}: ${r} 第${l}条记录值为空`),!1;l++}}}return!0}}class y{constructor(){o(this,"ruleName");o(this,"scope");o(this,"configVersion");o(this,"key");o(this,"effectTime");o(this,"enabled")}}class g{constructor(){o(this,"basicInfo",new y);o(this,"config",[]);o(this,"errorMsg",[]);o(this,"isAdd",!1)}fromData(e){this.basicInfo=e.basicInfo,this.config=e.config,this.isAdd=e.isAdd}fromApiOutput(e){this.basicInfo.configVerison=e.configVerison||"v3.0",this.basicInfo.scope=e.scope,this.basicInfo.key=e.key,this.basicInfo.enabled=e.enabled||!1,this.config=e.configs.map(t=>{let a=new m({enabled:t.enabled,side:t.side});return a.parseMatches(t.match),a.parseParameters(t.parameters),a})}toApiInput(e=!1){return this.errorMsg=[],{ruleName:this.basicInfo.ruleName==="_tmp"?this.basicInfo.key+".configurators":this.basicInfo.ruleName,scope:this.basicInfo.scope,key:this.basicInfo.key,enabled:this.basicInfo.enabled,configVersion:this.basicInfo.configVerison||"v3.0",configs:this.config.map((a,s)=>{const r={},i={};if(e){if(a.parametersKeys.length===0)throw this.errorMsg.push(`配置 ${s+1}${c.global.t("dynamicConfigDomain.configType")} 不能为空`),loading.value=!1,new Error("数据检查失败");if(!(a.checkArrConfig(`配置 ${s+1}${c.global.t("dynamicConfigDomain.matchType")} 检查失败`,a.matchesKeys,a.matchesValue,this.errorMsg)&&a.checkArrConfig(`配置 ${s+1}${c.global.t("dynamicConfigDomain.configType")} 检查失败`,a.parametersKeys,a.parametersValue,this.errorMsg)))throw new Error("数据检查失败")}for(let l of a.matchesKeys){let n=a.matchesValue[l];if(n.type==="obj")r[l]={[n.relation]:n.value};else if(n.type==="arr")r[l]={oneof:n.arr.map(f=>({[f.relation]:f.value}))};else{r[l]=[];for(let f of n.arr)r[l].push({key:f.key,value:{[f.relation]:f.value}})}}for(let l of a.parametersKeys){let n=a.parametersValue[l];if(n.type==="obj")i[l]=n.value;else{r[l]={};for(let f of n.arr)i[f.key]=f.value}}return{match:r,parameters:i,enabled:a.enabled,side:a.side}})}}}export{m as C,g as V}; diff --git a/app/dubbo-ui/dist/admin/assets/ConfigPage--FZz2L2D.js b/app/dubbo-ui/dist/admin/assets/ConfigPage--FZz2L2D.js deleted file mode 100644 index f973829df..000000000 --- a/app/dubbo-ui/dist/admin/assets/ConfigPage--FZz2L2D.js +++ /dev/null @@ -1 +0,0 @@ -import{d as G,l as J,z as K,a as O,c as k,b as a,w as t,e as r,o as l,j as C,n as e,I as h,f as _,t as u,J as Q,K as T,G as m,Q as b,a8 as U,m as w,p as q,h as A,_ as H}from"./index-hmLAZQYT.js";const M=d=>(q("data-v-4c314c51"),d=d(),A(),d),W={class:"__container_common_config"},X={class:"title"},Y=M(()=>C("div",{class:"bg"},null,-1)),Z={class:"truncate-text"},ee={key:0,style:{float:"right"}},te=G({__name:"ConfigPage",props:{options:{}},setup(d){let y=d,s=J(()=>y.options.list[y.options.current[0]]),x=K(null),g=K(!1),I=O();async function N(){g.value=!0,await x.value.validate().catch(c=>{w.error("submit failed [form check]: "+c),g.value=!1});let n=y.options.list[y.options.current[0]];await n.submit(n.form).catch(c=>{w.error("submit failed [server error]: "+c)}),g.value=!1,w.success("submit success")}function V(){s.value.reset(s.value.form)}return(n,c)=>{const L=r("a-tooltip"),P=r("a-menu-item"),R=r("a-menu"),$=r("a-card"),S=r("a-col"),v=r("a-button"),j=r("a-form"),D=r("a-form-item"),E=r("a-spin"),F=r("a-row");return l(),k("div",W,[a(F,{gutter:20},{default:t(()=>[a(S,{span:6},{default:t(()=>[a($,{class:"__opt"},{title:t(()=>[C("div",X,[Y,a(e(h),{class:"title-icon",icon:"icon-park-twotone:application-one"}),a(L,{placement:"topLeft"},{title:t(()=>{var o;return[_(u((o=e(I).params)==null?void 0:o.pathId),1)]}),default:t(()=>{var o;return[C("span",Z,u((o=e(I).params)==null?void 0:o.pathId),1)]}),_:1})])]),default:t(()=>[a(R,{selectedKeys:n.options.current,"onUpdate:selectedKeys":c[0]||(c[0]=o=>n.options.current=o)},{default:t(()=>[(l(!0),k(Q,null,T(n.options.list,(o,i)=>(l(),m(P,{key:i},{default:t(()=>[i===n.options.current[0]?(l(),m(e(h),{key:0,style:{"margin-bottom":"-5px","font-size":"20px"},icon:"material-symbols:settings-b-roll-rounded"})):(l(),m(e(h),{key:1,style:{"margin-bottom":"-5px","font-size":"20px",color:"grey"},icon:"material-symbols:settings-b-roll-outline-rounded"})),_(" "+u(n.$t(o.title)),1)]),_:2},1024))),128))]),_:1},8,["selectedKeys"])]),_:1})]),_:1}),a(S,{span:18},{default:t(()=>[a($,null,{title:t(()=>{var o;return[_(u(n.$t(e(s).title))+" ",1),(o=e(s))!=null&&o.ext?(l(),k("div",ee,[a(v,{type:"primary",onClick:c[1]||(c[1]=i=>{var p,f,z,B;return(B=(p=e(s))==null?void 0:p.ext)==null?void 0:B.fun((z=(f=e(s))==null?void 0:f.form)==null?void 0:z.rules)})},{default:t(()=>{var i,p;return[_(u((p=(i=e(s))==null?void 0:i.ext)==null?void 0:p.title),1)]}),_:1})])):b("",!0)]}),default:t(()=>[a(E,{spinning:e(g)},{default:t(()=>{var o,i;return[(l(),m(j,{style:{overflow:"auto","max-height":"calc(100vh - 450px)"},ref_key:"__config_form",ref:x,key:n.options.current,"wrapper-col":{span:14},model:e(s).form,"label-col":{style:{width:"100px"}},layout:"horizontal"},{default:t(()=>[U(n.$slots,"form_"+e(s).key,{current:e(s)},void 0,!0)]),_:3},8,["model"])),(o=e(s))!=null&&o.submit||(i=e(s))!=null&&i.reset?(l(),m(D,{key:0,style:{margin:"20px 0 0 100px"}},{default:t(()=>{var p,f;return[(p=e(s))!=null&&p.submit?(l(),m(v,{key:0,type:"primary",onClick:N},{default:t(()=>[_(u(n.$t("submit")),1)]),_:1})):b("",!0),(f=e(s))!=null&&f.reset?(l(),m(v,{key:1,style:{"margin-left":"10px"},onClick:V},{default:t(()=>[_(u(n.$t("reset")),1)]),_:1})):b("",!0)]}),_:1})):b("",!0)]}),_:3},8,["spinning"])]),_:3})]),_:3})]),_:3})])}}}),se=H(te,[["__scopeId","data-v-4c314c51"]]);export{se as C}; diff --git a/app/dubbo-ui/dist/admin/assets/ConfigPage-cVEIcX7I.css b/app/dubbo-ui/dist/admin/assets/ConfigPage-cVEIcX7I.css deleted file mode 100644 index e5105e9f4..000000000 --- a/app/dubbo-ui/dist/admin/assets/ConfigPage-cVEIcX7I.css +++ /dev/null @@ -1 +0,0 @@ -.__container_common_config .truncate-text[data-v-4c314c51]{max-width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__container_common_config[data-v-4c314c51] .ant-segmented-group{flex-flow:column}.__container_common_config .__opt .title[data-v-4c314c51]{padding:0 20px;font-size:30px;text-align:center;color:#605f5f;position:relative}.__container_common_config .__opt .title-icon[data-v-4c314c51]{margin-bottom:-5px}.__container_common_config .__opt[data-v-4c314c51] .ant-menu-item{width:80%}.__container_common_config .__opt[data-v-4c314c51] .ant-menu{border:none}.__container_common_config .__opt[data-v-4c314c51] .ant-card-head{border:none;background:url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'%20standalone='no'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20321.39%2078.54'%20version='1.1'%3e%3ctitle%20id='title19'%3eDUBBO%20LOGO%3c/title%3e%3cpath%20class='cls-1'%20d='M68.46,50.38c0,14.06,11.39,22.11,25.45,22.11s25.45-8.05,25.45-22.11V7.25H68.46Zm21.24-28h8.6V31H89.7Zm0,22.25h8.6v8.6H89.7ZM33.24,7.25H4.06v64H33.24c10.95,0,19.3-7.18,23.29-17.15a45.12,45.12,0,0,0,2.38-14.87A45.12,45.12,0,0,0,56.53,24.4C52.84,14.62,44.19,7.25,33.24,7.25Zm.43,14.63H30.34a3.44,3.44,0,0,0-3.44,3.44V53.23a3.44,3.44,0,0,0,3.44,3.44h3.33v4.63h-8.3a6.87,6.87,0,0,1-6.87-6.87V24.12a6.87,6.87,0,0,1,6.87-6.87h8.3ZM285.51,6.06c-17.05,0-30.88,10.28-30.88,33.21s13.83,33.21,30.88,33.21,30.88-10.28,30.88-33.21S302.56,6.06,285.51,6.06Zm7.59,48.36a6.87,6.87,0,0,1-6.87,6.87h-8.3V56.67h3.33a3.44,3.44,0,0,0,3.44-3.44V25.31a3.44,3.44,0,0,0-3.44-3.44h-3.33V17.25h8.3a6.87,6.87,0,0,1,6.87,6.87Zm-53.4-17.56A17.39,17.39,0,0,0,227.31,7.25H195.1v64h32.21a19.44,19.44,0,0,0,12.38-34.44ZM211.63,61.29h-6.08l18.68-44h6.08ZM177,36.85A17.39,17.39,0,0,0,164.65,7.25H132.43v64h32.21A19.44,19.44,0,0,0,177,36.85ZM149,61.29h-6.08l18.68-44h6.08Z'%20style='fill:%23ffffff;fill-opacity:1'/%3e%3c/svg%3e") #fafafa;background-size:100% auto;padding:20px 0}.__container_common_config .__opt[data-v-4c314c51] .ant-menu-item-selected{transition:all .4s;translate:10px;transform:scale(1.1)} diff --git a/app/dubbo-ui/dist/admin/assets/DateUtil-BI1mUH_z.js b/app/dubbo-ui/dist/admin/assets/DateUtil-BI1mUH_z.js deleted file mode 100644 index 34471c839..000000000 --- a/app/dubbo-ui/dist/admin/assets/DateUtil-BI1mUH_z.js +++ /dev/null @@ -1 +0,0 @@ -import{ab as t}from"./index-hmLAZQYT.js";const m=r=>r&&t(r).format("YYYY-MM-DD HH:mm:ss");export{m as f}; diff --git a/app/dubbo-ui/dist/admin/assets/GrafanaPage-RVDi4ROE.css b/app/dubbo-ui/dist/admin/assets/GrafanaPage-RVDi4ROE.css deleted file mode 100644 index 4a757d55b..000000000 --- a/app/dubbo-ui/dist/admin/assets/GrafanaPage-RVDi4ROE.css +++ /dev/null @@ -1 +0,0 @@ -.__container_iframe_container[data-v-c6fbb32b]{z-index:1;position:relative;width:calc(100vw - 332px);height:calc(100vh - 200px);clip-path:inset(0px 0px)}.__container_iframe_container #grafanaIframe[data-v-c6fbb32b]{z-index:0;top:-112px;position:absolute;width:calc(100vw - 332px);height:calc(100vh - 200px)} diff --git a/app/dubbo-ui/dist/admin/assets/GrafanaPage-_hmQyI5w.js b/app/dubbo-ui/dist/admin/assets/GrafanaPage-_hmQyI5w.js deleted file mode 100644 index c6b9ed85e..000000000 --- a/app/dubbo-ui/dist/admin/assets/GrafanaPage-_hmQyI5w.js +++ /dev/null @@ -1 +0,0 @@ -import{d as l,x as m,y as d,z as _,a as f,W as u,e as p,o as r,c as s,b as g,w as h,j as y,n,Q as v,_ as I}from"./index-hmLAZQYT.js";const w={class:"__container_tabDemo3"},b={class:"__container_iframe_container"},q=["src"],x=l({__name:"GrafanaPage",setup(S){const a=m(d.GRAFANA);_(""),f(),u(async()=>{var t;let e=await a.api({});a.url=`${window.location.origin}/grafana/d/${(t=e.data)==null?void 0:t.baseURL.split("/d/")[1].split("?")[0]}?var-${a.type}=${a.name}&kiosk=tv`,a.showIframe=!0});function o(e){try{e()}catch(t){console.log(t)}}function c(){console.log("The iframe has been loaded."),setTimeout(()=>{try{let e=document.querySelector("#grafanaIframe").contentDocument;o(()=>{e.querySelector("header").remove()}),o(()=>{e.querySelector("[data-testid*='controls']").remove()}),setTimeout(()=>{o(()=>{e.querySelector("[data-testid*='navigation mega-menu']").remove()}),o(()=>{for(let t of e.querySelectorAll("[data-testid*='Panel menu']"))t.remove()})},2e3)}catch{}a.showIframe=!0},1e3)}return(e,t)=>{const i=p("a-spin");return r(),s("div",w,[g(i,{class:"spin",spinning:!n(a).showIframe},{default:h(()=>[y("div",b,[n(a).showIframe?(r(),s("iframe",{key:0,onload:c,id:"grafanaIframe",style:{"padding-top":"60px"},src:n(a).url,frameborder:"0"},null,8,q)):v("",!0)])]),_:1},8,["spinning"])])}}}),A=I(x,[["__scopeId","data-v-c6fbb32b"]]);export{A as G}; diff --git a/app/dubbo-ui/dist/admin/assets/Login-OEOmZzrT.css b/app/dubbo-ui/dist/admin/assets/Login-OEOmZzrT.css deleted file mode 100644 index c7ad8572d..000000000 --- a/app/dubbo-ui/dist/admin/assets/Login-OEOmZzrT.css +++ /dev/null @@ -1 +0,0 @@ -.background[data-v-286ee7a5]{background:url(/admin/assets/login-aBMy9l95.jpg) no-repeat center center fixed;background-size:cover;width:100vw;height:100vh;display:flex;justify-content:center;align-items:center}.background .login[data-v-286ee7a5]{background-color:#fff;padding:20px;border-radius:12px;box-shadow:0 0 10px #0000001a;display:flex;justify-content:center;width:22vw}.background .login .title[data-v-286ee7a5]{width:100%;display:flex;justify-content:center;font-size:20px;font-weight:500;margin-bottom:20px}.background .login .login-btn[data-v-286ee7a5]{width:100%} diff --git a/app/dubbo-ui/dist/admin/assets/Login-imIhMlq6.js b/app/dubbo-ui/dist/admin/assets/Login-imIhMlq6.js deleted file mode 100644 index 59ad04742..000000000 --- a/app/dubbo-ui/dist/admin/assets/Login-imIhMlq6.js +++ /dev/null @@ -1 +0,0 @@ -import{l as w}from"./login-9T-XtNdg.js";import{d as v,r as b,u as h,a as y,c as D,b as e,w as o,e as s,o as S,f as k,t as C,g as I,m as q,i as B,p as N,h as V,j as $,_ as x}from"./index-hmLAZQYT.js";import"./request-8jI_GZey.js";const F=r=>(N("data-v-286ee7a5"),r=r(),V(),r),L={class:"background"},R=F(()=>$("div",null,"用户登录",-1)),U=v({__name:"Login",setup(r){const a=b({username:"",password:""}),d=h(),m=y().query.redirect||"/";function c(){let t=new FormData;t.append("user",a.username),t.append("password",a.password),w(t).then(()=>{I(!0,a.username),d.replace(m)}).catch(n=>{q.error(B.global.t("loginDomain.authFail"))})}return(t,n)=>{const i=s("a-row"),p=s("a-input"),l=s("a-form-item"),_=s("a-button"),f=s("a-form"),g=s("a-card");return S(),D("div",L,[e(g,{class:"login"},{default:o(()=>[e(i,{class:"title"},{default:o(()=>[R]),_:1}),e(i,null,{default:o(()=>[e(f,{layout:"vertical",model:a,ref:"login-form-ref"},{default:o(()=>[e(l,{class:"item",label:t.$t("loginDomain.username"),name:"username",rules:[{required:!0}]},{default:o(()=>[e(p,{type:"",value:a.username,"onUpdate:value":n[0]||(n[0]=u=>a.username=u)},null,8,["value"])]),_:1},8,["label"]),e(l,{class:"item",label:t.$t("loginDomain.password"),name:"password",rules:[{required:!0}]},{default:o(()=>[e(p,{type:"password",value:a.password,"onUpdate:value":n[1]||(n[1]=u=>a.password=u)},null,8,["value"])]),_:1},8,["label"]),e(l,{class:"item",label:""},{default:o(()=>[e(_,{onClick:c,size:"large",type:"primary",class:"login-btn"},{default:o(()=>[k(C(t.$t("loginDomain.login")),1)]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})]),_:1})])}}}),H=x(U,[["__scopeId","data-v-286ee7a5"]]);export{H as default}; diff --git a/app/dubbo-ui/dist/admin/assets/PromQueryUtil-2EbGMcmH.js b/app/dubbo-ui/dist/admin/assets/PromQueryUtil-2EbGMcmH.js deleted file mode 100644 index 2658aad18..000000000 --- a/app/dubbo-ui/dist/admin/assets/PromQueryUtil-2EbGMcmH.js +++ /dev/null @@ -1 +0,0 @@ -import{r as c}from"./request-8jI_GZey.js";import{r as i,a3 as s}from"./index-hmLAZQYT.js";const f=async t=>c({url:"promQL/query",method:"get",params:t});async function q(t){var o,a;try{let r=(a=(o=await f({query:t}))==null?void 0:o.data)==null?void 0:a.result[0];return r!=null&&r.value&&r.value.length>0?Number(r.value[1]):"NA"}catch(r){console.error("fetch from prom error: ",r)}return"NA"}function p(t,o,a){var u;const r=i(t);for(let l of o){let e=(u=t==null?void 0:t.data)==null?void 0:u.list;for(let n of e)n[l]="skeleton-loading"}return s(async()=>{var l;try{let e=((l=r==null?void 0:r.data)==null?void 0:l.list)||[];for(let n of e)a(n)}catch(e){console.error(e)}}),r}export{p,q}; diff --git a/app/dubbo-ui/dist/admin/assets/SearchUtil-Fi_1zs66.css b/app/dubbo-ui/dist/admin/assets/SearchUtil-Fi_1zs66.css deleted file mode 100644 index 99677997a..000000000 --- a/app/dubbo-ui/dist/admin/assets/SearchUtil-Fi_1zs66.css +++ /dev/null @@ -1 +0,0 @@ -.__container_search_table .search-query-container[data-v-e2b01919]{border-radius:10px 10px 0 0;border-bottom:1px solid rgba(220,219,219,.29);background:#fafafa;padding:20px 20px 0}.__container_search_table .select-type[data-v-e2b01919]{width:200px}.__container_search_table[data-v-e2b01919] .ant-pagination{padding:0 10px 20px 0}.__container_search_table[data-v-e2b01919] .ant-spin-container{background:#fafafa}.__container_search_table .common-tool[data-v-e2b01919]{margin-top:5px;width:100px;cursor:pointer;position:relative}.__container_search_table .common-tool .button[data-v-e2b01919]{vertical-align:center;line-height:24px;font-size:24px;float:right}.__container_search_table .common-tool .button[data-v-e2b01919]:hover{color:var(--3d09cf76)}.__container_search_table .common-tool .button svg[data-v-e2b01919]{margin-left:10px}.__container_search_table .common-tool .dropdown[data-v-e2b01919]{top:40px;right:-40px;position:absolute;height:auto;z-index:1000}.__container_search_table .common-tool .dropdown .body[data-v-e2b01919]{max-height:200px;overflow:auto}.__container_search_table .common-tool .dropdown .item[data-v-e2b01919]{line-height:30px}.__container_search_table .common-tool .dropdown .item[data-v-e2b01919]:hover{color:var(--3d09cf76)} diff --git a/app/dubbo-ui/dist/admin/assets/SearchUtil-sOWd6ofa.js b/app/dubbo-ui/dist/admin/assets/SearchUtil-sOWd6ofa.js deleted file mode 100644 index 99a8c0313..000000000 --- a/app/dubbo-ui/dist/admin/assets/SearchUtil-sOWd6ofa.js +++ /dev/null @@ -1 +0,0 @@ -var Q=Object.defineProperty;var X=(d,o,u)=>o in d?Q(d,o,{enumerable:!0,configurable:!0,writable:!0,value:u}):d[o]=u;var _=(d,o,u)=>(X(d,typeof o!="symbol"?o+"":o,u),u);import{d as Z,v as W,r as A,k as q,x as ee,y as te,l as D,c as m,j as g,b as i,w as n,n as s,e as c,P as ae,o as r,H as oe,J as b,K as C,G as y,f as P,t as S,ad as I,I as T,a8 as U,Z as se,a0 as le,ae as ne,Q as re,m as ie,_ as ce}from"./index-hmLAZQYT.js";const ue={class:"__container_search_table"},de={class:"search-query-container"},pe={class:"custom-column button"},_e={class:"dropdown"},me={class:"body"},he=["onClick"],fe={class:"search-table-container"},ge={key:0},ye={key:1},be=Z({__name:"SearchTable",setup(d){W(a=>({"3d09cf76":s(ae)}));const o=A({customColumns:!1}),{appContext:{config:{globalProperties:u}}}=q(),e=ee(te.SEARCH_DOMAIN);e.table.columns.forEach(a=>{if(a.title){const p=a.title;a.title=D(()=>u.$t(p))}});const h=D(()=>e.noPaged?!1:{pageSize:e.paged.pageSize,current:e.paged.curPage,total:e.paged.total,showTotal:a=>u.$t("searchDomain.total")+": "+a+" "+u.$t("searchDomain.unit")}),f=(a,p,v)=>{e.paged.pageSize=a.pageSize,e.paged.curPage=a.current,e.onSearch()};function k(a){let p=e==null?void 0:e.table.columns.filter(v=>!v.__hide);if(!a.__hide&&p.length<=1){ie.warn("must show at least one column");return}a.__hide=!a.__hide}return(a,p)=>{var N,O,E,V;const v=c("a-radio-button"),R=c("a-radio-group"),B=c("a-select-option"),K=c("a-select"),j=c("a-input"),$=c("a-form-item"),M=c("a-button"),F=c("a-flex"),Y=c("a-form"),x=c("a-col"),H=c("a-card"),J=c("a-row"),L=c("a-skeleton-button"),G=c("a-table");return r(),m("div",ue,[g("div",de,[i(J,null,{default:n(()=>[i(x,{span:18},{default:n(()=>[i(Y,{onKeyup:p[1]||(p[1]=oe(t=>s(e).onSearch(),["enter"]))},{default:n(()=>[i(F,{wrap:"wrap",gap:"large"},{default:n(()=>[(r(!0),m(b,null,C(s(e).params,t=>(r(),y($,{label:a.$t(t.label)},{default:n(()=>[t.dict&&t.dict.length>0?(r(),m(b,{key:0},[t.dictType==="BUTTON"?(r(),y(R,{key:0,"button-style":"solid",value:s(e).queryForm[t.param],"onUpdate:value":l=>s(e).queryForm[t.param]=l},{default:n(()=>[(r(!0),m(b,null,C(t.dict,l=>(r(),y(v,{value:l.value},{default:n(()=>[P(S(a.$t(l.label)),1)]),_:2},1032,["value"]))),256))]),_:2},1032,["value","onUpdate:value"])):(r(),y(K,{key:1,class:"select-type",style:I(t.style),value:s(e).queryForm[t.param],"onUpdate:value":l=>s(e).queryForm[t.param]=l},{default:n(()=>[(r(!0),m(b,null,C([...t.dict,{label:"none",value:""}],l=>(r(),y(B,{value:l.value},{default:n(()=>[P(S(a.$t(l.label)),1)]),_:2},1032,["value"]))),256))]),_:2},1032,["style","value","onUpdate:value"]))],64)):(r(),y(j,{key:1,style:I(t.style),placeholder:a.$t("placeholder."+(t.placeholder||"typeDefault")),value:s(e).queryForm[t.param],"onUpdate:value":l=>s(e).queryForm[t.param]=l},null,8,["style","placeholder","value","onUpdate:value"]))]),_:2},1032,["label"]))),256)),i($,{label:""},{default:n(()=>[i(M,{type:"primary",onClick:p[0]||(p[0]=t=>s(e).onSearch())},{default:n(()=>[i(s(T),{style:{"margin-bottom":"-2px","font-size":"1.3rem"},icon:"ic:outline-manage-search"})]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}),i(x,{span:6},{default:n(()=>[i(F,{style:{"justify-content":"flex-end"}},{default:n(()=>[U(a.$slots,"customOperation",{},void 0,!0),g("div",{class:"common-tool",onClick:p[2]||(p[2]=t=>o.customColumns=!o.customColumns)},[g("div",pe,[i(s(T),{icon:"material-symbols-light:format-list-bulleted-rounded"})]),se(g("div",_e,[i(H,{style:{"max-width":"300px"},title:"Custom Column"},{default:n(()=>{var t;return[g("div",me,[(r(!0),m(b,null,C((t=s(e))==null?void 0:t.table.columns,(l,w)=>(r(),m("div",{class:"item",onClick:ne(z=>k(l),["stop"])},[i(s(T),{style:{"margin-bottom":"-4px","font-size":"1rem","margin-right":"2px"},icon:l.__hide?"zondicons:view-hide":"zondicons:view-show"},null,8,["icon"]),P(" "+S(l.title),1)],8,he))),256))])]}),_:1})],512),[[le,o.customColumns]])])]),_:3})]),_:3})]),_:3})]),g("div",fe,[i(G,{loading:s(e).table.loading,pagination:h.value,scroll:{scrollToFirstRowOnChange:!0,y:((N=s(e).tableStyle)==null?void 0:N.scrollY)||"",x:((O=s(e).tableStyle)==null?void 0:O.scrollX)||""},columns:(E=s(e))==null?void 0:E.table.columns.filter(t=>!t.__hide),"data-source":(V=s(e))==null?void 0:V.result,onChange:f},{bodyCell:n(({text:t,record:l,index:w,column:z})=>[z.key==="idx"?(r(),m("span",ge,S(w+1),1)):re("",!0),t==="skeleton-loading"?(r(),m("span",ye,[i(L,{active:"",size:"small"})])):U(a.$slots,"bodyCell",{key:2,text:t,record:l,index:w,column:z},void 0,!0)]),_:3},8,["loading","pagination","scroll","columns","data-source"])])])}}}),Se=ce(be,[["__scopeId","data-v-e2b01919"]]);class ke{constructor(o,u,e,h,f,k){_(this,"noPaged");_(this,"queryForm");_(this,"params");_(this,"searchApi");_(this,"result");_(this,"handleResult");_(this,"tableStyle");_(this,"table",{columns:[]});_(this,"paged",{curPage:1,pageOffset:"0",total:0,pageSize:10});this.params=o,this.noPaged=f,this.queryForm=A({}),this.table.columns=e,o.forEach(a=>{a.defaultValue&&(this.queryForm[a.param]=a.defaultValue)}),h&&(this.paged={...this.paged,...h}),this.searchApi=u,this.handleResult=k}async onSearch(o){o&&(this.handleResult=o),this.table.loading=!0,setTimeout(()=>{this.table.loading=!1},1e4);const u={...this.queryForm,...this.noPaged?{}:{pageSize:this.paged.pageSize,pageOffset:(this.paged.curPage-1)*this.paged.pageSize}};this.searchApi(u).then(e=>{const{data:{list:h,pageInfo:f}}=e;this.result=o?o(h):h,this.noPaged||(this.paged.total=(f==null?void 0:f.Total)||0)}).catch(e=>{console.error("Error fetching data:",e)}).finally(()=>{this.table.loading=!1})}}function we(d,o){return isNaN(d-o)?d.localeCompare(o):d-o}export{ke as S,Se as a,we as s}; diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-G9GNoDTj.css b/app/dubbo-ui/dist/admin/assets/YAMLView-G9GNoDTj.css deleted file mode 100644 index 09141f872..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-G9GNoDTj.css +++ /dev/null @@ -1 +0,0 @@ -.editorBox[data-v-68fde8b4]{border-radius:.3rem;overflow:hidden;width:100%}.sliderBox[data-v-68fde8b4]{margin-left:5px;max-height:530px;overflow:auto}[data-v-68fde8b4] .left.ant-col,[data-v-68fde8b4] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-Kv0Zh07k.js b/app/dubbo-ui/dist/admin/assets/YAMLView-Kv0Zh07k.js deleted file mode 100644 index 928720763..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-Kv0Zh07k.js +++ /dev/null @@ -1 +0,0 @@ -import{y as V,_ as L}from"./js-yaml-8Gkz3BRW.js";import{d as R,a as K,z as r,x as P,y as q,W as z,l as G,r as N,u as Q,c as D,b as a,w as e,G as O,Q as b,J as B,e as d,o as y,j as I,K as U,f as v,m as g,a3 as W,p as $,h as H,_ as X}from"./index-hmLAZQYT.js";import{k as Z,l as aa,m as ea}from"./traffic-C2a-KjHH.js";import{V as ta}from"./ConfigModel-QFNd-Zdd.js";import"./request-8jI_GZey.js";const S=m=>($("data-v-68fde8b4"),m=m(),H(),m),sa={class:"editorBox"},na=S(()=>I("p",null,"修改时间: 2024/3/20 15:20:31",-1)),oa=S(()=>I("p",null,"版本号: xo842xqpx834",-1)),la=R({__name:"YAMLView",setup(m){const _=K(),C=r(_.params.isEdit==="1"),h=r(!1),f=r(!1),A=r(8),p=P(q.PROVIDE_INJECT_KEY),u=r(),k=r(),T=r("");z(async()=>{await E()}),G(()=>k.value!==JSON.stringify(u.value));const t=N(new ta);async function E(){var s,l,i;if((s=p.dynamicConfigForm)!=null&&s.data)t.fromData(p.dynamicConfigForm.data);else{if(((l=_.params)==null?void 0:l.pathId)==="_tmp")C.value=!0,t.isAdd=!0;else{t.isAdd=!1;const c=await Z({name:(i=_.params)==null?void 0:i.pathId});t.fromApiOutput(c.data)}p.dynamicConfigForm=N({data:t})}const n=t.toApiInput();T.value=n.ruleName,n.ruleName=void 0;const o=V.dump(n);k.value=JSON.stringify(o),u.value=o}async function F(){f.value=!0;try{p.dynamicConfigForm.data=null,await E(),g.success("config reset success")}finally{f.value=!1}}const j=Q();async function J(){var o;f.value=!0;let n=V.load(u.value);try{if(t.isAdd===!0){aa({name:t.basicInfo.key+".configurators"},n).then(l=>{p.dynamicConfigForm.data=null,W(()=>{j.replace("/traffic/dynamicConfig"),g.success("config add success")})}).catch(l=>{g.error("添加失败: "+l.msg)});return}let s=await ea({name:(o=_.params)==null?void 0:o.pathId},n);t.fromApiOutput(s.data),g.success("config save success")}finally{f.value=!1}}function M(n){t.fromApiOutput(V.load(u.value))}return(n,o)=>{const s=d("a-col"),l=d("a-row"),i=d("a-flex"),c=d("a-button"),x=d("a-card"),Y=d("a-spin");return y(),D(B,null,[a(x,null,{default:e(()=>[a(Y,{spinning:f.value},{default:e(()=>[a(i,{style:{width:"100%"}},{default:e(()=>[a(s,{span:h.value?24-A.value:24,class:"left"},{default:e(()=>[a(i,{vertical:"",align:"end"},{default:e(()=>[a(l,{style:{width:"100%"},justify:"space-between"},{default:e(()=>[a(s,{span:12}),a(s,{span:12})]),_:1}),I("div",sa,[a(L,{modelValue:u.value,"onUpdate:modelValue":o[0]||(o[0]=w=>u.value=w),onChange:M,theme:"vs-dark",height:"calc(100vh - 450px)",language:"yaml",readonly:!C.value},null,8,["modelValue","readonly"])])]),_:1})]),_:1},8,["span"]),a(s,{span:h.value?A.value:0,class:"right"},{default:e(()=>[h.value?(y(),O(x,{key:0,class:"sliderBox"},{default:e(()=>[(y(),D(B,null,U(2,w=>a(x,{key:w},{default:e(()=>[na,oa,a(i,{justify:"flex-end"},{default:e(()=>[a(c,{type:"text",style:{color:"#0a90d5"}},{default:e(()=>[v("查看")]),_:1}),a(c,{type:"text",style:{color:"#0a90d5"}},{default:e(()=>[v("回滚")]),_:1})]),_:1})]),_:2},1024)),64))]),_:1})):b("",!0)]),_:1},8,["span"])]),_:1})]),_:1},8,["spinning"])]),_:1}),C.value?(y(),O(i,{key:0,style:{"margin-top":"30px"}},{default:e(()=>[a(c,{type:"primary",onClick:J},{default:e(()=>[v("保存")]),_:1}),a(c,{style:{"margin-left":"30px"},onClick:F},{default:e(()=>[v("重置")]),_:1})]),_:1})):b("",!0)],64)}}}),fa=X(la,[["__scopeId","data-v-68fde8b4"]]);export{fa as default}; diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-aVJMfs-Z.css b/app/dubbo-ui/dist/admin/assets/YAMLView-aVJMfs-Z.css deleted file mode 100644 index 738f56b20..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-aVJMfs-Z.css +++ /dev/null @@ -1 +0,0 @@ -.editorBox[data-v-4f1417af]{border-radius:.3rem;overflow:hidden;width:100%}.sliderBox[data-v-4f1417af]{margin-left:5px;max-height:530px;overflow:auto}[data-v-4f1417af] .left.ant-col,[data-v-4f1417af] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-lT4dPq7F.js b/app/dubbo-ui/dist/admin/assets/YAMLView-lT4dPq7F.js deleted file mode 100644 index 7f8354350..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-lT4dPq7F.js +++ /dev/null @@ -1 +0,0 @@ -import{y as D,_ as R}from"./js-yaml-8Gkz3BRW.js";import{g as $}from"./traffic-C2a-KjHH.js";import{d as b,a as A,z as _,W as B,G as m,w as a,e as f,o as c,b as t,f as y,t as I,n as k,a9 as L,aa as S,j as g,c as M,K as O,J as Y,Q as j,p as q,h as z,_ as E}from"./index-hmLAZQYT.js";import"./request-8jI_GZey.js";const w=i=>(q("data-v-76e6a408"),i=i(),z(),i),F={class:"editorBox"},G=w(()=>g("p",null,"修改时间: 2024/3/20 15:20:31",-1)),J=w(()=>g("p",null,"版本号: xo842xqpx834",-1)),K=b({__name:"YAMLView",setup(i){const h=A(),N=_(!0),l=_(!1),V=_(8),v=_("");async function C(){var o,n;let e=await $((o=h.params)==null?void 0:o.ruleName);console.log(e),(e==null?void 0:e.code)===200&&e.data&&((n=h.params)!=null&&n.ruleName)&&e.data.scope==="service"&&(Array.isArray(e.data.conditions)&&(e.data.conditions=e.data.conditions.map(d=>{const s=d.split("=>");if(s.length===2){const r=s[0].trim();let x=s[1].trim();const u=x.match(/other\[(.*?)\]=(.*)/);return u&&u[1]&&u[2]&&(x=`${u[1]}=${u[2]}`),`${r} => ${x}`}return d})),v.value=D.dump(e.data))}return B(()=>{C()}),(e,o)=>{const n=f("a-button"),p=f("a-flex"),d=f("a-col"),s=f("a-card");return c(),m(s,null,{default:a(()=>[t(p,{style:{width:"100%"}},{default:a(()=>[t(d,{span:l.value?24-V.value:24,class:"left"},{default:a(()=>[t(p,{vertical:"",align:"end"},{default:a(()=>[t(n,{type:"text",style:{color:"#0a90d5"},onClick:o[0]||(o[0]=r=>l.value=!l.value)},{default:a(()=>[y(I(e.$t("flowControlDomain.versionRecords"))+" ",1),l.value?(c(),m(k(S),{key:1})):(c(),m(k(L),{key:0}))]),_:1}),g("div",F,[t(R,{modelValue:v.value,"onUpdate:modelValue":o[1]||(o[1]=r=>v.value=r),theme:"vs-dark",height:500,language:"yaml",readonly:N.value},null,8,["modelValue","readonly"])])]),_:1})]),_:1},8,["span"]),y(" Ï "),t(d,{span:l.value?V.value:0,class:"right"},{default:a(()=>[l.value?(c(),m(s,{key:0,class:"sliderBox"},{default:a(()=>[(c(),M(Y,null,O(2,r=>t(s,{key:r},{default:a(()=>[G,J,t(p,{justify:"flex-end"},{default:a(()=>[t(n,{type:"text",style:{color:"#0a90d5"}},{default:a(()=>[y("查看")]),_:1}),t(n,{type:"text",style:{color:"#0a90d5"}},{default:a(()=>[y("回滚")]),_:1})]),_:1})]),_:2},1024)),64))]),_:1})):j("",!0)]),_:1},8,["span"])]),_:1})]),_:1})}}}),W=E(K,[["__scopeId","data-v-76e6a408"]]);export{W as default}; diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-pRLW5CcG.css b/app/dubbo-ui/dist/admin/assets/YAMLView-pRLW5CcG.css deleted file mode 100644 index 09434ca3b..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-pRLW5CcG.css +++ /dev/null @@ -1 +0,0 @@ -.editorBox[data-v-76e6a408]{border-radius:.3rem;overflow:hidden;width:100%}.sliderBox[data-v-76e6a408]{margin-left:5px;max-height:530px;overflow:auto}[data-v-76e6a408] .left.ant-col,[data-v-76e6a408] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/YAMLView-q7Cf5xIc.js b/app/dubbo-ui/dist/admin/assets/YAMLView-q7Cf5xIc.js deleted file mode 100644 index 2317c5d65..000000000 --- a/app/dubbo-ui/dist/admin/assets/YAMLView-q7Cf5xIc.js +++ /dev/null @@ -1,10 +0,0 @@ -import{y as D,_ as b}from"./js-yaml-8Gkz3BRW.js";import{e as B}from"./traffic-C2a-KjHH.js";import{d as C,a as R,z as u,W as I,G as r,w as e,e as c,o as s,b as a,f as p,t as L,n as x,a9 as N,aa as S,j as f,c as A,K as M,J as O,Q as T,p as Y,h as $,_ as j}from"./index-hmLAZQYT.js";import"./request-8jI_GZey.js";const h=n=>(Y("data-v-4f1417af"),n=n(),$(),n),q={class:"editorBox"},z=h(()=>f("p",null,"修改时间: 2024/3/20 15:20:31",-1)),E=h(()=>f("p",null,"版本号: xo842xqpx834",-1)),F=C({__name:"YAMLView",setup(n){const k=R(),V=u(!0),t=u(!1),m=u(8),y=u(`configVersion: v3.0 -force: true -enabled: true -key: shop-detail -tags: -  - name: gray -    match: -      - key: env -        value: -          exact: gray`),w=async()=>{var l;const o=await B((l=k.params)==null?void 0:l.ruleName);o.code===200&&(y.value=D.dump(o==null?void 0:o.data))};return I(()=>{w()}),(o,l)=>{const d=c("a-button"),_=c("a-flex"),v=c("a-col"),i=c("a-card");return s(),r(i,null,{default:e(()=>[a(_,{style:{width:"100%"}},{default:e(()=>[a(v,{span:t.value?24-m.value:24,class:"left"},{default:e(()=>[a(_,{vertical:"",align:"end"},{default:e(()=>[a(d,{type:"text",style:{color:"#0a90d5"},onClick:l[0]||(l[0]=g=>t.value=!t.value)},{default:e(()=>[p(L(o.$t("flowControlDomain.versionRecords"))+" ",1),t.value?(s(),r(x(S),{key:1})):(s(),r(x(N),{key:0}))]),_:1}),f("div",q,[a(b,{modelValue:y.value,theme:"vs-dark",height:500,language:"yaml",readonly:V.value},null,8,["modelValue","readonly"])])]),_:1})]),_:1},8,["span"]),a(v,{span:t.value?m.value:0,class:"right"},{default:e(()=>[t.value?(s(),r(i,{key:0,class:"sliderBox"},{default:e(()=>[(s(),A(O,null,M(2,g=>a(i,{key:g},{default:e(()=>[z,E,a(_,{justify:"flex-end"},{default:e(()=>[a(d,{type:"text",style:{color:"#0a90d5"}},{default:e(()=>[p("查看")]),_:1}),a(d,{type:"text",style:{color:"#0a90d5"}},{default:e(()=>[p("回滚")]),_:1})]),_:1})]),_:2},1024)),64))]),_:1})):T("",!0)]),_:1},8,["span"])]),_:1})]),_:1})}}}),Q=j(F,[["__scopeId","data-v-4f1417af"]]);export{Q as default}; diff --git a/app/dubbo-ui/dist/admin/assets/abap-ze8r6a4j.js b/app/dubbo-ui/dist/admin/assets/abap-ze8r6a4j.js deleted file mode 100644 index b281b2a51..000000000 --- a/app/dubbo-ui/dist/admin/assets/abap-ze8r6a4j.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"*"},brackets:[["[","]"],["(",")"]]},t={defaultToken:"invalid",ignoreCase:!0,tokenPostfix:".abap",keywords:["abap-source","abbreviated","abstract","accept","accepting","according","activation","actual","add","add-corresponding","adjacent","after","alias","aliases","align","all","allocate","alpha","analysis","analyzer","and","append","appendage","appending","application","archive","area","arithmetic","as","ascending","aspect","assert","assign","assigned","assigning","association","asynchronous","at","attributes","authority","authority-check","avg","back","background","backup","backward","badi","base","before","begin","between","big","binary","bintohex","bit","black","blank","blanks","blob","block","blocks","blue","bound","boundaries","bounds","boxed","break-point","buffer","by","bypassing","byte","byte-order","call","calling","case","cast","casting","catch","center","centered","chain","chain-input","chain-request","change","changing","channels","character","char-to-hex","check","checkbox","ci_","circular","class","class-coding","class-data","class-events","class-methods","class-pool","cleanup","clear","client","clob","clock","close","coalesce","code","coding","col_background","col_group","col_heading","col_key","col_negative","col_normal","col_positive","col_total","collect","color","column","columns","comment","comments","commit","common","communication","comparing","component","components","compression","compute","concat","concat_with_space","concatenate","cond","condense","condition","connect","connection","constants","context","contexts","continue","control","controls","conv","conversion","convert","copies","copy","corresponding","country","cover","cpi","create","creating","critical","currency","currency_conversion","current","cursor","cursor-selection","customer","customer-function","dangerous","data","database","datainfo","dataset","date","dats_add_days","dats_add_months","dats_days_between","dats_is_valid","daylight","dd/mm/yy","dd/mm/yyyy","ddmmyy","deallocate","decimal_shift","decimals","declarations","deep","default","deferred","define","defining","definition","delete","deleting","demand","department","descending","describe","destination","detail","dialog","directory","disconnect","display","display-mode","distinct","divide","divide-corresponding","division","do","dummy","duplicate","duplicates","duration","during","dynamic","dynpro","edit","editor-call","else","elseif","empty","enabled","enabling","encoding","end","endat","endcase","endcatch","endchain","endclass","enddo","endenhancement","end-enhancement-section","endexec","endform","endfunction","endian","endif","ending","endinterface","end-lines","endloop","endmethod","endmodule","end-of-definition","end-of-editing","end-of-file","end-of-page","end-of-selection","endon","endprovide","endselect","end-test-injection","end-test-seam","endtry","endwhile","endwith","engineering","enhancement","enhancement-point","enhancements","enhancement-section","entries","entry","enum","environment","equiv","errormessage","errors","escaping","event","events","exact","except","exception","exceptions","exception-table","exclude","excluding","exec","execute","exists","exit","exit-command","expand","expanding","expiration","explicit","exponent","export","exporting","extend","extended","extension","extract","fail","fetch","field","field-groups","fields","field-symbol","field-symbols","file","filter","filters","filter-table","final","find","first","first-line","fixed-point","fkeq","fkge","flush","font","for","form","format","forward","found","frame","frames","free","friends","from","function","functionality","function-pool","further","gaps","generate","get","giving","gkeq","gkge","global","grant","green","group","groups","handle","handler","harmless","hashed","having","hdb","header","headers","heading","head-lines","help-id","help-request","hextobin","hide","high","hint","hold","hotspot","icon","id","identification","identifier","ids","if","ignore","ignoring","immediately","implementation","implementations","implemented","implicit","import","importing","in","inactive","incl","include","includes","including","increment","index","index-line","infotypes","inheriting","init","initial","initialization","inner","inout","input","insert","instance","instances","instr","intensified","interface","interface-pool","interfaces","internal","intervals","into","inverse","inverted-date","is","iso","job","join","keep","keeping","kernel","key","keys","keywords","kind","language","last","late","layout","leading","leave","left","left-justified","leftplus","leftspace","legacy","length","let","level","levels","like","line","lines","line-count","linefeed","line-selection","line-size","list","listbox","list-processing","little","llang","load","load-of-program","lob","local","locale","locator","logfile","logical","log-point","long","loop","low","lower","lpad","lpi","ltrim","mail","main","major-id","mapping","margin","mark","mask","match","matchcode","max","maximum","medium","members","memory","mesh","message","message-id","messages","messaging","method","methods","min","minimum","minor-id","mm/dd/yy","mm/dd/yyyy","mmddyy","mode","modif","modifier","modify","module","move","move-corresponding","multiply","multiply-corresponding","name","nametab","native","nested","nesting","new","new-line","new-page","new-section","next","no","no-display","no-extension","no-gap","no-gaps","no-grouping","no-heading","no-scrolling","no-sign","no-title","no-topofpage","no-zero","node","nodes","non-unicode","non-unique","not","null","number","object","objects","obligatory","occurrence","occurrences","occurs","of","off","offset","ole","on","only","open","option","optional","options","or","order","other","others","out","outer","output","output-length","overflow","overlay","pack","package","pad","padding","page","pages","parameter","parameters","parameter-table","part","partially","pattern","percentage","perform","performing","person","pf1","pf10","pf11","pf12","pf13","pf14","pf15","pf2","pf3","pf4","pf5","pf6","pf7","pf8","pf9","pf-status","pink","places","pool","pos_high","pos_low","position","pragmas","precompiled","preferred","preserving","primary","print","print-control","priority","private","procedure","process","program","property","protected","provide","public","push","pushbutton","put","queue-only","quickinfo","radiobutton","raise","raising","range","ranges","read","reader","read-only","receive","received","receiver","receiving","red","redefinition","reduce","reduced","ref","reference","refresh","regex","reject","remote","renaming","replace","replacement","replacing","report","request","requested","reserve","reset","resolution","respecting","responsible","result","results","resumable","resume","retry","return","returncode","returning","returns","right","right-justified","rightplus","rightspace","risk","rmc_communication_failure","rmc_invalid_status","rmc_system_failure","role","rollback","rows","rpad","rtrim","run","sap","sap-spool","saving","scale_preserving","scale_preserving_scientific","scan","scientific","scientific_with_leading_zero","scroll","scroll-boundary","scrolling","search","secondary","seconds","section","select","selection","selections","selection-screen","selection-set","selection-sets","selection-table","select-options","send","separate","separated","set","shared","shift","short","shortdump-id","sign_as_postfix","single","size","skip","skipping","smart","some","sort","sortable","sorted","source","specified","split","spool","spots","sql","sqlscript","stable","stamp","standard","starting","start-of-editing","start-of-selection","state","statement","statements","static","statics","statusinfo","step-loop","stop","structure","structures","style","subkey","submatches","submit","subroutine","subscreen","subtract","subtract-corresponding","suffix","sum","summary","summing","supplied","supply","suppress","switch","switchstates","symbol","syncpoints","syntax","syntax-check","syntax-trace","system-call","system-exceptions","system-exit","tab","tabbed","table","tables","tableview","tabstrip","target","task","tasks","test","testing","test-injection","test-seam","text","textpool","then","throw","time","times","timestamp","timezone","tims_is_valid","title","titlebar","title-lines","to","tokenization","tokens","top-lines","top-of-page","trace-file","trace-table","trailing","transaction","transfer","transformation","translate","transporting","trmac","truncate","truncation","try","tstmp_add_seconds","tstmp_current_utctimestamp","tstmp_is_valid","tstmp_seconds_between","type","type-pool","type-pools","types","uline","unassign","under","unicode","union","unique","unit_conversion","unix","unpack","until","unwind","up","update","upper","user","user-command","using","utf-8","valid","value","value-request","values","vary","varying","verification-message","version","via","view","visible","wait","warning","when","whenever","where","while","width","window","windows","with","with-heading","without","with-title","word","work","write","writer","xml","xsd","yellow","yes","yymmdd","zero","zone","abap_system_timezone","abap_user_timezone","access","action","adabas","adjust_numbers","allow_precision_loss","allowed","amdp","applicationuser","as_geo_json","as400","associations","balance","behavior","breakup","bulk","cds","cds_client","check_before_save","child","clients","corr","corr_spearman","cross","cycles","datn_add_days","datn_add_months","datn_days_between","dats_from_datn","dats_tims_to_tstmp","dats_to_datn","db2","db6","ddl","dense_rank","depth","deterministic","discarding","entities","entity","error","failed","finalize","first_value","fltp_to_dec","following","fractional","full","graph","grouping","hierarchy","hierarchy_ancestors","hierarchy_ancestors_aggregate","hierarchy_descendants","hierarchy_descendants_aggregate","hierarchy_siblings","incremental","indicators","lag","last_value","lead","leaves","like_regexpr","link","locale_sap","lock","locks","many","mapped","matched","measures","median","mssqlnt","multiple","nodetype","ntile","nulls","occurrences_regexpr","one","operations","oracle","orphans","over","parent","parents","partition","pcre","period","pfcg_mapping","preceding","privileged","product","projection","rank","redirected","replace_regexpr","reported","response","responses","root","row","row_number","sap_system_date","save","schema","session","sets","shortdump","siblings","spantree","start","stddev","string_agg","subtotal","sybase","tims_from_timn","tims_to_timn","to_blob","to_clob","total","trace-entry","tstmp_to_dats","tstmp_to_dst","tstmp_to_tims","tstmpl_from_utcl","tstmpl_to_utcl","unbounded","utcl_add_seconds","utcl_current","utcl_seconds_between","uuid","var","verbatim"],builtinFunctions:["abs","acos","asin","atan","bit-set","boolc","boolx","ceil","char_off","charlen","cmax","cmin","concat_lines_of","contains","contains_any_not_of","contains_any_of","cos","cosh","count","count_any_not_of","count_any_of","dbmaxlen","distance","escape","exp","find_any_not_of","find_any_of","find_end","floor","frac","from_mixed","ipow","line_exists","line_index","log","log10","matches","nmax","nmin","numofchar","repeat","rescale","reverse","round","segment","shift_left","shift_right","sign","sin","sinh","sqrt","strlen","substring","substring_after","substring_before","substring_from","substring_to","tan","tanh","to_lower","to_mixed","to_upper","trunc","utclong_add","utclong_current","utclong_diff","xsdbool","xstrlen"],typeKeywords:["b","c","d","decfloat16","decfloat34","f","i","int8","n","p","s","string","t","utclong","x","xstring","any","clike","csequence","decfloat","numeric","simple","xsequence","accp","char","clnt","cuky","curr","datn","dats","d16d","d16n","d16r","d34d","d34n","d34r","dec","df16_dec","df16_raw","df34_dec","df34_raw","fltp","geom_ewkb","int1","int2","int4","lang","lchr","lraw","numc","quan","raw","rawstring","sstring","timn","tims","unit","utcl","df16_scl","df34_scl","prec","varc","abap_bool","abap_false","abap_true","abap_undefined","me","screen","space","super","sy","syst","table_line","*sys*"],builtinMethods:["class_constructor","constructor"],derivedTypes:["%CID","%CID_REF","%CONTROL","%DATA","%ELEMENT","%FAIL","%KEY","%MSG","%PARAM","%PID","%PID_ASSOC","%PID_PARENT","%_HINTS"],cdsLanguage:["@AbapAnnotation","@AbapCatalog","@AccessControl","@API","@ClientDependent","@ClientHandling","@CompatibilityContract","@DataAging","@EndUserText","@Environment","@LanguageDependency","@MappingRole","@Metadata","@MetadataExtension","@ObjectModel","@Scope","@Semantics","$EXTENSION","$SELF"],selectors:["->","->*","=>","~","~*"],operators:[" +"," -","/","*","**","div","mod","=","#","@","+=","-=","*=","/=","**=","&&=","?=","&","&&","bit-and","bit-not","bit-or","bit-xor","m","o","z","<"," >","<=",">=","<>","><","=<","=>","bt","byte-ca","byte-cn","byte-co","byte-cs","byte-na","byte-ns","ca","cn","co","cp","cs","eq","ge","gt","le","lt","na","nb","ne","np","ns","*/","*:","--","/*","//"],symbols:/[=>))*/,{cases:{"@typeKeywords":"type","@keywords":"keyword","@cdsLanguage":"annotation","@derivedTypes":"type","@builtinFunctions":"type","@builtinMethods":"type","@operators":"key","@default":"identifier"}}],[/<[\w]+>/,"identifier"],[/##[\w|_]+/,"comment"],{include:"@whitespace"},[/[:,.]/,"delimiter"],[/[{}()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@selectors":"tag","@operators":"key","@default":""}}],[/'/,{token:"string",bracket:"@open",next:"@stringquote"}],[/`/,{token:"string",bracket:"@open",next:"@stringping"}],[/\|/,{token:"string",bracket:"@open",next:"@stringtemplate"}],[/\d+/,"number"]],stringtemplate:[[/[^\\\|]+/,"string"],[/\\\|/,"string"],[/\|/,{token:"string",bracket:"@close",next:"@pop"}]],stringping:[[/[^\\`]+/,"string"],[/`/,{token:"string",bracket:"@close",next:"@pop"}]],stringquote:[[/[^\\']+/,"string"],[/'/,{token:"string",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/^\*.*$/,"comment"],[/\".*$/,"comment"]]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/addByFormView-L619fQ34.js b/app/dubbo-ui/dist/admin/assets/addByFormView-L619fQ34.js deleted file mode 100644 index 84e0c2720..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByFormView-L619fQ34.js +++ /dev/null @@ -1 +0,0 @@ -import{u as ce}from"./index-Va7nxJVK.js";import{d as ue,x as de,y as re,W as pe,F as z,k as _e,a as fe,z as N,u as ye,r as ve,D as J,c as W,b as e,w as t,e as i,o as k,f as r,G as g,n as S,a9 as be,aa as he,J as me,K as ke,j as x,t as B,I as L,Q as P,p as ge,h as xe,_ as we}from"./index-hmLAZQYT.js";import{f as $e}from"./traffic-C2a-KjHH.js";import"./request-8jI_GZey.js";const E=A=>(ge("data-v-74fb5f17"),A=A(),xe(),A),Ce={class:"__container_tagRule_detail"},Ue={style:{"max-width":"400px",overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"}},Ke=E(()=>x("br",null,null,-1)),Ne=E(()=>x("br",null,null,-1)),Oe=E(()=>x("br",null,null,-1)),Re=E(()=>x("br",null,null,-1)),Ee=E(()=>x("br",null,null,-1)),Te=E(()=>x("br",null,null,-1)),je={class:"bottom-action-footer"},Se=ue({__name:"addByFormView",setup(A){const w=de(re.PROVIDE_INJECT_KEY);pe(()=>{if(!z.isNil(w.tagRule)){const{enabled:a=!0,key:l,scope:u,runtime:p=!0,tags:n}=w.tagRule;c.enable=a,c.objectOfAction=l,c.ruleGranularity=u,c.runtime=p,n&&n.length&&n.forEach((b,d)=>{m.value.push({tagName:b.name,scope:{type:"labels",labels:[],addresses:{condition:"=",addressesStr:""}}});const{match:_}=b;let s=[];_.forEach((y,f)=>{s.push({myKey:y.key,condition:Object.keys(y.value)[0],value:y.value[Object.keys(y.value)[0]]})}),m.value[d]&&m.value[d].scope&&(m.value[d].scope.labels=s)})}}),_e(),fe();const O=N(!1),G=N(8);ce().toClipboard;const Y=ye(),q=(a,l)=>{var n,b,d,_;let u=`对于应用 ${l||"未指定"},将满足 `;const p=[];if(((n=a.scope)==null?void 0:n.type)==="labels"&&((b=a.scope.labels)==null?void 0:b.length)>0)a.scope.labels.forEach(s=>{var C,v;let y="";if(s.myKey==="method")y="请求方法";else if((C=s.myKey)!=null&&C.startsWith("args[")){const T=(v=s.myKey.match(/\[(\d+)\]/))==null?void 0:v[1];T!==void 0?y=`第 ${parseInt(T)+1} 个参数`:y=`标签 ${s.myKey||"未指定"}`}else y=`标签 ${s.myKey||"未指定"}`;let f="";const h=s.value||"未指定";switch(s.condition){case"exact":f=`exact ${h}`;break;case"regex":f=`regex ${h}`;break;case"prefix":f=`prefix ${h}`;break;case"noempty":f="noempty";break;case"empty":f="empty";break;case"wildcard":f=`wildcard ${h}`;break;case"!=":f=`!= ${h}`;break;default:f=`${s.condition||"未知关系"} ${h}`}s.condition!=="empty"&&s.condition!=="noempty"&&!s.value?p.push(`${y} 未填写`):p.push(`${y} ${f}`)});else if(((d=a.scope)==null?void 0:d.type)==="addresses"&&((_=a.scope.addresses)!=null&&_.addressesStr)){const s=a.scope.addresses.condition==="="?"等于":"不等于";p.push(`地址 ${s} [${a.scope.addresses.addressesStr}]`)}return p.length===0?u+="任意请求":u+=p.join(" 且 "),u+=` 的实例,打上 ${a.tagName||"未指定"} 标签,划入 ${a.tagName||"未指定"} 的隔离环境`,u},c=ve({ruleGranularity:"application",objectOfAction:"",enable:!0,faultTolerantProtection:!0,runtime:!0,priority:1,configVersion:"v3.0"});J(c,a=>{const{enable:l,objectOfAction:u,runtime:p,ruleGranularity:n}=a;w.tagRule={...w.tagRule,enabled:l,key:u,runtime:p,scope:n}},{immediate:!!z.isNil(w.tagRule)});const M=N([{label:"labels",value:"labels"}]),Q=N([{label:"exact",value:"exact"},{label:"regex",value:"regex"},{label:"prefix",value:"prefix"},{label:"noempty",value:"noempty"},{label:"empty",value:"empty"},{label:"wildcard",value:"wildcard"}]),H=N([{label:"=",value:"="},{label:"!=",value:"!="}]),X=N([{title:"键",dataIndex:"myKey",key:"myKey"},{title:"关系",dataIndex:"condition",key:"condition"},{title:"值",dataIndex:"value",key:"value"},{title:"操作",dataIndex:"operation",key:"operation"}]),m=N([]);J(m,a=>{console.log(a);const l=[];a.forEach(u=>{const{tagName:p,scope:n}=u,b=n.labels,d={name:p,match:[]};b&&b.length>0&&b.forEach(_=>{d.match.push({key:_.myKey,value:{[_.condition]:_.value}})}),l.push(d)}),w.tagRule={...w.tagRule,tags:l}},{deep:!0,immediate:!!z.isNil(w.tagRule)});const Z=(a,l)=>{if(m.value[a].scope.labels.length===1){m.value[a].scope.type="addresses";return}m.value[a].scope.labels.splice(l,1)},I=a=>{m.value[a].scope.labels.push({myKey:"",condition:"exact",value:""})},ee=()=>{m.value.push({tagName:"",scope:{type:"labels",labels:[{myKey:"",condition:"",value:""}],addresses:{condition:"",addressesStr:""}}})},te=a=>{m.value.splice(a,1)},ae=async()=>{const{ruleGranularity:a,objectOfAction:l,enable:u,faultTolerantProtection:p,runtime:n,priority:b,configVersion:d}=c,_={configVersion:d,scope:a,key:l,enabled:u,runtime:n,tags:[]};m.value.forEach((f,h)=>{const C={name:f.tagName,match:[]};f.scope.labels.forEach((v,T)=>{const D={key:v.myKey,value:{}};D.value[v.condition]=v.value,C.match.push(D)}),_.tags.push(C)});let s="";a=="application"?s=`${l}.tag-router`:s=`${l}:${d}.tag-router`,(await $e(s,_)).code===200&&Y.push("/traffic/tagRule")};return(a,l)=>{const u=i("a-button"),p=i("a-flex"),n=i("a-form-item"),b=i("a-switch"),d=i("a-col"),_=i("a-input"),s=i("a-input-number"),y=i("a-row"),f=i("a-form"),h=i("a-card"),C=i("a-tooltip"),v=i("a-space"),T=i("a-radio-group"),D=i("a-tag"),F=i("a-select"),le=i("a-table"),oe=i("a-textarea"),V=i("a-descriptions-item"),ne=i("a-descriptions"),se=i("a-affix");return k(),W("div",Ce,[e(p,{style:{width:"100%"}},{default:t(()=>[e(d,{span:O.value?24-G.value:24,class:"left"},{default:t(()=>[e(h,null,{default:t(()=>[e(v,{style:{width:"100%"},direction:"vertical",size:"middle"},{default:t(()=>[e(y,null,{default:t(()=>[e(p,{justify:"end",style:{width:"100%"}},{default:t(()=>[e(u,{type:"text",style:{color:"#0a90d5"},onClick:l[0]||(l[0]=o=>O.value=!O.value)},{default:t(()=>[r(" 字段说明 "),O.value?(k(),g(S(he),{key:1})):(k(),g(S(be),{key:0}))]),_:1})]),_:1}),e(h,{title:"基础信息",style:{width:"100%"},class:"_detail"},{default:t(()=>[e(f,{layout:"horizontal"},{default:t(()=>[e(y,{style:{width:"100%"}},{default:t(()=>[e(d,{span:12},{default:t(()=>[e(n,{label:"规则粒度",required:""},{default:t(()=>[r(" 应用")]),_:1}),e(n,{label:"容错保护"},{default:t(()=>[e(b,{checked:c.faultTolerantProtection,"onUpdate:checked":l[1]||(l[1]=o=>c.faultTolerantProtection=o),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1}),e(n,{label:"运行时生效"},{default:t(()=>[e(b,{checked:c.runtime,"onUpdate:checked":l[2]||(l[2]=o=>c.runtime=o),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1})]),_:1}),e(d,{span:12},{default:t(()=>[e(n,{label:"作用对象",required:""},{default:t(()=>[e(_,{value:c.objectOfAction,"onUpdate:value":l[3]||(l[3]=o=>c.objectOfAction=o),style:{width:"200px"}},null,8,["value"])]),_:1}),e(n,{label:"立即启用"},{default:t(()=>[e(b,{checked:c.enable,"onUpdate:checked":l[4]||(l[4]=o=>c.enable=o),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1}),e(n,{label:"优先级"},{default:t(()=>[e(s,{min:"1",value:c.priority,"onUpdate:value":l[5]||(l[5]=o=>c.priority=o)},null,8,["value"])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}),e(h,{title:"标签列表",style:{width:"100%"},class:"_detail"},{default:t(()=>[(k(!0),W(me,null,ke(m.value,(o,j)=>(k(),g(h,{key:j},{title:t(()=>[e(v,{align:"center"},{default:t(()=>[x("div",null,"路由【"+B(j+1)+"】",1),e(C,null,{title:t(()=>[r(B(q(o,c.objectOfAction)),1)]),default:t(()=>[x("div",Ue,B(q(o,c.objectOfAction)),1)]),_:2},1024)]),_:2},1024)]),default:t(()=>[e(f,{layout:"horizontal"},{default:t(()=>[e(v,{style:{width:"100%"},direction:"vertical",size:"large"},{default:t(()=>[e(p,{justify:"end"},{default:t(()=>[e(S(L),{onClick:U=>te(j),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024),e(n,{label:"标签名",required:""},{default:t(()=>[e(_,{placeholder:"隔离环境名",value:o.tagName,"onUpdate:value":U=>o.tagName=U},null,8,["value","onUpdate:value"])]),_:2},1024),e(n,{label:"作用范围",required:""},{default:t(()=>[e(h,null,{default:t(()=>[e(v,{style:{width:"100%"},direction:"vertical"},{default:t(()=>[e(n,{label:"匹配条件类型"},{default:t(()=>[e(T,{value:o.scope.type,"onUpdate:value":U=>o.scope.type=U,options:M.value},null,8,["value","onUpdate:value","options"])]),_:2},1024),e(v,{align:"start",style:{width:"100%"},direction:"horizontal"},{default:t(()=>{var U;return[e(D,{bordered:!1,color:"processing"},{default:t(()=>[r(B(o.scope.type),1)]),_:2},1024),o.scope.type==="labels"?(k(),g(le,{key:0,pagination:!1,columns:X.value,"data-source":(U=o.scope)==null?void 0:U.labels},{bodyCell:t(({column:$,record:R,text:Ae,index:ie})=>[$.key==="myKey"?(k(),g(_,{key:0,placeholder:"label key",value:R.myKey,"onUpdate:value":K=>R.myKey=K},null,8,["value","onUpdate:value"])):P("",!0),$.key==="condition"?(k(),g(F,{key:1,value:R.condition,"onUpdate:value":K=>R.condition=K,style:{width:"120px"},options:Q.value},null,8,["value","onUpdate:value","options"])):P("",!0),$.key==="value"?(k(),g(_,{key:2,placeholder:"label value",value:R.value,"onUpdate:value":K=>R.value=K},null,8,["value","onUpdate:value"])):$.key==="operation"?(k(),g(v,{key:3,align:"center"},{default:t(()=>[e(S(L),{icon:"tdesign:remove",class:"action-icon",onClick:K=>Z(j,ie)},null,8,["onClick"]),e(S(L),{class:"action-icon",icon:"tdesign:add",onClick:K=>I(j)},null,8,["onClick"])]),_:2},1024)):P("",!0)]),_:2},1032,["columns","data-source"])):(k(),g(v,{key:1,align:"start"},{default:t(()=>[e(F,{style:{width:"120px"},value:o.scope.addresses.condition,"onUpdate:value":$=>o.scope.addresses.condition=$,options:H.value},null,8,["value","onUpdate:value","options"]),e(oe,{style:{width:"500px"},value:o.scope.addresses.addressesStr,"onUpdate:value":$=>o.scope.addresses.addressesStr=$,placeholder:'地址列表,如有多个用","隔开'},null,8,["value","onUpdate:value"])]),_:2},1024))]}),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1}),e(u,{onClick:ee,type:"primary"},{default:t(()=>[r(" 增加标签")]),_:1})]),_:1})]),_:1})]),_:1},8,["span"]),e(d,{span:O.value?G.value:0,class:"right"},{default:t(()=>[O.value?(k(),g(h,{key:0,class:"sliderBox"},{default:t(()=>[x("div",null,[e(ne,{title:"字段说明",column:1},{default:t(()=>[e(V,{label:"key"},{default:t(()=>[r(" 作用对象"),Ke,r(" 可能的值:Dubbo应用名或者服务名 ")]),_:1}),e(V,{label:"scope"},{default:t(()=>[r(" 规则粒度"),Ne,r(" 可能的值:application, service ")]),_:1}),e(V,{label:"force"},{default:t(()=>[r(" 容错保护"),Oe,r(" 可能的值:true, false"),Re,r(" 描述:如果为true,则路由筛选后若没有可用的地址则会直接报异常;如果为false,则会从可用地址中选择完成RPC调用 ")]),_:1}),e(V,{label:"runtime"},{default:t(()=>[r(" 运行时生效"),Ee,r(" 可能的值:true, false"),Te,r(" 描述:如果为true,则该rule下的所有路由将会实时生效;若为false,则只有在启动时才会生效 ")]),_:1})]),_:1})])]),_:1})):P("",!0)]),_:1},8,["span"])]),_:1}),e(se,{"offset-bottom":10},{default:t(()=>[x("div",je,[e(v,{align:"center",size:"large"},{default:t(()=>[e(u,{type:"primary",onClick:ae},{default:t(()=>[r(" 确认")]),_:1}),e(u,null,{default:t(()=>[r(" 取消")]),_:1})]),_:1})])]),_:1})])}}}),ze=we(Se,[["__scopeId","data-v-74fb5f17"]]);export{ze as default}; diff --git a/app/dubbo-ui/dist/admin/assets/addByFormView-PDTQ6Oi5.js b/app/dubbo-ui/dist/admin/assets/addByFormView-PDTQ6Oi5.js deleted file mode 100644 index 2f6461ed7..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByFormView-PDTQ6Oi5.js +++ /dev/null @@ -1 +0,0 @@ -import{u as Ue}from"./index-Va7nxJVK.js";import{d as we,x as Re,y as De,W as Ke,F as Q,k as Se,u as qe,z as W,r as Oe,D as le,c as F,b as e,w as l,e as K,o as v,f as C,G as _,n as j,a9 as je,aa as Ee,Q as q,J as L,K as X,j as N,t as A,I as z,p as Ae,h as ze,_ as Be}from"./index-hmLAZQYT.js";import{a as Ve}from"./traffic-C2a-KjHH.js";import"./request-8jI_GZey.js";const J=Y=>(Ae("data-v-d3c6be66"),Y=Y(),ze(),Y),Ge={class:"__container_routingRule_detail"},Ne={style:{"max-width":"400px",overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"}},me=J(()=>N("br",null,null,-1)),Pe=J(()=>N("br",null,null,-1)),We=J(()=>N("br",null,null,-1)),xe=J(()=>N("br",null,null,-1)),Fe=J(()=>N("br",null,null,-1)),Je=J(()=>N("br",null,null,-1)),Le=we({__name:"addByFormView",setup(Y){const E=Re(De.PROVIDE_INJECT_KEY);Ke(()=>{if(!Q.isNil(E.conditionRule)){const{enabled:s=!0,key:t,scope:i,runtime:h=!0,conditions:$}=E.conditionRule;g.enable=s,g.objectOfAction=t,g.ruleGranularity=i,g.runtime=h,$&&$.length&&$.forEach((r,n)=>{var f,S;const k=r.split("=>"),o=(f=k[0])==null?void 0:f.trim(),M=(S=k[1])==null?void 0:S.trim();d.value[n].requestMatch=$e(o,n),d.value[n].routeDistribute=Te(M,n)})}if(!Q.isNil(E.addConditionRuleSate)){const{version:s,group:t}=E.addConditionRuleSate;g.version=s,g.group=t}}),Se();const ae=qe(),x=W(!1),Z=W(8);Ue().toClipboard;const g=Oe({version:"",ruleGranularity:"",objectOfAction:"",enable:!0,faultTolerantProtection:!1,runtime:!0,priority:null,group:""});le(g,s=>{const{ruleGranularity:t,enable:i=!0,runtime:h=!0,objectOfAction:$}=s;E.conditionRule={...E.conditionRule,enabled:i,key:$,runtime:h,scope:t},E.addConditionRuleSate={version:s.version,group:s.group}},{immediate:!!Q.isNil(E.conditionRule)});const ne=W([{label:"host",value:"host"},{label:"application",value:"application"},{label:"method",value:"method"},{label:"arguments",value:"arguments"},{label:"attachments",value:"attachments"},{label:"其他",value:"other"}]),se=W([{label:"host",value:"host"},{label:"其他",value:"other"}]),m=W([{label:"=",value:"="},{label:"!=",value:"!="}]),oe=W([{label:"应用",value:"application"},{label:"服务",value:"service"}]),d=W([{selectedMatchConditionTypes:[],requestMatch:[],selectedRouteDistributeMatchTypes:[],routeDistribute:[{type:"host",condition:"",value:""},{type:"other",list:[{myKey:"",condition:"",value:""}]}]}]);le(d,s=>{E.conditionRule={...E.conditionRule,conditions:te()}},{deep:!0,immediate:!!Q.isNil(E.conditionRule)});const ie=()=>{d.value.push({selectedMatchConditionTypes:[],requestMatch:[],selectedRouteDistributeMatchTypes:[],routeDistribute:[{type:"host",condition:"=",value:"127.0.0.1"},{type:"other",list:[{myKey:"key",condition:"=",value:"value"}]}]})},ue=s=>{d.value.splice(s,1)},ce=s=>{d.value[s].requestMatch=[],d.value[s].selectedMatchConditionTypes=[]},de=s=>{d.value[s].requestMatch=[{type:"host",condition:"",value:""},{type:"application",condition:"",value:""},{type:"method",condition:"",value:""},{type:"arguments",list:[{index:0,condition:"",value:""}]},{type:"attachments",list:[{myKey:"key",condition:"",value:""}]},{type:"other",list:[{myKey:"key",condition:"",value:""}]}]},H=(s,t)=>{d.value[t].selectedMatchConditionTypes=d.value[t].selectedMatchConditionTypes.filter(i=>i!==s)},re=(s,t)=>{d.value[t].selectedRouteDistributeMatchTypes=d.value[t].selectedRouteDistributeMatchTypes.filter(i=>i!==s)},pe=[{dataIndex:"index",key:"index",title:"参数索引"},{dataIndex:"condition",key:"condition",title:"关系"},{dataIndex:"value",key:"value",title:"值"},{dataIndex:"operation",key:"operation",title:"操作"}],ve=(s,t)=>{d.value[s].requestMatch[t].list.push({index:0,condition:"=",value:""})},ye=(s,t,i)=>{d.value[s].requestMatch[t].list.length===1&&(d.value[s].selectedMatchConditionTypes=d.value[s].selectedMatchConditionTypes.filter(h=>h!=="arguments")),d.value[s].requestMatch[t].list.splice(i,1)},he=[{dataIndex:"myKey",key:"myKey",title:"键"},{dataIndex:"condition",key:"condition",title:"关系"},{dataIndex:"value",key:"value",title:"值"},{dataIndex:"operation",key:"operation",title:"操作"}],fe=(s,t)=>{d.value[s].requestMatch[t].list.push({key:"key",condition:"=",value:""})},_e=(s,t,i)=>{d.value[s].requestMatch[t].list.length===1&&(d.value[s].selectedMatchConditionTypes=d.value[s].selectedMatchConditionTypes.filter(h=>h!=="attachments")),d.value[s].requestMatch[t].list.splice(i,1)},I=[{dataIndex:"myKey",key:"myKey",title:"键"},{dataIndex:"condition",key:"condition",title:"关系"},{dataIndex:"value",key:"value",title:"值"},{dataIndex:"operation",key:"operation",title:"操作"}],ke=(s,t)=>{d.value[s].requestMatch[t].list.push({myKey:"",condition:"=",value:""})},be=(s,t,i)=>{if(d.value[s].requestMatch[t].list.length===1){d.value[s].selectedMatchConditionTypes=d.value[s].selectedMatchConditionTypes.filter(h=>h!=="other");return}d.value[s].requestMatch[t].list.splice(i,1)},ge=(s,t)=>{d.value[s].routeDistribute[t].list.push({myKey:"",condition:"=",value:""})},Ce=(s,t,i)=>{if(d.value[s].routeDistribute[t].list.length===1){d.value[s].selectedRouteDistributeMatchTypes=d.value[s].selectedRouteDistributeMatchTypes.filter(h=>h!=="other");return}d.value[s].routeDistribute[t].list.splice(i,1)};function ee(s){var f,S;const t=d.value[s],{ruleGranularity:i,objectOfAction:h}=g;let r=`对于${i==="service"?"服务":"应用"}【${h||"未指定"}】`,n=[];(f=t.selectedMatchConditionTypes)==null||f.forEach(U=>{var V,P,p,b;const R=(V=t.requestMatch)==null?void 0:V.find(a=>a.type===U);if(!R)return;let y="";const O=R.condition==="="?"等于":R.condition==="!="?"不等于":R.condition||"",B=R.value||"未指定";switch(U){case"host":y=`请求来源主机 ${O} ${B}`;break;case"application":y=`请求来源应用 ${O} ${B}`;break;case"method":y=`请求方法 ${O} ${B}`;break;case"arguments":const a=(P=R.list)==null?void 0:P.map(u=>{const G=u.condition==="="?"等于":u.condition==="!="?"不等于":u.condition||"",D=u.value!==void 0&&u.value!==""?u.value:"未指定";return`参数[${u.index}] ${G} ${D}`}).filter(Boolean);(a==null?void 0:a.length)>0&&(y=a.join(" 且 "));break;case"attachments":const T=(p=R.list)==null?void 0:p.map(u=>{const G=u.condition==="="?"等于":u.condition==="!="?"不等于":u.condition||"",D=u.value!==void 0&&u.value!==""?u.value:"未指定";return`附件[${u.myKey||"未指定"}] ${G} ${D}`}).filter(Boolean);(T==null?void 0:T.length)>0&&(y=T.join(" 且 "));break;case"other":const c=(b=R.list)==null?void 0:b.map(u=>{const G=u.condition==="="?"等于":u.condition==="!="?"不等于":u.condition||"",D=u.value!==void 0&&u.value!==""?u.value:"未指定";return`自定义匹配[${u.myKey||"未指定"}] ${G} ${D}`}).filter(Boolean);(c==null?void 0:c.length)>0&&(y=c.join(" 且 "));break}y&&((U==="host"||U==="application"||U==="method")&&!R.value?n.push(`${U==="host"?"请求来源主机":U==="application"?"请求来源应用":"请求方法"} 未填写`):n.push(y))});const k=n.length>0?n.join(" 且 "):"任意请求";let o=[];(S=t.selectedRouteDistributeMatchTypes)==null||S.forEach(U=>{var V,P;const R=(V=t.routeDistribute)==null?void 0:V.find(p=>p.type===U);if(!R)return;let y="";const O=R.condition==="="?"等于":R.condition==="!="?"不等于":R.condition||"",B=R.value||"未指定";switch(U){case"host":y=`目标主机 ${O} ${B}`;break;case"other":const p=(P=R.list)==null?void 0:P.map(b=>{const a=b.condition==="="?"等于":b.condition==="!="?"不等于":b.condition||"",T=b.value!==void 0&&b.value!==""?b.value:"未指定";return`目标标签[${b.myKey||"未指定"}] ${a} ${T}`}).filter(Boolean);(p==null?void 0:p.length)>0&&(y=p.join(" 且 "));break}y&&(U==="host"&&!R.value?o.push("目标主机 未填写"):o.push(y))});const M=o.length>0?`满足 【${o.join(" 且 ")}】`:"默认路由规则";return`${r},将满足 【${k}】 条件的请求,转发到 ${M} 的实例。`}function te(){let s=[],t="",i="";return d.value.forEach((h,$)=>{h.selectedMatchConditionTypes.forEach((n,k)=>{h.requestMatch.forEach((o,M)=>{if(n==(o==null?void 0:o.type))switch(o==null?void 0:o.type){case"arguments":o.list.forEach((f,S)=>{t.length>0&&(t+=" & "),t+=`${n}[${f.index}]${f.condition}${f.value}`});break;case"attachments":o.list.forEach((f,S)=>{t.length>0&&(t+=" & "),t+=`${n}[${f.myKey}]${f.condition}${f.value}`});break;case"other":o.list.forEach((f,S)=>{t.length>0&&(t+=" & "),t+=`${f.myKey}${f.condition}${f.value}`});break;default:t.length>0&&(t+=" & "),t+=`${o.type}${o.condition}${o.value}`}})}),h.selectedRouteDistributeMatchTypes.forEach((n,k)=>{h.routeDistribute.forEach((o,M)=>{if(n==(o==null?void 0:o.type))switch(o==null?void 0:o.type){case"other":o==null||o.list.forEach((f,S)=>{i.length>0&&(i+=" & "),i+=`${f.myKey}${f.condition}${f.value}`});break;default:i.length>0&&(i+=" & "),i+=`${o.type}${o.condition}${o.value}`}})});let r="";t.length>0&&i.length>0?r=`${t} => ${i}`:t.length>0&&i.length==0&&(r=`${t}`),s.push(r)}),s}const Me=async()=>{const{version:s,ruleGranularity:t,objectOfAction:i,enable:h,faultTolerantProtection:$,runtime:r,group:n}=g,k={configVersion:"v3.0",scope:t,key:i,enabled:h,force:$,runtime:r,conditions:te()};let o="";t=="application"?o=`${i}.condition-router`:o=`${i}:${s||""}:${n||""}.condition-router`,(await Ve(o,k)).code===200&&ae.push("/traffic/routingRule")};function $e(s,t){const i=[],h=s.split(" & ");return[{type:"host",condition:"",value:""},{type:"application",condition:"",value:""},{type:"method",condition:"",value:""},{type:"arguments",list:[]},{type:"attachments",list:[]},{type:"other",list:[]}].forEach(r=>i.push({...r})),h.forEach(r=>{if(r=r.trim(),r.startsWith("host")){d.value[t].selectedMatchConditionTypes.push("host");const n=r.match(/^host(!=|=)(.+)/);if(n){const k=n[1],o=n[2].trim(),M=i.find(f=>f.type==="host");M.condition=k,M.value=o}}else if(r.startsWith("application")){d.value[t].selectedMatchConditionTypes.push("application");const n=r.match(/^application(!=|=)(.+)/);if(n){const k=n[1],o=n[2].trim(),M=i.find(f=>f.type==="application");M.condition=k,M.value=o}}else if(r.startsWith("method")){d.value[t].selectedMatchConditionTypes.push("method");const n=r.match(/^method(!=|=)(.+)/);if(n){const k=n[1],o=n[2].trim(),M=i.find(f=>f.type==="method");M.condition=k,M.value=o}}else if(r.startsWith("arguments")){!d.value[t].selectedMatchConditionTypes.includes("arguments")&&d.value[t].selectedMatchConditionTypes.push("arguments");const n=r.match(/^arguments\[(\d+)\](!=|=)(.+)/);if(n){const k=parseInt(n[1],10),o=n[2],M=n[3].trim();i.find(S=>S.type==="arguments").list.push({index:k,condition:o,value:M})}}else if(r.startsWith("attachments")){!d.value[t].selectedMatchConditionTypes.includes("attachments")&&d.value[t].selectedMatchConditionTypes.push("attachments");const n=r.match(/^attachments\[(.+)\](!=|=)(.+)/);if(n){const k=n[1].trim(),o=n[2],M=n[3].trim();i.find(S=>S.type==="attachments").list.push({myKey:k,condition:o,value:M})}}else{const n=r.match(/^([^!=]+)(!?=)(.+)$/);if(n){!d.value[t].selectedMatchConditionTypes.includes("other")&&d.value[t].selectedMatchConditionTypes.push("other");const k=i.find(o=>o.type==="other");k&&k.list.push({myKey:n[1].trim(),condition:n[2],value:n[3].trim()})}}}),i}function Te(s,t){const i=[],h=s==null?void 0:s.split(" & ");return[{type:"host",condition:"",value:""},{type:"other",list:[]}].forEach(r=>i.push({...r})),h!=null&&h.length&&h.forEach(r=>{if(r=r.trim(),r.startsWith("host")){d.value[t].selectedRouteDistributeMatchTypes.push("host");const n=r.match(/^host(!=|=)(.+)/);if(n){const k=n[1],o=n[2].trim(),M=i.find(f=>f.type==="host");M.condition=k,M.value=o}}else{const n=r.match(/^([^!=]+)(!?=)(.+)$/);if(n){!d.value[t].selectedRouteDistributeMatchTypes.includes("other")&&d.value[t].selectedRouteDistributeMatchTypes.push("other");const k=i.find(o=>o.type==="other");k&&k.list.push({myKey:n[1].trim(),condition:n[2],value:n[3].trim()})}}}),i}return(s,t)=>{const i=K("a-button"),h=K("a-flex"),$=K("a-select"),r=K("a-form-item"),n=K("a-input"),k=K("a-switch"),o=K("a-col"),M=K("a-input-number"),f=K("a-row"),S=K("a-form"),U=K("a-card"),R=K("a-tooltip"),y=K("a-space"),O=K("a-tag"),B=K("a-table"),V=K("a-descriptions-item"),P=K("a-descriptions");return v(),F("div",Ge,[e(h,{style:{width:"100%"}},{default:l(()=>[e(o,{span:x.value?24-Z.value:24,class:"left"},{default:l(()=>[e(U,null,{default:l(()=>[e(y,{style:{width:"100%"},direction:"vertical",size:"middle"},{default:l(()=>[e(f,null,{default:l(()=>[e(h,{justify:"end",style:{width:"100%"}},{default:l(()=>[e(i,{type:"text",style:{color:"#0a90d5"},onClick:t[0]||(t[0]=p=>x.value=!x.value)},{default:l(()=>[C(" 字段说明 "),x.value?(v(),_(j(Ee),{key:1})):(v(),_(j(je),{key:0}))]),_:1})]),_:1}),e(U,{title:"基础信息",style:{width:"100%"},class:"_detail"},{default:l(()=>[e(S,{layout:"horizontal"},{default:l(()=>[e(f,{style:{width:"100%"}},{default:l(()=>[e(o,{span:12},{default:l(()=>[e(r,{label:"规则粒度",required:""},{default:l(()=>[e($,{value:g.ruleGranularity,"onUpdate:value":t[1]||(t[1]=p=>g.ruleGranularity=p),style:{width:"120px"},options:oe.value},null,8,["value","options"])]),_:1}),g.ruleGranularity==="service"?(v(),_(r,{key:0,label:"版本",required:""},{default:l(()=>[e(n,{value:g.version,"onUpdate:value":t[2]||(t[2]=p=>g.version=p),style:{width:"300px"}},null,8,["value"])]),_:1})):q("",!0),e(r,{label:"容错保护"},{default:l(()=>[e(k,{checked:g.faultTolerantProtection,"onUpdate:checked":t[3]||(t[3]=p=>g.faultTolerantProtection=p),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1}),e(r,{label:"运行时生效"},{default:l(()=>[e(k,{checked:g.runtime,"onUpdate:checked":t[4]||(t[4]=p=>g.runtime=p),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1})]),_:1}),e(o,{span:12},{default:l(()=>[e(r,{label:"作用对象",required:""},{default:l(()=>[e(n,{value:g.objectOfAction,"onUpdate:value":t[5]||(t[5]=p=>g.objectOfAction=p),style:{width:"300px"}},null,8,["value"])]),_:1}),g.ruleGranularity==="service"?(v(),_(r,{key:0,label:"分组",required:""},{default:l(()=>[e(n,{value:g.group,"onUpdate:value":t[6]||(t[6]=p=>g.group=p),style:{width:"300px"}},null,8,["value"])]),_:1})):q("",!0),e(r,{label:"立即启用"},{default:l(()=>[e(k,{checked:g.enable,"onUpdate:checked":t[7]||(t[7]=p=>g.enable=p),"checked-children":"开","un-checked-children":"关"},null,8,["checked"])]),_:1}),e(r,{label:"优先级"},{default:l(()=>[e(M,{value:g.priority,"onUpdate:value":t[8]||(t[8]=p=>g.priority=p),min:"1"},null,8,["value"])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}),e(U,{title:"路由列表",style:{width:"100%"},class:"_detail"},{default:l(()=>[(v(!0),F(L,null,X(d.value,(p,b)=>(v(),_(U,null,{title:l(()=>[e(h,{justify:"space-between"},{default:l(()=>[e(y,{align:"center"},{default:l(()=>[N("div",null,"路由【"+A(b+1)+"】",1),e(R,null,{title:l(()=>[C(A(ee(b)),1)]),default:l(()=>[N("div",Ne,A(ee(b)),1)]),_:2},1024)]),_:2},1024),e(j(z),{onClick:a=>ue(b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024)]),default:l(()=>[e(S,{layout:"horizontal"},{default:l(()=>[e(y,{style:{width:"100%"},direction:"vertical",size:"large"},{default:l(()=>[e(r,{label:"请求匹配"},{default:l(()=>[p.requestMatch.length>0?(v(),_(U,{key:0},{default:l(()=>[e(y,{style:{width:"100%"},direction:"vertical",size:"small"},{default:l(()=>[e(h,{align:"center",justify:"space-between"},{default:l(()=>[e(r,{label:"匹配条件类型"},{default:l(()=>[e($,{value:p.selectedMatchConditionTypes,"onUpdate:value":a=>p.selectedMatchConditionTypes=a,options:ne.value,mode:"multiple",style:{"min-width":"200px"}},null,8,["value","onUpdate:value","options"])]),_:2},1024),e(j(z),{onClick:a=>ce(b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024),(v(!0),F(L,null,X(p.requestMatch,(a,T)=>(v(),F(L,null,[p.selectedMatchConditionTypes.includes("host")&&a.type==="host"?(v(),_(y,{key:0,size:"large",align:"center"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e($,{value:a.condition,"onUpdate:value":c=>a.condition=c,style:{"min-width":"120px"},options:m.value},null,8,["value","onUpdate:value","options"]),e(n,{value:a.value,"onUpdate:value":c=>a.value=c,placeholder:"请求来源ip"},null,8,["value","onUpdate:value"]),e(j(z),{onClick:c=>H(a==null?void 0:a.type,b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024)):q("",!0),p.selectedMatchConditionTypes.includes("application")&&a.type==="application"?(v(),_(y,{key:1,size:"large",align:"center"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e($,{value:a.condition,"onUpdate:value":c=>a.condition=c,style:{"min-width":"120px"},options:m.value},null,8,["value","onUpdate:value","options"]),e(n,{value:a.value,"onUpdate:value":c=>a.value=c,placeholder:"请求来源应用名"},null,8,["value","onUpdate:value"]),e(j(z),{onClick:c=>H(a==null?void 0:a.type,b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024)):q("",!0),p.selectedMatchConditionTypes.includes("method")&&a.type==="method"?(v(),_(y,{key:2,size:"large",align:"center"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e($,{value:a.condition,"onUpdate:value":c=>a.condition=c,style:{"min-width":"120px"},options:m.value},null,8,["value","onUpdate:value","options"]),e(n,{value:a.value,"onUpdate:value":c=>a.value=c,placeholder:"方法值"},null,8,["value","onUpdate:value"]),e(j(z),{onClick:c=>H(a==null?void 0:a.type,b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024)):q("",!0),p.selectedMatchConditionTypes.includes("arguments")&&a.type==="arguments"?(v(),_(y,{key:3,style:{width:"100%"},size:"large",align:"start"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e(y,{direction:"vertical"},{default:l(()=>[e(i,{type:"primary",onClick:c=>ve(b,T)},{default:l(()=>[C(" 添加argument ")]),_:2},1032,["onClick"]),e(B,{pagination:!1,columns:pe,"data-source":p.requestMatch[T].list},{bodyCell:l(({column:c,record:u,text:G,index:D})=>[c.key==="index"?(v(),_(n,{key:0,value:u.index,"onUpdate:value":w=>u.index=w,placeholder:"index"},null,8,["value","onUpdate:value"])):c.key==="condition"?(v(),_($,{key:1,value:u.condition,"onUpdate:value":w=>u.condition=w,options:m.value},null,8,["value","onUpdate:value","options"])):c.key==="value"?(v(),_(n,{key:2,value:u.value,"onUpdate:value":w=>u.value=w,placeholder:"value"},null,8,["value","onUpdate:value"])):c.key==="operation"?(v(),_(y,{key:3,align:"center"},{default:l(()=>[e(j(z),{onClick:w=>ye(b,T,D),icon:"tdesign:remove",class:"action-icon"},null,8,["onClick"])]),_:2},1024)):q("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1024)):q("",!0),p.selectedMatchConditionTypes.includes("attachments")&&a.type==="attachments"?(v(),_(y,{key:4,style:{width:"100%"},size:"large",align:"start"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e(y,{direction:"vertical"},{default:l(()=>[e(i,{type:"primary",onClick:c=>fe(b,T)},{default:l(()=>[C(" 添加attachment ")]),_:2},1032,["onClick"]),e(B,{pagination:!1,columns:he,"data-source":p.requestMatch[T].list},{bodyCell:l(({column:c,record:u,text:G,index:D})=>[c.key==="myKey"?(v(),_(n,{key:0,value:u.myKey,"onUpdate:value":w=>u.myKey=w,placeholder:"key"},null,8,["value","onUpdate:value"])):c.key==="condition"?(v(),_($,{key:1,value:u.condition,"onUpdate:value":w=>u.condition=w,options:m.value},null,8,["value","onUpdate:value","options"])):c.key==="value"?(v(),_(n,{key:2,value:u.value,"onUpdate:value":w=>u.value=w,placeholder:"value"},null,8,["value","onUpdate:value"])):c.key==="operation"?(v(),_(y,{key:3,align:"center"},{default:l(()=>[e(j(z),{onClick:w=>_e(b,T,D),icon:"tdesign:remove",class:"action-icon"},null,8,["onClick"])]),_:2},1024)):q("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1024)):q("",!0),p.selectedMatchConditionTypes.includes("other")&&a.type==="other"?(v(),_(y,{key:5,style:{width:"100%"},size:"large",align:"start"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A((a==null?void 0:a.type)=="other"?"其他":a==null?void 0:a.type),1)]),_:2},1024),e(y,{direction:"vertical"},{default:l(()=>[e(i,{type:"primary",onClick:c=>ke(b,T)},{default:l(()=>[C(" 添加other ")]),_:2},1032,["onClick"]),e(B,{pagination:!1,columns:I,"data-source":p.requestMatch[T].list},{bodyCell:l(({column:c,record:u,text:G})=>[c.key==="myKey"?(v(),_(n,{key:0,value:u.myKey,"onUpdate:value":D=>u.myKey=D,placeholder:"key"},null,8,["value","onUpdate:value"])):c.key==="condition"?(v(),_($,{key:1,value:u.condition,"onUpdate:value":D=>u.condition=D,options:m.value},null,8,["value","onUpdate:value","options"])):c.key==="value"?(v(),_(n,{key:2,value:u.value,"onUpdate:value":D=>u.value=D,placeholder:"value"},null,8,["value","onUpdate:value"])):c.key==="operation"?(v(),_(y,{key:3,align:"center"},{default:l(()=>[e(j(z),{onClick:D=>be(b,T,u.index),icon:"tdesign:remove",class:"action-icon"},null,8,["onClick"])]),_:2},1024)):q("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1024)):q("",!0)],64))),256))]),_:2},1024)]),_:2},1024)):(v(),_(i,{key:1,onClick:a=>de(b),type:"dashed",size:"large"},{icon:l(()=>[e(j(z),{icon:"tdesign:add"})]),default:l(()=>[C(" 增加匹配条件 ")]),_:2},1032,["onClick"]))]),_:2},1024),e(r,{label:"路由分发",required:""},{default:l(()=>[e(U,null,{default:l(()=>[e(y,{style:{width:"100%"},direction:"vertical",size:"small"},{default:l(()=>[e(h,null,{default:l(()=>[e(r,{label:"匹配条件类型"},{default:l(()=>[e($,{value:p.selectedRouteDistributeMatchTypes,"onUpdate:value":a=>p.selectedRouteDistributeMatchTypes=a,options:se.value,mode:"multiple",style:{"min-width":"200px"}},null,8,["value","onUpdate:value","options"])]),_:2},1024)]),_:2},1024),(v(!0),F(L,null,X(p.routeDistribute,(a,T)=>(v(),F(L,{key:T},[p.selectedRouteDistributeMatchTypes.includes("host")&&a.type==="host"?(v(),_(y,{key:0,size:"large",align:"center"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A(a==null?void 0:a.type),1)]),_:2},1024),e($,{value:a.condition,"onUpdate:value":c=>a.condition=c,style:{"min-width":"120px"},options:m.value},null,8,["value","onUpdate:value","options"]),e(n,{value:a.value,"onUpdate:value":c=>a.value=c,placeholder:"请求来源ip"},null,8,["value","onUpdate:value"]),e(j(z),{onClick:c=>re(a==null?void 0:a.type,b),class:"action-icon",icon:"tdesign:delete"},null,8,["onClick"])]),_:2},1024)):q("",!0),p.selectedRouteDistributeMatchTypes.includes("other")&&a.type==="other"?(v(),_(y,{key:1,style:{width:"100%"},size:"large",align:"start"},{default:l(()=>[e(O,{class:"match-condition-type-label",bordered:!1,color:"processing"},{default:l(()=>[C(A((a==null?void 0:a.type)=="other"?"其他":a==null?void 0:a.type),1)]),_:2},1024),e(y,{direction:"vertical"},{default:l(()=>[e(i,{type:"primary",onClick:c=>ge(b,T)},{default:l(()=>[C(" 添加其他 ")]),_:2},1032,["onClick"]),e(B,{pagination:!1,columns:I,"data-source":p.routeDistribute[T].list},{bodyCell:l(({column:c,record:u,text:G,index:D})=>[c.key==="myKey"?(v(),_(n,{key:0,value:u.myKey,"onUpdate:value":w=>u.myKey=w,placeholder:"key"},null,8,["value","onUpdate:value"])):c.key==="condition"?(v(),_($,{key:1,value:u.condition,"onUpdate:value":w=>u.condition=w,options:m.value},null,8,["value","onUpdate:value","options"])):c.key==="value"?(v(),_(n,{key:2,value:u.value,"onUpdate:value":w=>u.value=w,placeholder:"value"},null,8,["value","onUpdate:value"])):c.key==="operation"?(v(),_(y,{key:3,align:"center"},{default:l(()=>[e(j(z),{onClick:w=>Ce(b,T,D),icon:"tdesign:remove",class:"action-icon"},null,8,["onClick"])]),_:2},1024)):q("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1024)):q("",!0)],64))),128))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024))),256))]),_:1}),e(i,{onClick:ie,type:"primary"},{default:l(()=>[C(" 增加路由")]),_:1})]),_:1})]),_:1})]),_:1},8,["span"]),e(o,{span:x.value?Z.value:0,class:"right"},{default:l(()=>[x.value?(v(),_(U,{key:0,class:"sliderBox"},{default:l(()=>[N("div",null,[e(P,{title:"字段说明",column:1},{default:l(()=>[e(V,{label:"key"},{default:l(()=>[C(" 作用对象"),me,C(" 可能的值:Dubbo应用名或者服务名 ")]),_:1}),e(V,{label:"scope"},{default:l(()=>[C(" 规则粒度"),Pe,C(" 可能的值:application, service ")]),_:1}),e(V,{label:"force"},{default:l(()=>[C(" 容错保护"),We,C(" 可能的值:true, false"),xe,C(" 描述:如果为true,则路由筛选后若没有可用的地址则会直接报异常;如果为false,则会从可用地址中选择完成RPC调用 ")]),_:1}),e(V,{label:"runtime"},{default:l(()=>[C(" 运行时生效"),Fe,C(" 可能的值:true, false"),Je,C(" 描述:如果为true,则该rule下的所有路由将会实时生效;若为false,则只有在启动时才会生效 ")]),_:1})]),_:1})])]),_:1})):q("",!0)]),_:1},8,["span"])]),_:1}),e(U,{class:"footer"},{default:l(()=>[e(h,null,{default:l(()=>[e(i,{type:"primary",onClick:Me},{default:l(()=>[C("确认")]),_:1})]),_:1})]),_:1})])}}}),Ze=Be(Le,[["__scopeId","data-v-d3c6be66"]]);export{Ze as default}; diff --git a/app/dubbo-ui/dist/admin/assets/addByFormView-WZtXwxTg.css b/app/dubbo-ui/dist/admin/assets/addByFormView-WZtXwxTg.css deleted file mode 100644 index 5724f8045..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByFormView-WZtXwxTg.css +++ /dev/null @@ -1 +0,0 @@ -.__container_tagRule_detail .action-icon[data-v-74fb5f17]{font-size:17px;margin-left:10px;cursor:pointer}.__container_tagRule_detail .match-condition-type-label[data-v-74fb5f17]{min-width:100px;text-align:center}.__container_tagRule_detail .bottom-action-footer[data-v-74fb5f17]{width:100%;background-color:#fff;height:50px;display:flex;align-items:center;padding-left:20px;box-shadow:0 -2px 4px #0000001a}.__container_tagRule_detail .sliderBox[data-v-74fb5f17]{margin-left:5px;max-height:530px;overflow:auto}.__container_tagRule_detail[data-v-74fb5f17] .left.ant-col,.__container_tagRule_detail[data-v-74fb5f17] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/addByFormView-dOXVpw6L.css b/app/dubbo-ui/dist/admin/assets/addByFormView-dOXVpw6L.css deleted file mode 100644 index 789d1c0e4..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByFormView-dOXVpw6L.css +++ /dev/null @@ -1 +0,0 @@ -.__container_routingRule_detail[data-v-d3c6be66]{overflow:auto;max-height:calc(100vh - 200px)}.__container_routingRule_detail[data-v-d3c6be66]::-webkit-scrollbar{display:none}.__container_routingRule_detail .action-icon[data-v-d3c6be66]{font-size:17px;margin-left:10px;cursor:pointer}.__container_routingRule_detail .match-condition-type-label[data-v-d3c6be66]{min-width:100px;text-align:center}.__container_routingRule_detail .bottom-action-footer[data-v-d3c6be66]{width:100%;background-color:#fff;height:50px;display:flex;align-items:center;padding-left:20px;box-shadow:0 -2px 4px #0000001a}.__container_routingRule_detail .sliderBox[data-v-d3c6be66]{margin-left:5px;max-height:530px;overflow:auto}.__container_routingRule_detail[data-v-d3c6be66] .left.ant-col,.__container_routingRule_detail[data-v-d3c6be66] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/addByYAMLView-BhMg41Un.css b/app/dubbo-ui/dist/admin/assets/addByYAMLView-BhMg41Un.css deleted file mode 100644 index 6832bba24..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByYAMLView-BhMg41Un.css +++ /dev/null @@ -1 +0,0 @@ -.editorBox[data-v-f0b44ffc]{border-radius:.3rem;overflow:hidden;width:100%}.bottom-action-footer[data-v-f0b44ffc]{width:100%;background-color:#fff;height:50px;display:flex;align-items:center;padding-left:20px;box-shadow:0 -2px 4px #0000001a}.sliderBox[data-v-f0b44ffc]{margin-left:5px;max-height:530px;overflow:auto}[data-v-f0b44ffc] .left.ant-col,[data-v-f0b44ffc] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/addByYAMLView-JtG8ss_3.css b/app/dubbo-ui/dist/admin/assets/addByYAMLView-JtG8ss_3.css deleted file mode 100644 index bc3fdd3e9..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByYAMLView-JtG8ss_3.css +++ /dev/null @@ -1 +0,0 @@ -.editorBox[data-v-169bd129]{border-radius:.3rem;overflow:hidden;width:100%}.bottom-action-footer[data-v-169bd129]{width:100%;background-color:#fff;height:50px;display:flex;align-items:center;padding-left:20px;box-shadow:0 -2px 4px #0000001a}.sliderBox[data-v-169bd129]{margin-left:5px;max-height:530px;overflow:auto}[data-v-169bd129] .left.ant-col,[data-v-169bd129] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/addByYAMLView-KSfwZr8J.js b/app/dubbo-ui/dist/admin/assets/addByYAMLView-KSfwZr8J.js deleted file mode 100644 index b412c0b3a..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByYAMLView-KSfwZr8J.js +++ /dev/null @@ -1,10 +0,0 @@ -import{y as g,_ as T}from"./js-yaml-8Gkz3BRW.js";import{f as A}from"./traffic-C2a-KjHH.js";import{d as D,x as O,y as S,u as Y,a as $,z as p,W as L,F as M,G as m,w as e,e as n,o as v,b as a,f as t,n as E,a9 as P,aa as j,j as o,Q as z,p as G,h as J,_ as K}from"./index-hmLAZQYT.js";import"./request-8jI_GZey.js";const r=f=>(G("data-v-169bd129"),f=f(),J(),f),F={class:"editorBox"},Q={class:"bottom-action-footer"},U=r(()=>o("br",null,null,-1)),W=r(()=>o("br",null,null,-1)),q=r(()=>o("br",null,null,-1)),H=r(()=>o("br",null,null,-1)),X=r(()=>o("br",null,null,-1)),Z=r(()=>o("br",null,null,-1)),ee=D({__name:"addByYAMLView",setup(f){const y=O(S.PROVIDE_INJECT_KEY),I=Y();$();const w=p(!1),s=p(!1),h=p(8),u=p(`configVersion: v3.0 -force: true -enabled: true -key: shop-detail -tags: -  - name: gray -    match: -      - key: env -        value: -          exact: gray`);L(()=>{if(M.isNil(y.tagRule))u.value="";else{const c=y.tagRule;u.value=g.dump(c)}});const B=c=>{y.tagRule=g.load(u.value)},N=async()=>{const c=g.load(u.value),{configVersion:d,scope:i,key:_,runtime:x,force:V,conditions:b}=c;let l="";i=="application"?l=`${_}.tag-router`:l=`${_}:${d}.tag-router`,(await A(l,c)).code===200&&I.push("/traffic/tagRule")};return(c,d)=>{const i=n("a-button"),_=n("a-flex"),x=n("a-space"),V=n("a-affix"),b=n("a-col"),l=n("a-descriptions-item"),R=n("a-descriptions"),k=n("a-card");return v(),m(k,null,{default:e(()=>[a(_,{style:{width:"100%"}},{default:e(()=>[a(b,{span:s.value?24-h.value:24,class:"left"},{default:e(()=>[a(_,{vertical:"",align:"end"},{default:e(()=>[a(i,{type:"text",style:{color:"#0a90d5"},onClick:d[0]||(d[0]=C=>s.value=!s.value)},{default:e(()=>[t(" 字段说明 "),s.value?(v(),m(E(j),{key:1})):(v(),m(E(P),{key:0}))]),_:1}),o("div",F,[a(T,{onChange:B,modelValue:u.value,"onUpdate:modelValue":d[1]||(d[1]=C=>u.value=C),theme:"vs-dark",height:500,language:"yaml",readonly:w.value},null,8,["modelValue","readonly"])])]),_:1}),a(V,{"offset-bottom":10},{default:e(()=>[o("div",Q,[a(x,{align:"center",size:"large"},{default:e(()=>[a(i,{type:"primary",onClick:N},{default:e(()=>[t(" 确认 ")]),_:1}),a(i,null,{default:e(()=>[t(" 取消 ")]),_:1})]),_:1})])]),_:1})]),_:1},8,["span"]),a(b,{span:s.value?h.value:0,class:"right"},{default:e(()=>[s.value?(v(),m(k,{key:0,class:"sliderBox"},{default:e(()=>[o("div",null,[a(R,{title:"字段说明",column:1},{default:e(()=>[a(l,{label:"key"},{default:e(()=>[t(" 作用对象"),U,t(" 可能的值:Dubbo应用名或者服务名 ")]),_:1}),a(l,{label:"scope"},{default:e(()=>[t(" 规则粒度"),W,t(" 可能的值:application, service ")]),_:1}),a(l,{label:"force"},{default:e(()=>[t(" 容错保护"),q,t(" 可能的值:true, false"),H,t(" 描述:如果为true,则路由筛选后若没有可用的地址则会直接报异常;如果为false,则会从可用地址中选择完成RPC调用 ")]),_:1}),a(l,{label:"runtime"},{default:e(()=>[t(" 运行时生效"),X,t(" 可能的值:true, false"),Z,t(" 描述:如果为true,则该rule下的所有路由将会实时生效;若为false,则只有在启动时才会生效 ")]),_:1})]),_:1})])]),_:1})):z("",!0)]),_:1},8,["span"])]),_:1})]),_:1})}}}),ne=K(ee,[["__scopeId","data-v-169bd129"]]);export{ne as default}; diff --git a/app/dubbo-ui/dist/admin/assets/addByYAMLView-mp4IQp11.js b/app/dubbo-ui/dist/admin/assets/addByYAMLView-mp4IQp11.js deleted file mode 100644 index 4c6e9497f..000000000 --- a/app/dubbo-ui/dist/admin/assets/addByYAMLView-mp4IQp11.js +++ /dev/null @@ -1,26 +0,0 @@ -import{y as R,_ as D}from"./js-yaml-8Gkz3BRW.js";import{d as T,x as $,y as O,u as Y,z as h,W as L,F as w,G as v,w as e,e as s,o as b,b as t,f as a,n as E,a9 as M,aa as P,j as o,Q as j,m as I,p as z,h as J,_ as K}from"./index-hmLAZQYT.js";import{a as F}from"./traffic-C2a-KjHH.js";import"./request-8jI_GZey.js";const c=p=>(z("data-v-f0b44ffc"),p=p(),J(),p),G={class:"editorBox"},Q={class:"bottom-action-footer"},U=c(()=>o("br",null,null,-1)),W=c(()=>o("br",null,null,-1)),q=c(()=>o("br",null,null,-1)),H=c(()=>o("br",null,null,-1)),X=c(()=>o("br",null,null,-1)),Z=c(()=>o("br",null,null,-1)),ee=T({__name:"addByYAMLView",setup(p){const d=$(O.PROVIDE_INJECT_KEY),N=Y(),B=h(!1),r=h(!1),V=h(8),i=h(`conditions: - - from: - match: >- - method=string & arguments[method]=string & - arguments[arguments[method]]=string & - arguments[arguments[arguments[method]]]=string & - arguments[arguments[arguments[arguments[string]]]]!=string - to: - - match: string!=string - weight: 0 - - from: - match: >- - method=string & arguments[method]=string & - arguments[arguments[method]]=string & - arguments[arguments[arguments[string]]]!=string - to: - - match: string!=lggbond - weight: 0 - - match: ss!=ss - weight: 0 -configVersion: v3.1 -enabled: true -force: false -key: org.apache.dubbo.samples.CommentService -runtime: true -scope: service`);L(()=>{if(w.isNil(d.conditionRule))i.value="";else{const l=d.conditionRule;i.value=R.dump(l)}});const S=l=>{d.conditionRule=R.load(i.value)},A=async()=>{const l=R.load(i.value),{configVersion:_,scope:g,key:u,runtime:x,force:C,conditions:y}=l;let n="";if(u=="application")n=`${u}.condition-router`;else if(w.isNil(d.addConditionRuleSate)){I.error("请先填写版本和分组字段");return}else{const{version:m,group:f}=d.addConditionRuleSate;if(m==""||f==""){I.error("请先填写版本和分组字段");return}n=`${u}:${m}:${f}.condition-router`}l.configVersion="v3.0",(await F(n,l)).code===200&&N.push("/traffic/routingRule")};return(l,_)=>{const g=s("a-button"),u=s("a-flex"),x=s("a-space"),C=s("a-affix"),y=s("a-col"),n=s("a-descriptions-item"),k=s("a-descriptions"),m=s("a-card");return b(),v(m,null,{default:e(()=>[t(u,{style:{width:"100%"}},{default:e(()=>[t(y,{span:r.value?24-V.value:24,class:"left"},{default:e(()=>[t(u,{vertical:"",align:"end"},{default:e(()=>[t(g,{type:"text",style:{color:"#0a90d5"},onClick:_[0]||(_[0]=f=>r.value=!r.value)},{default:e(()=>[a(" 字段说明 "),r.value?(b(),v(E(P),{key:1})):(b(),v(E(M),{key:0}))]),_:1}),o("div",G,[t(D,{onChange:S,modelValue:i.value,"onUpdate:modelValue":_[1]||(_[1]=f=>i.value=f),theme:"vs-dark",height:500,language:"yaml",readonly:B.value},null,8,["modelValue","readonly"])])]),_:1}),t(C,{"offset-bottom":10},{default:e(()=>[o("div",Q,[t(x,{align:"center",size:"large"},{default:e(()=>[t(g,{type:"primary",onClick:A},{default:e(()=>[a(" 确认 ")]),_:1}),t(g,null,{default:e(()=>[a(" 取消 ")]),_:1})]),_:1})])]),_:1})]),_:1},8,["span"]),t(y,{span:r.value?V.value:0,class:"right"},{default:e(()=>[r.value?(b(),v(m,{key:0,class:"sliderBox"},{default:e(()=>[o("div",null,[t(k,{title:"字段说明",column:1},{default:e(()=>[t(n,{label:"key"},{default:e(()=>[a(" 作用对象"),U,a(" 可能的值:Dubbo应用名或者服务名 ")]),_:1}),t(n,{label:"scope"},{default:e(()=>[a(" 规则粒度"),W,a(" 可能的值:application, service ")]),_:1}),t(n,{label:"force"},{default:e(()=>[a(" 容错保护"),q,a(" 可能的值:true, false"),H,a(" 描述:如果为true,则路由筛选后若没有可用的地址则会直接报异常;如果为false,则会从可用地址中选择完成RPC调用 ")]),_:1}),t(n,{label:"runtime"},{default:e(()=>[a(" 运行时生效"),X,a(" 可能的值:true, false"),Z,a(" 描述:如果为true,则该rule下的所有路由将会实时生效;若为false,则只有在启动时才会生效 ")]),_:1})]),_:1})])]),_:1})):j("",!0)]),_:1},8,["span"])]),_:1})]),_:1})}}}),se=K(ee,[["__scopeId","data-v-f0b44ffc"]]);export{se as default}; diff --git a/app/dubbo-ui/dist/admin/assets/apex-l4wq3GX1.js b/app/dubbo-ui/dist/admin/assets/apex-l4wq3GX1.js deleted file mode 100644 index 5818b396a..000000000 --- a/app/dubbo-ui/dist/admin/assets/apex-l4wq3GX1.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var n={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}],folding:{markers:{start:new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))")}}},s=["abstract","activate","and","any","array","as","asc","assert","autonomous","begin","bigdecimal","blob","boolean","break","bulk","by","case","cast","catch","char","class","collect","commit","const","continue","convertcurrency","decimal","default","delete","desc","do","double","else","end","enum","exception","exit","export","extends","false","final","finally","float","for","from","future","get","global","goto","group","having","hint","if","implements","import","in","inner","insert","instanceof","int","interface","into","join","last_90_days","last_month","last_n_days","last_week","like","limit","list","long","loop","map","merge","native","new","next_90_days","next_month","next_n_days","next_week","not","null","nulls","number","object","of","on","or","outer","override","package","parallel","pragma","private","protected","public","retrieve","return","returning","rollback","savepoint","search","select","set","short","sort","stat","static","strictfp","super","switch","synchronized","system","testmethod","then","this","this_month","this_week","throw","throws","today","tolabel","tomorrow","transaction","transient","trigger","true","try","type","undelete","update","upsert","using","virtual","void","volatile","webservice","when","where","while","yesterday"],o=e=>e.charAt(0).toUpperCase()+e.substr(1),t=[];s.forEach(e=>{t.push(e),t.push(e.toUpperCase()),t.push(o(e))});var i={defaultToken:"",tokenPostfix:".apex",keywords:t,operators:["=",">","<","!","~","?",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>",">>>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>=",">>>="],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,"annotation"],[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)[fFdD]/,"number.float"],[/(@digits)[lL]?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string",'@string."'],[/'/,"string","@string.'"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@apexdoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],apexdoc:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]]}};export{n as conf,i as language}; diff --git a/app/dubbo-ui/dist/admin/assets/app-duU6O0cq.js b/app/dubbo-ui/dist/admin/assets/app-duU6O0cq.js deleted file mode 100644 index 55cacf1ce..000000000 --- a/app/dubbo-ui/dist/admin/assets/app-duU6O0cq.js +++ /dev/null @@ -1 +0,0 @@ -import{r as a}from"./request-8jI_GZey.js";const r=t=>a({url:"/application/search",method:"get",params:t}),p=t=>a({url:"/application/detail",method:"get",params:t}),i=t=>a({url:"/application/instance/info",method:"get",params:t}),n=t=>a({url:"/application/service/form",method:"get",params:t}),c=t=>a({url:"/application/metric-dashboard",method:"get",params:t}),s=t=>a({url:"/application/trace-dashboard",method:"get",params:t}),l=t=>a({url:"/application/event",method:"get",params:t}),g=t=>a({url:"/application/config/operatorLog",method:"get",params:{appName:t}}),u=(t,o)=>a({url:"/application/config/operatorLog",method:"put",params:{appName:t,operatorLog:o}}),d=t=>a({url:"/application/config/flowWeight",method:"get",params:{appName:t}}),h=(t,o)=>a({url:"/application/config/flowWeight",method:"put",params:{appName:t},data:{flowWeightSets:o}}),m=t=>a({url:"/application/config/gray",method:"get",params:{appName:t}}),f=(t,o)=>a({url:"/application/config/gray",method:"put",params:{appName:t},data:{graySets:o}});export{i as a,n as b,c,s as d,d as e,h as f,p as g,m as h,f as i,g as j,l,r as s,u}; diff --git a/app/dubbo-ui/dist/admin/assets/azcli-bA_AuLZG.js b/app/dubbo-ui/dist/admin/assets/azcli-bA_AuLZG.js deleted file mode 100644 index 4df3fd7ee..000000000 --- a/app/dubbo-ui/dist/admin/assets/azcli-bA_AuLZG.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"#"}},t={defaultToken:"keyword",ignoreCase:!0,tokenPostfix:".azcli",str:/[^#\s]/,tokenizer:{root:[{include:"@comment"},[/\s-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}],[/^-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}]],type:[{include:"@comment"},[/-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":"key.identifier"}}],[/@str+\s*/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}]],comment:[[/#.*$/,{cases:{"@eos":{token:"comment",next:"@popall"}}}]]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/bat-0sCTlecs.js b/app/dubbo-ui/dist/admin/assets/bat-0sCTlecs.js deleted file mode 100644 index 514addfaa..000000000 --- a/app/dubbo-ui/dist/admin/assets/bat-0sCTlecs.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"REM"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],folding:{markers:{start:new RegExp("^\\s*(::\\s*|REM\\s+)#region"),end:new RegExp("^\\s*(::\\s*|REM\\s+)#endregion")}}},s={defaultToken:"",ignoreCase:!0,tokenPostfix:".bat",brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"}],keywords:/call|defined|echo|errorlevel|exist|for|goto|if|pause|set|shift|start|title|not|pushd|popd/,symbols:/[=>`\\b${e}\\b`,t="[_a-zA-Z]",o="[_a-zA-Z0-9]",r=n(`${t}${o}*`),i=["targetScope","resource","module","param","var","output","for","in","if","existing"],a=["true","false","null"],s="[ \\t\\r\\n]",c="[0-9]+",g={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'"},{open:"'''",close:"'''"}],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:"'''",close:"'''",notIn:["string","comment"]}],autoCloseBefore:`:.,=}])' - `,indentationRules:{increaseIndentPattern:new RegExp("^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$"),decreaseIndentPattern:new RegExp("^((?!.*?\\/\\*).*\\*/)?\\s*[\\}\\]].*$")}},l={defaultToken:"",tokenPostfix:".bicep",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"}],symbols:/[=>"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'},{open:"(*",close:"*)"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'},{open:"(*",close:"*)"}]},o={defaultToken:"",tokenPostfix:".cameligo",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["abs","assert","block","Bytes","case","Crypto","Current","else","failwith","false","for","fun","if","in","let","let%entry","let%init","List","list","Map","map","match","match%nat","mod","not","operation","Operation","of","record","Set","set","sender","skip","source","String","then","to","true","type","with"],typeKeywords:["int","unit","string","tz","nat","bool"],operators:["=",">","<","<=",">=","<>",":",":=","and","mod","or","+","-","*","/","@","&","^","%","->","<-","&&","||"],symbols:/[=><:@\^&|+\-*\/\^%]+/,tokenizer:{root:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\$[0-9a-fA-F]{1,16}/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/'/,"string","@string"],[/'[^\\']'/,"string"],[/'/,"string.invalid"],[/\#\d+/,"string"]],comment:[[/[^\(\*]+/,"comment"],[/\*\)/,"comment","@pop"],[/\(\*/,"comment"]],string:[[/[^\\']+/,"string"],[/\\./,"string.escape.invalid"],[/'/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,"white"],[/\(\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}};export{e as conf,o as language}; diff --git a/app/dubbo-ui/dist/admin/assets/clojure-aJ1F8HHH.js b/app/dubbo-ui/dist/admin/assets/clojure-aJ1F8HHH.js deleted file mode 100644 index 09dc3ac5d..000000000 --- a/app/dubbo-ui/dist/admin/assets/clojure-aJ1F8HHH.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:";;"},brackets:[["[","]"],["(",")"],["{","}"]],autoClosingPairs:[{open:"[",close:"]"},{open:'"',close:'"'},{open:"(",close:")"},{open:"{",close:"}"}],surroundingPairs:[{open:"[",close:"]"},{open:'"',close:'"'},{open:"(",close:")"},{open:"{",close:"}"}]},t={defaultToken:"",ignoreCase:!0,tokenPostfix:".clj",brackets:[{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"{",close:"}",token:"delimiter.curly"}],constants:["true","false","nil"],numbers:/^(?:[+\-]?\d+(?:(?:N|(?:[eE][+\-]?\d+))|(?:\.?\d*(?:M|(?:[eE][+\-]?\d+))?)|\/\d+|[xX][0-9a-fA-F]+|r[0-9a-zA-Z]+)?(?=[\\\[\]\s"#'(),;@^`{}~]|$))/,characters:/^(?:\\(?:backspace|formfeed|newline|return|space|tab|o[0-7]{3}|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{4}|.)?(?=[\\\[\]\s"(),;@^`{}~]|$))/,escapes:/^\\(?:["'\\bfnrt]|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,qualifiedSymbols:/^(?:(?:[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*(?:\.[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*\/)?(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*(?=[\\\[\]\s"(),;@^`{}~]|$))/,specialForms:[".","catch","def","do","if","monitor-enter","monitor-exit","new","quote","recur","set!","throw","try","var"],coreSymbols:["*","*'","*1","*2","*3","*agent*","*allow-unresolved-vars*","*assert*","*clojure-version*","*command-line-args*","*compile-files*","*compile-path*","*compiler-options*","*data-readers*","*default-data-reader-fn*","*e","*err*","*file*","*flush-on-newline*","*fn-loader*","*in*","*math-context*","*ns*","*out*","*print-dup*","*print-length*","*print-level*","*print-meta*","*print-namespace-maps*","*print-readably*","*read-eval*","*reader-resolver*","*source-path*","*suppress-read*","*unchecked-math*","*use-context-classloader*","*verbose-defrecords*","*warn-on-reflection*","+","+'","-","-'","->","->>","->ArrayChunk","->Eduction","->Vec","->VecNode","->VecSeq","-cache-protocol-fn","-reset-methods","..","/","<","<=","=","==",">",">=","EMPTY-NODE","Inst","StackTraceElement->vec","Throwable->map","accessor","aclone","add-classpath","add-watch","agent","agent-error","agent-errors","aget","alength","alias","all-ns","alter","alter-meta!","alter-var-root","amap","ancestors","and","any?","apply","areduce","array-map","as->","aset","aset-boolean","aset-byte","aset-char","aset-double","aset-float","aset-int","aset-long","aset-short","assert","assoc","assoc!","assoc-in","associative?","atom","await","await-for","await1","bases","bean","bigdec","bigint","biginteger","binding","bit-and","bit-and-not","bit-clear","bit-flip","bit-not","bit-or","bit-set","bit-shift-left","bit-shift-right","bit-test","bit-xor","boolean","boolean-array","boolean?","booleans","bound-fn","bound-fn*","bound?","bounded-count","butlast","byte","byte-array","bytes","bytes?","case","cast","cat","char","char-array","char-escape-string","char-name-string","char?","chars","chunk","chunk-append","chunk-buffer","chunk-cons","chunk-first","chunk-next","chunk-rest","chunked-seq?","class","class?","clear-agent-errors","clojure-version","coll?","comment","commute","comp","comparator","compare","compare-and-set!","compile","complement","completing","concat","cond","cond->","cond->>","condp","conj","conj!","cons","constantly","construct-proxy","contains?","count","counted?","create-ns","create-struct","cycle","dec","dec'","decimal?","declare","dedupe","default-data-readers","definline","definterface","defmacro","defmethod","defmulti","defn","defn-","defonce","defprotocol","defrecord","defstruct","deftype","delay","delay?","deliver","denominator","deref","derive","descendants","destructure","disj","disj!","dissoc","dissoc!","distinct","distinct?","doall","dorun","doseq","dosync","dotimes","doto","double","double-array","double?","doubles","drop","drop-last","drop-while","eduction","empty","empty?","ensure","ensure-reduced","enumeration-seq","error-handler","error-mode","eval","even?","every-pred","every?","ex-data","ex-info","extend","extend-protocol","extend-type","extenders","extends?","false?","ffirst","file-seq","filter","filterv","find","find-keyword","find-ns","find-protocol-impl","find-protocol-method","find-var","first","flatten","float","float-array","float?","floats","flush","fn","fn?","fnext","fnil","for","force","format","frequencies","future","future-call","future-cancel","future-cancelled?","future-done?","future?","gen-class","gen-interface","gensym","get","get-in","get-method","get-proxy-class","get-thread-bindings","get-validator","group-by","halt-when","hash","hash-combine","hash-map","hash-ordered-coll","hash-set","hash-unordered-coll","ident?","identical?","identity","if-let","if-not","if-some","ifn?","import","in-ns","inc","inc'","indexed?","init-proxy","inst-ms","inst-ms*","inst?","instance?","int","int-array","int?","integer?","interleave","intern","interpose","into","into-array","ints","io!","isa?","iterate","iterator-seq","juxt","keep","keep-indexed","key","keys","keyword","keyword?","last","lazy-cat","lazy-seq","let","letfn","line-seq","list","list*","list?","load","load-file","load-reader","load-string","loaded-libs","locking","long","long-array","longs","loop","macroexpand","macroexpand-1","make-array","make-hierarchy","map","map-entry?","map-indexed","map?","mapcat","mapv","max","max-key","memfn","memoize","merge","merge-with","meta","method-sig","methods","min","min-key","mix-collection-hash","mod","munge","name","namespace","namespace-munge","nat-int?","neg-int?","neg?","newline","next","nfirst","nil?","nnext","not","not-any?","not-empty","not-every?","not=","ns","ns-aliases","ns-imports","ns-interns","ns-map","ns-name","ns-publics","ns-refers","ns-resolve","ns-unalias","ns-unmap","nth","nthnext","nthrest","num","number?","numerator","object-array","odd?","or","parents","partial","partition","partition-all","partition-by","pcalls","peek","persistent!","pmap","pop","pop!","pop-thread-bindings","pos-int?","pos?","pr","pr-str","prefer-method","prefers","primitives-classnames","print","print-ctor","print-dup","print-method","print-simple","print-str","printf","println","println-str","prn","prn-str","promise","proxy","proxy-call-with-super","proxy-mappings","proxy-name","proxy-super","push-thread-bindings","pvalues","qualified-ident?","qualified-keyword?","qualified-symbol?","quot","rand","rand-int","rand-nth","random-sample","range","ratio?","rational?","rationalize","re-find","re-groups","re-matcher","re-matches","re-pattern","re-seq","read","read-line","read-string","reader-conditional","reader-conditional?","realized?","record?","reduce","reduce-kv","reduced","reduced?","reductions","ref","ref-history-count","ref-max-history","ref-min-history","ref-set","refer","refer-clojure","reify","release-pending-sends","rem","remove","remove-all-methods","remove-method","remove-ns","remove-watch","repeat","repeatedly","replace","replicate","require","reset!","reset-meta!","reset-vals!","resolve","rest","restart-agent","resultset-seq","reverse","reversible?","rseq","rsubseq","run!","satisfies?","second","select-keys","send","send-off","send-via","seq","seq?","seqable?","seque","sequence","sequential?","set","set-agent-send-executor!","set-agent-send-off-executor!","set-error-handler!","set-error-mode!","set-validator!","set?","short","short-array","shorts","shuffle","shutdown-agents","simple-ident?","simple-keyword?","simple-symbol?","slurp","some","some->","some->>","some-fn","some?","sort","sort-by","sorted-map","sorted-map-by","sorted-set","sorted-set-by","sorted?","special-symbol?","spit","split-at","split-with","str","string?","struct","struct-map","subs","subseq","subvec","supers","swap!","swap-vals!","symbol","symbol?","sync","tagged-literal","tagged-literal?","take","take-last","take-nth","take-while","test","the-ns","thread-bound?","time","to-array","to-array-2d","trampoline","transduce","transient","tree-seq","true?","type","unchecked-add","unchecked-add-int","unchecked-byte","unchecked-char","unchecked-dec","unchecked-dec-int","unchecked-divide-int","unchecked-double","unchecked-float","unchecked-inc","unchecked-inc-int","unchecked-int","unchecked-long","unchecked-multiply","unchecked-multiply-int","unchecked-negate","unchecked-negate-int","unchecked-remainder-int","unchecked-short","unchecked-subtract","unchecked-subtract-int","underive","unquote","unquote-splicing","unreduced","unsigned-bit-shift-right","update","update-in","update-proxy","uri?","use","uuid?","val","vals","var-get","var-set","var?","vary-meta","vec","vector","vector-of","vector?","volatile!","volatile?","vreset!","vswap!","when","when-first","when-let","when-not","when-some","while","with-bindings","with-bindings*","with-in-str","with-loading-context","with-local-vars","with-meta","with-open","with-out-str","with-precision","with-redefs","with-redefs-fn","xml-seq","zero?","zipmap"],tokenizer:{root:[{include:"@whitespace"},[/@numbers/,"number"],[/@characters/,"string"],{include:"@string"},[/[()\[\]{}]/,"@brackets"],[/\/#"(?:\.|(?:")|[^"\n])*"\/g/,"regexp"],[/[#'@^`~]/,"meta"],[/@qualifiedSymbols/,{cases:{"^:.+$":"constant","@specialForms":"keyword","@coreSymbols":"keyword","@constants":"constant","@default":"identifier"}}]],whitespace:[[/[\s,]+/,"white"],[/;.*$/,"comment"],[/\(comment\b/,"comment","@comment"]],comment:[[/\(/,"comment","@push"],[/\)/,"comment","@pop"],[/[^()]/,"comment"]],string:[[/"/,"string","@multiLineString"]],multiLineString:[[/"/,"string","@popall"],[/@escapes/,"string.escape"],[/./,"string"]]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/codicon-wpoHPmsu.ttf b/app/dubbo-ui/dist/admin/assets/codicon-wpoHPmsu.ttf deleted file mode 100644 index 27ee4c68c..000000000 Binary files a/app/dubbo-ui/dist/admin/assets/codicon-wpoHPmsu.ttf and /dev/null differ diff --git a/app/dubbo-ui/dist/admin/assets/coffee-dz-c8Bgx.js b/app/dubbo-ui/dist/admin/assets/coffee-dz-c8Bgx.js deleted file mode 100644 index bf64b4ad7..000000000 --- a/app/dubbo-ui/dist/admin/assets/coffee-dz-c8Bgx.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\$\-\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{blockComment:["###","###"],lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*#region\\b"),end:new RegExp("^\\s*#endregion\\b")}}},r={defaultToken:"",ignoreCase:!0,tokenPostfix:".coffee",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"}],regEx:/\/(?!\/\/)(?:[^\/\\]|\\.)*\/[igm]*/,keywords:["and","or","is","isnt","not","on","yes","@","no","off","true","false","null","this","new","delete","typeof","in","instanceof","return","throw","break","continue","debugger","if","else","switch","for","while","do","try","catch","finally","class","extends","super","undefined","then","unless","until","loop","of","by","when"],symbols:/[=>{var m;(m=document.getElementById(D))==null||m.scrollIntoView({behavior:"smooth"})},re={class:"__container_app_config"},de={style:{float:"right"}},fe={style:{float:"right"}},pe=X({__name:"config",setup(D){const m=Y(),A=[{key:"key",title:"label"},{key:"condition",title:"condition"},{key:"value",title:"value"},{key:"operation",title:"操作"}];let r=Z({list:[{title:"applicationDomain.operatorLog",key:"log",form:{logFlag:!1},submit:e=>new Promise(a=>{a(N(e==null?void 0:e.logFlag))}),reset(e){e.logFlag=!1}},{title:"applicationDomain.flowWeight",key:"flow",ext:{title:"添加权重配置",fun(e){V(),ee(()=>{var t;const a=((t=r.list.find(n=>n.key==="flow"))==null?void 0:t.form.rules.length)-1;a>=0&&ce("flowWeight"+a)})}},form:{rules:[{weight:10,scope:[]}]},submit(e){return new Promise(a=>{a(O())})},reset(){x()}},{title:"applicationDomain.gray",key:"gray",ext:{title:"添加灰度环境",fun(){M()}},form:{rules:[{name:"env-nam",scope:{key:"env",value:{exact:"gray"}}}]},submit(e){return new Promise(a=>{a(K())})},reset(){F()}}],current:[0]});const G=async()=>{var a;const e=await ue((a=m.params)==null?void 0:a.pathId);console.log(e),(e==null?void 0:e.code)==200&&r.list.forEach(t=>{if(t.key==="log"){t.form.logFlag=e.data.operatorLog;return}})},N=async e=>{var t;const a=await oe((t=m.params)==null?void 0:t.pathId,e);console.log(a),(a==null?void 0:a.code)==200&&await G()},x=async()=>{var a;const e=await le((a=m.params)==null?void 0:a.pathId);(e==null?void 0:e.code)==200&&r.list.forEach(t=>{t.key==="flow"&&(t.form.rules=JSON.parse(JSON.stringify(e.data.flowWeightSets)),t.form.rules.forEach(n=>{n.scope.forEach(s=>{s.label=s.key,s.condition=s.value?Object.keys(s.value)[0]:"",s.value=s.value?Object.values(s.value)[0]:""})}))})},O=async()=>{var t;let e=[];r.list.forEach(n=>{n.key==="flow"&&n.form.rules.forEach(s=>{let i={weight:s.weight,scope:[]};s.scope.forEach(b=>{const{key:v,value:E,condition:h}=b;let y={key:b.label||v,value:{}};h&&(y.value[h]=E),i.scope.push(y)}),e.push(i)})}),(await ne((t=m.params)==null?void 0:t.pathId,e)).code===200&&await x()},V=()=>{r.list.forEach(e=>{e.key==="flow"&&e.form.rules.push({weight:10,scope:[{key:"",condition:"",value:""}]})})},z=e=>{r.list.forEach(a=>{a.key==="flow"&&a.form.rules.splice(e,1)})},B=e=>{r.list.forEach(a=>{if(a.key==="flow"){let t={key:"",condition:"",value:""};a.form.rules[e].scope.push(t);return}})},P=(e,a)=>{r.list.forEach(t=>{t.key==="flow"&&t.form.rules[e].scope.splice(a,1)})},J=[{key:"label",title:"label",dataIndex:"label"},{key:"condition",title:"condition",dataIndex:"condition"},{key:"value",title:"value",dataIndex:"value"},{key:"operation",title:"operation",dataIndex:"operation"}],F=async()=>{var a;const e=await se((a=m.params)==null?void 0:a.pathId);(e==null?void 0:e.code)==200&&r.list.forEach(t=>{if(t.key==="gray"){const n=e.data.graySets;n.length>0&&n.forEach(s=>{s.scope.forEach(i=>{i.label=i.key,i.condition=i.value?Object.keys(i.value)[0]:"",i.value=i.value?Object.values(i.value)[0]:""})}),t.form.rules=n}})},K=async()=>{var t;let e=[];r.list.forEach(n=>{n.key==="gray"&&n.form.rules.forEach(s=>{let i={name:s.name,scope:[]};s.scope.forEach(b=>{const{key:v,value:E,condition:h}=b;let y={key:b.label,value:{}};h&&(y.value[h]=E),i.scope.push(y)}),e.push(i)})}),(await ie((t=m.params)==null?void 0:t.pathId,e)).code===200&&await F()},M=()=>{r.list.forEach(e=>{e.key==="gray"&&e.form.rules.push({name:"",scope:[{key:"",condition:"",value:""}]})})},Q=e=>{r.list.forEach(a=>{if(a.key==="gray"){let t={key:"",condition:"",value:""};a.form.rules[e].scope.push(t);return}})},R=(e,a)=>{r.list.forEach(t=>{t.key==="gray"&&t.form.rules[e].scope.splice(a,1)})},q=e=>{r.list.forEach(a=>{a.key==="gray"&&a.form.rules.splice(e,1)})};return ae(()=>{G(),x(),F()}),(e,a)=>{const t=_("a-switch"),n=_("a-form-item"),s=_("a-button"),i=_("a-space"),b=_("a-input-number"),v=_("a-input"),E=_("a-table"),h=_("a-card");return p(),W("div",re,[l(H,{options:I(r)},{form_log:o(({current:y})=>[l(n,{label:e.$t("applicationDomain.operatorLog"),name:"logFlag"},{default:o(()=>[l(t,{checked:y.form.logFlag,"onUpdate:checked":k=>y.form.logFlag=k},null,8,["checked","onUpdate:checked"])]),_:2},1032,["label"])]),form_flow:o(({current:y})=>[l(i,{direction:"vertical",size:"middle",class:"flowWeight-box"},{default:o(()=>[(p(!0),W(T,null,$(y.form.rules,(k,u)=>(p(),g(h,{id:"flowWeight"+u},{title:o(()=>[C(U(e.$t("applicationDomain.flowWeight"))+" "+U(u+1)+" ",1),L("div",de,[l(i,null,{default:o(()=>[l(s,{danger:"",type:"dashed",onClick:c=>z(u)},{default:o(()=>[l(I(j),{style:{"font-size":"20px"},icon:"fluent:delete-12-filled"})]),_:2},1032,["onClick"])]),_:2},1024)])]),default:o(()=>[l(n,{name:"rules["+u+"].weight",label:"权重"},{default:o(()=>[l(b,{min:"1",value:k.weight,"onUpdate:value":c=>k.weight=c},null,8,["value","onUpdate:value"])]),_:2},1032,["name"]),l(n,{label:"作用范围"},{default:o(()=>[l(s,{type:"primary",onClick:c=>B(u)},{default:o(()=>[C(" 添加")]),_:2},1032,["onClick"]),l(E,{style:{width:"40vw"},pagination:!1,columns:A,"data-source":k.scope},{bodyCell:o(({column:c,record:d,index:S})=>[c.key==="key"?(p(),g(n,{key:0,name:"rules["+u+"].scope.key"},{default:o(()=>[l(v,{value:d.key,"onUpdate:value":f=>d.key=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="condition"?(p(),g(n,{key:1,name:"rules["+u+"].scope.condition"},{default:o(()=>[l(v,{value:d.condition,"onUpdate:value":f=>d.condition=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="value"?(p(),g(n,{key:2,name:"rules["+u+"].scope.value"},{default:o(()=>[l(v,{value:d.value,"onUpdate:value":f=>d.value=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="operation"?(p(),g(n,{key:3,name:"rules["+u+"].scope.operation"},{default:o(()=>[l(s,{type:"link",onClick:f=>P(u,S)},{default:o(()=>[C(" 删除")]),_:2},1032,["onClick"])]),_:2},1032,["name"])):w("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1032,["id"]))),256))]),_:2},1024)]),form_gray:o(({current:y})=>[l(i,{direction:"vertical",size:"middle"},{default:o(()=>[(p(!0),W(T,null,$(y.form.rules,(k,u)=>(p(),g(h,null,{title:o(()=>[C(U(e.$t("applicationDomain.gray"))+" "+U(u+1)+" ",1),L("div",fe,[l(i,null,{default:o(()=>[l(s,{danger:"",type:"dashed",onClick:c=>q(u)},{default:o(()=>[l(I(j),{style:{"font-size":"20px"},icon:"fluent:delete-12-filled"})]),_:2},1032,["onClick"])]),_:2},1024)])]),default:o(()=>[l(n,{name:"rules["+u+"].name",label:"环境名称"},{default:o(()=>[l(v,{value:k.name,"onUpdate:value":c=>k.name=c},null,8,["value","onUpdate:value"])]),_:2},1032,["name"]),l(n,{label:"作用范围"},{default:o(()=>[l(i,{direction:"vertical",size:"middle"},{default:o(()=>[l(s,{type:"primary",onClick:c=>Q(u)},{default:o(()=>[C(" 添加")]),_:2},1032,["onClick"]),l(E,{style:{width:"40vw"},pagination:!1,columns:J,"data-source":k.scope},{bodyCell:o(({column:c,record:d,index:S})=>[c.key==="label"?(p(),g(n,{key:0,name:"rules["+u+"].scope.key"},{default:o(()=>[l(v,{value:d.label,"onUpdate:value":f=>d.label=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="condition"?(p(),g(n,{key:1,name:"rules["+u+"].scope.condition"},{default:o(()=>[l(v,{value:d.condition,"onUpdate:value":f=>d.condition=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="value"?(p(),g(n,{key:2,name:"rules["+u+"].scope.value"},{default:o(()=>[l(v,{value:d.value,"onUpdate:value":f=>d.value=f},null,8,["value","onUpdate:value"])]),_:2},1032,["name"])):w("",!0),c.key==="operation"?(p(),g(n,{key:3,name:"rules["+u+"].scope.operation"},{default:o(()=>[l(s,{type:"link",onClick:f=>R(u,S)},{default:o(()=>[C(" 删除")]),_:2},1032,["onClick"])]),_:2},1032,["name"])):w("",!0)]),_:2},1032,["data-source"])]),_:2},1024)]),_:2},1024)]),_:2},1024))),256))]),_:2},1024)]),_:1},8,["options"])])}}}),ke=te(pe,[["__scopeId","data-v-2bf9591a"]]);export{ke as default}; diff --git a/app/dubbo-ui/dist/admin/assets/config-c0xW8oe-.css b/app/dubbo-ui/dist/admin/assets/config-c0xW8oe-.css deleted file mode 100644 index dfaad50bb..000000000 --- a/app/dubbo-ui/dist/admin/assets/config-c0xW8oe-.css +++ /dev/null @@ -1 +0,0 @@ -.__container_app_config .flowWeight-box[data-v-2bf9591a]{width:100%;height:100%} diff --git a/app/dubbo-ui/dist/admin/assets/configuration-c8iwuhKj.js b/app/dubbo-ui/dist/admin/assets/configuration-c8iwuhKj.js deleted file mode 100644 index 4d59e4d24..000000000 --- a/app/dubbo-ui/dist/admin/assets/configuration-c8iwuhKj.js +++ /dev/null @@ -1 +0,0 @@ -import{C as w}from"./ConfigPage--FZz2L2D.js";import{d as _,a as h,r as u,W as b,c as I,b as c,w as l,n as D,e as d,o as k,_ as F}from"./index-hmLAZQYT.js";import{u as y,c as S,d as L,e as P}from"./instance-9-P3Wy8N.js";import"./request-8jI_GZey.js";const C={class:"__container_ins_config"},N=_({__name:"configuration",setup(v){const s=h();let i=u({list:[{title:"instanceDomain.operatorLog",key:"log",form:{logFlag:!1},submit:a=>new Promise(e=>{e(p(a==null?void 0:a.logFlag))}),reset(a){a.logFlag=!1}},{title:"instanceDomain.flowDisabled",form:{flowDisabledFlag:!1},key:"flowDisabled",submit:a=>new Promise(e=>{e(m(a==null?void 0:a.flowDisabledFlag))}),reset(a){a.logFlag=!1}}],current:[0]});const f=async()=>{var e,o;const a=await L((e=s.params)==null?void 0:e.pathId,(o=s.params)==null?void 0:o.appName);(a==null?void 0:a.code)==200&&i.list.forEach(t=>{if(t.key==="log"){t.form.logFlag=a.data.operatorLog;return}})},p=async a=>{var o,t;const e=await y((o=s.params)==null?void 0:o.pathId,(t=s.params)==null?void 0:t.appName,a);(e==null?void 0:e.code)==200&&await f()},g=async()=>{var e,o;const a=await P((e=s.params)==null?void 0:e.pathId,(o=s.params)==null?void 0:o.appName);(a==null?void 0:a.code)==200&&i.list.forEach(t=>{t.key==="flowDisabled"&&(t.form.flowDisabledFlag=a.data.trafficDisable)})},m=async a=>{var o,t;const e=await S((o=s.params)==null?void 0:o.pathId,(t=s.params)==null?void 0:t.appName,a);console.log(e)};return b(()=>{console.log(333),f(),g()}),(a,e)=>{const o=d("a-switch"),t=d("a-form-item");return k(),I("div",C,[c(w,{options:D(i)},{form_log:l(({current:n})=>[c(t,{label:a.$t("instanceDomain.operatorLog"),name:"logFlag"},{default:l(()=>[c(o,{checked:n.form.logFlag,"onUpdate:checked":r=>n.form.logFlag=r},null,8,["checked","onUpdate:checked"])]),_:2},1032,["label"])]),form_flowDisabled:l(({current:n})=>[c(t,{label:a.$t("instanceDomain.flowDisabled"),name:"flowDisabledFlag"},{default:l(()=>[c(o,{checked:n.form.flowDisabledFlag,"onUpdate:checked":r=>n.form.flowDisabledFlag=r},null,8,["checked","onUpdate:checked"])]),_:2},1032,["label"])]),_:1},8,["options"])])}}}),x=F(N,[["__scopeId","data-v-452f673d"]]);export{x as default}; diff --git a/app/dubbo-ui/dist/admin/assets/cpp-2U_pDMGk.js b/app/dubbo-ui/dist/admin/assets/cpp-2U_pDMGk.js deleted file mode 100644 index 293f73190..000000000 --- a/app/dubbo-ui/dist/admin/assets/cpp-2U_pDMGk.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"[",close:"]"},{open:"{",close:"}"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*#pragma\\s+region\\b"),end:new RegExp("^\\s*#pragma\\s+endregion\\b")}}},n={defaultToken:"",tokenPostfix:".cpp",brackets:[{token:"delimiter.curly",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"},{token:"delimiter.angle",open:"<",close:">"}],keywords:["abstract","amp","array","auto","bool","break","case","catch","char","class","const","constexpr","const_cast","continue","cpu","decltype","default","delegate","delete","do","double","dynamic_cast","each","else","enum","event","explicit","export","extern","false","final","finally","float","for","friend","gcnew","generic","goto","if","in","initonly","inline","int","interface","interior_ptr","internal","literal","long","mutable","namespace","new","noexcept","nullptr","__nullptr","operator","override","partial","pascal","pin_ptr","private","property","protected","public","ref","register","reinterpret_cast","restrict","return","safe_cast","sealed","short","signed","sizeof","static","static_assert","static_cast","struct","switch","template","this","thread_local","throw","tile_static","true","try","typedef","typeid","typename","union","unsigned","using","virtual","void","volatile","wchar_t","where","while","_asm","_based","_cdecl","_declspec","_fastcall","_if_exists","_if_not_exists","_inline","_multiple_inheritance","_pascal","_single_inheritance","_stdcall","_virtual_inheritance","_w64","__abstract","__alignof","__asm","__assume","__based","__box","__builtin_alignof","__cdecl","__clrcall","__declspec","__delegate","__event","__except","__fastcall","__finally","__forceinline","__gc","__hook","__identifier","__if_exists","__if_not_exists","__inline","__int128","__int16","__int32","__int64","__int8","__interface","__leave","__m128","__m128d","__m128i","__m256","__m256d","__m256i","__m512","__m512d","__m512i","__m64","__multiple_inheritance","__newslot","__nogc","__noop","__nounwind","__novtordisp","__pascal","__pin","__pragma","__property","__ptr32","__ptr64","__raise","__restrict","__resume","__sealed","__single_inheritance","__stdcall","__super","__thiscall","__try","__try_cast","__typeof","__unaligned","__unhook","__uuidof","__value","__virtual_inheritance","__w64","__wchar_t"],operators:["=",">","<","!","~","?",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>="],symbols:/[=>\[\]]/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/,"number.float"],[/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/,"number.hex"],[/0[0-7']*[0-7](@integersuffix)/,"number.octal"],[/0[bB][0-1']*[0-1](@integersuffix)/,"number.binary"],[/\d[\d']*\d(@integersuffix)/,"number"],[/\d(@integersuffix)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@doccomment"],[/\/\*/,"comment","@comment"],[/\/\/.*\\$/,"comment","@linecomment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],linecomment:[[/.*[^\\]$/,"comment","@pop"],[/[^]+/,"comment"]],doccomment:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],raw:[[/[^)]+/,"string.raw"],[/\)$S2\"/,{token:"string.raw.end",next:"@pop"}],[/\)/,"string.raw"]],annotation:[{include:"@whitespace"},[/using|alignas/,"keyword"],[/[a-zA-Z0-9_]+/,"annotation"],[/[,:]/,"delimiter"],[/[()]/,"@brackets"],[/\]\s*\]/,{token:"annotation",next:"@pop"}]],include:[[/(\s*)(<)([^<>]*)(>)/,["","keyword.directive.include.begin","string.include.identifier",{token:"keyword.directive.include.end",next:"@pop"}]],[/(\s*)(")([^"]*)(")/,["","keyword.directive.include.begin","string.include.identifier",{token:"keyword.directive.include.end",next:"@pop"}]]]}};export{e as conf,n as language}; diff --git a/app/dubbo-ui/dist/admin/assets/csharp-4Zs2zOBj.js b/app/dubbo-ui/dist/admin/assets/csharp-4Zs2zOBj.js deleted file mode 100644 index 258a1ed30..000000000 --- a/app/dubbo-ui/dist/admin/assets/csharp-4Zs2zOBj.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}],folding:{markers:{start:new RegExp("^\\s*#region\\b"),end:new RegExp("^\\s*#endregion\\b")}}},t={defaultToken:"",tokenPostfix:".cs",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["extern","alias","using","bool","decimal","sbyte","byte","short","ushort","int","uint","long","ulong","char","float","double","object","dynamic","string","assembly","is","as","ref","out","this","base","new","typeof","void","checked","unchecked","default","delegate","var","const","if","else","switch","case","while","do","for","foreach","in","break","continue","goto","return","throw","try","catch","finally","lock","yield","from","let","where","join","on","equals","into","orderby","ascending","descending","select","group","by","namespace","partial","class","field","event","method","param","public","protected","internal","private","abstract","sealed","static","struct","readonly","volatile","virtual","override","params","get","set","add","remove","operator","true","false","implicit","explicit","interface","enum","null","async","await","fixed","sizeof","stackalloc","unsafe","nameof","when"],namespaceFollows:["namespace","using"],parenFollows:["if","for","while","switch","foreach","using","catch","when"],operators:["=","??","||","&&","|","^","&","==","!=","<=",">=","<<","+","-","*","/","%","!","~","++","--","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=",">>","=>"],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/[0-9_]*\.[0-9_]+([eE][\-+]?\d+)?[fFdD]?/,"number.float"],[/0[xX][0-9a-fA-F_]+/,"number.hex"],[/0[bB][01_]+/,"number.hex"],[/[0-9_]+/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",next:"@string"}],[/\$\@"/,{token:"string.quote",next:"@litinterpstring"}],[/\@"/,{token:"string.quote",next:"@litstring"}],[/\$"/,{token:"string.quote",next:"@interpolatedstring"}],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],qualified:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],[/\./,"delimiter"],["","","@pop"]],namespace:[{include:"@whitespace"},[/[A-Z]\w*/,"namespace"],[/[\.=]/,"delimiter"],["","","@pop"]],comment:[[/[^\/*]+/,"comment"],["\\*/","comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",next:"@pop"}]],litstring:[[/[^"]+/,"string"],[/""/,"string.escape"],[/"/,{token:"string.quote",next:"@pop"}]],litinterpstring:[[/[^"{]+/,"string"],[/""/,"string.escape"],[/{{/,"string.escape"],[/}}/,"string.escape"],[/{/,{token:"string.quote",next:"root.litinterpstring"}],[/"/,{token:"string.quote",next:"@pop"}]],interpolatedstring:[[/[^\\"{]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/{{/,"string.escape"],[/}}/,"string.escape"],[/{/,{token:"string.quote",next:"root.interpolatedstring"}],[/"/,{token:"string.quote",next:"@pop"}]],whitespace:[[/^[ \t\v\f]*#((r)|(load))(?=\s)/,"directive.csx"],[/^[ \t\v\f]*#\w.*$/,"namespace.cpp"],[/[ \t\v\f\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/csp-lGMKRGPG.js b/app/dubbo-ui/dist/admin/assets/csp-lGMKRGPG.js deleted file mode 100644 index 7475a4a4d..000000000 --- a/app/dubbo-ui/dist/admin/assets/csp-lGMKRGPG.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var t={brackets:[],autoClosingPairs:[],surroundingPairs:[]},r={keywords:[],typeKeywords:[],tokenPostfix:".csp",operators:[],symbols:/[=>",token:"delimiter.angle"}],tokenizer:{root:[{include:"@selector"}],selector:[{include:"@comments"},{include:"@import"},{include:"@strings"},["[@](keyframes|-webkit-keyframes|-moz-keyframes|-o-keyframes)",{token:"keyword",next:"@keyframedeclaration"}],["[@](page|content|font-face|-moz-document)",{token:"keyword"}],["[@](charset|namespace)",{token:"keyword",next:"@declarationbody"}],["(url-prefix)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],["(url)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],{include:"@selectorname"},["[\\*]","tag"],["[>\\+,]","delimiter"],["\\[",{token:"delimiter.bracket",next:"@selectorattribute"}],["{",{token:"delimiter.bracket",next:"@selectorbody"}]],selectorbody:[{include:"@comments"},["[*_]?@identifier@ws:(?=(\\s|\\d|[^{;}]*[;}]))","attribute.name","@rulevalue"],["}",{token:"delimiter.bracket",next:"@pop"}]],selectorname:[["(\\.|#(?=[^{])|%|(@identifier)|:)+","tag"]],selectorattribute:[{include:"@term"},["]",{token:"delimiter.bracket",next:"@pop"}]],term:[{include:"@comments"},["(url-prefix)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],["(url)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],{include:"@functioninvocation"},{include:"@numbers"},{include:"@name"},{include:"@strings"},["([<>=\\+\\-\\*\\/\\^\\|\\~,])","delimiter"],[",","delimiter"]],rulevalue:[{include:"@comments"},{include:"@strings"},{include:"@term"},["!important","keyword"],[";","delimiter","@pop"],["(?=})",{token:"",next:"@pop"}]],warndebug:[["[@](warn|debug)",{token:"keyword",next:"@declarationbody"}]],import:[["[@](import)",{token:"keyword",next:"@declarationbody"}]],urldeclaration:[{include:"@strings"},[`[^)\r -]+`,"string"],["\\)",{token:"delimiter.parenthesis",next:"@pop"}]],parenthizedterm:[{include:"@term"},["\\)",{token:"delimiter.parenthesis",next:"@pop"}]],declarationbody:[{include:"@term"},[";","delimiter","@pop"],["(?=})",{token:"",next:"@pop"}]],comments:[["\\/\\*","comment","@comment"],["\\/\\/+.*","comment"]],comment:[["\\*\\/","comment","@pop"],[/[^*/]+/,"comment"],[/./,"comment"]],name:[["@identifier","attribute.value"]],numbers:[["-?(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?",{token:"attribute.value.number",next:"@units"}],["#[0-9a-fA-F_]+(?!\\w)","attribute.value.hex"]],units:[["(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?","attribute.value.unit","@pop"]],keyframedeclaration:[["@identifier","attribute.value"],["{",{token:"delimiter.bracket",switchTo:"@keyframebody"}]],keyframebody:[{include:"@term"},["{",{token:"delimiter.bracket",next:"@selectorbody"}],["}",{token:"delimiter.bracket",next:"@pop"}]],functioninvocation:[["@identifier\\(",{token:"attribute.value",next:"@functionarguments"}]],functionarguments:[["\\$@identifier@ws:","attribute.name"],["[,]","delimiter"],{include:"@term"},["\\)",{token:"attribute.value",next:"@pop"}]],strings:[['~?"',{token:"string",next:"@stringenddoublequote"}],["~?'",{token:"string",next:"@stringendquote"}]],stringenddoublequote:[["\\\\.","string"],['"',{token:"string",next:"@pop"}],[/[^\\"]+/,"string"],[".","string"]],stringendquote:[["\\\\.","string"],["'",{token:"string",next:"@pop"}],[/[^\\']+/,"string"],[".","string"]]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/cssMode-3d_RQH6d.js b/app/dubbo-ui/dist/admin/assets/cssMode-3d_RQH6d.js deleted file mode 100644 index e4e4a69d4..000000000 --- a/app/dubbo-ui/dist/admin/assets/cssMode-3d_RQH6d.js +++ /dev/null @@ -1,9 +0,0 @@ -import{m as tt}from"./js-yaml-8Gkz3BRW.js";import"./index-hmLAZQYT.js";/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var rt=Object.defineProperty,nt=Object.getOwnPropertyDescriptor,it=Object.getOwnPropertyNames,ot=Object.prototype.hasOwnProperty,Y=(e,n,i,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of it(n))!ot.call(e,t)&&t!==i&&rt(e,t,{get:()=>n[t],enumerable:!(r=nt(n,t))||r.enumerable});return e},at=(e,n,i)=>(Y(e,n,"default"),i&&Y(i,n,"default")),d={};at(d,tt);var st=2*60*1e3,ut=class{constructor(e){this._defaults=e,this._worker=null,this._client=null,this._idleCheckInterval=window.setInterval(()=>this._checkIfIdle(),30*1e3),this._lastUsedTime=0,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker())}_stopWorker(){this._worker&&(this._worker.dispose(),this._worker=null),this._client=null}dispose(){clearInterval(this._idleCheckInterval),this._configChangeListener.dispose(),this._stopWorker()}_checkIfIdle(){if(!this._worker)return;Date.now()-this._lastUsedTime>st&&this._stopWorker()}_getClient(){return this._lastUsedTime=Date.now(),this._client||(this._worker=d.editor.createWebWorker({moduleId:"vs/language/css/cssWorker",label:this._defaults.languageId,createData:{options:this._defaults.options,languageId:this._defaults.languageId}}),this._client=this._worker.getProxy()),this._client}getLanguageServiceWorker(...e){let n;return this._getClient().then(i=>{n=i}).then(i=>{if(this._worker)return this._worker.withSyncedResources(e)}).then(i=>n)}},Z;(function(e){function n(i){return typeof i=="string"}e.is=n})(Z||(Z={}));var O;(function(e){function n(i){return typeof i=="string"}e.is=n})(O||(O={}));var T;(function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647;function n(i){return typeof i=="number"&&e.MIN_VALUE<=i&&i<=e.MAX_VALUE}e.is=n})(T||(T={}));var M;(function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647;function n(i){return typeof i=="number"&&e.MIN_VALUE<=i&&i<=e.MAX_VALUE}e.is=n})(M||(M={}));var w;(function(e){function n(r,t){return r===Number.MAX_VALUE&&(r=M.MAX_VALUE),t===Number.MAX_VALUE&&(t=M.MAX_VALUE),{line:r,character:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&a.uinteger(t.line)&&a.uinteger(t.character)}e.is=i})(w||(w={}));var h;(function(e){function n(r,t,o,s){if(a.uinteger(r)&&a.uinteger(t)&&a.uinteger(o)&&a.uinteger(s))return{start:w.create(r,t),end:w.create(o,s)};if(w.is(r)&&w.is(t))return{start:r,end:t};throw new Error(`Range#create called with invalid arguments[${r}, ${t}, ${o}, ${s}]`)}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&w.is(t.start)&&w.is(t.end)}e.is=i})(h||(h={}));var C;(function(e){function n(r,t){return{uri:r,range:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.range)&&(a.string(t.uri)||a.undefined(t.uri))}e.is=i})(C||(C={}));var K;(function(e){function n(r,t,o,s){return{targetUri:r,targetRange:t,targetSelectionRange:o,originSelectionRange:s}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.targetRange)&&a.string(t.targetUri)&&h.is(t.targetSelectionRange)&&(h.is(t.originSelectionRange)||a.undefined(t.originSelectionRange))}e.is=i})(K||(K={}));var S;(function(e){function n(r,t,o,s){return{red:r,green:t,blue:o,alpha:s}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.numberRange(t.red,0,1)&&a.numberRange(t.green,0,1)&&a.numberRange(t.blue,0,1)&&a.numberRange(t.alpha,0,1)}e.is=i})(S||(S={}));var ee;(function(e){function n(r,t){return{range:r,color:t}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&h.is(t.range)&&S.is(t.color)}e.is=i})(ee||(ee={}));var te;(function(e){function n(r,t,o){return{label:r,textEdit:t,additionalTextEdits:o}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.string(t.label)&&(a.undefined(t.textEdit)||E.is(t))&&(a.undefined(t.additionalTextEdits)||a.typedArray(t.additionalTextEdits,E.is))}e.is=i})(te||(te={}));var A;(function(e){e.Comment="comment",e.Imports="imports",e.Region="region"})(A||(A={}));var re;(function(e){function n(r,t,o,s,u,f){const c={startLine:r,endLine:t};return a.defined(o)&&(c.startCharacter=o),a.defined(s)&&(c.endCharacter=s),a.defined(u)&&(c.kind=u),a.defined(f)&&(c.collapsedText=f),c}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.uinteger(t.startLine)&&a.uinteger(t.startLine)&&(a.undefined(t.startCharacter)||a.uinteger(t.startCharacter))&&(a.undefined(t.endCharacter)||a.uinteger(t.endCharacter))&&(a.undefined(t.kind)||a.string(t.kind))}e.is=i})(re||(re={}));var U;(function(e){function n(r,t){return{location:r,message:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&C.is(t.location)&&a.string(t.message)}e.is=i})(U||(U={}));var x;(function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4})(x||(x={}));var ne;(function(e){e.Unnecessary=1,e.Deprecated=2})(ne||(ne={}));var ie;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&a.string(r.href)}e.is=n})(ie||(ie={}));var y;(function(e){function n(r,t,o,s,u,f){let c={range:r,message:t};return a.defined(o)&&(c.severity=o),a.defined(s)&&(c.code=s),a.defined(u)&&(c.source=u),a.defined(f)&&(c.relatedInformation=f),c}e.create=n;function i(r){var t;let o=r;return a.defined(o)&&h.is(o.range)&&a.string(o.message)&&(a.number(o.severity)||a.undefined(o.severity))&&(a.integer(o.code)||a.string(o.code)||a.undefined(o.code))&&(a.undefined(o.codeDescription)||a.string((t=o.codeDescription)===null||t===void 0?void 0:t.href))&&(a.string(o.source)||a.undefined(o.source))&&(a.undefined(o.relatedInformation)||a.typedArray(o.relatedInformation,U.is))}e.is=i})(y||(y={}));var I;(function(e){function n(r,t,...o){let s={title:r,command:t};return a.defined(o)&&o.length>0&&(s.arguments=o),s}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.title)&&a.string(t.command)}e.is=i})(I||(I={}));var E;(function(e){function n(o,s){return{range:o,newText:s}}e.replace=n;function i(o,s){return{range:{start:o,end:o},newText:s}}e.insert=i;function r(o){return{range:o,newText:""}}e.del=r;function t(o){const s=o;return a.objectLiteral(s)&&a.string(s.newText)&&h.is(s.range)}e.is=t})(E||(E={}));var V;(function(e){function n(r,t,o){const s={label:r};return t!==void 0&&(s.needsConfirmation=t),o!==void 0&&(s.description=o),s}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.string(t.label)&&(a.boolean(t.needsConfirmation)||t.needsConfirmation===void 0)&&(a.string(t.description)||t.description===void 0)}e.is=i})(V||(V={}));var L;(function(e){function n(i){const r=i;return a.string(r)}e.is=n})(L||(L={}));var oe;(function(e){function n(o,s,u){return{range:o,newText:s,annotationId:u}}e.replace=n;function i(o,s,u){return{range:{start:o,end:o},newText:s,annotationId:u}}e.insert=i;function r(o,s){return{range:o,newText:"",annotationId:s}}e.del=r;function t(o){const s=o;return E.is(s)&&(V.is(s.annotationId)||L.is(s.annotationId))}e.is=t})(oe||(oe={}));var W;(function(e){function n(r,t){return{textDocument:r,edits:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&B.is(t.textDocument)&&Array.isArray(t.edits)}e.is=i})(W||(W={}));var H;(function(e){function n(r,t,o){let s={kind:"create",uri:r};return t!==void 0&&(t.overwrite!==void 0||t.ignoreIfExists!==void 0)&&(s.options=t),o!==void 0&&(s.annotationId=o),s}e.create=n;function i(r){let t=r;return t&&t.kind==="create"&&a.string(t.uri)&&(t.options===void 0||(t.options.overwrite===void 0||a.boolean(t.options.overwrite))&&(t.options.ignoreIfExists===void 0||a.boolean(t.options.ignoreIfExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})(H||(H={}));var X;(function(e){function n(r,t,o,s){let u={kind:"rename",oldUri:r,newUri:t};return o!==void 0&&(o.overwrite!==void 0||o.ignoreIfExists!==void 0)&&(u.options=o),s!==void 0&&(u.annotationId=s),u}e.create=n;function i(r){let t=r;return t&&t.kind==="rename"&&a.string(t.oldUri)&&a.string(t.newUri)&&(t.options===void 0||(t.options.overwrite===void 0||a.boolean(t.options.overwrite))&&(t.options.ignoreIfExists===void 0||a.boolean(t.options.ignoreIfExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})(X||(X={}));var $;(function(e){function n(r,t,o){let s={kind:"delete",uri:r};return t!==void 0&&(t.recursive!==void 0||t.ignoreIfNotExists!==void 0)&&(s.options=t),o!==void 0&&(s.annotationId=o),s}e.create=n;function i(r){let t=r;return t&&t.kind==="delete"&&a.string(t.uri)&&(t.options===void 0||(t.options.recursive===void 0||a.boolean(t.options.recursive))&&(t.options.ignoreIfNotExists===void 0||a.boolean(t.options.ignoreIfNotExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})($||($={}));var z;(function(e){function n(i){let r=i;return r&&(r.changes!==void 0||r.documentChanges!==void 0)&&(r.documentChanges===void 0||r.documentChanges.every(t=>a.string(t.kind)?H.is(t)||X.is(t)||$.is(t):W.is(t)))}e.is=n})(z||(z={}));var ae;(function(e){function n(r){return{uri:r}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)}e.is=i})(ae||(ae={}));var se;(function(e){function n(r,t){return{uri:r,version:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&a.integer(t.version)}e.is=i})(se||(se={}));var B;(function(e){function n(r,t){return{uri:r,version:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&(t.version===null||a.integer(t.version))}e.is=i})(B||(B={}));var ue;(function(e){function n(r,t,o,s){return{uri:r,languageId:t,version:o,text:s}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&a.string(t.languageId)&&a.integer(t.version)&&a.string(t.text)}e.is=i})(ue||(ue={}));var q;(function(e){e.PlainText="plaintext",e.Markdown="markdown";function n(i){const r=i;return r===e.PlainText||r===e.Markdown}e.is=n})(q||(q={}));var P;(function(e){function n(i){const r=i;return a.objectLiteral(i)&&q.is(r.kind)&&a.string(r.value)}e.is=n})(P||(P={}));var v;(function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25})(v||(v={}));var Q;(function(e){e.PlainText=1,e.Snippet=2})(Q||(Q={}));var ce;(function(e){e.Deprecated=1})(ce||(ce={}));var de;(function(e){function n(r,t,o){return{newText:r,insert:t,replace:o}}e.create=n;function i(r){const t=r;return t&&a.string(t.newText)&&h.is(t.insert)&&h.is(t.replace)}e.is=i})(de||(de={}));var le;(function(e){e.asIs=1,e.adjustIndentation=2})(le||(le={}));var fe;(function(e){function n(i){const r=i;return r&&(a.string(r.detail)||r.detail===void 0)&&(a.string(r.description)||r.description===void 0)}e.is=n})(fe||(fe={}));var ge;(function(e){function n(i){return{label:i}}e.create=n})(ge||(ge={}));var he;(function(e){function n(i,r){return{items:i||[],isIncomplete:!!r}}e.create=n})(he||(he={}));var F;(function(e){function n(r){return r.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}e.fromPlainText=n;function i(r){const t=r;return a.string(t)||a.objectLiteral(t)&&a.string(t.language)&&a.string(t.value)}e.is=i})(F||(F={}));var ve;(function(e){function n(i){let r=i;return!!r&&a.objectLiteral(r)&&(P.is(r.contents)||F.is(r.contents)||a.typedArray(r.contents,F.is))&&(i.range===void 0||h.is(i.range))}e.is=n})(ve||(ve={}));var pe;(function(e){function n(i,r){return r?{label:i,documentation:r}:{label:i}}e.create=n})(pe||(pe={}));var me;(function(e){function n(i,r,...t){let o={label:i};return a.defined(r)&&(o.documentation=r),a.defined(t)?o.parameters=t:o.parameters=[],o}e.create=n})(me||(me={}));var R;(function(e){e.Text=1,e.Read=2,e.Write=3})(R||(R={}));var _e;(function(e){function n(i,r){let t={range:i};return a.number(r)&&(t.kind=r),t}e.create=n})(_e||(_e={}));var p;(function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26})(p||(p={}));var be;(function(e){e.Deprecated=1})(be||(be={}));var we;(function(e){function n(i,r,t,o,s){let u={name:i,kind:r,location:{uri:o,range:t}};return s&&(u.containerName=s),u}e.create=n})(we||(we={}));var ke;(function(e){function n(i,r,t,o){return o!==void 0?{name:i,kind:r,location:{uri:t,range:o}}:{name:i,kind:r,location:{uri:t}}}e.create=n})(ke||(ke={}));var xe;(function(e){function n(r,t,o,s,u,f){let c={name:r,detail:t,kind:o,range:s,selectionRange:u};return f!==void 0&&(c.children=f),c}e.create=n;function i(r){let t=r;return t&&a.string(t.name)&&a.number(t.kind)&&h.is(t.range)&&h.is(t.selectionRange)&&(t.detail===void 0||a.string(t.detail))&&(t.deprecated===void 0||a.boolean(t.deprecated))&&(t.children===void 0||Array.isArray(t.children))&&(t.tags===void 0||Array.isArray(t.tags))}e.is=i})(xe||(xe={}));var Ie;(function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"})(Ie||(Ie={}));var j;(function(e){e.Invoked=1,e.Automatic=2})(j||(j={}));var Ee;(function(e){function n(r,t,o){let s={diagnostics:r};return t!=null&&(s.only=t),o!=null&&(s.triggerKind=o),s}e.create=n;function i(r){let t=r;return a.defined(t)&&a.typedArray(t.diagnostics,y.is)&&(t.only===void 0||a.typedArray(t.only,a.string))&&(t.triggerKind===void 0||t.triggerKind===j.Invoked||t.triggerKind===j.Automatic)}e.is=i})(Ee||(Ee={}));var Le;(function(e){function n(r,t,o){let s={title:r},u=!0;return typeof t=="string"?(u=!1,s.kind=t):I.is(t)?s.command=t:s.edit=t,u&&o!==void 0&&(s.kind=o),s}e.create=n;function i(r){let t=r;return t&&a.string(t.title)&&(t.diagnostics===void 0||a.typedArray(t.diagnostics,y.is))&&(t.kind===void 0||a.string(t.kind))&&(t.edit!==void 0||t.command!==void 0)&&(t.command===void 0||I.is(t.command))&&(t.isPreferred===void 0||a.boolean(t.isPreferred))&&(t.edit===void 0||z.is(t.edit))}e.is=i})(Le||(Le={}));var Ae;(function(e){function n(r,t){let o={range:r};return a.defined(t)&&(o.data=t),o}e.create=n;function i(r){let t=r;return a.defined(t)&&h.is(t.range)&&(a.undefined(t.command)||I.is(t.command))}e.is=i})(Ae||(Ae={}));var Re;(function(e){function n(r,t){return{tabSize:r,insertSpaces:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.uinteger(t.tabSize)&&a.boolean(t.insertSpaces)}e.is=i})(Re||(Re={}));var Pe;(function(e){function n(r,t,o){return{range:r,target:t,data:o}}e.create=n;function i(r){let t=r;return a.defined(t)&&h.is(t.range)&&(a.undefined(t.target)||a.string(t.target))}e.is=i})(Pe||(Pe={}));var De;(function(e){function n(r,t){return{range:r,parent:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.range)&&(t.parent===void 0||e.is(t.parent))}e.is=i})(De||(De={}));var Me;(function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"})(Me||(Me={}));var Ce;(function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"})(Ce||(Ce={}));var ye;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&(r.resultId===void 0||typeof r.resultId=="string")&&Array.isArray(r.data)&&(r.data.length===0||typeof r.data[0]=="number")}e.is=n})(ye||(ye={}));var Fe;(function(e){function n(r,t){return{range:r,text:t}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&a.string(t.text)}e.is=i})(Fe||(Fe={}));var je;(function(e){function n(r,t,o){return{range:r,variableName:t,caseSensitiveLookup:o}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&a.boolean(t.caseSensitiveLookup)&&(a.string(t.variableName)||t.variableName===void 0)}e.is=i})(je||(je={}));var Ne;(function(e){function n(r,t){return{range:r,expression:t}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&(a.string(t.expression)||t.expression===void 0)}e.is=i})(Ne||(Ne={}));var Oe;(function(e){function n(r,t){return{frameId:r,stoppedLocation:t}}e.create=n;function i(r){const t=r;return a.defined(t)&&h.is(r.stoppedLocation)}e.is=i})(Oe||(Oe={}));var G;(function(e){e.Type=1,e.Parameter=2;function n(i){return i===1||i===2}e.is=n})(G||(G={}));var J;(function(e){function n(r){return{value:r}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&(t.tooltip===void 0||a.string(t.tooltip)||P.is(t.tooltip))&&(t.location===void 0||C.is(t.location))&&(t.command===void 0||I.is(t.command))}e.is=i})(J||(J={}));var Se;(function(e){function n(r,t,o){const s={position:r,label:t};return o!==void 0&&(s.kind=o),s}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&w.is(t.position)&&(a.string(t.label)||a.typedArray(t.label,J.is))&&(t.kind===void 0||G.is(t.kind))&&t.textEdits===void 0||a.typedArray(t.textEdits,E.is)&&(t.tooltip===void 0||a.string(t.tooltip)||P.is(t.tooltip))&&(t.paddingLeft===void 0||a.boolean(t.paddingLeft))&&(t.paddingRight===void 0||a.boolean(t.paddingRight))}e.is=i})(Se||(Se={}));var Ue;(function(e){function n(i){return{kind:"snippet",value:i}}e.createSnippet=n})(Ue||(Ue={}));var Ve;(function(e){function n(i,r,t,o){return{insertText:i,filterText:r,range:t,command:o}}e.create=n})(Ve||(Ve={}));var We;(function(e){function n(i){return{items:i}}e.create=n})(We||(We={}));var He;(function(e){e.Invoked=0,e.Automatic=1})(He||(He={}));var Xe;(function(e){function n(i,r){return{range:i,text:r}}e.create=n})(Xe||(Xe={}));var $e;(function(e){function n(i,r){return{triggerKind:i,selectedCompletionInfo:r}}e.create=n})($e||($e={}));var ze;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&O.is(r.uri)&&a.string(r.name)}e.is=n})(ze||(ze={}));var Be;(function(e){function n(o,s,u,f){return new ct(o,s,u,f)}e.create=n;function i(o){let s=o;return!!(a.defined(s)&&a.string(s.uri)&&(a.undefined(s.languageId)||a.string(s.languageId))&&a.uinteger(s.lineCount)&&a.func(s.getText)&&a.func(s.positionAt)&&a.func(s.offsetAt))}e.is=i;function r(o,s){let u=o.getText(),f=t(s,(g,_)=>{let b=g.range.start.line-_.range.start.line;return b===0?g.range.start.character-_.range.start.character:b}),c=u.length;for(let g=f.length-1;g>=0;g--){let _=f[g],b=o.offsetAt(_.range.start),l=o.offsetAt(_.range.end);if(l<=c)u=u.substring(0,b)+_.newText+u.substring(l,u.length);else throw new Error("Overlapping edit");c=b}return u}e.applyEdits=r;function t(o,s){if(o.length<=1)return o;const u=o.length/2|0,f=o.slice(0,u),c=o.slice(u);t(f,s),t(c,s);let g=0,_=0,b=0;for(;g0&&e.push(n.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let n=this.getLineOffsets(),i=0,r=n.length;if(r===0)return w.create(0,e);for(;ie?r=o:i=o+1}let t=i-1;return w.create(t,e-n[t])}offsetAt(e){let n=this.getLineOffsets();if(e.line>=n.length)return this._content.length;if(e.line<0)return 0;let i=n[e.line],r=e.line+1"u"}e.undefined=r;function t(l){return l===!0||l===!1}e.boolean=t;function o(l){return n.call(l)==="[object String]"}e.string=o;function s(l){return n.call(l)==="[object Number]"}e.number=s;function u(l,N,et){return n.call(l)==="[object Number]"&&N<=l&&l<=et}e.numberRange=u;function f(l){return n.call(l)==="[object Number]"&&-2147483648<=l&&l<=2147483647}e.integer=f;function c(l){return n.call(l)==="[object Number]"&&0<=l&&l<=2147483647}e.uinteger=c;function g(l){return n.call(l)==="[object Function]"}e.func=g;function _(l){return l!==null&&typeof l=="object"}e.objectLiteral=_;function b(l,N){return Array.isArray(l)&&l.every(N)}e.typedArray=b})(a||(a={}));var dt=class{constructor(e,n,i){this._languageId=e,this._worker=n,this._disposables=[],this._listener=Object.create(null);const r=o=>{let s=o.getLanguageId();if(s!==this._languageId)return;let u;this._listener[o.uri.toString()]=o.onDidChangeContent(()=>{window.clearTimeout(u),u=window.setTimeout(()=>this._doValidate(o.uri,s),500)}),this._doValidate(o.uri,s)},t=o=>{d.editor.setModelMarkers(o,this._languageId,[]);let s=o.uri.toString(),u=this._listener[s];u&&(u.dispose(),delete this._listener[s])};this._disposables.push(d.editor.onDidCreateModel(r)),this._disposables.push(d.editor.onWillDisposeModel(t)),this._disposables.push(d.editor.onDidChangeModelLanguage(o=>{t(o.model),r(o.model)})),this._disposables.push(i(o=>{d.editor.getModels().forEach(s=>{s.getLanguageId()===this._languageId&&(t(s),r(s))})})),this._disposables.push({dispose:()=>{d.editor.getModels().forEach(t);for(let o in this._listener)this._listener[o].dispose()}}),d.editor.getModels().forEach(r)}dispose(){this._disposables.forEach(e=>e&&e.dispose()),this._disposables.length=0}_doValidate(e,n){this._worker(e).then(i=>i.doValidation(e.toString())).then(i=>{const r=i.map(o=>ft(e,o));let t=d.editor.getModel(e);t&&t.getLanguageId()===n&&d.editor.setModelMarkers(t,n,r)}).then(void 0,i=>{console.error(i)})}};function lt(e){switch(e){case x.Error:return d.MarkerSeverity.Error;case x.Warning:return d.MarkerSeverity.Warning;case x.Information:return d.MarkerSeverity.Info;case x.Hint:return d.MarkerSeverity.Hint;default:return d.MarkerSeverity.Info}}function ft(e,n){let i=typeof n.code=="number"?String(n.code):n.code;return{severity:lt(n.severity),startLineNumber:n.range.start.line+1,startColumn:n.range.start.character+1,endLineNumber:n.range.end.line+1,endColumn:n.range.end.character+1,message:n.message,code:i,source:n.source}}var gt=class{constructor(e,n){this._worker=e,this._triggerCharacters=n}get triggerCharacters(){return this._triggerCharacters}provideCompletionItems(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.doComplete(t.toString(),k(n))).then(o=>{if(!o)return;const s=e.getWordUntilPosition(n),u=new d.Range(n.lineNumber,s.startColumn,n.lineNumber,s.endColumn),f=o.items.map(c=>{const g={label:c.label,insertText:c.insertText||c.label,sortText:c.sortText,filterText:c.filterText,documentation:c.documentation,detail:c.detail,command:pt(c.command),range:u,kind:vt(c.kind)};return c.textEdit&&(ht(c.textEdit)?g.range={insert:m(c.textEdit.insert),replace:m(c.textEdit.replace)}:g.range=m(c.textEdit.range),g.insertText=c.textEdit.newText),c.additionalTextEdits&&(g.additionalTextEdits=c.additionalTextEdits.map(D)),c.insertTextFormat===Q.Snippet&&(g.insertTextRules=d.languages.CompletionItemInsertTextRule.InsertAsSnippet),g});return{isIncomplete:o.isIncomplete,suggestions:f}})}};function k(e){if(e)return{character:e.column-1,line:e.lineNumber-1}}function Ge(e){if(e)return{start:{line:e.startLineNumber-1,character:e.startColumn-1},end:{line:e.endLineNumber-1,character:e.endColumn-1}}}function m(e){if(e)return new d.Range(e.start.line+1,e.start.character+1,e.end.line+1,e.end.character+1)}function ht(e){return typeof e.insert<"u"&&typeof e.replace<"u"}function vt(e){const n=d.languages.CompletionItemKind;switch(e){case v.Text:return n.Text;case v.Method:return n.Method;case v.Function:return n.Function;case v.Constructor:return n.Constructor;case v.Field:return n.Field;case v.Variable:return n.Variable;case v.Class:return n.Class;case v.Interface:return n.Interface;case v.Module:return n.Module;case v.Property:return n.Property;case v.Unit:return n.Unit;case v.Value:return n.Value;case v.Enum:return n.Enum;case v.Keyword:return n.Keyword;case v.Snippet:return n.Snippet;case v.Color:return n.Color;case v.File:return n.File;case v.Reference:return n.Reference}return n.Property}function D(e){if(e)return{range:m(e.range),text:e.newText}}function pt(e){return e&&e.command==="editor.action.triggerSuggest"?{id:e.command,title:e.title,arguments:e.arguments}:void 0}var mt=class{constructor(e){this._worker=e}provideHover(e,n,i){let r=e.uri;return this._worker(r).then(t=>t.doHover(r.toString(),k(n))).then(t=>{if(t)return{range:m(t.range),contents:bt(t.contents)}})}};function _t(e){return e&&typeof e=="object"&&typeof e.kind=="string"}function qe(e){return typeof e=="string"?{value:e}:_t(e)?e.kind==="plaintext"?{value:e.value.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}:{value:e.value}:{value:"```"+e.language+` -`+e.value+"\n```\n"}}function bt(e){if(e)return Array.isArray(e)?e.map(qe):[qe(e)]}var wt=class{constructor(e){this._worker=e}provideDocumentHighlights(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.findDocumentHighlights(r.toString(),k(n))).then(t=>{if(t)return t.map(o=>({range:m(o.range),kind:kt(o.kind)}))})}};function kt(e){switch(e){case R.Read:return d.languages.DocumentHighlightKind.Read;case R.Write:return d.languages.DocumentHighlightKind.Write;case R.Text:return d.languages.DocumentHighlightKind.Text}return d.languages.DocumentHighlightKind.Text}var xt=class{constructor(e){this._worker=e}provideDefinition(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.findDefinition(r.toString(),k(n))).then(t=>{if(t)return[Je(t)]})}};function Je(e){return{uri:d.Uri.parse(e.uri),range:m(e.range)}}var It=class{constructor(e){this._worker=e}provideReferences(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.findReferences(t.toString(),k(n))).then(o=>{if(o)return o.map(Je)})}},Et=class{constructor(e){this._worker=e}provideRenameEdits(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.doRename(t.toString(),k(n),i)).then(o=>Lt(o))}};function Lt(e){if(!e||!e.changes)return;let n=[];for(let i in e.changes){const r=d.Uri.parse(i);for(let t of e.changes[i])n.push({resource:r,versionId:void 0,textEdit:{range:m(t.range),text:t.newText}})}return{edits:n}}var At=class{constructor(e){this._worker=e}provideDocumentSymbols(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentSymbols(i.toString())).then(r=>{if(r)return r.map(t=>Rt(t)?Ye(t):{name:t.name,detail:"",containerName:t.containerName,kind:Ze(t.kind),range:m(t.location.range),selectionRange:m(t.location.range),tags:[]})})}};function Rt(e){return"children"in e}function Ye(e){return{name:e.name,detail:e.detail??"",kind:Ze(e.kind),range:m(e.range),selectionRange:m(e.selectionRange),tags:e.tags??[],children:(e.children??[]).map(n=>Ye(n))}}function Ze(e){let n=d.languages.SymbolKind;switch(e){case p.File:return n.File;case p.Module:return n.Module;case p.Namespace:return n.Namespace;case p.Package:return n.Package;case p.Class:return n.Class;case p.Method:return n.Method;case p.Property:return n.Property;case p.Field:return n.Field;case p.Constructor:return n.Constructor;case p.Enum:return n.Enum;case p.Interface:return n.Interface;case p.Function:return n.Function;case p.Variable:return n.Variable;case p.Constant:return n.Constant;case p.String:return n.String;case p.Number:return n.Number;case p.Boolean:return n.Boolean;case p.Array:return n.Array}return n.Function}var Ot=class{constructor(e){this._worker=e}provideLinks(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentLinks(i.toString())).then(r=>{if(r)return{links:r.map(t=>({range:m(t.range),url:t.target}))}})}},Pt=class{constructor(e){this._worker=e}provideDocumentFormattingEdits(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.format(r.toString(),null,Te(n)).then(o=>{if(!(!o||o.length===0))return o.map(D)}))}},Dt=class{constructor(e){this._worker=e,this.canFormatMultipleRanges=!1}provideDocumentRangeFormattingEdits(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.format(t.toString(),Ge(n),Te(i)).then(s=>{if(!(!s||s.length===0))return s.map(D)}))}};function Te(e){return{tabSize:e.tabSize,insertSpaces:e.insertSpaces}}var Mt=class{constructor(e){this._worker=e}provideDocumentColors(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentColors(i.toString())).then(r=>{if(r)return r.map(t=>({color:t.color,range:m(t.range)}))})}provideColorPresentations(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getColorPresentations(r.toString(),n.color,Ge(n.range))).then(t=>{if(t)return t.map(o=>{let s={label:o.label};return o.textEdit&&(s.textEdit=D(o.textEdit)),o.additionalTextEdits&&(s.additionalTextEdits=o.additionalTextEdits.map(D)),s})})}},Ct=class{constructor(e){this._worker=e}provideFoldingRanges(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getFoldingRanges(r.toString(),n)).then(t=>{if(t)return t.map(o=>{const s={start:o.startLine+1,end:o.endLine+1};return typeof o.kind<"u"&&(s.kind=yt(o.kind)),s})})}};function yt(e){switch(e){case A.Comment:return d.languages.FoldingRangeKind.Comment;case A.Imports:return d.languages.FoldingRangeKind.Imports;case A.Region:return d.languages.FoldingRangeKind.Region}}var Ft=class{constructor(e){this._worker=e}provideSelectionRanges(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getSelectionRanges(r.toString(),n.map(k))).then(t=>{if(t)return t.map(o=>{const s=[];for(;o;)s.push({range:m(o.range)}),o=o.parent;return s})})}};function St(e){const n=[],i=[],r=new ut(e);n.push(r);const t=(...s)=>r.getLanguageServiceWorker(...s);function o(){const{languageId:s,modeConfiguration:u}=e;Ke(i),u.completionItems&&i.push(d.languages.registerCompletionItemProvider(s,new gt(t,["/","-",":"]))),u.hovers&&i.push(d.languages.registerHoverProvider(s,new mt(t))),u.documentHighlights&&i.push(d.languages.registerDocumentHighlightProvider(s,new wt(t))),u.definitions&&i.push(d.languages.registerDefinitionProvider(s,new xt(t))),u.references&&i.push(d.languages.registerReferenceProvider(s,new It(t))),u.documentSymbols&&i.push(d.languages.registerDocumentSymbolProvider(s,new At(t))),u.rename&&i.push(d.languages.registerRenameProvider(s,new Et(t))),u.colors&&i.push(d.languages.registerColorProvider(s,new Mt(t))),u.foldingRanges&&i.push(d.languages.registerFoldingRangeProvider(s,new Ct(t))),u.diagnostics&&i.push(new dt(s,t,e.onDidChange)),u.selectionRanges&&i.push(d.languages.registerSelectionRangeProvider(s,new Ft(t))),u.documentFormattingEdits&&i.push(d.languages.registerDocumentFormattingEditProvider(s,new Pt(t))),u.documentRangeFormattingEdits&&i.push(d.languages.registerDocumentRangeFormattingEditProvider(s,new Dt(t)))}return o(),n.push(Qe(i)),Qe(n)}function Qe(e){return{dispose:()=>Ke(e)}}function Ke(e){for(;e.length;)e.pop().dispose()}export{gt as CompletionAdapter,xt as DefinitionAdapter,dt as DiagnosticsAdapter,Mt as DocumentColorAdapter,Pt as DocumentFormattingEditProvider,wt as DocumentHighlightAdapter,Ot as DocumentLinkAdapter,Dt as DocumentRangeFormattingEditProvider,At as DocumentSymbolAdapter,Ct as FoldingRangeAdapter,mt as HoverAdapter,It as ReferenceAdapter,Et as RenameAdapter,Ft as SelectionRangeAdapter,ut as WorkerManager,k as fromPosition,Ge as fromRange,St as setupMode,m as toRange,D as toTextEdit}; diff --git a/app/dubbo-ui/dist/admin/assets/cypher-5YIL2BCq.js b/app/dubbo-ui/dist/admin/assets/cypher-5YIL2BCq.js deleted file mode 100644 index cc9d33651..000000000 --- a/app/dubbo-ui/dist/admin/assets/cypher-5YIL2BCq.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}]},i={defaultToken:"",tokenPostfix:".cypher",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.bracket"},{open:"(",close:")",token:"delimiter.parenthesis"}],keywords:["ALL","AND","AS","ASC","ASCENDING","BY","CALL","CASE","CONTAINS","CREATE","DELETE","DESC","DESCENDING","DETACH","DISTINCT","ELSE","END","ENDS","EXISTS","IN","IS","LIMIT","MANDATORY","MATCH","MERGE","NOT","ON","ON","OPTIONAL","OR","ORDER","REMOVE","RETURN","SET","SKIP","STARTS","THEN","UNION","UNWIND","WHEN","WHERE","WITH","XOR","YIELD"],builtinLiterals:["true","TRUE","false","FALSE","null","NULL"],builtinFunctions:["abs","acos","asin","atan","atan2","avg","ceil","coalesce","collect","cos","cot","count","degrees","e","endNode","exists","exp","floor","head","id","keys","labels","last","left","length","log","log10","lTrim","max","min","nodes","percentileCont","percentileDisc","pi","properties","radians","rand","range","relationships","replace","reverse","right","round","rTrim","sign","sin","size","split","sqrt","startNode","stDev","stDevP","substring","sum","tail","tan","timestamp","toBoolean","toFloat","toInteger","toLower","toString","toUpper","trim","type"],operators:["+","-","*","/","%","^","=","<>","<",">","<=",">=","->","<-","-->","<--"],escapes:/\\(?:[tbnrf\\"'`]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+/,octaldigits:/[0-7]+/,hexdigits:/[0-9a-fA-F]+/,tokenizer:{root:[[/[{}[\]()]/,"@brackets"],{include:"common"}],common:[{include:"@whitespace"},{include:"@numbers"},{include:"@strings"},[/:[a-zA-Z_][\w]*/,"type.identifier"],[/[a-zA-Z_][\w]*(?=\()/,{cases:{"@builtinFunctions":"predefined.function"}}],[/[a-zA-Z_$][\w$]*/,{cases:{"@keywords":"keyword","@builtinLiterals":"predefined.literal","@default":"identifier"}}],[/`/,"identifier.escape","@identifierBacktick"],[/[;,.:|]/,"delimiter"],[/[<>=%+\-*/^]+/,{cases:{"@operators":"delimiter","@default":""}}]],numbers:[[/-?(@digits)[eE](-?(@digits))?/,"number.float"],[/-?(@digits)?\.(@digits)([eE]-?(@digits))?/,"number.float"],[/-?0x(@hexdigits)/,"number.hex"],[/-?0(@octaldigits)/,"number.octal"],[/-?(@digits)/,"number"]],strings:[[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string","@stringDouble"],[/'/,"string","@stringSingle"]],whitespace:[[/[ \t\r\n]+/,"white"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/\/\/.*/,"comment"],[/[^/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[/*]/,"comment"]],stringDouble:[[/[^\\"]+/,"string"],[/@escapes/,"string"],[/\\./,"string.invalid"],[/"/,"string","@pop"]],stringSingle:[[/[^\\']+/,"string"],[/@escapes/,"string"],[/\\./,"string.invalid"],[/'/,"string","@pop"]],identifierBacktick:[[/[^\\`]+/,"identifier.escape"],[/@escapes/,"identifier.escape"],[/\\./,"identifier.escape.invalid"],[/`/,"identifier.escape","@pop"]]}};export{e as conf,i as language}; diff --git a/app/dubbo-ui/dist/admin/assets/dart-qjFgolkP.js b/app/dubbo-ui/dist/admin/assets/dart-qjFgolkP.js deleted file mode 100644 index c1b8b7a97..000000000 --- a/app/dubbo-ui/dist/admin/assets/dart-qjFgolkP.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string"]},{open:"`",close:"`",notIn:["string","comment"]},{open:"/**",close:" */",notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:"(",close:")"},{open:'"',close:'"'},{open:"`",close:"`"}],folding:{markers:{start:/^\s*\s*#?region\b/,end:/^\s*\s*#?endregion\b/}}},n={defaultToken:"invalid",tokenPostfix:".dart",keywords:["abstract","dynamic","implements","show","as","else","import","static","assert","enum","in","super","async","export","interface","switch","await","extends","is","sync","break","external","library","this","case","factory","mixin","throw","catch","false","new","true","class","final","null","try","const","finally","on","typedef","continue","for","operator","var","covariant","Function","part","void","default","get","rethrow","while","deferred","hide","return","with","do","if","set","yield"],typeKeywords:["int","double","String","bool"],operators:["+","-","*","/","~/","%","++","--","==","!=",">","<",">=","<=","=","-=","/=","%=",">>=","^=","+=","*=","~/=","<<=","&=","!=","||","&&","&","|","^","~","<<",">>","!",">>>","??","?",":","|="],symbols:/[=>](?!@symbols)/,"@brackets"],[/!(?=([^=]|$))/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/(@digits)[eE]([\-+]?(@digits))?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,"number.float"],[/0[xX](@hexdigits)n?/,"number.hex"],[/0[oO]?(@octaldigits)n?/,"number.octal"],[/0[bB](@binarydigits)n?/,"number.binary"],[/(@digits)n?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string_double"],[/'/,"string","@string_single"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@jsdoc"],[/\/\*/,"comment","@comment"],[/\/\/\/.*$/,"comment.doc"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],jsdoc:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,["regexp.escape.control","regexp.escape.control","regexp.escape.control"]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,["regexp.escape.control",{token:"regexp.escape.control",next:"@regexrange"}]],[/(\()(\?:|\?=|\?!)/,["regexp.escape.control","regexp.escape.control"]],[/[()]/,"regexp.escape.control"],[/@regexpctl/,"regexp.escape.control"],[/[^\\\/]/,"regexp"],[/@regexpesc/,"regexp.escape"],[/\\\./,"regexp.invalid"],[/(\/)([gimsuy]*)/,[{token:"regexp",bracket:"@close",next:"@pop"},"keyword.other"]]],regexrange:[[/-/,"regexp.escape.control"],[/\^/,"regexp.invalid"],[/@regexpesc/,"regexp.escape"],[/[^\]]/,"regexp"],[/\]/,{token:"regexp.escape.control",next:"@pop",bracket:"@close"}]],string_double:[[/[^\\"\$]+/,"string"],[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"],[/\$\w+/,"identifier"]],string_single:[[/[^\\'\$]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/'/,"string","@pop"],[/\$\w+/,"identifier"]]}};export{e as conf,n as language}; diff --git a/app/dubbo-ui/dist/admin/assets/detail-ZfcGZsJx.js b/app/dubbo-ui/dist/admin/assets/detail-ZfcGZsJx.js deleted file mode 100644 index df9699c04..000000000 --- a/app/dubbo-ui/dist/admin/assets/detail-ZfcGZsJx.js +++ /dev/null @@ -1 +0,0 @@ -import{u as z}from"./index-Va7nxJVK.js";import{d as H,a as U,u as X,r as L,k as Z,Y as x,W as D,c,b as o,w as t,e as n,o as u,j as y,f as r,t as a,n as b,$ as h,G as k,Q as P,J as V,K as A,m as ee,_ as oe}from"./index-hmLAZQYT.js";import{g as te}from"./instance-9-P3Wy8N.js";import{f as j}from"./DateUtil-BI1mUH_z.js";import"./request-8jI_GZey.js";const le={class:"__container_instance_detail"},ae={class:"white_space"},se={class:"white_space"},re={class:"white_space"},pe=H({__name:"detail",setup(de){const S=U(),E=X(),W=L({}),{appContext:{config:{globalProperties:M}}}=Z();x("20");const e=L({});D(async()=>{const{appName:l,pathId:p}=S.params;let s={instanceName:l,instanceIP:p};W.detail=await te(s),Object.assign(e,W.detail.data)});const Y=l=>{console.log("appName",l),E.push({path:"/resources/applications/detail/"+l})},F=z().toClipboard;function f(l){ee.success(M.$t("messageDomain.success.copy")),F(l)}const $=l=>l?"开启":"关闭";return(l,p)=>{const s=n("a-descriptions-item"),_=n("a-typography-paragraph"),C=n("a-descriptions"),m=n("a-card"),w=n("a-col"),G=n("a-row"),v=n("a-typography-link"),J=n("a-space"),K=n("a-tag"),Q=n("a-card-grid"),q=n("a-flex");return u(),c("div",le,[o(q,null,{default:t(()=>[o(Q,null,{default:t(()=>[o(G,{gutter:10},{default:t(()=>[o(w,{span:12},{default:t(()=>[o(m,{class:"_detail"},{default:t(()=>[o(C,{class:"description-column",column:1},{default:t(()=>[o(s,{label:l.$t("instanceDomain.instanceName"),labelStyle:{fontWeight:"bold"}},{default:t(()=>{var d;return[y("p",{onClick:p[0]||(p[0]=i=>{var g;return f((g=b(S).params)==null?void 0:g.appName)}),class:"description-item-content with-card"},[r(a((d=b(S).params)==null?void 0:d.appName)+" ",1),o(b(h))])]}),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.creationTime_k8s"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(_,null,{default:t(()=>[r(a(b(j)(e==null?void 0:e.createTime)),1)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.deployState"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[(e==null?void 0:e.deployState)==="Running"?(u(),k(_,{key:0,type:"success"},{default:t(()=>[r(" Running ")]),_:1})):(u(),k(_,{key:1,type:"danger"},{default:t(()=>[r(" Stop")]),_:1}))]),_:1},8,["label"])]),_:1})]),_:1})]),_:1}),o(w,{span:12},{default:t(()=>[o(m,{class:"_detail",style:{height:"100%"}},{default:t(()=>[o(C,{class:"description-column",column:1},{default:t(()=>[o(s,{label:l.$t("instanceDomain.startTime_k8s"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(_,null,{default:t(()=>[r(a(b(j)(e==null?void 0:e.readyTime)),1)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.registerState"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(_,{type:(e==null?void 0:e.registerState)==="Registed"?"success":"danger"},{default:t(()=>[r(a(e==null?void 0:e.registerState),1)]),_:1},8,["type"])]),_:1},8,["label"])]),_:1})]),_:1})]),_:1})]),_:1}),o(m,{style:{"margin-top":"10px"},class:"_detail"},{default:t(()=>[o(C,{class:"description-column",column:1},{default:t(()=>[o(s,{label:l.$t("instanceDomain.instanceIP"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[y("p",{onClick:p[1]||(p[1]=d=>f(e==null?void 0:e.ip)),class:"description-item-content with-card"},[r(a(e==null?void 0:e.ip)+" ",1),o(b(h))])]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.deployCluster"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(_,null,{default:t(()=>[r(a(e==null?void 0:e.deployCluster),1)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.dubboPort"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[e!=null&&e.rpcPort?(u(),c("p",{key:0,onClick:p[2]||(p[2]=d=>f(e==null?void 0:e.rpcPort)),class:"description-item-content with-card"},[r(a(e==null?void 0:e.rpcPort)+" ",1),o(b(h))])):P("",!0)]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.registerCluster"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(J,null,{default:t(()=>[(u(!0),c(V,null,A(e==null?void 0:e.registerClusters,d=>(u(),k(v,null,{default:t(()=>[r(a(d),1)]),_:2},1024))),256))]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.whichApplication"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(v,{onClick:p[3]||(p[3]=d=>Y(e==null?void 0:e.appName))},{default:t(()=>[r(a(e==null?void 0:e.appName),1)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.node"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[e!=null&&e.node?(u(),c("p",{key:0,onClick:p[4]||(p[4]=d=>f(e==null?void 0:e.node)),class:"description-item-content with-card"},[r(a(e==null?void 0:e.node)+" ",1),o(b(h))])):P("",!0)]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.owningWorkload_k8s"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(_,null,{default:t(()=>[r(a(e==null?void 0:e.workloadName),1)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.instanceImage_k8s"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(m,{class:"description-item-card"},{default:t(()=>[e!=null&&e.image?(u(),c("p",{key:0,onClick:p[5]||(p[5]=d=>f(e==null?void 0:e.image)),class:"description-item-content with-card"},[r(a(e==null?void 0:e.image)+" ",1),o(b(h))])):P("",!0)]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.instanceLabel"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(m,{class:"description-item-card"},{default:t(()=>[(u(!0),c(V,null,A(e==null?void 0:e.labels,(d,i)=>(u(),k(K,null,{default:t(()=>[r(a(i)+" : "+a(d),1)]),_:2},1024))),256))]),_:1})]),_:1},8,["label"]),o(s,{label:l.$t("instanceDomain.healthExamination_k8s"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(m,{class:"description-item-card"},{default:t(()=>{var d,i,g,N,I,R,T,O,B;return[y("p",ae," 启动探针(StartupProbe):"+a($((d=e==null?void 0:e.probes)==null?void 0:d.startupProbe.open))+" 类型: "+a((i=e==null?void 0:e.probes)==null?void 0:i.startupProbe.type)+" 端口:"+a((g=e==null?void 0:e.probes)==null?void 0:g.startupProbe.port),1),y("p",se," 就绪探针(ReadinessProbe):"+a($((N=e==null?void 0:e.probes)==null?void 0:N.readinessProbe.open))+" 类型: "+a((I=e==null?void 0:e.probes)==null?void 0:I.readinessProbe.type)+" 端口:"+a((R=e==null?void 0:e.probes)==null?void 0:R.readinessProbe.port),1),y("p",re," 存活探针(LivenessProbe):"+a($((T=e==null?void 0:e.probes)==null?void 0:T.livenessProbe.open))+" 类型: "+a((O=e==null?void 0:e.probes)==null?void 0:O.livenessProbe.type)+" 端口:"+a((B=e==null?void 0:e.probes)==null?void 0:B.livenessProbe.port),1)]}),_:1})]),_:1},8,["label"])]),_:1})]),_:1})]),_:1})]),_:1})])}}}),ce=oe(pe,[["__scopeId","data-v-fb65b5f4"]]);export{ce as default}; diff --git a/app/dubbo-ui/dist/admin/assets/detail-c9-keEBq.js b/app/dubbo-ui/dist/admin/assets/detail-c9-keEBq.js deleted file mode 100644 index 10e66268f..000000000 --- a/app/dubbo-ui/dist/admin/assets/detail-c9-keEBq.js +++ /dev/null @@ -1 +0,0 @@ -import{d as B,a as O,r as I,k as T,Y as V,W as A,c as s,b as a,w as e,e as c,o,J as u,K as m,Z as P,G as b,f as S,t as h,n as y,$ as L,m as Y,a0 as $,_ as j}from"./index-hmLAZQYT.js";import{g as E}from"./app-duU6O0cq.js";import{u as F}from"./index-Va7nxJVK.js";import"./request-8jI_GZey.js";const G={class:"__container_app_detail"},J={class:"description-item-content no-card"},K=["onClick"],Z=B({__name:"detail",setup(q){const N=O(),C=I({}),{appContext:{config:{globalProperties:M}}}=T();V("20");let r=I({left:{},right:{},bottom:{}});A(async()=>{var i;let l=(i=N.params)==null?void 0:i.pathId;C.detail=await E({appName:l}),console.log(C.detail);let{appName:w,rpcProtocols:p,dubboVersions:_,dubboPorts:d,serialProtocols:f,appTypes:x,images:k,workloads:D,deployClusters:t,registerClusters:n,registerModes:g}=C.detail.data;r.left={appName:w,appTypes:x,serialProtocols:f},r.right={rpcProtocols:p,dubboPorts:d,dubboVersions:_},r.bottom={images:k,workloads:D,deployClusters:t,registerClusters:n,registerModes:g},console.log(w)});const R=F().toClipboard;function W(l){Y.success(M.$t("messageDomain.success.copy")),R(l)}return(l,w)=>{const p=c("a-descriptions-item"),_=c("a-descriptions"),d=c("a-card"),f=c("a-col"),x=c("a-row"),k=c("a-card-grid"),D=c("a-flex");return o(),s("div",G,[a(D,null,{default:e(()=>[a(k,null,{default:e(()=>[a(x,{gutter:10},{default:e(()=>[a(f,{span:12},{default:e(()=>[a(d,{class:"_detail"},{default:e(()=>[a(_,{class:"description-column",column:1},{default:e(()=>[(o(!0),s(u,null,m(y(r).left,(t,n,g)=>P((o(),b(p,{labelStyle:{fontWeight:"bold",width:"100px"},label:l.$t("applicationDomain."+n)},{default:e(()=>[S(h(typeof t=="object"?t[0]:t),1)]),_:2},1032,["label"])),[[$,!!t]])),256))]),_:1})]),_:1})]),_:1}),a(f,{span:12},{default:e(()=>[a(d,{class:"_detail"},{default:e(()=>[a(_,{class:"description-column",column:1},{default:e(()=>[(o(!0),s(u,null,m(y(r).right,(t,n,g)=>P((o(),b(p,{labelStyle:{fontWeight:"bold",width:"100px"},label:l.$t("applicationDomain."+n)},{default:e(()=>[S(h(t[0]),1)]),_:2},1032,["label"])),[[$,!!t]])),256))]),_:1})]),_:1})]),_:1})]),_:1}),a(d,{style:{"margin-top":"10px"},class:"_detail"},{default:e(()=>[a(_,{class:"description-column",column:1},{default:e(()=>[(o(!0),s(u,null,m(y(r).bottom,(t,n,g)=>P((o(),b(p,{labelStyle:{fontWeight:"bold"},label:l.$t("applicationDomain."+n)},{default:e(()=>[(t==null?void 0:t.length)<3?(o(!0),s(u,{key:0},m(t,i=>(o(),s("p",J,h(i),1))),256)):(o(),b(d,{key:1,class:"description-item-card"},{default:e(()=>[(o(!0),s(u,null,m(t,i=>(o(),s("p",{onClick:z=>W(i.toString()),class:"description-item-content with-card"},[S(h(i)+" ",1),a(y(L))],8,K))),256))]),_:2},1024))]),_:2},1032,["label"])),[[$,!!t]])),256))]),_:1})]),_:1})]),_:1})]),_:1})])}}}),v=j(Z,[["__scopeId","data-v-2ded24e2"]]);export{v as default}; diff --git a/app/dubbo-ui/dist/admin/assets/distribution-6xS25HWj.css b/app/dubbo-ui/dist/admin/assets/distribution-6xS25HWj.css deleted file mode 100644 index b9d9eb0a0..000000000 --- a/app/dubbo-ui/dist/admin/assets/distribution-6xS25HWj.css +++ /dev/null @@ -1 +0,0 @@ -.__container_services_tabs_distribution .service-filter[data-v-549fa778]{margin-bottom:20px}.__container_services_tabs_distribution .service-filter .service-filter-select[data-v-549fa778]{margin-left:10px;width:250px}.__container_services_tabs_distribution .service-filter .service-filter-input[data-v-549fa778]{margin-left:30px;width:300px}.__container_services_tabs_distribution .link[data-v-549fa778]{padding:4px 10px 4px 4px;border-radius:4px;color:var(--70895fcd)}.__container_services_tabs_distribution .link[data-v-549fa778]:hover{cursor:pointer;background:#85838321} diff --git a/app/dubbo-ui/dist/admin/assets/distribution-rzJg55IY.js b/app/dubbo-ui/dist/admin/assets/distribution-rzJg55IY.js deleted file mode 100644 index 35734db2b..000000000 --- a/app/dubbo-ui/dist/admin/assets/distribution-rzJg55IY.js +++ /dev/null @@ -1 +0,0 @@ -import{d as $,v as E,u as F,a as G,k as U,z as g,r as x,F as j,c as f,b as s,w as p,e as d,n as r,P as O,o as v,f as m,j as A,I as z,t as b,Q as h,J,G as L,_ as M}from"./index-hmLAZQYT.js";import{g as Q}from"./service-HiIVI9X0.js";import{f as Y}from"./DateUtil-BI1mUH_z.js";import"./request-8jI_GZey.js";const q={class:"__container_services_tabs_distribution"},H=["onClick"],K=["onClick"],W=$({__name:"distribution",setup(X){E(a=>({"70895fcd":r(O)}));const I=F(),C=G(),{appContext:{config:{globalProperties:S}}}=U(),y=g(""),R=x([{label:"不指定",value:""},{label:"version=1.0.0",value:"version=1.0.0"},{label:"group=group1",value:"group=group1"},{label:"version=1.0.0,group=group1",value:"version=1.0.0,group=group1"}]);g(R[0].value);const N=g("provider"),D=[{title:"应用名",dataIndex:"appName",width:"20%",customCell:(a,e)=>{const t=o.value[e].appName;return e===0||o.value[e-1].appName!==t?{rowSpan:o.value.filter(i=>i.appName===t).length}:{rowSpan:0}}},{title:"实例数",dataIndex:"instanceNum",width:"15%",customRender:({record:a})=>{const e=a.appName;return o.value.filter(l=>l.appName===e).length??0},customCell:(a,e)=>{const t=o.value[e].appName;return e===0||o.value[e-1].appName!==t?{rowSpan:o.value.filter(i=>i.appName===t).length}:{rowSpan:0}}},{title:"实例名",dataIndex:"instanceName",width:"25%",ellipsis:!0},{title:"RPC端口",dataIndex:"rpcPort",width:"8%"},{title:"超时时间",dataIndex:"timeOut",width:"10%"},{title:"重试次数",dataIndex:"retryNum",width:"10%"}],o=g([]),n=x({total:0,pageSize:10,current:1,pageOffset:0,showTotal:a=>S.$t("searchDomain.total")+": "+a+" "+S.$t("searchDomain.unit")}),w=async()=>{var l,i,_;let a={serviceName:(l=C.params)==null?void 0:l.pathId,side:N.value,version:((i=C.params)==null?void 0:i.version)||"",group:((_=C.params)==null?void 0:_.group)||"",pageOffset:n.pageOffset,pageSize:n.pageSize};const{data:{list:e,pageInfo:t}}=await Q(a);o.value=e,n.total=t.Total};w();const k=j.debounce(w,300),P=a=>{n.pageSize=a.pageSize||10,n.current=a.current||1,n.pageOffset=(n.current-1)*n.pageSize,k()};return(a,e)=>{const t=d("a-radio-button"),l=d("a-radio-group"),i=d("a-input-search"),_=d("a-flex"),V=d("a-tag"),B=d("a-table");return v(),f("div",q,[s(_,{vertical:""},{default:p(()=>[s(_,{class:"service-filter"},{default:p(()=>[s(l,{value:N.value,"onUpdate:value":e[0]||(e[0]=u=>N.value=u),"button-style":"solid",onClick:r(k)},{default:p(()=>[s(t,{value:"provider"},{default:p(()=>[m("生产者")]),_:1}),s(t,{value:"consumer"},{default:p(()=>[m("消费者")]),_:1})]),_:1},8,["value","onClick"]),s(i,{value:y.value,"onUpdate:value":e[1]||(e[1]=u=>y.value=u),placeholder:"搜索应用,ip,支持前缀搜索",class:"service-filter-input",onSearch:r(k),"enter-button":""},null,8,["value","onSearch"])]),_:1}),s(B,{columns:D,"data-source":o.value,scroll:{y:"45vh"},pagination:n,onChange:P},{bodyCell:p(({column:u,text:c})=>[u.dataIndex==="appName"?(v(),f("span",{key:0,class:"link",onClick:T=>r(I).push("/resources/applications/detail/"+c)},[A("b",null,[s(r(z),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),m(" "+b(c),1)])],8,H)):h("",!0),u.dataIndex==="instanceName"?(v(),f("span",{key:1,class:"link",onClick:T=>r(I).push("/resources/instances/detail/"+c)},[A("b",null,[s(r(z),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),m(" "+b(c),1)])],8,K)):h("",!0),u.dataIndex==="timeOut"?(v(),f(J,{key:2},[m(b(r(Y)(c)),1)],64)):h("",!0),u.dataIndex==="label"?(v(),L(V,{key:3,color:r(O)},{default:p(()=>[m(b(c),1)]),_:2},1032,["color"])):h("",!0)]),_:1},8,["data-source","pagination"])]),_:1})])}}}),oe=M(W,[["__scopeId","data-v-549fa778"]]);export{oe as default}; diff --git a/app/dubbo-ui/dist/admin/assets/dockerfile-5toe0RAn.js b/app/dubbo-ui/dist/admin/assets/dockerfile-5toe0RAn.js deleted file mode 100644 index 5add7f89e..000000000 --- a/app/dubbo-ui/dist/admin/assets/dockerfile-5toe0RAn.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},o={defaultToken:"",tokenPostfix:".dockerfile",variable:/\${?[\w]+}?/,tokenizer:{root:[{include:"@whitespace"},{include:"@comment"},[/(ONBUILD)(\s+)/,["keyword",""]],[/(ENV)(\s+)([\w]+)/,["keyword","",{token:"variable",next:"@arguments"}]],[/(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|ARG|VOLUME|LABEL|USER|WORKDIR|COPY|CMD|STOPSIGNAL|SHELL|HEALTHCHECK|ENTRYPOINT)/,{token:"keyword",next:"@arguments"}]],arguments:[{include:"@whitespace"},{include:"@strings"},[/(@variable)/,{cases:{"@eos":{token:"variable",next:"@popall"},"@default":"variable"}}],[/\\/,{cases:{"@eos":"","@default":""}}],[/./,{cases:{"@eos":{token:"",next:"@popall"},"@default":""}}]],whitespace:[[/\s+/,{cases:{"@eos":{token:"",next:"@popall"},"@default":""}}]],comment:[[/(^#.*$)/,"comment","@popall"]],strings:[[/\\'$/,"","@popall"],[/\\'/,""],[/'$/,"string","@popall"],[/'/,"string","@stringBody"],[/"$/,"string","@popall"],[/"/,"string","@dblStringBody"]],stringBody:[[/[^\\\$']/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}],[/\\./,"string.escape"],[/'$/,"string","@popall"],[/'/,"string","@pop"],[/(@variable)/,"variable"],[/\\$/,"string"],[/$/,"string","@popall"]],dblStringBody:[[/[^\\\$"]/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}],[/\\./,"string.escape"],[/"$/,"string","@popall"],[/"/,"string","@pop"],[/(@variable)/,"variable"],[/\\$/,"string"],[/$/,"string","@popall"]]}};export{e as conf,o as language}; diff --git a/app/dubbo-ui/dist/admin/assets/ecl-1L3WRmRU.js b/app/dubbo-ui/dist/admin/assets/ecl-1L3WRmRU.js deleted file mode 100644 index 917258a0a..000000000 --- a/app/dubbo-ui/dist/admin/assets/ecl-1L3WRmRU.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}]},o={defaultToken:"",tokenPostfix:".ecl",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],pounds:["append","break","declare","demangle","end","for","getdatatype","if","inmodule","loop","mangle","onwarning","option","set","stored","uniquename"].join("|"),keywords:["__compressed__","after","all","and","any","as","atmost","before","beginc","best","between","case","cluster","compressed","compression","const","counter","csv","default","descend","embed","encoding","encrypt","end","endc","endembed","endmacro","enum","escape","except","exclusive","expire","export","extend","fail","few","fileposition","first","flat","forward","from","full","function","functionmacro","group","grouped","heading","hole","ifblock","import","in","inner","interface","internal","joined","keep","keyed","last","left","limit","linkcounted","literal","little_endian","load","local","locale","lookup","lzw","macro","many","maxcount","maxlength","min skew","module","mofn","multiple","named","namespace","nocase","noroot","noscan","nosort","not","noxpath","of","onfail","only","opt","or","outer","overwrite","packed","partition","penalty","physicallength","pipe","prefetch","quote","record","repeat","retry","return","right","right1","right2","rows","rowset","scan","scope","self","separator","service","shared","skew","skip","smart","soapaction","sql","stable","store","terminator","thor","threshold","timelimit","timeout","token","transform","trim","type","unicodeorder","unordered","unsorted","unstable","update","use","validate","virtual","whole","width","wild","within","wnotrim","xml","xpath"],functions:["abs","acos","aggregate","allnodes","apply","ascii","asin","assert","asstring","atan","atan2","ave","build","buildindex","case","catch","choose","choosen","choosesets","clustersize","combine","correlation","cos","cosh","count","covariance","cron","dataset","dedup","define","denormalize","dictionary","distribute","distributed","distribution","ebcdic","enth","error","evaluate","event","eventextra","eventname","exists","exp","fail","failcode","failmessage","fetch","fromunicode","fromxml","getenv","getisvalid","global","graph","group","hash","hash32","hash64","hashcrc","hashmd5","having","httpcall","httpheader","if","iff","index","intformat","isvalid","iterate","join","keydiff","keypatch","keyunicode","length","library","limit","ln","loadxml","local","log","loop","map","matched","matchlength","matchposition","matchtext","matchunicode","max","merge","mergejoin","min","nofold","nolocal","nonempty","normalize","nothor","notify","output","parallel","parse","pipe","power","preload","process","project","pull","random","range","rank","ranked","realformat","recordof","regexfind","regexreplace","regroup","rejected","rollup","round","roundup","row","rowdiff","sample","sequential","set","sin","sinh","sizeof","soapcall","sort","sorted","sqrt","stepped","stored","sum","table","tan","tanh","thisnode","topn","tounicode","toxml","transfer","transform","trim","truncate","typeof","ungroup","unicodeorder","variance","wait","which","workunit","xmldecode","xmlencode","xmltext","xmlunicode"],typesint:["integer","unsigned"].join("|"),typesnum:["data","qstring","string","unicode","utf8","varstring","varunicode"],typesone:["ascii","big_endian","boolean","data","decimal","ebcdic","grouped","integer","linkcounted","pattern","qstring","real","record","rule","set of","streamed","string","token","udecimal","unicode","unsigned","utf8","varstring","varunicode"].join("|"),operators:["+","-","/",":=","<","<>","=",">","\\","and","in","not","or"],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/[0-9_]*\.[0-9_]+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F_]+/,"number.hex"],[/0[bB][01]+/,"number.hex"],[/[0-9_]+/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\v\f\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/'/,"string","@pop"]]}};export{e as conf,o as language}; diff --git a/app/dubbo-ui/dist/admin/assets/elixir-4vH1gF-H.js b/app/dubbo-ui/dist/admin/assets/elixir-4vH1gF-H.js deleted file mode 100644 index a89389439..000000000 --- a/app/dubbo-ui/dist/admin/assets/elixir-4vH1gF-H.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'"},{open:'"',close:'"'}],autoClosingPairs:[{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["comment"]},{open:'"""',close:'"""'},{open:"`",close:"`",notIn:["string","comment"]},{open:"(",close:")"},{open:"{",close:"}"},{open:"[",close:"]"},{open:"<<",close:">>"}],indentationRules:{increaseIndentPattern:/^\s*(after|else|catch|rescue|fn|[^#]*(do|<\-|\->|\{|\[|\=))\s*$/,decreaseIndentPattern:/^\s*((\}|\])\s*$|(after|else|catch|rescue|end)\b)/}},t={defaultToken:"source",tokenPostfix:".elixir",brackets:[{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"{",close:"}",token:"delimiter.curly"},{open:"<<",close:">>",token:"delimiter.angle.special"}],declarationKeywords:["def","defp","defn","defnp","defguard","defguardp","defmacro","defmacrop","defdelegate","defcallback","defmacrocallback","defmodule","defprotocol","defexception","defimpl","defstruct"],operatorKeywords:["and","in","not","or","when"],namespaceKeywords:["alias","import","require","use"],otherKeywords:["after","case","catch","cond","do","else","end","fn","for","if","quote","raise","receive","rescue","super","throw","try","unless","unquote_splicing","unquote","with"],constants:["true","false","nil"],nameBuiltin:["__MODULE__","__DIR__","__ENV__","__CALLER__","__STACKTRACE__"],operator:/-[->]?|!={0,2}|\*{1,2}|\/|\\\\|&{1,3}|\.\.?|\^(?:\^\^)?|\+\+?|<(?:-|<<|=|>|\|>|~>?)?|=~|={1,3}|>(?:=|>>)?|\|~>|\|>|\|{1,3}|~>>?|~~~|::/,variableName:/[a-z_][a-zA-Z0-9_]*[?!]?/,atomName:/[a-zA-Z_][a-zA-Z0-9_@]*[?!]?|@specialAtomName|@operator/,specialAtomName:/\.\.\.|<<>>|%\{\}|%|\{\}/,aliasPart:/[A-Z][a-zA-Z0-9_]*/,moduleName:/@aliasPart(?:\.@aliasPart)*/,sigilSymmetricDelimiter:/"""|'''|"|'|\/|\|/,sigilStartDelimiter:/@sigilSymmetricDelimiter|<|\{|\[|\(/,sigilEndDelimiter:/@sigilSymmetricDelimiter|>|\}|\]|\)/,sigilModifiers:/[a-zA-Z0-9]*/,decimal:/\d(?:_?\d)*/,hex:/[0-9a-fA-F](_?[0-9a-fA-F])*/,octal:/[0-7](_?[0-7])*/,binary:/[01](_?[01])*/,escape:/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}|\\./,tokenizer:{root:[{include:"@whitespace"},{include:"@comments"},{include:"@keywordsShorthand"},{include:"@numbers"},{include:"@identifiers"},{include:"@strings"},{include:"@atoms"},{include:"@sigils"},{include:"@attributes"},{include:"@symbols"}],whitespace:[[/\s+/,"white"]],comments:[[/(#)(.*)/,["comment.punctuation","comment"]]],keywordsShorthand:[[/(@atomName)(:)(\s+)/,["constant","constant.punctuation","white"]],[/"(?=([^"]|#\{.*?\}|\\")*":)/,{token:"constant.delimiter",next:"@doubleQuotedStringKeyword"}],[/'(?=([^']|#\{.*?\}|\\')*':)/,{token:"constant.delimiter",next:"@singleQuotedStringKeyword"}]],doubleQuotedStringKeyword:[[/":/,{token:"constant.delimiter",next:"@pop"}],{include:"@stringConstantContentInterpol"}],singleQuotedStringKeyword:[[/':/,{token:"constant.delimiter",next:"@pop"}],{include:"@stringConstantContentInterpol"}],numbers:[[/0b@binary/,"number.binary"],[/0o@octal/,"number.octal"],[/0x@hex/,"number.hex"],[/@decimal\.@decimal([eE]-?@decimal)?/,"number.float"],[/@decimal/,"number"]],identifiers:[[/\b(defp?|defnp?|defmacrop?|defguardp?|defdelegate)(\s+)(@variableName)(?!\s+@operator)/,["keyword.declaration","white",{cases:{unquote:"keyword","@default":"function"}}]],[/(@variableName)(?=\s*\.?\s*\()/,{cases:{"@declarationKeywords":"keyword.declaration","@namespaceKeywords":"keyword","@otherKeywords":"keyword","@default":"function.call"}}],[/(@moduleName)(\s*)(\.)(\s*)(@variableName)/,["type.identifier","white","operator","white","function.call"]],[/(:)(@atomName)(\s*)(\.)(\s*)(@variableName)/,["constant.punctuation","constant","white","operator","white","function.call"]],[/(\|>)(\s*)(@variableName)/,["operator","white",{cases:{"@otherKeywords":"keyword","@default":"function.call"}}]],[/(&)(\s*)(@variableName)/,["operator","white","function.call"]],[/@variableName/,{cases:{"@declarationKeywords":"keyword.declaration","@operatorKeywords":"keyword.operator","@namespaceKeywords":"keyword","@otherKeywords":"keyword","@constants":"constant.language","@nameBuiltin":"variable.language","_.*":"comment.unused","@default":"identifier"}}],[/@moduleName/,"type.identifier"]],strings:[[/"""/,{token:"string.delimiter",next:"@doubleQuotedHeredoc"}],[/'''/,{token:"string.delimiter",next:"@singleQuotedHeredoc"}],[/"/,{token:"string.delimiter",next:"@doubleQuotedString"}],[/'/,{token:"string.delimiter",next:"@singleQuotedString"}]],doubleQuotedHeredoc:[[/"""/,{token:"string.delimiter",next:"@pop"}],{include:"@stringContentInterpol"}],singleQuotedHeredoc:[[/'''/,{token:"string.delimiter",next:"@pop"}],{include:"@stringContentInterpol"}],doubleQuotedString:[[/"/,{token:"string.delimiter",next:"@pop"}],{include:"@stringContentInterpol"}],singleQuotedString:[[/'/,{token:"string.delimiter",next:"@pop"}],{include:"@stringContentInterpol"}],atoms:[[/(:)(@atomName)/,["constant.punctuation","constant"]],[/:"/,{token:"constant.delimiter",next:"@doubleQuotedStringAtom"}],[/:'/,{token:"constant.delimiter",next:"@singleQuotedStringAtom"}]],doubleQuotedStringAtom:[[/"/,{token:"constant.delimiter",next:"@pop"}],{include:"@stringConstantContentInterpol"}],singleQuotedStringAtom:[[/'/,{token:"constant.delimiter",next:"@pop"}],{include:"@stringConstantContentInterpol"}],sigils:[[/~[a-z]@sigilStartDelimiter/,{token:"@rematch",next:"@sigil.interpol"}],[/~([A-Z]+)@sigilStartDelimiter/,{token:"@rematch",next:"@sigil.noInterpol"}]],sigil:[[/~([a-z]|[A-Z]+)\{/,{token:"@rematch",switchTo:"@sigilStart.$S2.$1.{.}"}],[/~([a-z]|[A-Z]+)\[/,{token:"@rematch",switchTo:"@sigilStart.$S2.$1.[.]"}],[/~([a-z]|[A-Z]+)\(/,{token:"@rematch",switchTo:"@sigilStart.$S2.$1.(.)"}],[/~([a-z]|[A-Z]+)\"}],[/~([a-z]|[A-Z]+)(@sigilSymmetricDelimiter)/,{token:"@rematch",switchTo:"@sigilStart.$S2.$1.$2.$2"}]],"sigilStart.interpol.s":[[/~s@sigilStartDelimiter/,{token:"string.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.interpol.s":[[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"string.delimiter",next:"@pop"},"@default":"string"}}],{include:"@stringContentInterpol"}],"sigilStart.noInterpol.S":[[/~S@sigilStartDelimiter/,{token:"string.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.noInterpol.S":[[/(^|[^\\])\\@sigilEndDelimiter/,"string"],[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"string.delimiter",next:"@pop"},"@default":"string"}}],{include:"@stringContent"}],"sigilStart.interpol.r":[[/~r@sigilStartDelimiter/,{token:"regexp.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.interpol.r":[[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"regexp.delimiter",next:"@pop"},"@default":"regexp"}}],{include:"@regexpContentInterpol"}],"sigilStart.noInterpol.R":[[/~R@sigilStartDelimiter/,{token:"regexp.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.noInterpol.R":[[/(^|[^\\])\\@sigilEndDelimiter/,"regexp"],[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"regexp.delimiter",next:"@pop"},"@default":"regexp"}}],{include:"@regexpContent"}],"sigilStart.interpol":[[/~([a-z]|[A-Z]+)@sigilStartDelimiter/,{token:"sigil.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.interpol":[[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"sigil.delimiter",next:"@pop"},"@default":"sigil"}}],{include:"@sigilContentInterpol"}],"sigilStart.noInterpol":[[/~([a-z]|[A-Z]+)@sigilStartDelimiter/,{token:"sigil.delimiter",switchTo:"@sigilContinue.$S2.$S3.$S4.$S5"}]],"sigilContinue.noInterpol":[[/(^|[^\\])\\@sigilEndDelimiter/,"sigil"],[/(@sigilEndDelimiter)@sigilModifiers/,{cases:{"$1==$S5":{token:"sigil.delimiter",next:"@pop"},"@default":"sigil"}}],{include:"@sigilContent"}],attributes:[[/\@(module|type)?doc (~[sS])?"""/,{token:"comment.block.documentation",next:"@doubleQuotedHeredocDocstring"}],[/\@(module|type)?doc (~[sS])?'''/,{token:"comment.block.documentation",next:"@singleQuotedHeredocDocstring"}],[/\@(module|type)?doc (~[sS])?"/,{token:"comment.block.documentation",next:"@doubleQuotedStringDocstring"}],[/\@(module|type)?doc (~[sS])?'/,{token:"comment.block.documentation",next:"@singleQuotedStringDocstring"}],[/\@(module|type)?doc false/,"comment.block.documentation"],[/\@(@variableName)/,"variable"]],doubleQuotedHeredocDocstring:[[/"""/,{token:"comment.block.documentation",next:"@pop"}],{include:"@docstringContent"}],singleQuotedHeredocDocstring:[[/'''/,{token:"comment.block.documentation",next:"@pop"}],{include:"@docstringContent"}],doubleQuotedStringDocstring:[[/"/,{token:"comment.block.documentation",next:"@pop"}],{include:"@docstringContent"}],singleQuotedStringDocstring:[[/'/,{token:"comment.block.documentation",next:"@pop"}],{include:"@docstringContent"}],symbols:[[/\?(\\.|[^\\\s])/,"number.constant"],[/&\d+/,"operator"],[/<<<|>>>/,"operator"],[/[()\[\]\{\}]|<<|>>/,"@brackets"],[/\.\.\./,"identifier"],[/=>/,"punctuation"],[/@operator/,"operator"],[/[:;,.%]/,"punctuation"]],stringContentInterpol:[{include:"@interpolation"},{include:"@escapeChar"},{include:"@stringContent"}],stringContent:[[/./,"string"]],stringConstantContentInterpol:[{include:"@interpolation"},{include:"@escapeChar"},{include:"@stringConstantContent"}],stringConstantContent:[[/./,"constant"]],regexpContentInterpol:[{include:"@interpolation"},{include:"@escapeChar"},{include:"@regexpContent"}],regexpContent:[[/(\s)(#)(\s.*)$/,["white","comment.punctuation","comment"]],[/./,"regexp"]],sigilContentInterpol:[{include:"@interpolation"},{include:"@escapeChar"},{include:"@sigilContent"}],sigilContent:[[/./,"sigil"]],docstringContent:[[/./,"comment.block.documentation"]],escapeChar:[[/@escape/,"constant.character.escape"]],interpolation:[[/#{/,{token:"delimiter.bracket.embed",next:"@interpolationContinue"}]],interpolationContinue:[[/}/,{token:"delimiter.bracket.embed",next:"@pop"}],{include:"@root"}]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/event-0p00qhH9.css b/app/dubbo-ui/dist/admin/assets/event-0p00qhH9.css deleted file mode 100644 index 7f95c237f..000000000 --- a/app/dubbo-ui/dist/admin/assets/event-0p00qhH9.css +++ /dev/null @@ -1 +0,0 @@ -.__container_app_event[data-v-e2aef936]{background:#fafafa;border-radius:10px;padding:80px 300px 20px}.__container_app_event[data-v-e2aef936] .ant-timeline-item-label{width:200px}.__container_app_event .box[data-v-e2aef936]{position:relative;height:100px;margin-bottom:20px}.__container_app_event .box .label[data-v-e2aef936]{position:absolute;height:100px;top:-40px}.__container_app_event .box .label.yellow .type[data-v-e2aef936]{border-right-color:#f8d347}.__container_app_event .box .label.yellow .body[data-v-e2aef936]{background:#f8d347}.__container_app_event .box .label.red .type[data-v-e2aef936]{border-right-color:#eb4325}.__container_app_event .box .label.red .body[data-v-e2aef936]{background:#eb4325}.__container_app_event .box .label.blue .type[data-v-e2aef936]{border-right-color:#3d89f6}.__container_app_event .box .label.blue .body[data-v-e2aef936]{background:#3d89f6}.__container_app_event .box .label.green .type[data-v-e2aef936]{border-right-color:#9cac35}.__container_app_event .box .label.green .body[data-v-e2aef936]{background:#9cac35}.__container_app_event .box .label .type[data-v-e2aef936]{position:absolute;width:50px;height:50px;border-style:solid;border-color:transparent;border-width:50px 26px 50px 0px;border-right-color:var(--f166166e);display:inline;border-radius:4px}.__container_app_event .box .label .body[data-v-e2aef936]{position:absolute;left:49px;width:50vw;border-radius:3px 5px 5px 3px;height:100%;display:inline;color:#fff;padding-left:20px;background:var(--f166166e);box-shadow:8px 5px 10px #9f9c9c}.__container_app_event .box .label .body .title[data-v-e2aef936]{font-size:30px;line-height:40px}.__container_app_event .box .time[data-v-e2aef936]{position:absolute;left:-200px} diff --git a/app/dubbo-ui/dist/admin/assets/event-PfSKfl9X.js b/app/dubbo-ui/dist/admin/assets/event-PfSKfl9X.js deleted file mode 100644 index 36a0702b5..000000000 --- a/app/dubbo-ui/dist/admin/assets/event-PfSKfl9X.js +++ /dev/null @@ -1 +0,0 @@ -import{b as s,A as b,d as C,c as d,w as a,e as r,o as p,n as u,J as M,K as S,P as y,f as x,t as _,j as f,p as P,h as w,_ as I}from"./index-hmLAZQYT.js";var j={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M696 480H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"minus-circle",theme:"outlined"};const z=j;function m(e){for(var t=1;t(P("data-v-9245080e"),e=e(),w(),e),D={class:"__container_services_tabs_event"},R={class:"description"},V=N(()=>f("span",null,"过期事件不会存储",-1)),E=C({__name:"event",setup(e){const t=[{time:"2022-01-01",description:"description"},{time:"2022-01-02",description:"description"},{time:"2022-01-03",description:"description"},{time:"2022-01-04",description:"description"},{time:"2022-01-05",description:"description"}];return(n,c)=>{const i=r("a-timeline-item"),v=r("a-tag"),O=r("a-timeline"),g=r("a-card");return p(),d("div",D,[s(g,{class:"timeline-container"},{default:a(()=>[s(O,{class:"timeline"},{default:a(()=>[s(i,null,{dot:a(()=>[s(u(B),{style:{"font-size":"18px"}})]),_:1}),(p(),d(M,null,S(t,(l,h)=>s(i,{key:h},{default:a(()=>[s(v,{class:"time",color:u(y)},{default:a(()=>[x(_(l.time),1)]),_:2},1032,["color"]),f("span",R,_(l.description),1)]),_:2},1024)),64)),s(i,null,{dot:a(()=>[]),default:a(()=>[V]),_:1})]),_:1})]),_:1})])}}}),$=I(E,[["__scopeId","data-v-9245080e"]]);export{$ as default}; diff --git a/app/dubbo-ui/dist/admin/assets/event-WVUl-Hrs.js b/app/dubbo-ui/dist/admin/assets/event-WVUl-Hrs.js deleted file mode 100644 index a14424477..000000000 --- a/app/dubbo-ui/dist/admin/assets/event-WVUl-Hrs.js +++ /dev/null @@ -1 +0,0 @@ -import{d as e,c as t,o as n}from"./index-hmLAZQYT.js";const s=e({__name:"event",setup(o){return(a,c)=>(n(),t("div",null,"event todo"))}});export{s as default}; diff --git a/app/dubbo-ui/dist/admin/assets/event-lmBmBbXg.css b/app/dubbo-ui/dist/admin/assets/event-lmBmBbXg.css deleted file mode 100644 index 46cccc3b6..000000000 --- a/app/dubbo-ui/dist/admin/assets/event-lmBmBbXg.css +++ /dev/null @@ -1 +0,0 @@ -.__container_services_tabs_event[data-v-9245080e]{display:flex}.__container_services_tabs_event .timeline-container[data-v-9245080e]{width:100%}.__container_services_tabs_event .timeline-container .timeline[data-v-9245080e]{margin-left:30px}.__container_services_tabs_event .timeline-container .timeline .description[data-v-9245080e]{font-size:18px} diff --git a/app/dubbo-ui/dist/admin/assets/event-ympyACpm.js b/app/dubbo-ui/dist/admin/assets/event-ympyACpm.js deleted file mode 100644 index d627fc860..000000000 --- a/app/dubbo-ui/dist/admin/assets/event-ympyACpm.js +++ /dev/null @@ -1 +0,0 @@ -import{d as v,v as f,r as h,W as y,c as d,b as r,w as n,e as p,n as l,P as C,o as c,J as x,K as b,G as k,a4 as w,a5 as I,j as e,a6 as S,t as i,p as B,h as R,_ as g}from"./index-hmLAZQYT.js";import{l as O}from"./app-duU6O0cq.js";import"./request-8jI_GZey.js";const V=t=>(B("data-v-e2aef936"),t=t(),R(),t),z={class:"__container_app_event"},A={class:"box"},E=V(()=>e("div",{class:"type"},null,-1)),L={class:"body"},M={class:"title"},N={class:"time"},P=v({__name:"event",setup(t){f(a=>({f166166e:l(C)}));let s=h({list:[]});return y(async()=>{let a=await O({});s.list=a.data.list,console.log(s)}),(a,j)=>{const m=p("a-timeline-item"),u=p("a-timeline");return c(),d("div",z,[r(u,{mode:"left"},{default:n(()=>[(c(!0),d(x,null,b(l(s).list,(o,_)=>(c(),k(m,null,w({default:n(()=>[e("div",A,[e("div",{class:S(["label",{yellow:_===0}])},[E,e("div",L,[e("b",M,i(o.type),1),e("p",null,i(o.desc),1)])],2),e("span",N,i(o.time),1)])]),_:2},[_===0?{name:"dot",fn:n(()=>[r(l(I),{style:{"font-size":"16px",color:"red"}})]),key:"0"}:void 0]),1024))),256))]),_:1})])}}}),J=g(P,[["__scopeId","data-v-e2aef936"]]);export{J as default}; diff --git a/app/dubbo-ui/dist/admin/assets/flow9-7owDGJzV.js b/app/dubbo-ui/dist/admin/assets/flow9-7owDGJzV.js deleted file mode 100644 index 064961d43..000000000 --- a/app/dubbo-ui/dist/admin/assets/flow9-7owDGJzV.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{blockComment:["/*","*/"],lineComment:"//"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}",notIn:["string"]},{open:"[",close:"]",notIn:["string"]},{open:"(",close:")",notIn:["string"]},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}]},o={defaultToken:"",tokenPostfix:".flow",keywords:["import","require","export","forbid","native","if","else","cast","unsafe","switch","default"],types:["io","mutable","bool","int","double","string","flow","void","ref","true","false","with"],operators:["=",">","<","<=",">=","==","!","!=",":=","::=","&&","||","+","-","*","/","@","&","%",":","->","\\","$","??","^"],symbols:/[@$=>](?!@symbols)/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]]}};export{e as conf,o as language}; diff --git a/app/dubbo-ui/dist/admin/assets/formView--eWAQ02R.js b/app/dubbo-ui/dist/admin/assets/formView--eWAQ02R.js deleted file mode 100644 index ccd701c76..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView--eWAQ02R.js +++ /dev/null @@ -1,17 +0,0 @@ -import{d as tn,v as en,x as rn,y as nn,k as sn,a as an,u as on,z as Ge,r as Ke,l as Fi,W as ln,c as Ct,b as D,w as S,G as $,Q as zt,a3 as Ii,e as rt,n as G,P as Ft,o as E,j as Re,J as Wt,K as qt,f as nt,t as dt,ad as un,I as ne,ag as fn,m as ge,_ as hn}from"./index-hmLAZQYT.js";import{u as _n}from"./index-Va7nxJVK.js";import{k as dn,l as cn,m as pn}from"./traffic-C2a-KjHH.js";import{V as mn,C as gn}from"./ConfigModel-QFNd-Zdd.js";import"./request-8jI_GZey.js";function Mt(l){if(l===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return l}function tr(l,t){l.prototype=Object.create(t.prototype),l.prototype.constructor=l,l.__proto__=t}/*! - * GSAP 3.12.7 - * https://gsap.com - * - * @license Copyright 2008-2025, GreenSock. All rights reserved. - * Subject to the terms at https://gsap.com/standard-license or for - * Club GSAP members, the agreement issued with that membership. - * @author: Jack Doyle, jack@greensock.com -*/var gt={autoSleep:120,force3D:"auto",nullTargetWarn:1,units:{lineHeight:""}},he={duration:.5,overwrite:!1,delay:0},yi,J,Y,wt=1e8,L=1/wt,ri=Math.PI*2,yn=ri/4,vn=0,er=Math.sqrt,bn=Math.cos,xn=Math.sin,H=function(t){return typeof t=="string"},q=function(t){return typeof t=="function"},Rt=function(t){return typeof t=="number"},vi=function(t){return typeof t>"u"},Dt=function(t){return typeof t=="object"},st=function(t){return t!==!1},bi=function(){return typeof window<"u"},Ee=function(t){return q(t)||H(t)},ir=typeof ArrayBuffer=="function"&&ArrayBuffer.isView||function(){},et=Array.isArray,ni=/(?:-?\.?\d|\.)+/gi,rr=/[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,ae=/[-+=.]*\d+[.e-]*\d*[a-z%]*/g,je=/[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,nr=/[+-]=-?[.\d]+/,sr=/[^,'"\[\]\s]+/gi,wn=/^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,X,kt,si,xi,yt={},Ve={},ar,or=function(t){return(Ve=_e(t,yt))&&ut},wi=function(t,e){return console.warn("Invalid property",t,"set to",e,"Missing plugin? gsap.registerPlugin()")},Ce=function(t,e){return!e&&console.warn(t)},lr=function(t,e){return t&&(yt[t]=e)&&Ve&&(Ve[t]=e)||yt},ke=function(){return 0},Tn={suppressEvents:!0,isStart:!0,kill:!1},ze={suppressEvents:!0,kill:!1},Cn={suppressEvents:!0},Ti={},Lt=[],ai={},ur,ct={},Qe={},Vi=30,Fe=[],Ci="",ki=function(t){var e=t[0],i,r;if(Dt(e)||q(e)||(t=[t]),!(i=(e._gsap||{}).harness)){for(r=Fe.length;r--&&!Fe[r].targetTest(e););i=Fe[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new Er(t[r],i)))||t.splice(r,1);return t},Zt=function(t){return t._gsap||ki(Tt(t))[0]._gsap},fr=function(t,e,i){return(i=t[e])&&q(i)?t[e]():vi(i)&&t.getAttribute&&t.getAttribute(e)||i},at=function(t,e){return(t=t.split(",")).forEach(e)||t},K=function(t){return Math.round(t*1e5)/1e5||0},Z=function(t){return Math.round(t*1e7)/1e7||0},le=function(t,e){var i=e.charAt(0),r=parseFloat(e.substr(2));return t=parseFloat(t),i==="+"?t+r:i==="-"?t-r:i==="*"?t*r:t/r},kn=function(t,e){for(var i=e.length,r=0;t.indexOf(e[r])<0&&++ra;)s=s._prev;return s?(e._next=s._next,s._next=e):(e._next=t[i],t[i]=e),e._next?e._next._prev=e:t[r]=e,e._prev=s,e.parent=e._dp=t,e},Xe=function(t,e,i,r){i===void 0&&(i="_first"),r===void 0&&(r="_last");var n=e._prev,s=e._next;n?n._next=s:t[i]===e&&(t[i]=s),s?s._prev=n:t[r]===e&&(t[r]=n),e._next=e._prev=e.parent=null},Bt=function(t,e){t.parent&&(!e||t.parent.autoRemoveChildren)&&t.parent.remove&&t.parent.remove(t),t._act=0},Ht=function(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var i=t;i;)i._dirty=1,i=i.parent;return t},Sn=function(t){for(var e=t.parent;e&&e.parent;)e._dirty=1,e.totalDuration(),e=e.parent;return t},oi=function(t,e,i,r){return t._startAt&&(J?t._startAt.revert(ze):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,r))},Dn=function l(t){return!t||t._ts&&l(t.parent)},Li=function(t){return t._repeat?de(t._tTime,t=t.duration()+t._rDelay)*t:0},de=function(t,e){var i=Math.floor(t=Z(t/e));return t&&i===t?i-1:i},Ne=function(t,e){return(t-e._start)*e._ts+(e._ts>=0?0:e._dirty?e.totalDuration():e._tDur)},We=function(t){return t._end=Z(t._start+(t._tDur/Math.abs(t._ts||t._rts||L)||0))},qe=function(t,e){var i=t._dp;return i&&i.smoothChildTiming&&t._ts&&(t._start=Z(i._time-(t._ts>0?e/t._ts:((t._dirty?t.totalDuration():t._tDur)-e)/-t._ts)),We(t),i._dirty||Ht(i,t)),t},pr=function(t,e){var i;if((e._time||!e._dur&&e._initted||e._startL)&&e.render(i,!0)),Ht(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur=0&&i.totalTime(i._tTime),i=i._dp;t._zTime=-L}},Ot=function(t,e,i,r){return e.parent&&Bt(e),e._start=Z((Rt(i)?i:i||t!==X?xt(t,i,e):t._time)+e._delay),e._end=Z(e._start+(e.totalDuration()/Math.abs(e.timeScale())||0)),cr(t,e,"_first","_last",t._sort?"_start":0),li(e)||(t._recent=e),r||pr(t,e),t._ts<0&&qe(t,t._tTime),t},mr=function(t,e){return(yt.ScrollTrigger||wi("scrollTrigger",e))&&yt.ScrollTrigger.create(e,t)},gr=function(t,e,i,r,n){if(Pi(t,e,n),!t._initted)return 1;if(!i&&t._pt&&!J&&(t._dur&&t.vars.lazy!==!1||!t._dur&&t.vars.lazy)&&ur!==pt.frame)return Lt.push(t),t._lazy=[n,r],1},Mn=function l(t){var e=t.parent;return e&&e._ts&&e._initted&&!e._lock&&(e.rawTime()<0||l(e))},li=function(t){var e=t.data;return e==="isFromStart"||e==="isStart"},An=function(t,e,i,r){var n=t.ratio,s=e<0||!e&&(!t._start&&Mn(t)&&!(!t._initted&&li(t))||(t._ts<0||t._dp._ts<0)&&!li(t))?0:1,a=t._rDelay,o=0,u,f,_;if(a&&t._repeat&&(o=Ae(0,t._tDur,e),f=de(o,a),t._yoyo&&f&1&&(s=1-s),f!==de(t._tTime,a)&&(n=1-s,t.vars.repeatRefresh&&t._initted&&t.invalidate())),s!==n||J||r||t._zTime===L||!e&&t._zTime){if(!t._initted&&gr(t,e,r,i,o))return;for(_=t._zTime,t._zTime=e||(i?L:0),i||(i=e&&!_),t.ratio=s,t._from&&(s=1-s),t._time=0,t._tTime=o,u=t._pt;u;)u.r(s,u.d),u=u._next;e<0&&oi(t,e,i,!0),t._onUpdate&&!i&&mt(t,"onUpdate"),o&&t._repeat&&!i&&t.parent&&mt(t,"onRepeat"),(e>=t._tDur||e<0)&&t.ratio===s&&(s&&Bt(t,1),!i&&!J&&(mt(t,s?"onComplete":"onReverseComplete",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)},Rn=function(t,e,i){var r;if(i>e)for(r=t._first;r&&r._start<=i;){if(r.data==="isPause"&&r._start>e)return r;r=r._next}else for(r=t._last;r&&r._start>=i;){if(r.data==="isPause"&&r._start0&&!r&&qe(t,t._tTime=t._tDur*a),t.parent&&We(t),i||Ht(t.parent,t),t},Ni=function(t){return t instanceof it?Ht(t):ce(t,t._dur)},En={_start:0,endTime:ke,totalDuration:ke},xt=function l(t,e,i){var r=t.labels,n=t._recent||En,s=t.duration()>=wt?n.endTime(!1):t._dur,a,o,u;return H(e)&&(isNaN(e)||e in r)?(o=e.charAt(0),u=e.substr(-1)==="%",a=e.indexOf("="),o==="<"||o===">"?(a>=0&&(e=e.replace(/=/,"")),(o==="<"?n._start:n.endTime(n._repeat>=0))+(parseFloat(e.substr(1))||0)*(u?(a<0?n:i).totalDuration()/100:1)):a<0?(e in r||(r[e]=s),r[e]):(o=parseFloat(e.charAt(a-1)+e.substr(a+1)),u&&i&&(o=o/100*(et(i)?i[0]:i).totalDuration()),a>1?l(t,e.substr(0,a-1),i)+o:s+o)):e==null?s:+e},we=function(t,e,i){var r=Rt(e[1]),n=(r?2:1)+(t<2?0:1),s=e[n],a,o;if(r&&(s.duration=e[1]),s.parent=i,t){for(a=s,o=i;o&&!("immediateRender"in a);)a=o.vars.defaults||{},o=st(o.vars.inherit)&&o.parent;s.immediateRender=st(a.immediateRender),t<2?s.runBackwards=1:s.startAt=e[n-1]}return new Q(e[0],s,e[n+1])},$t=function(t,e){return t||t===0?e(t):e},Ae=function(t,e,i){return ie?e:i},tt=function(t,e){return!H(t)||!(e=wn.exec(t))?"":e[1]},zn=function(t,e,i){return $t(i,function(r){return Ae(t,e,r)})},ui=[].slice,yr=function(t,e){return t&&Dt(t)&&"length"in t&&(!e&&!t.length||t.length-1 in t&&Dt(t[0]))&&!t.nodeType&&t!==kt},Fn=function(t,e,i){return i===void 0&&(i=[]),t.forEach(function(r){var n;return H(r)&&!e||yr(r,1)?(n=i).push.apply(n,Tt(r)):i.push(r)})||i},Tt=function(t,e,i){return Y&&!e&&Y.selector?Y.selector(t):H(t)&&!i&&(si||!pe())?ui.call((e||xi).querySelectorAll(t),0):et(t)?Fn(t,i):yr(t)?ui.call(t,0):t?[t]:[]},fi=function(t){return t=Tt(t)[0]||Ce("Invalid scope")||{},function(e){var i=t.current||t.nativeElement||t;return Tt(e,i.querySelectorAll?i:i===t?Ce("Invalid scope")||xi.createElement("div"):t)}},vr=function(t){return t.sort(function(){return .5-Math.random()})},br=function(t){if(q(t))return t;var e=Dt(t)?t:{each:t},i=Jt(e.ease),r=e.from||0,n=parseFloat(e.base)||0,s={},a=r>0&&r<1,o=isNaN(r)||a,u=e.axis,f=r,_=r;return H(r)?f=_={center:.5,edges:.5,end:1}[r]||0:!a&&o&&(f=r[0],_=r[1]),function(d,c,m){var h=(m||e).length,g=s[h],v,b,T,k,p,x,C,w,y;if(!g){if(y=e.grid==="auto"?0:(e.grid||[1,wt])[1],!y){for(C=-wt;C<(C=m[y++].getBoundingClientRect().left)&&yC&&(C=p),ph?h-1:u?u==="y"?h/y:y:Math.max(y,h/y))||0)*(r==="edges"?-1:1),g.b=h<0?n-h:n,g.u=tt(e.amount||e.each)||0,i=i&&h<0?Mr(i):i}return h=(g[d]-g.min)/g.max||0,Z(g.b+(i?i(h):h)*g.v)+g.u}},hi=function(t){var e=Math.pow(10,((t+"").split(".")[1]||"").length);return function(i){var r=Z(Math.round(parseFloat(i)/t)*t*e);return(r-r%1)/e+(Rt(i)?0:tt(i))}},xr=function(t,e){var i=et(t),r,n;return!i&&Dt(t)&&(r=i=t.radius||wt,t.values?(t=Tt(t.values),(n=!Rt(t[0]))&&(r*=r)):t=hi(t.increment)),$t(e,i?q(t)?function(s){return n=t(s),Math.abs(n-s)<=r?n:s}:function(s){for(var a=parseFloat(n?s.x:s),o=parseFloat(n?s.y:0),u=wt,f=0,_=t.length,d,c;_--;)n?(d=t[_].x-a,c=t[_].y-o,d=d*d+c*c):d=Math.abs(t[_]-a),dr?n-s:s)})},Oe=function(t){for(var e=0,i="",r,n,s,a;~(r=t.indexOf("random(",e));)s=t.indexOf(")",r),a=t.charAt(r+7)==="[",n=t.substr(r+7,s-r-7).match(a?sr:ni),i+=t.substr(e,r-e)+wr(a?n:+n[0],a?0:+n[1],+n[2]||1e-5),e=s+1;return i+t.substr(e,t.length-e)},Cr=function(t,e,i,r,n){var s=e-t,a=r-i;return $t(n,function(o){return i+((o-t)/s*a||0)})},Bn=function l(t,e,i,r){var n=isNaN(t+e)?0:function(c){return(1-c)*t+c*e};if(!n){var s=H(t),a={},o,u,f,_,d;if(i===!0&&(r=1)&&(i=null),s)t={p:t},e={p:e};else if(et(t)&&!et(e)){for(f=[],_=t.length,d=_-2,u=1;u<_;u++)f.push(l(t[u-1],t[u]));_--,n=function(m){m*=_;var h=Math.min(d,~~m);return f[h](m-h)},i=e}else r||(t=_e(et(t)?[]:{},t));if(!f){for(o in e)Oi.call(a,t,o,"get",e[o]);n=function(m){return Mi(m,a)||(s?t.p:t)}}}return $t(i,n)},Bi=function(t,e,i){var r=t.labels,n=wt,s,a,o;for(s in r)a=r[s]-e,a<0==!!i&&a&&n>(a=Math.abs(a))&&(o=s,n=a);return o},mt=function(t,e,i){var r=t.vars,n=r[e],s=Y,a=t._ctx,o,u,f;if(n)return o=r[e+"Params"],u=r.callbackScope||t,i&&Lt.length&&Ue(),a&&(Y=a),f=o?n.apply(u,o):n.call(u),Y=s,f},ve=function(t){return Bt(t),t.scrollTrigger&&t.scrollTrigger.kill(!!J),t.progress()<1&&mt(t,"onInterrupt"),t},oe,kr=[],Or=function(t){if(t)if(t=!t.name&&t.default||t,bi()||t.headless){var e=t.name,i=q(t),r=e&&!i&&t.init?function(){this._props=[]}:t,n={init:ke,render:Mi,add:Oi,kill:rs,modifier:is,rawVars:0},s={targetTest:0,get:0,getSetter:Di,aliases:{},register:0};if(pe(),t!==r){if(ct[e])return;vt(r,vt(Le(t,n),s)),_e(r.prototype,_e(n,Le(t,s))),ct[r.prop=e]=r,t.targetTest&&(Fe.push(r),Ti[e]=1),e=(e==="css"?"CSS":e.charAt(0).toUpperCase()+e.substr(1))+"Plugin"}lr(e,r),t.register&&t.register(ut,r,ot)}else kr.push(t)},U=255,be={aqua:[0,U,U],lime:[0,U,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,U],navy:[0,0,128],white:[U,U,U],olive:[128,128,0],yellow:[U,U,0],orange:[U,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[U,0,0],pink:[U,192,203],cyan:[0,U,U],transparent:[U,U,U,0]},Ze=function(t,e,i){return t+=t<0?1:t>1?-1:0,(t*6<1?e+(i-e)*t*6:t<.5?i:t*3<2?e+(i-e)*(2/3-t)*6:e)*U+.5|0},Pr=function(t,e,i){var r=t?Rt(t)?[t>>16,t>>8&U,t&U]:0:be.black,n,s,a,o,u,f,_,d,c,m;if(!r){if(t.substr(-1)===","&&(t=t.substr(0,t.length-1)),be[t])r=be[t];else if(t.charAt(0)==="#"){if(t.length<6&&(n=t.charAt(1),s=t.charAt(2),a=t.charAt(3),t="#"+n+n+s+s+a+a+(t.length===5?t.charAt(4)+t.charAt(4):"")),t.length===9)return r=parseInt(t.substr(1,6),16),[r>>16,r>>8&U,r&U,parseInt(t.substr(7),16)/255];t=parseInt(t.substr(1),16),r=[t>>16,t>>8&U,t&U]}else if(t.substr(0,3)==="hsl"){if(r=m=t.match(ni),!e)o=+r[0]%360/360,u=+r[1]/100,f=+r[2]/100,s=f<=.5?f*(u+1):f+u-f*u,n=f*2-s,r.length>3&&(r[3]*=1),r[0]=Ze(o+1/3,n,s),r[1]=Ze(o,n,s),r[2]=Ze(o-1/3,n,s);else if(~t.indexOf("="))return r=t.match(rr),i&&r.length<4&&(r[3]=1),r}else r=t.match(ni)||be.transparent;r=r.map(Number)}return e&&!m&&(n=r[0]/U,s=r[1]/U,a=r[2]/U,_=Math.max(n,s,a),d=Math.min(n,s,a),f=(_+d)/2,_===d?o=u=0:(c=_-d,u=f>.5?c/(2-_-d):c/(_+d),o=_===n?(s-a)/c+(st||v<0)&&(i+=v-e),r+=v,p=r-i,T=p-s,(T>0||b)&&(x=++_.frame,d=p-_.time*1e3,_.time=p=p/1e3,s+=T+(T>=n?4:n-T),k=1),b||(o=u(h)),k)for(c=0;c=v&&c--},_listeners:a},_}(),pe=function(){return!Pe&&pt.wake()},R={},$n=/^[\d.\-M][\d.\-,\s]/,Xn=/["']/g,Wn=function(t){for(var e={},i=t.substr(1,t.length-3).split(":"),r=i[0],n=1,s=i.length,a,o,u;n1&&i.config?i.config.apply(null,~t.indexOf("{")?[Wn(e[1])]:qn(t).split(",").map(_r)):R._CE&&$n.test(t)?R._CE("",t):i},Mr=function(t){return function(e){return 1-t(1-e)}},Ar=function l(t,e){for(var i=t._first,r;i;)i instanceof it?l(i,e):i.vars.yoyoEase&&(!i._yoyo||!i._repeat)&&i._yoyo!==e&&(i.timeline?l(i.timeline,e):(r=i._ease,i._ease=i._yEase,i._yEase=r,i._yoyo=e)),i=i._next},Jt=function(t,e){return t&&(q(t)?t:R[t]||Gn(t))||e},ie=function(t,e,i,r){i===void 0&&(i=function(o){return 1-e(1-o)}),r===void 0&&(r=function(o){return o<.5?e(o*2)/2:1-e((1-o)*2)/2});var n={easeIn:e,easeOut:i,easeInOut:r},s;return at(t,function(a){R[a]=yt[a]=n,R[s=a.toLowerCase()]=i;for(var o in n)R[s+(o==="easeIn"?".in":o==="easeOut"?".out":".inOut")]=R[a+"."+o]=n[o]}),n},Rr=function(t){return function(e){return e<.5?(1-t(1-e*2))/2:.5+t((e-.5)*2)/2}},He=function l(t,e,i){var r=e>=1?e:1,n=(i||(t?.3:.45))/(e<1?e:1),s=n/ri*(Math.asin(1/r)||0),a=function(f){return f===1?1:r*Math.pow(2,-10*f)*xn((f-s)*n)+1},o=t==="out"?a:t==="in"?function(u){return 1-a(1-u)}:Rr(a);return n=ri/n,o.config=function(u,f){return l(t,u,f)},o},Je=function l(t,e){e===void 0&&(e=1.70158);var i=function(s){return s?--s*s*((e+1)*s+e)+1:0},r=t==="out"?i:t==="in"?function(n){return 1-i(1-n)}:Rr(i);return r.config=function(n){return l(t,n)},r};at("Linear,Quad,Cubic,Quart,Quint,Strong",function(l,t){var e=t<5?t+1:t;ie(l+",Power"+(e-1),t?function(i){return Math.pow(i,e)}:function(i){return i},function(i){return 1-Math.pow(1-i,e)},function(i){return i<.5?Math.pow(i*2,e)/2:1-Math.pow((1-i)*2,e)/2})});R.Linear.easeNone=R.none=R.Linear.easeIn;ie("Elastic",He("in"),He("out"),He());(function(l,t){var e=1/t,i=2*e,r=2.5*e,n=function(a){return a0?i+(i+this._rDelay)*this._repeat:i):this.totalDuration()&&this._dur},t.totalDuration=function(i){return arguments.length?(this._dirty=0,ce(this,this._repeat<0?i:(i-this._repeat*this._rDelay)/(this._repeat+1))):this._tDur},t.totalTime=function(i,r){if(pe(),!arguments.length)return this._tTime;var n=this._dp;if(n&&n.smoothChildTiming&&this._ts){for(qe(this,i),!n._dp||n.parent||pr(n,this);n&&n.parent;)n.parent._time!==n._start+(n._ts>=0?n._tTime/n._ts:(n.totalDuration()-n._tTime)/-n._ts)&&n.totalTime(n._tTime,!0),n=n.parent;!this.parent&&this._dp.autoRemoveChildren&&(this._ts>0&&i0||!this._tDur&&!i)&&Ot(this._dp,this,this._start-this._delay)}return(this._tTime!==i||!this._dur&&!r||this._initted&&Math.abs(this._zTime)===L||!i&&!this._initted&&(this.add||this._ptLookup))&&(this._ts||(this._pTime=i),hr(this,i,r)),this},t.time=function(i,r){return arguments.length?this.totalTime(Math.min(this.totalDuration(),i+Li(this))%(this._dur+this._rDelay)||(i?this._dur:0),r):this._time},t.totalProgress=function(i,r){return arguments.length?this.totalTime(this.totalDuration()*i,r):this.totalDuration()?Math.min(1,this._tTime/this._tDur):this.rawTime()>=0&&this._initted?1:0},t.progress=function(i,r){return arguments.length?this.totalTime(this.duration()*(this._yoyo&&!(this.iteration()&1)?1-i:i)+Li(this),r):this.duration()?Math.min(1,this._time/this._dur):this.rawTime()>0?1:0},t.iteration=function(i,r){var n=this.duration()+this._rDelay;return arguments.length?this.totalTime(this._time+(i-1)*n,r):this._repeat?de(this._tTime,n)+1:1},t.timeScale=function(i,r){if(!arguments.length)return this._rts===-L?0:this._rts;if(this._rts===i)return this;var n=this.parent&&this._ts?Ne(this.parent._time,this):this._tTime;return this._rts=+i||0,this._ts=this._ps||i===-L?0:this._rts,this.totalTime(Ae(-Math.abs(this._delay),this._tDur,n),r!==!1),We(this),Sn(this)},t.paused=function(i){return arguments.length?(this._ps!==i&&(this._ps=i,i?(this._pTime=this._tTime||Math.max(-this._delay,this.rawTime()),this._ts=this._act=0):(pe(),this._ts=this._rts,this.totalTime(this.parent&&!this.parent.smoothChildTiming?this.rawTime():this._tTime||this._pTime,this.progress()===1&&Math.abs(this._zTime)!==L&&(this._tTime-=L)))),this):this._ps},t.startTime=function(i){if(arguments.length){this._start=i;var r=this.parent||this._dp;return r&&(r._sort||!this.parent)&&Ot(r,this,i-this._delay),this}return this._start},t.endTime=function(i){return this._start+(st(i)?this.totalDuration():this.duration())/Math.abs(this._ts||1)},t.rawTime=function(i){var r=this.parent||this._dp;return r?i&&(!this._ts||this._repeat&&this._time&&this.totalProgress()<1)?this._tTime%(this._dur+this._rDelay):this._ts?Ne(r.rawTime(i),this):this._tTime:this._tTime},t.revert=function(i){i===void 0&&(i=Cn);var r=J;return J=i,(this._initted||this._startAt)&&(this.timeline&&this.timeline.revert(i),this.totalTime(-.01,i.suppressEvents)),this.data!=="nested"&&i.kill!==!1&&this.kill(),J=r,this},t.globalTime=function(i){for(var r=this,n=arguments.length?i:r.rawTime();r;)n=r._start+n/(Math.abs(r._ts)||1),r=r._dp;return!this.parent&&this._sat?this._sat.globalTime(i):n},t.repeat=function(i){return arguments.length?(this._repeat=i===1/0?-2:i,Ni(this)):this._repeat===-2?1/0:this._repeat},t.repeatDelay=function(i){if(arguments.length){var r=this._time;return this._rDelay=i,Ni(this),r?this.time(r):this}return this._rDelay},t.yoyo=function(i){return arguments.length?(this._yoyo=i,this):this._yoyo},t.seek=function(i,r){return this.totalTime(xt(this,i),st(r))},t.restart=function(i,r){return this.play().totalTime(i?-this._delay:0,st(r)),this._dur||(this._zTime=-L),this},t.play=function(i,r){return i!=null&&this.seek(i,r),this.reversed(!1).paused(!1)},t.reverse=function(i,r){return i!=null&&this.seek(i||this.totalDuration(),r),this.reversed(!0).paused(!1)},t.pause=function(i,r){return i!=null&&this.seek(i,r),this.paused(!0)},t.resume=function(){return this.paused(!1)},t.reversed=function(i){return arguments.length?(!!i!==this.reversed()&&this.timeScale(-this._rts||(i?-L:0)),this):this._rts<0},t.invalidate=function(){return this._initted=this._act=0,this._zTime=-L,this},t.isActive=function(){var i=this.parent||this._dp,r=this._start,n;return!!(!i||this._ts&&this._initted&&i.isActive()&&(n=i.rawTime(!0))>=r&&n1?(r?(s[i]=r,n&&(s[i+"Params"]=n),i==="onUpdate"&&(this._onUpdate=r)):delete s[i],this):s[i]},t.then=function(i){var r=this;return new Promise(function(n){var s=q(i)?i:dr,a=function(){var u=r.then;r.then=null,q(s)&&(s=s(r))&&(s.then||s===r)&&(r.then=u),n(s),r.then=u};r._initted&&r.totalProgress()===1&&r._ts>=0||!r._tTime&&r._ts<0?a():r._prom=a})},t.kill=function(){ve(this)},l}();vt(Se.prototype,{_time:0,_start:0,_end:0,_tTime:0,_tDur:0,_dirty:0,_repeat:0,_yoyo:!1,parent:null,_initted:!1,_rDelay:0,_ts:1,_dp:0,ratio:0,_zTime:-L,_prom:0,_ps:!1,_rts:1});var it=function(l){tr(t,l);function t(i,r){var n;return i===void 0&&(i={}),n=l.call(this,i)||this,n.labels={},n.smoothChildTiming=!!i.smoothChildTiming,n.autoRemoveChildren=!!i.autoRemoveChildren,n._sort=st(i.sortChildren),X&&Ot(i.parent||X,Mt(n),r),i.reversed&&n.reverse(),i.paused&&n.paused(!0),i.scrollTrigger&&mr(Mt(n),i.scrollTrigger),n}var e=t.prototype;return e.to=function(r,n,s){return we(0,arguments,this),this},e.from=function(r,n,s){return we(1,arguments,this),this},e.fromTo=function(r,n,s,a){return we(2,arguments,this),this},e.set=function(r,n,s){return n.duration=0,n.parent=this,xe(n).repeatDelay||(n.repeat=0),n.immediateRender=!!n.immediateRender,new Q(r,n,xt(this,s),1),this},e.call=function(r,n,s){return Ot(this,Q.delayedCall(0,r,n),s)},e.staggerTo=function(r,n,s,a,o,u,f){return s.duration=n,s.stagger=s.stagger||a,s.onComplete=u,s.onCompleteParams=f,s.parent=this,new Q(r,s,xt(this,o)),this},e.staggerFrom=function(r,n,s,a,o,u,f){return s.runBackwards=1,xe(s).immediateRender=st(s.immediateRender),this.staggerTo(r,n,s,a,o,u,f)},e.staggerFromTo=function(r,n,s,a,o,u,f,_){return a.startAt=s,xe(a).immediateRender=st(a.immediateRender),this.staggerTo(r,n,a,o,u,f,_)},e.render=function(r,n,s){var a=this._time,o=this._dirty?this.totalDuration():this._tDur,u=this._dur,f=r<=0?0:Z(r),_=this._zTime<0!=r<0&&(this._initted||!u),d,c,m,h,g,v,b,T,k,p,x,C;if(this!==X&&f>o&&r>=0&&(f=o),f!==this._tTime||s||_){if(a!==this._time&&u&&(f+=this._time-a,r+=this._time-a),d=f,k=this._start,T=this._ts,v=!T,_&&(u||(a=this._zTime),(r||!n)&&(this._zTime=r)),this._repeat){if(x=this._yoyo,g=u+this._rDelay,this._repeat<-1&&r<0)return this.totalTime(g*100+r,n,s);if(d=Z(f%g),f===o?(h=this._repeat,d=u):(p=Z(f/g),h=~~p,h&&h===p&&(d=u,h--),d>u&&(d=u)),p=de(this._tTime,g),!a&&this._tTime&&p!==h&&this._tTime-p*g-this._dur<=0&&(p=h),x&&h&1&&(d=u-d,C=1),h!==p&&!this._lock){var w=x&&p&1,y=w===(x&&h&1);if(h=a&&r>=0)for(c=this._first;c;){if(m=c._next,(c._act||d>=c._start)&&c._ts&&b!==c){if(c.parent!==this)return this.render(r,n,s);if(c.render(c._ts>0?(d-c._start)*c._ts:(c._dirty?c.totalDuration():c._tDur)+(d-c._start)*c._ts,n,s),d!==this._time||!this._ts&&!v){b=0,m&&(f+=this._zTime=-L);break}}c=m}else{c=this._last;for(var M=r<0?r:d;c;){if(m=c._prev,(c._act||M<=c._end)&&c._ts&&b!==c){if(c.parent!==this)return this.render(r,n,s);if(c.render(c._ts>0?(M-c._start)*c._ts:(c._dirty?c.totalDuration():c._tDur)+(M-c._start)*c._ts,n,s||J&&(c._initted||c._startAt)),d!==this._time||!this._ts&&!v){b=0,m&&(f+=this._zTime=M?-L:L);break}}c=m}}if(b&&!n&&(this.pause(),b.render(d>=a?0:-L)._zTime=d>=a?1:-1,this._ts))return this._start=k,We(this),this.render(r,n,s);this._onUpdate&&!n&&mt(this,"onUpdate",!0),(f===o&&this._tTime>=this.totalDuration()||!f&&a)&&(k===this._start||Math.abs(T)!==Math.abs(this._ts))&&(this._lock||((r||!u)&&(f===o&&this._ts>0||!f&&this._ts<0)&&Bt(this,1),!n&&!(r<0&&!a)&&(f||a||!o)&&(mt(this,f===o&&r>=0?"onComplete":"onReverseComplete",!0),this._prom&&!(f0)&&this._prom())))}return this},e.add=function(r,n){var s=this;if(Rt(n)||(n=xt(this,n,r)),!(r instanceof Se)){if(et(r))return r.forEach(function(a){return s.add(a,n)}),this;if(H(r))return this.addLabel(r,n);if(q(r))r=Q.delayedCall(0,r);else return this}return this!==r?Ot(this,r,n):this},e.getChildren=function(r,n,s,a){r===void 0&&(r=!0),n===void 0&&(n=!0),s===void 0&&(s=!0),a===void 0&&(a=-wt);for(var o=[],u=this._first;u;)u._start>=a&&(u instanceof Q?n&&o.push(u):(s&&o.push(u),r&&o.push.apply(o,u.getChildren(!0,n,s)))),u=u._next;return o},e.getById=function(r){for(var n=this.getChildren(1,1,1),s=n.length;s--;)if(n[s].vars.id===r)return n[s]},e.remove=function(r){return H(r)?this.removeLabel(r):q(r)?this.killTweensOf(r):(r.parent===this&&Xe(this,r),r===this._recent&&(this._recent=this._last),Ht(this))},e.totalTime=function(r,n){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=Z(pt.time-(this._ts>0?r/this._ts:(this.totalDuration()-r)/-this._ts))),l.prototype.totalTime.call(this,r,n),this._forcing=0,this):this._tTime},e.addLabel=function(r,n){return this.labels[r]=xt(this,n),this},e.removeLabel=function(r){return delete this.labels[r],this},e.addPause=function(r,n,s){var a=Q.delayedCall(0,n||ke,s);return a.data="isPause",this._hasPause=1,Ot(this,a,xt(this,r))},e.removePause=function(r){var n=this._first;for(r=xt(this,r);n;)n._start===r&&n.data==="isPause"&&Bt(n),n=n._next},e.killTweensOf=function(r,n,s){for(var a=this.getTweensOf(r,s),o=a.length;o--;)It!==a[o]&&a[o].kill(r,n);return this},e.getTweensOf=function(r,n){for(var s=[],a=Tt(r),o=this._first,u=Rt(n),f;o;)o instanceof Q?kn(o._targets,a)&&(u?(!It||o._initted&&o._ts)&&o.globalTime(0)<=n&&o.globalTime(o.totalDuration())>n:!n||o.isActive())&&s.push(o):(f=o.getTweensOf(a,n)).length&&s.push.apply(s,f),o=o._next;return s},e.tweenTo=function(r,n){n=n||{};var s=this,a=xt(s,r),o=n,u=o.startAt,f=o.onStart,_=o.onStartParams,d=o.immediateRender,c,m=Q.to(s,vt({ease:n.ease||"none",lazy:!1,immediateRender:!1,time:a,overwrite:"auto",duration:n.duration||Math.abs((a-(u&&"time"in u?u.time:s._time))/s.timeScale())||L,onStart:function(){if(s.pause(),!c){var g=n.duration||Math.abs((a-(u&&"time"in u?u.time:s._time))/s.timeScale());m._dur!==g&&ce(m,g,0,1).render(m._time,!0,!0),c=1}f&&f.apply(m,_||[])}},n));return d?m.render(0):m},e.tweenFromTo=function(r,n,s){return this.tweenTo(n,vt({startAt:{time:xt(this,r)}},s))},e.recent=function(){return this._recent},e.nextLabel=function(r){return r===void 0&&(r=this._time),Bi(this,xt(this,r))},e.previousLabel=function(r){return r===void 0&&(r=this._time),Bi(this,xt(this,r),1)},e.currentLabel=function(r){return arguments.length?this.seek(r,!0):this.previousLabel(this._time+L)},e.shiftChildren=function(r,n,s){s===void 0&&(s=0);for(var a=this._first,o=this.labels,u;a;)a._start>=s&&(a._start+=r,a._end+=r),a=a._next;if(n)for(u in o)o[u]>=s&&(o[u]+=r);return Ht(this)},e.invalidate=function(r){var n=this._first;for(this._lock=0;n;)n.invalidate(r),n=n._next;return l.prototype.invalidate.call(this,r)},e.clear=function(r){r===void 0&&(r=!0);for(var n=this._first,s;n;)s=n._next,this.remove(n),n=s;return this._dp&&(this._time=this._tTime=this._pTime=0),r&&(this.labels={}),Ht(this)},e.totalDuration=function(r){var n=0,s=this,a=s._last,o=wt,u,f,_;if(arguments.length)return s.timeScale((s._repeat<0?s.duration():s.totalDuration())/(s.reversed()?-r:r));if(s._dirty){for(_=s.parent;a;)u=a._prev,a._dirty&&a.totalDuration(),f=a._start,f>o&&s._sort&&a._ts&&!s._lock?(s._lock=1,Ot(s,a,f-a._delay,1)._lock=0):o=f,f<0&&a._ts&&(n-=f,(!_&&!s._dp||_&&_.smoothChildTiming)&&(s._start+=f/s._ts,s._time-=f,s._tTime-=f),s.shiftChildren(-f,!1,-1/0),o=0),a._end>n&&a._ts&&(n=a._end),a=u;ce(s,s===X&&s._time>n?s._time:n,1,1),s._dirty=0}return s._tDur},t.updateRoot=function(r){if(X._ts&&(hr(X,Ne(r,X)),ur=pt.frame),pt.frame>=Vi){Vi+=gt.autoSleep||120;var n=X._first;if((!n||!n._ts)&>.autoSleep&&pt._listeners.length<2){for(;n&&!n._ts;)n=n._next;n||pt.sleep()}}},t}(Se);vt(it.prototype,{_lock:0,_hasPause:0,_forcing:0});var Kn=function(t,e,i,r,n,s,a){var o=new ot(this._pt,t,e,0,1,Lr,null,n),u=0,f=0,_,d,c,m,h,g,v,b;for(o.b=i,o.e=r,i+="",r+="",(v=~r.indexOf("random("))&&(r=Oe(r)),s&&(b=[i,r],s(b,t,e),i=b[0],r=b[1]),d=i.match(je)||[];_=je.exec(r);)m=_[0],h=r.substring(u,_.index),c?c=(c+1)%5:h.substr(-5)==="rgba("&&(c=1),m!==d[f++]&&(g=parseFloat(d[f-1])||0,o._pt={_next:o._pt,p:h||f===1?h:",",s:g,c:m.charAt(1)==="="?le(g,m)-g:parseFloat(m)-g,m:c&&c<4?Math.round:0},u=je.lastIndex);return o.c=u")}),k.duration();else{x={};for(w in m)w==="ease"||w==="easeEach"||Hn(w,m[w],x,m.easeEach);for(w in x)for(A=x[w].sort(function(V,N){return V.t-N.t}),z=0,p=0;po-L&&!f?o:ru&&(d=u)),v=this._yoyo&&m&1,v&&(k=this._yEase,d=u-d),g=de(this._tTime,h),d===a&&!s&&this._initted&&m===g)return this._tTime=_,this;m!==g&&(T&&this._yEase&&Ar(T,v),this.vars.repeatRefresh&&!v&&!this._lock&&d!==h&&this._initted&&(this._lock=s=1,this.render(Z(h*m),!0).invalidate()._lock=0))}if(!this._initted){if(gr(this,f?r:d,s,n,_))return this._tTime=0,this;if(a!==this._time&&!(s&&this.vars.repeatRefresh&&m!==g))return this;if(u!==this._dur)return this.render(r,n,s)}if(this._tTime=_,this._time=d,!this._act&&this._ts&&(this._act=1,this._lazy=0),this.ratio=b=(k||this._ease)(d/u),this._from&&(this.ratio=b=1-b),d&&!a&&!n&&!m&&(mt(this,"onStart"),this._tTime!==_))return this;for(c=this._pt;c;)c.r(b,c.d),c=c._next;T&&T.render(r<0?r:T._dur*T._ease(d/this._dur),n,s)||this._startAt&&(this._zTime=r),this._onUpdate&&!n&&(f&&oi(this,r,n,s),mt(this,"onUpdate")),this._repeat&&m!==g&&this.vars.onRepeat&&!n&&this.parent&&mt(this,"onRepeat"),(_===this._tDur||!_)&&this._tTime===_&&(f&&!this._onUpdate&&oi(this,r,!0,!0),(r||!u)&&(_===this._tDur&&this._ts>0||!_&&this._ts<0)&&Bt(this,1),!n&&!(f&&!a)&&(_||a||v)&&(mt(this,_===o?"onComplete":"onReverseComplete",!0),this._prom&&!(_0)&&this._prom()))}return this},e.targets=function(){return this._targets},e.invalidate=function(r){return(!r||!this.vars.runBackwards)&&(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(r),l.prototype.invalidate.call(this,r)},e.resetTo=function(r,n,s,a,o){Pe||pt.wake(),this._ts||this.play();var u=Math.min(this._dur,(this._dp._time-this._start)*this._ts),f;return this._initted||Pi(this,u),f=this._ease(u/this._dur),Qn(this,r,n,s,a,f,u,o)?this.resetTo(r,n,s,a,1):(qe(this,0),this.parent||cr(this._dp,this,"_first","_last",this._dp._sort?"_start":0),this.render(0))},e.kill=function(r,n){if(n===void 0&&(n="all"),!r&&(!n||n==="all"))return this._lazy=this._pt=0,this.parent?ve(this):this.scrollTrigger&&this.scrollTrigger.kill(!!J),this;if(this.timeline){var s=this.timeline.totalDuration();return this.timeline.killTweensOf(r,n,It&&It.vars.overwrite!==!0)._first||ve(this),this.parent&&s!==this.timeline.totalDuration()&&ce(this,this._dur*this.timeline._tDur/s,0,1),this}var a=this._targets,o=r?Tt(r):a,u=this._ptLookup,f=this._pt,_,d,c,m,h,g,v;if((!n||n==="all")&&Pn(a,o))return n==="all"&&(this._pt=0),ve(this);for(_=this._op=this._op||[],n!=="all"&&(H(n)&&(h={},at(n,function(b){return h[b]=1}),n=h),n=Zn(a,n)),v=a.length;v--;)if(~o.indexOf(a[v])){d=u[v],n==="all"?(_[v]=n,m=d,c={}):(c=_[v]=_[v]||{},m=n);for(h in m)g=d&&d[h],g&&((!("kill"in g.d)||g.d.kill(h)===!0)&&Xe(this,g,"_pt"),delete d[h]),c!=="all"&&(c[h]=1)}return this._initted&&!this._pt&&f&&ve(this),this},t.to=function(r,n){return new t(r,n,arguments[2])},t.from=function(r,n){return we(1,arguments)},t.delayedCall=function(r,n,s,a){return new t(n,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:r,onComplete:n,onReverseComplete:n,onCompleteParams:s,onReverseCompleteParams:s,callbackScope:a})},t.fromTo=function(r,n,s){return we(2,arguments)},t.set=function(r,n){return n.duration=0,n.repeatDelay||(n.repeat=0),new t(r,n)},t.killTweensOf=function(r,n,s){return X.killTweensOf(r,n,s)},t}(Se);vt(Q.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0});at("staggerTo,staggerFrom,staggerFromTo",function(l){Q[l]=function(){var t=new it,e=ui.call(arguments,0);return e.splice(l==="staggerFromTo"?5:4,0,0),t[l].apply(t,e)}});var Si=function(t,e,i){return t[e]=i},Vr=function(t,e,i){return t[e](i)},Jn=function(t,e,i,r){return t[e](r.fp,i)},ts=function(t,e,i){return t.setAttribute(e,i)},Di=function(t,e){return q(t[e])?Vr:vi(t[e])&&t.setAttribute?ts:Si},Ur=function(t,e){return e.set(e.t,e.p,Math.round((e.s+e.c*t)*1e6)/1e6,e)},es=function(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},Lr=function(t,e){var i=e._pt,r="";if(!t&&e.b)r=e.b;else if(t===1&&e.e)r=e.e;else{for(;i;)r=i.p+(i.m?i.m(i.s+i.c*t):Math.round((i.s+i.c*t)*1e4)/1e4)+r,i=i._next;r+=e.c}e.set(e.t,e.p,r,e)},Mi=function(t,e){for(var i=e._pt;i;)i.r(t,i.d),i=i._next},is=function(t,e,i,r){for(var n=this._pt,s;n;)s=n._next,n.p===r&&n.modifier(t,e,i),n=s},rs=function(t){for(var e=this._pt,i,r;e;)r=e._next,e.p===t&&!e.op||e.op===t?Xe(this,e,"_pt"):e.dep||(i=1),e=r;return!i},ns=function(t,e,i,r){r.mSet(t,e,r.m.call(r.tween,i,r.mt),r)},Nr=function(t){for(var e=t._pt,i,r,n,s;e;){for(i=e._next,r=n;r&&r.pr>e.pr;)r=r._next;(e._prev=r?r._prev:s)?e._prev._next=e:n=e,(e._next=r)?r._prev=e:s=e,e=i}t._pt=n},ot=function(){function l(e,i,r,n,s,a,o,u,f){this.t=i,this.s=n,this.c=s,this.p=r,this.r=a||Ur,this.d=o||this,this.set=u||Si,this.pr=f||0,this._next=e,e&&(e._prev=this)}var t=l.prototype;return t.modifier=function(i,r,n){this.mSet=this.mSet||this.set,this.set=ns,this.m=i,this.mt=n,this.tween=r},l}();at(Ci+"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger",function(l){return Ti[l]=1});yt.TweenMax=yt.TweenLite=Q;yt.TimelineLite=yt.TimelineMax=it;X=new it({sortChildren:!1,defaults:he,autoRemoveChildren:!0,id:"root",smoothChildTiming:!0});gt.stringFilter=Dr;var te=[],Ie={},ss=[],$i=0,as=0,ti=function(t){return(Ie[t]||ss).map(function(e){return e()})},di=function(){var t=Date.now(),e=[];t-$i>2&&(ti("matchMediaInit"),te.forEach(function(i){var r=i.queries,n=i.conditions,s,a,o,u;for(a in r)s=kt.matchMedia(r[a]).matches,s&&(o=1),s!==n[a]&&(n[a]=s,u=1);u&&(i.revert(),o&&e.push(i))}),ti("matchMediaRevert"),e.forEach(function(i){return i.onMatch(i,function(r){return i.add(null,r)})}),$i=t,ti("matchMedia"))},Br=function(){function l(e,i){this.selector=i&&fi(i),this.data=[],this._r=[],this.isReverted=!1,this.id=as++,e&&this.add(e)}var t=l.prototype;return t.add=function(i,r,n){q(i)&&(n=r,r=i,i=q);var s=this,a=function(){var u=Y,f=s.selector,_;return u&&u!==s&&u.data.push(s),n&&(s.selector=fi(n)),Y=s,_=r.apply(s,arguments),q(_)&&s._r.push(_),Y=u,s.selector=f,s.isReverted=!1,_};return s.last=a,i===q?a(s,function(o){return s.add(null,o)}):i?s[i]=a:a},t.ignore=function(i){var r=Y;Y=null,i(this),Y=r},t.getTweens=function(){var i=[];return this.data.forEach(function(r){return r instanceof l?i.push.apply(i,r.getTweens()):r instanceof Q&&!(r.parent&&r.parent.data==="nested")&&i.push(r)}),i},t.clear=function(){this._r.length=this.data.length=0},t.kill=function(i,r){var n=this;if(i?function(){for(var a=n.getTweens(),o=n.data.length,u;o--;)u=n.data[o],u.data==="isFlip"&&(u.revert(),u.getChildren(!0,!0,!1).forEach(function(f){return a.splice(a.indexOf(f),1)}));for(a.map(function(f){return{g:f._dur||f._delay||f._sat&&!f._sat.vars.immediateRender?f.globalTime(0):-1/0,t:f}}).sort(function(f,_){return _.g-f.g||-1/0}).forEach(function(f){return f.t.revert(i)}),o=n.data.length;o--;)u=n.data[o],u instanceof it?u.data!=="nested"&&(u.scrollTrigger&&u.scrollTrigger.revert(),u.kill()):!(u instanceof Q)&&u.revert&&u.revert(i);n._r.forEach(function(f){return f(i,n)}),n.isReverted=!0}():this.data.forEach(function(a){return a.kill&&a.kill()}),this.clear(),r)for(var s=te.length;s--;)te[s].id===this.id&&te.splice(s,1)},t.revert=function(i){this.kill(i||{})},l}(),os=function(){function l(e){this.contexts=[],this.scope=e,Y&&Y.data.push(this)}var t=l.prototype;return t.add=function(i,r,n){Dt(i)||(i={matches:i});var s=new Br(0,n||this.scope),a=s.conditions={},o,u,f;Y&&!s.selector&&(s.selector=Y.selector),this.contexts.push(s),r=s.add("onMatch",r),s.queries=i;for(u in i)u==="all"?f=1:(o=kt.matchMedia(i[u]),o&&(te.indexOf(s)<0&&te.push(s),(a[u]=o.matches)&&(f=1),o.addListener?o.addListener(di):o.addEventListener("change",di)));return f&&r(s,function(_){return s.add(null,_)}),this},t.revert=function(i){this.kill(i||{})},t.kill=function(i){this.contexts.forEach(function(r){return r.kill(i,!0)})},l}(),Be={registerPlugin:function(){for(var t=arguments.length,e=new Array(t),i=0;i1){var r=t.map(function(f){return ut.quickSetter(f,e,i)}),n=r.length;return function(f){for(var _=n;_--;)r[_](f)}}t=t[0]||{};var s=ct[e],a=Zt(t),o=a.harness&&(a.harness.aliases||{})[e]||e,u=s?function(f){var _=new s;oe._pt=0,_.init(t,i?f+i:f,oe,0,[t]),_.render(1,_),oe._pt&&Mi(1,oe)}:a.set(t,o);return s?u:function(f){return u(t,o,i?f+i:f,a,1)}},quickTo:function(t,e,i){var r,n=ut.to(t,vt((r={},r[e]="+=0.1",r.paused=!0,r.stagger=0,r),i||{})),s=function(o,u,f){return n.resetTo(e,o,u,f)};return s.tween=n,s},isTweening:function(t){return X.getTweensOf(t,!0).length>0},defaults:function(t){return t&&t.ease&&(t.ease=Jt(t.ease,he.ease)),Ui(he,t||{})},config:function(t){return Ui(gt,t||{})},registerEffect:function(t){var e=t.name,i=t.effect,r=t.plugins,n=t.defaults,s=t.extendTimeline;(r||"").split(",").forEach(function(a){return a&&!ct[a]&&!yt[a]&&Ce(e+" effect requires "+a+" plugin.")}),Qe[e]=function(a,o,u){return i(Tt(a),vt(o||{},n),u)},s&&(it.prototype[e]=function(a,o,u){return this.add(Qe[e](a,Dt(o)?o:(u=o)&&{},this),u)})},registerEase:function(t,e){R[t]=Jt(e)},parseEase:function(t,e){return arguments.length?Jt(t,e):R},getById:function(t){return X.getById(t)},exportRoot:function(t,e){t===void 0&&(t={});var i=new it(t),r,n;for(i.smoothChildTiming=st(t.smoothChildTiming),X.remove(i),i._dp=0,i._time=i._tTime=X._time,r=X._first;r;)n=r._next,(e||!(!r._dur&&r instanceof Q&&r.vars.onComplete===r._targets[0]))&&Ot(i,r,r._start-r._delay),r=n;return Ot(X,i,0),i},context:function(t,e){return t?new Br(t,e):Y},matchMedia:function(t){return new os(t)},matchMediaRefresh:function(){return te.forEach(function(t){var e=t.conditions,i,r;for(r in e)e[r]&&(e[r]=!1,i=1);i&&t.revert()})||di()},addEventListener:function(t,e){var i=Ie[t]||(Ie[t]=[]);~i.indexOf(e)||i.push(e)},removeEventListener:function(t,e){var i=Ie[t],r=i&&i.indexOf(e);r>=0&&i.splice(r,1)},utils:{wrap:Ln,wrapYoyo:Nn,distribute:br,random:wr,snap:xr,normalize:Un,getUnit:tt,clamp:zn,splitColor:Pr,toArray:Tt,selector:fi,mapRange:Cr,pipe:In,unitize:Vn,interpolate:Bn,shuffle:vr},install:or,effects:Qe,ticker:pt,updateRoot:it.updateRoot,plugins:ct,globalTimeline:X,core:{PropTween:ot,globals:lr,Tween:Q,Timeline:it,Animation:Se,getCache:Zt,_removeLinkedListItem:Xe,reverting:function(){return J},context:function(t){return t&&Y&&(Y.data.push(t),t._ctx=Y),Y},suppressOverwrites:function(t){return yi=t}}};at("to,from,fromTo,delayedCall,set,killTweensOf",function(l){return Be[l]=Q[l]});pt.add(it.updateRoot);oe=Be.to({},{duration:0});var ls=function(t,e){for(var i=t._pt;i&&i.p!==e&&i.op!==e&&i.fp!==e;)i=i._next;return i},us=function(t,e){var i=t._targets,r,n,s;for(r in e)for(n=i.length;n--;)s=t._ptLookup[n][r],s&&(s=s.d)&&(s._pt&&(s=ls(s,r)),s&&s.modifier&&s.modifier(e[r],t,i[n],r))},ei=function(t,e){return{name:t,rawVars:1,init:function(r,n,s){s._onInit=function(a){var o,u;if(H(n)&&(o={},at(n,function(f){return o[f]=1}),n=o),e){o={};for(u in n)o[u]=e(n[u]);n=o}us(a,n)}}}},ut=Be.registerPlugin({name:"attr",init:function(t,e,i,r,n){var s,a,o;this.tween=i;for(s in e)o=t.getAttribute(s)||"",a=this.add(t,"setAttribute",(o||0)+"",e[s],r,n,0,0,s),a.op=s,a.b=o,this._props.push(s)},render:function(t,e){for(var i=e._pt;i;)J?i.set(i.t,i.p,i.b,i):i.r(t,i.d),i=i._next}},{name:"endArray",init:function(t,e){for(var i=e.length;i--;)this.add(t,i,t[i]||0,e[i],0,0,0,0,0,1)}},ei("roundProps",hi),ei("modifiers"),ei("snap",xr))||Be;Q.version=it.version=ut.version="3.12.7";ar=1;bi()&&pe();R.Power0;R.Power1;R.Power2;R.Power3;R.Power4;R.Linear;R.Quad;R.Cubic;R.Quart;R.Quint;R.Strong;R.Elastic;R.Back;R.SteppedEase;R.Bounce;R.Sine;R.Expo;R.Circ;/*! - * CSSPlugin 3.12.7 - * https://gsap.com - * - * Copyright 2008-2025, GreenSock. All rights reserved. - * Subject to the terms at https://gsap.com/standard-license or for - * Club GSAP members, the agreement issued with that membership. - * @author: Jack Doyle, jack@greensock.com -*/var Xi,Vt,ue,Ai,Qt,Wi,Ri,fs=function(){return typeof window<"u"},Et={},jt=180/Math.PI,fe=Math.PI/180,se=Math.atan2,qi=1e8,Ei=/([A-Z])/g,hs=/(left|right|width|margin|padding|x)/i,_s=/[\s,\(]\S/,Pt={autoAlpha:"opacity,visibility",scale:"scaleX,scaleY",alpha:"opacity"},ci=function(t,e){return e.set(e.t,e.p,Math.round((e.s+e.c*t)*1e4)/1e4+e.u,e)},ds=function(t,e){return e.set(e.t,e.p,t===1?e.e:Math.round((e.s+e.c*t)*1e4)/1e4+e.u,e)},cs=function(t,e){return e.set(e.t,e.p,t?Math.round((e.s+e.c*t)*1e4)/1e4+e.u:e.b,e)},ps=function(t,e){var i=e.s+e.c*t;e.set(e.t,e.p,~~(i+(i<0?-.5:.5))+e.u,e)},Yr=function(t,e){return e.set(e.t,e.p,t?e.e:e.b,e)},$r=function(t,e){return e.set(e.t,e.p,t!==1?e.b:e.e,e)},ms=function(t,e,i){return t.style[e]=i},gs=function(t,e,i){return t.style.setProperty(e,i)},ys=function(t,e,i){return t._gsap[e]=i},vs=function(t,e,i){return t._gsap.scaleX=t._gsap.scaleY=i},bs=function(t,e,i,r,n){var s=t._gsap;s.scaleX=s.scaleY=i,s.renderTransform(n,s)},xs=function(t,e,i,r,n){var s=t._gsap;s[e]=i,s.renderTransform(n,s)},W="transform",lt=W+"Origin",ws=function l(t,e){var i=this,r=this.target,n=r.style,s=r._gsap;if(t in Et&&n){if(this.tfm=this.tfm||{},t!=="transform")t=Pt[t]||t,~t.indexOf(",")?t.split(",").forEach(function(a){return i.tfm[a]=At(r,a)}):this.tfm[t]=s.x?s[t]:At(r,t),t===lt&&(this.tfm.zOrigin=s.zOrigin);else return Pt.transform.split(",").forEach(function(a){return l.call(i,a,e)});if(this.props.indexOf(W)>=0)return;s.svg&&(this.svgo=r.getAttribute("data-svg-origin"),this.props.push(lt,e,"")),t=W}(n||e)&&this.props.push(t,e,n[t])},Xr=function(t){t.translate&&(t.removeProperty("translate"),t.removeProperty("scale"),t.removeProperty("rotate"))},Ts=function(){var t=this.props,e=this.target,i=e.style,r=e._gsap,n,s;for(n=0;n=0?Gi[s]:"")+t},mi=function(){fs()&&window.document&&(Xi=window,Vt=Xi.document,ue=Vt.documentElement,Qt=pi("div")||{style:{}},pi("div"),W=me(W),lt=W+"Origin",Qt.style.cssText="border-width:0;line-height:0;position:absolute;padding:0",qr=!!me("perspective"),Ri=ut.core.reverting,Ai=1)},Ki=function(t){var e=t.ownerSVGElement,i=pi("svg",e&&e.getAttribute("xmlns")||"http://www.w3.org/2000/svg"),r=t.cloneNode(!0),n;r.style.display="block",i.appendChild(r),ue.appendChild(i);try{n=r.getBBox()}catch{}return i.removeChild(r),ue.removeChild(i),n},ji=function(t,e){for(var i=e.length;i--;)if(t.hasAttribute(e[i]))return t.getAttribute(e[i])},Gr=function(t){var e,i;try{e=t.getBBox()}catch{e=Ki(t),i=1}return e&&(e.width||e.height)||i||(e=Ki(t)),e&&!e.width&&!e.x&&!e.y?{x:+ji(t,["x","cx","x1"])||0,y:+ji(t,["y","cy","y1"])||0,width:0,height:0}:e},Kr=function(t){return!!(t.getCTM&&(!t.parentNode||t.ownerSVGElement)&&Gr(t))},ee=function(t,e){if(e){var i=t.style,r;e in Et&&e!==lt&&(e=W),i.removeProperty?(r=e.substr(0,2),(r==="ms"||e.substr(0,6)==="webkit")&&(e="-"+e),i.removeProperty(r==="--"?e:e.replace(Ei,"-$1").toLowerCase())):i.removeAttribute(e)}},Ut=function(t,e,i,r,n,s){var a=new ot(t._pt,e,i,0,1,s?$r:Yr);return t._pt=a,a.b=r,a.e=n,t._props.push(i),a},Qi={deg:1,rad:1,turn:1},Cs={grid:1,flex:1},Yt=function l(t,e,i,r){var n=parseFloat(i)||0,s=(i+"").trim().substr((n+"").length)||"px",a=Qt.style,o=hs.test(e),u=t.tagName.toLowerCase()==="svg",f=(u?"client":"offset")+(o?"Width":"Height"),_=100,d=r==="px",c=r==="%",m,h,g,v;if(r===s||!n||Qi[r]||Qi[s])return n;if(s!=="px"&&!d&&(n=l(t,e,i,"px")),v=t.getCTM&&Kr(t),(c||s==="%")&&(Et[e]||~e.indexOf("adius")))return m=v?t.getBBox()[o?"width":"height"]:t[f],K(c?n/m*_:n/100*m);if(a[o?"width":"height"]=_+(d?s:r),h=r!=="rem"&&~e.indexOf("adius")||r==="em"&&t.appendChild&&!u?t:t.parentNode,v&&(h=(t.ownerSVGElement||{}).parentNode),(!h||h===Vt||!h.appendChild)&&(h=Vt.body),g=h._gsap,g&&c&&g.width&&o&&g.time===pt.time&&!g.uncache)return K(n/g.width*_);if(c&&(e==="height"||e==="width")){var b=t.style[e];t.style[e]=_+r,m=t[f],b?t.style[e]=b:ee(t,e)}else(c||s==="%")&&!Cs[St(h,"display")]&&(a.position=St(t,"position")),h===t&&(a.position="static"),h.appendChild(Qt),m=Qt[f],h.removeChild(Qt),a.position="absolute";return o&&c&&(g=Zt(h),g.time=pt.time,g.width=h[f]),K(d?m*n/_:m&&n?_/m*n:0)},At=function(t,e,i,r){var n;return Ai||mi(),e in Pt&&e!=="transform"&&(e=Pt[e],~e.indexOf(",")&&(e=e.split(",")[0])),Et[e]&&e!=="transform"?(n=Me(t,r),n=e!=="transformOrigin"?n[e]:n.svg?n.origin:$e(St(t,lt))+" "+n.zOrigin+"px"):(n=t.style[e],(!n||n==="auto"||r||~(n+"").indexOf("calc("))&&(n=Ye[e]&&Ye[e](t,e,i)||St(t,e)||fr(t,e)||(e==="opacity"?1:0))),i&&!~(n+"").trim().indexOf(" ")?Yt(t,e,n,i)+i:n},ks=function(t,e,i,r){if(!i||i==="none"){var n=me(e,t,1),s=n&&St(t,n,1);s&&s!==i?(e=n,i=s):e==="borderColor"&&(i=St(t,"borderTopColor"))}var a=new ot(this._pt,t.style,e,0,1,Lr),o=0,u=0,f,_,d,c,m,h,g,v,b,T,k,p;if(a.b=i,a.e=r,i+="",r+="",r==="auto"&&(h=t.style[e],t.style[e]=r,r=St(t,e)||r,h?t.style[e]=h:ee(t,e)),f=[i,r],Dr(f),i=f[0],r=f[1],d=i.match(ae)||[],p=r.match(ae)||[],p.length){for(;_=ae.exec(r);)g=_[0],b=r.substring(o,_.index),m?m=(m+1)%5:(b.substr(-5)==="rgba("||b.substr(-5)==="hsla(")&&(m=1),g!==(h=d[u++]||"")&&(c=parseFloat(h)||0,k=h.substr((c+"").length),g.charAt(1)==="="&&(g=le(c,g)+k),v=parseFloat(g),T=g.substr((v+"").length),o=ae.lastIndex-T.length,T||(T=T||gt.units[e]||k,o===r.length&&(r+=T,a.e+=T)),k!==T&&(c=Yt(t,e,h,T)||0),a._pt={_next:a._pt,p:b||u===1?b:",",s:c,c:v-c,m:m&&m<4||e==="zIndex"?Math.round:0});a.c=o-1;)a=n[u],Et[a]&&(o=1,a=a==="transformOrigin"?lt:W),ee(i,a);o&&(ee(i,W),s&&(s.svg&&i.removeAttribute("transform"),r.scale=r.rotate=r.translate="none",Me(i,1),s.uncache=1,Xr(r)))}},Ye={clearProps:function(t,e,i,r,n){if(n.data!=="isFromStart"){var s=t._pt=new ot(t._pt,e,i,0,0,Ps);return s.u=r,s.pr=-10,s.tween=n,t._props.push(i),1}}},De=[1,0,0,1,0,0],jr={},Qr=function(t){return t==="matrix(1, 0, 0, 1, 0, 0)"||t==="none"||!t},Hi=function(t){var e=St(t,W);return Qr(e)?De:e.substr(7).match(rr).map(K)},zi=function(t,e){var i=t._gsap||Zt(t),r=t.style,n=Hi(t),s,a,o,u;return i.svg&&t.getAttribute("transform")?(o=t.transform.baseVal.consolidate().matrix,n=[o.a,o.b,o.c,o.d,o.e,o.f],n.join(",")==="1,0,0,1,0,0"?De:n):(n===De&&!t.offsetParent&&t!==ue&&!i.svg&&(o=r.display,r.display="block",s=t.parentNode,(!s||!t.offsetParent&&!t.getBoundingClientRect().width)&&(u=1,a=t.nextElementSibling,ue.appendChild(t)),n=Hi(t),o?r.display=o:ee(t,"display"),u&&(a?s.insertBefore(t,a):s?s.appendChild(t):ue.removeChild(t))),e&&n.length>6?[n[0],n[1],n[4],n[5],n[12],n[13]]:n)},gi=function(t,e,i,r,n,s){var a=t._gsap,o=n||zi(t,!0),u=a.xOrigin||0,f=a.yOrigin||0,_=a.xOffset||0,d=a.yOffset||0,c=o[0],m=o[1],h=o[2],g=o[3],v=o[4],b=o[5],T=e.split(" "),k=parseFloat(T[0])||0,p=parseFloat(T[1])||0,x,C,w,y;i?o!==De&&(C=c*g-m*h)&&(w=k*(g/C)+p*(-h/C)+(h*b-g*v)/C,y=k*(-m/C)+p*(c/C)-(c*b-m*v)/C,k=w,p=y):(x=Gr(t),k=x.x+(~T[0].indexOf("%")?k/100*x.width:k),p=x.y+(~(T[1]||T[0]).indexOf("%")?p/100*x.height:p)),r||r!==!1&&a.smooth?(v=k-u,b=p-f,a.xOffset=_+(v*c+b*h)-v,a.yOffset=d+(v*m+b*g)-b):a.xOffset=a.yOffset=0,a.xOrigin=k,a.yOrigin=p,a.smooth=!!r,a.origin=e,a.originIsAbsolute=!!i,t.style[lt]="0px 0px",s&&(Ut(s,a,"xOrigin",u,k),Ut(s,a,"yOrigin",f,p),Ut(s,a,"xOffset",_,a.xOffset),Ut(s,a,"yOffset",d,a.yOffset)),t.setAttribute("data-svg-origin",k+" "+p)},Me=function(t,e){var i=t._gsap||new Er(t);if("x"in i&&!e&&!i.uncache)return i;var r=t.style,n=i.scaleX<0,s="px",a="deg",o=getComputedStyle(t),u=St(t,lt)||"0",f,_,d,c,m,h,g,v,b,T,k,p,x,C,w,y,M,I,z,A,B,j,V,N,ft,re,Xt,O,bt,P,F,ht;return f=_=d=h=g=v=b=T=k=0,c=m=1,i.svg=!!(t.getCTM&&Kr(t)),o.translate&&((o.translate!=="none"||o.scale!=="none"||o.rotate!=="none")&&(r[W]=(o.translate!=="none"?"translate3d("+(o.translate+" 0 0").split(" ").slice(0,3).join(", ")+") ":"")+(o.rotate!=="none"?"rotate("+o.rotate+") ":"")+(o.scale!=="none"?"scale("+o.scale.split(" ").join(",")+") ":"")+(o[W]!=="none"?o[W]:"")),r.scale=r.rotate=r.translate="none"),C=zi(t,i.svg),i.svg&&(i.uncache?(ft=t.getBBox(),u=i.xOrigin-ft.x+"px "+(i.yOrigin-ft.y)+"px",N=""):N=!e&&t.getAttribute("data-svg-origin"),gi(t,N||u,!!N||i.originIsAbsolute,i.smooth!==!1,C)),p=i.xOrigin||0,x=i.yOrigin||0,C!==De&&(I=C[0],z=C[1],A=C[2],B=C[3],f=j=C[4],_=V=C[5],C.length===6?(c=Math.sqrt(I*I+z*z),m=Math.sqrt(B*B+A*A),h=I||z?se(z,I)*jt:0,b=A||B?se(A,B)*jt+h:0,b&&(m*=Math.abs(Math.cos(b*fe))),i.svg&&(f-=p-(p*I+x*A),_-=x-(p*z+x*B))):(ht=C[6],P=C[7],Xt=C[8],O=C[9],bt=C[10],F=C[11],f=C[12],_=C[13],d=C[14],w=se(ht,bt),g=w*jt,w&&(y=Math.cos(-w),M=Math.sin(-w),N=j*y+Xt*M,ft=V*y+O*M,re=ht*y+bt*M,Xt=j*-M+Xt*y,O=V*-M+O*y,bt=ht*-M+bt*y,F=P*-M+F*y,j=N,V=ft,ht=re),w=se(-A,bt),v=w*jt,w&&(y=Math.cos(-w),M=Math.sin(-w),N=I*y-Xt*M,ft=z*y-O*M,re=A*y-bt*M,F=B*M+F*y,I=N,z=ft,A=re),w=se(z,I),h=w*jt,w&&(y=Math.cos(w),M=Math.sin(w),N=I*y+z*M,ft=j*y+V*M,z=z*y-I*M,V=V*y-j*M,I=N,j=ft),g&&Math.abs(g)+Math.abs(h)>359.9&&(g=h=0,v=180-v),c=K(Math.sqrt(I*I+z*z+A*A)),m=K(Math.sqrt(V*V+ht*ht)),w=se(j,V),b=Math.abs(w)>2e-4?w*jt:0,k=F?1/(F<0?-F:F):0),i.svg&&(N=t.getAttribute("transform"),i.forceCSS=t.setAttribute("transform","")||!Qr(St(t,W)),N&&t.setAttribute("transform",N))),Math.abs(b)>90&&Math.abs(b)<270&&(n?(c*=-1,b+=h<=0?180:-180,h+=h<=0?180:-180):(m*=-1,b+=b<=0?180:-180)),e=e||i.uncache,i.x=f-((i.xPercent=f&&(!e&&i.xPercent||(Math.round(t.offsetWidth/2)===Math.round(-f)?-50:0)))?t.offsetWidth*i.xPercent/100:0)+s,i.y=_-((i.yPercent=_&&(!e&&i.yPercent||(Math.round(t.offsetHeight/2)===Math.round(-_)?-50:0)))?t.offsetHeight*i.yPercent/100:0)+s,i.z=d+s,i.scaleX=K(c),i.scaleY=K(m),i.rotation=K(h)+a,i.rotationX=K(g)+a,i.rotationY=K(v)+a,i.skewX=b+a,i.skewY=T+a,i.transformPerspective=k+s,(i.zOrigin=parseFloat(u.split(" ")[2])||!e&&i.zOrigin||0)&&(r[lt]=$e(u)),i.xOffset=i.yOffset=0,i.force3D=gt.force3D,i.renderTransform=i.svg?Ds:qr?Zr:Ss,i.uncache=0,i},$e=function(t){return(t=t.split(" "))[0]+" "+t[1]},ii=function(t,e,i){var r=tt(e);return K(parseFloat(e)+parseFloat(Yt(t,"x",i+"px",r)))+r},Ss=function(t,e){e.z="0px",e.rotationY=e.rotationX="0deg",e.force3D=0,Zr(t,e)},Gt="0deg",ye="0px",Kt=") ",Zr=function(t,e){var i=e||this,r=i.xPercent,n=i.yPercent,s=i.x,a=i.y,o=i.z,u=i.rotation,f=i.rotationY,_=i.rotationX,d=i.skewX,c=i.skewY,m=i.scaleX,h=i.scaleY,g=i.transformPerspective,v=i.force3D,b=i.target,T=i.zOrigin,k="",p=v==="auto"&&t&&t!==1||v===!0;if(T&&(_!==Gt||f!==Gt)){var x=parseFloat(f)*fe,C=Math.sin(x),w=Math.cos(x),y;x=parseFloat(_)*fe,y=Math.cos(x),s=ii(b,s,C*y*-T),a=ii(b,a,-Math.sin(x)*-T),o=ii(b,o,w*y*-T+T)}g!==ye&&(k+="perspective("+g+Kt),(r||n)&&(k+="translate("+r+"%, "+n+"%) "),(p||s!==ye||a!==ye||o!==ye)&&(k+=o!==ye||p?"translate3d("+s+", "+a+", "+o+") ":"translate("+s+", "+a+Kt),u!==Gt&&(k+="rotate("+u+Kt),f!==Gt&&(k+="rotateY("+f+Kt),_!==Gt&&(k+="rotateX("+_+Kt),(d!==Gt||c!==Gt)&&(k+="skew("+d+", "+c+Kt),(m!==1||h!==1)&&(k+="scale("+m+", "+h+Kt),b.style[W]=k||"translate(0, 0)"},Ds=function(t,e){var i=e||this,r=i.xPercent,n=i.yPercent,s=i.x,a=i.y,o=i.rotation,u=i.skewX,f=i.skewY,_=i.scaleX,d=i.scaleY,c=i.target,m=i.xOrigin,h=i.yOrigin,g=i.xOffset,v=i.yOffset,b=i.forceCSS,T=parseFloat(s),k=parseFloat(a),p,x,C,w,y;o=parseFloat(o),u=parseFloat(u),f=parseFloat(f),f&&(f=parseFloat(f),u+=f,o+=f),o||u?(o*=fe,u*=fe,p=Math.cos(o)*_,x=Math.sin(o)*_,C=Math.sin(o-u)*-d,w=Math.cos(o-u)*d,u&&(f*=fe,y=Math.tan(u-f),y=Math.sqrt(1+y*y),C*=y,w*=y,f&&(y=Math.tan(f),y=Math.sqrt(1+y*y),p*=y,x*=y)),p=K(p),x=K(x),C=K(C),w=K(w)):(p=_,w=d,x=C=0),(T&&!~(s+"").indexOf("px")||k&&!~(a+"").indexOf("px"))&&(T=Yt(c,"x",s,"px"),k=Yt(c,"y",a,"px")),(m||h||g||v)&&(T=K(T+m-(m*p+h*C)+g),k=K(k+h-(m*x+h*w)+v)),(r||n)&&(y=c.getBBox(),T=K(T+r/100*y.width),k=K(k+n/100*y.height)),y="matrix("+p+","+x+","+C+","+w+","+T+","+k+")",c.setAttribute("transform",y),b&&(c.style[W]=y)},Ms=function(t,e,i,r,n){var s=360,a=H(n),o=parseFloat(n)*(a&&~n.indexOf("rad")?jt:1),u=o-r,f=r+u+"deg",_,d;return a&&(_=n.split("_")[1],_==="short"&&(u%=s,u!==u%(s/2)&&(u+=u<0?s:-s)),_==="cw"&&u<0?u=(u+s*qi)%s-~~(u/s)*s:_==="ccw"&&u>0&&(u=(u-s*qi)%s-~~(u/s)*s)),t._pt=d=new ot(t._pt,e,i,r,u,ds),d.e=f,d.u="deg",t._props.push(i),d},Ji=function(t,e){for(var i in e)t[i]=e[i];return t},As=function(t,e,i){var r=Ji({},i._gsap),n="perspective,force3D,transformOrigin,svgOrigin",s=i.style,a,o,u,f,_,d,c,m;r.svg?(u=i.getAttribute("transform"),i.setAttribute("transform",""),s[W]=e,a=Me(i,1),ee(i,W),i.setAttribute("transform",u)):(u=getComputedStyle(i)[W],s[W]=e,a=Me(i,1),s[W]=u);for(o in Et)u=r[o],f=a[o],u!==f&&n.indexOf(o)<0&&(c=tt(u),m=tt(f),_=c!==m?Yt(i,o,u,m):parseFloat(u),d=parseFloat(f),t._pt=new ot(t._pt,a,o,_,d-_,ci),t._pt.u=m||0,t._props.push(o));Ji(a,r)};at("padding,margin,Width,Radius",function(l,t){var e="Top",i="Right",r="Bottom",n="Left",s=(t<3?[e,i,r,n]:[e+n,e+i,r+i,r+n]).map(function(a){return t<2?l+a:"border"+a+l});Ye[t>1?"border"+l:l]=function(a,o,u,f,_){var d,c;if(arguments.length<4)return d=s.map(function(m){return At(a,m,u)}),c=d.join(" "),c.split(d[0]).length===5?d[0]:c;d=(f+"").split(" "),c={},s.forEach(function(m,h){return c[m]=d[h]=d[h]||d[(h-1)/2|0]}),a.init(o,c,_)}});var Hr={name:"css",register:mi,targetTest:function(t){return t.style&&t.nodeType},init:function(t,e,i,r,n){var s=this._props,a=t.style,o=i.vars.startAt,u,f,_,d,c,m,h,g,v,b,T,k,p,x,C,w;Ai||mi(),this.styles=this.styles||Wr(t),w=this.styles.props,this.tween=i;for(h in e)if(h!=="autoRound"&&(f=e[h],!(ct[h]&&zr(h,e,i,r,t,n)))){if(c=typeof f,m=Ye[h],c==="function"&&(f=f.call(i,r,t,n),c=typeof f),c==="string"&&~f.indexOf("random(")&&(f=Oe(f)),m)m(this,t,h,f,i)&&(C=1);else if(h.substr(0,2)==="--")u=(getComputedStyle(t).getPropertyValue(h)+"").trim(),f+="",Nt.lastIndex=0,Nt.test(u)||(g=tt(u),v=tt(f)),v?g!==v&&(u=Yt(t,h,u,v)+v):g&&(f+=g),this.add(a,"setProperty",u,f,r,n,0,0,h),s.push(h),w.push(h,0,a[h]);else if(c!=="undefined"){if(o&&h in o?(u=typeof o[h]=="function"?o[h].call(i,r,t,n):o[h],H(u)&&~u.indexOf("random(")&&(u=Oe(u)),tt(u+"")||u==="auto"||(u+=gt.units[h]||tt(At(t,h))||""),(u+"").charAt(1)==="="&&(u=At(t,h))):u=At(t,h),d=parseFloat(u),b=c==="string"&&f.charAt(1)==="="&&f.substr(0,2),b&&(f=f.substr(2)),_=parseFloat(f),h in Pt&&(h==="autoAlpha"&&(d===1&&At(t,"visibility")==="hidden"&&_&&(d=0),w.push("visibility",0,a.visibility),Ut(this,a,"visibility",d?"inherit":"hidden",_?"inherit":"hidden",!_)),h!=="scale"&&h!=="transform"&&(h=Pt[h],~h.indexOf(",")&&(h=h.split(",")[0]))),T=h in Et,T){if(this.styles.save(h),k||(p=t._gsap,p.renderTransform&&!e.parseTransform||Me(t,e.parseTransform),x=e.smoothOrigin!==!1&&p.smooth,k=this._pt=new ot(this._pt,a,W,0,1,p.renderTransform,p,0,-1),k.dep=1),h==="scale")this._pt=new ot(this._pt,p,"scaleY",p.scaleY,(b?le(p.scaleY,b+_):_)-p.scaleY||0,ci),this._pt.u=0,s.push("scaleY",h),h+="X";else if(h==="transformOrigin"){w.push(lt,0,a[lt]),f=Os(f),p.svg?gi(t,f,0,x,0,this):(v=parseFloat(f.split(" ")[2])||0,v!==p.zOrigin&&Ut(this,p,"zOrigin",p.zOrigin,v),Ut(this,a,h,$e(u),$e(f)));continue}else if(h==="svgOrigin"){gi(t,f,1,x,0,this);continue}else if(h in jr){Ms(this,p,h,d,b?le(d,b+f):f);continue}else if(h==="smoothOrigin"){Ut(this,p,"smooth",p.smooth,f);continue}else if(h==="force3D"){p[h]=f;continue}else if(h==="transform"){As(this,f,t);continue}}else h in a||(h=me(h)||h);if(T||(_||_===0)&&(d||d===0)&&!_s.test(f)&&h in a)g=(u+"").substr((d+"").length),_||(_=0),v=tt(f)||(h in gt.units?gt.units[h]:g),g!==v&&(d=Yt(t,h,u,v)),this._pt=new ot(this._pt,T?p:a,h,d,(b?le(d,b+_):_)-d,!T&&(v==="px"||h==="zIndex")&&e.autoRound!==!1?ps:ci),this._pt.u=v||0,g!==v&&v!=="%"&&(this._pt.b=u,this._pt.r=cs);else if(h in a)ks.call(this,t,h,u,b?b+f:f);else if(h in t)this.add(t,h,u||t[h],b?b+f:f,r,n);else if(h!=="parseTransform"){wi(h,f);continue}T||(h in a?w.push(h,0,a[h]):typeof t[h]=="function"?w.push(h,2,t[h]()):w.push(h,1,u||t[h])),s.push(h)}}C&&Nr(this)},render:function(t,e){if(e.tween._time||!Ri())for(var i=e._pt;i;)i.r(t,i.d),i=i._next;else e.styles.revert()},get:At,aliases:Pt,getSetter:function(t,e,i){var r=Pt[e];return r&&r.indexOf(",")<0&&(e=r),e in Et&&e!==lt&&(t._gsap.x||At(t,"x"))?i&&Wi===i?e==="scale"?vs:ys:(Wi=i||{})&&(e==="scale"?bs:xs):t.style&&!vi(t.style[e])?ms:~e.indexOf("-")?gs:Di(t,e)},core:{_removeProperty:ee,_getMatrix:zi}};ut.utils.checkPrefix=me;ut.core.getStyleSaver=Wr;(function(l,t,e,i){var r=at(l+","+t+","+e,function(n){Et[n]=1});at(t,function(n){gt.units[n]="deg",jr[n]=1}),Pt[r[13]]=l+","+t,at(i,function(n){var s=n.split(":");Pt[s[1]]=r[s[0]]})})("x,y,z,scale,scaleX,scaleY,xPercent,yPercent","rotation,rotationX,rotationY,skewX,skewY","transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective","0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY");at("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective",function(l){gt.units[l]="px"});ut.registerPlugin(Hr);var Jr=ut.registerPlugin(Hr)||ut;Jr.core.Tween;const Rs={class:"__container_traffic_config_form"},Es=tn({__name:"formView",setup(l){en(p=>({"6abd4bde":G(Ft)}));const t=rn(nn.PROVIDE_INJECT_KEY);sn();const e=an(),i=on(),r=Ge(e.params.isEdit==="1");_n().toClipboard;const n=Ke(new mn),s=n,a=Ke([{label:"应用",value:"application"},{label:"服务",value:"service"}]),o=[{label:"provider",value:"provider"},{label:"consumer",value:"consumer"}],u=[{label:"wildcard",value:"wildcard"},{label:"cird",value:"cird"},{label:"exact",value:"exact"}],f=[{label:"exact",value:"exact"},{label:"prefix",value:"prefix"},{label:"regex",value:"regex"},{label:"noempty",value:"noempty"},{label:"empty",value:"empty"},{label:"wildcard",value:"wildcard"}],_=Fi(()=>p=>p.descMatches()),d=Fi(()=>p=>p.descParameters()),c=()=>{const p=document.getElementById("layout-tab-body");s.config.push(new gn(null)),Ii(()=>{Jr.to(p,{duration:1,scrollTop:p.scrollHeight,ease:"power2.out"})})},m=(p,x,C)=>{const w=n.config[p];w[x]=w[x].filter(y=>w[C].find(M=>M===y.key)),w[C].forEach(y=>{w[x].find(M=>M.key===y)||w[x].push({key:y,relation:x==="parameters"?"=":"exact",value:""})})};function h(p){p&&n.fromApiOutput(p)}Ge(!0),ln(async()=>{await T()});const g=p=>{fn.confirm({title:"确认删除该配置么?",onOk(){s.config.splice(p,1)}})},v=Ge(!1);async function b(){v.value=!0;try{t.dynamicConfigForm.data=null,await T(),ge.success("config reset success")}finally{v.value=!1}}async function T(){var p,x,C;if((p=t.dynamicConfigForm)!=null&&p.data)n.fromData(t.dynamicConfigForm.data);else{if(((x=e.params)==null?void 0:x.pathId)!=="_tmp"){const w=await dn({name:(C=e.params)==null?void 0:C.pathId});h(w.data)}else n.basicInfo.ruleName="_tmp",r.value=!0,n.isAdd=!0;t.dynamicConfigForm=Ke({data:n})}}async function k(){var p;v.value=!0;try{let x=s.toApiInput(!0);if(n.isAdd===!0){cn({name:s.basicInfo.key+".configurators"},x).then(w=>{t.dynamicConfigForm.data=null,Ii(()=>{i.replace("/traffic/dynamicConfig"),ge.success("config add success")})}).catch(w=>{ge.error("添加失败: "+w.msg)});return}let C=await pn({name:(p=e.params)==null?void 0:p.pathId},x);h(C.data),ge.success("config save success")}catch(x){ge.error(s.errorMsg.join(";")),console.error(x)}finally{v.value=!1}}return(p,x)=>{const C=rt("a-select"),w=rt("a-descriptions-item"),y=rt("a-input"),M=rt("a-switch"),I=rt("a-descriptions"),z=rt("a-card"),A=rt("a-button"),B=rt("a-tag"),j=rt("a-radio-group"),V=rt("a-input-group"),N=rt("a-form-item"),ft=rt("a-form"),re=rt("a-spin"),Xt=rt("a-flex");return E(),Ct("div",Rs,[D(z,{title:"基础信息",class:"dynamic-config-card"},{default:S(()=>[Re("div",null,[D(I,{column:2,layout:"vertical"},{default:S(()=>[D(w,{label:p.$t("flowControlDomain.scope"),labelStyle:{fontWeight:"bold"}},{default:S(()=>[D(C,{value:G(s).basicInfo.scope,"onUpdate:value":x[0]||(x[0]=O=>G(s).basicInfo.scope=O),style:{"min-width":"120px"},options:a,disabled:!r.value},null,8,["value","options","disabled"])]),_:1},8,["label"]),D(w,{label:p.$t("flowControlDomain.key"),labelStyle:{fontWeight:"bold"}},{default:S(()=>[D(y,{value:G(s).basicInfo.key,"onUpdate:value":x[1]||(x[1]=O=>G(s).basicInfo.key=O),style:{"min-width":"300px"},disabled:!r.value},null,8,["value","disabled"])]),_:1},8,["label"]),D(w,{label:p.$t("flowControlDomain.enabled"),labelStyle:{fontWeight:"bold"}},{default:S(()=>[D(M,{checked:G(s).basicInfo.enabled,"onUpdate:checked":x[2]||(x[2]=O=>G(s).basicInfo.enabled=O),"checked-children":"是","un-checked-children":"否",disabled:!r.value},null,8,["checked","disabled"])]),_:1},8,["label"])]),_:1})])]),_:1}),D(re,{spinning:v.value},{default:S(()=>[D(ft,{ref:"formRef"},{default:S(()=>[(E(!0),Ct(Wt,null,qt(G(s).config,(O,bt)=>(E(),$(z,{class:"dynamic-config-card"},{title:S(()=>{var P;return[r.value?zt("",!0):(E(),$(A,{key:0,danger:"",size:"small",onClick:F=>g(bt),style:{"margin-right":"10px"}},{default:S(()=>[nt("删除 ")]),_:2},1032,["onClick"])),nt(" 配置【"+dt(bt+1)+"】 ",1),Re("div",{class:"desc-config",style:un({color:G(Ft)})},[nt(" 对于"+dt(((P=n==null?void 0:n.basicInfo)==null?void 0:P.scope)==="application"?"应用":"服务")+"的"+dt(O.side==="provider"?"提供者":"消费者")+",将满足 ",1),(E(!0),Ct(Wt,null,qt(_.value(O),F=>(E(),$(B,{color:G(Ft)},{default:S(()=>[nt(dt(F),1)]),_:2},1032,["color"]))),256)),nt(" 的实例,配置 "),(E(!0),Ct(Wt,null,qt(d.value(O),F=>(E(),$(B,{color:G(Ft)},{default:S(()=>[nt(dt(F),1)]),_:2},1032,["color"]))),256))],4)]}),default:S(()=>[D(I,{column:2},{default:S(()=>[D(w,{label:p.$t("flowControlDomain.enabled"),labelStyle:{fontWeight:"bold"}},{default:S(()=>[D(M,{disabled:!r.value,checked:O.enabled,"onUpdate:checked":P=>O.enabled=P,"checked-children":"是","un-checked-children":"否"},null,8,["disabled","checked","onUpdate:checked"])]),_:2},1032,["label"]),D(w,{label:p.$t("flowControlDomain.side"),labelStyle:{fontWeight:"bold"}},{default:S(()=>[D(j,{disabled:!r.value,value:O.side,"onUpdate:value":P=>O.side=P,options:o},null,8,["disabled","value","onUpdate:value"])]),_:2},1032,["label"]),D(w,{label:p.$t("flowControlDomain.matches"),labelStyle:{fontWeight:"bold"},span:2},{default:S(()=>[Re("div",null,[O.hasMatch?(E(),$(z,{key:1,style:{display:"block","margin-top":"10px",width:"60vw"}},{default:S(()=>[D(N,{"label-col":{style:{width:"9vw"}},label:p.$t("dynamicConfigDomain.matchType")},{default:S(()=>[D(V,{compact:""},{default:S(()=>[D(C,{disabled:!r.value,ref_for:!0,ref:"select",value:O.matchesKeys,"onUpdate:value":P=>O.matchesKeys=P,style:{width:"30vw"},onChange:P=>m(bt,"matches","matchesKeys"),mode:"multiple",options:Object.keys(O.matchesValue).map(P=>({value:P}))},null,8,["disabled","value","onUpdate:value","onChange","options"]),r.value?zt("",!0):(E(),$(A,{key:0,onClick:P=>O.hasMatch=!1,style:{"margin-left":"10px",padding:"5px"},danger:""},{default:S(()=>[D(G(ne),{style:{"font-size":"20px","margin-bottom":"-2px"},icon:"mynaui:minus-solid"})]),_:2},1032,["onClick"]))]),_:2},1024)]),_:2},1032,["label"]),(E(!0),Ct(Wt,null,qt(Object.keys(O.matchesValue).filter(P=>O.matchesKeys.includes(P)),P=>(E(),Ct("div",{key:P},[O.matchesValue[P].type==="obj"?(E(),$(N,{key:0,"label-col":{style:{width:"9vw"}}},{label:S(()=>[D(B,{color:G(Ft)},{default:S(()=>[nt(dt(P),1)]),_:2},1032,["color"])]),default:S(()=>[D(V,{compact:""},{default:S(()=>[D(y,{disabled:"",value:P,style:{width:"10vw","margin-bottom":"5px"}},null,8,["value"]),D(C,{disabled:!r.value,placeholder:"relation",options:u,value:O.matchesValue[P].relation,"onUpdate:value":F=>O.matchesValue[P].relation=F,style:{width:"8vw"}},null,8,["disabled","value","onUpdate:value"]),D(y,{disabled:!r.value,placeholder:"value",value:O.matchesValue[P].value,"onUpdate:value":F=>O.matchesValue[P].value=F,style:{width:"15vw"}},null,8,["disabled","value","onUpdate:value"])]),_:2},1024)]),_:2},1024)):(E(),$(N,{key:1,"label-col":{style:{width:"9vw"}}},{label:S(()=>[D(B,{color:G(Ft)},{default:S(()=>[nt(dt(P),1)]),_:2},1032,["color"])]),default:S(()=>[(E(!0),Ct(Wt,null,qt(O.matchesValue[P].arr,(F,ht)=>(E(),$(V,{disabled:!r.value,style:{"margin-bottom":"5px"},compact:""},{default:S(()=>[O.matchesValue[P].type==="arr"?(E(),$(y,{key:0,placeholder:"key",disabled:"",value:"oneof",style:{width:"10vw"}})):(E(),$(y,{key:1,placeholder:"key",disabled:!r.value||O.matchesValue[P].type==="arr",value:F.key,"onUpdate:value":_t=>F.key=_t,style:{width:"10vw"}},null,8,["disabled","value","onUpdate:value"])),D(C,{placeholder:"relation",disabled:!r.value,value:F.relation,"onUpdate:value":_t=>F.relation=_t,options:f,style:{width:"8vw"}},null,8,["disabled","value","onUpdate:value"]),D(y,{placeholder:"value",disabled:!r.value,value:F.value,"onUpdate:value":_t=>F.value=_t,style:{width:"15vw"}},null,8,["disabled","value","onUpdate:value"]),r.value?zt("",!0):(E(),$(A,{key:2,disabled:O.matchesValue[P].arr.length===1,onClick:_t=>O.delArrConfig(O.matchesValue,P,ht),style:{"margin-left":"10px",padding:"5px"},danger:""},{default:S(()=>[D(G(ne),{style:{"font-size":"20px","margin-bottom":"-2px"},icon:"mynaui:minus-solid"})]),_:2},1032,["disabled","onClick"])),r.value?zt("",!0):(E(),$(A,{key:3,onClick:_t=>O.addArrConfig(O.matchesValue,P,ht),style:{"margin-left":"10px",padding:"5px"},type:"primary"},{default:S(()=>[D(G(ne),{style:{"font-size":"20px","margin-bottom":"-2px"},icon:"mynaui:plus-solid"})]),_:2},1032,["onClick"]))]),_:2},1032,["disabled"]))),256))]),_:2},1024))]))),128))]),_:2},1024)):(E(),$(A,{key:0,disabled:!r.value,onClick:P=>O.hasMatch=!0,type:"dashed"},{default:S(()=>[D(G(ne),{style:{"margin-bottom":"-2px","font-size":"16px"},icon:"si:add-fill"}),nt(" "+dt(p.$t("dynamicConfigDomain.addMatches")),1)]),_:2},1032,["disabled","onClick"]))])]),_:2},1032,["label"]),D(w,{label:p.$t("flowControlDomain.configurationItem"),labelStyle:{fontWeight:"bold"},span:2},{default:S(()=>[Re("div",null,[D(z,{style:{display:"block","margin-top":"10px",width:"60vw"}},{default:S(()=>[D(N,{"label-col":{style:{width:"9vw"}},label:p.$t("dynamicConfigDomain.configType")},{default:S(()=>[D(V,{compact:""},{default:S(()=>[D(C,{ref_for:!0,ref:"select",disabled:!r.value,value:O.parametersKeys,"onUpdate:value":P=>O.parametersKeys=P,style:{width:"30vw"},onChange:P=>m(bt,"matches","matchesKeys"),mode:"multiple",options:Object.keys(O.parametersValue).map(P=>({value:P}))},null,8,["disabled","value","onUpdate:value","onChange","options"])]),_:2},1024)]),_:2},1032,["label"]),(E(!0),Ct(Wt,null,qt(Object.keys(O.parametersValue).filter(P=>O.parametersKeys.includes(P)),P=>(E(),Ct("div",{key:P},[O.parametersValue[P].type==="obj"?(E(),$(N,{key:0,"label-col":{style:{width:"9vw"}}},{label:S(()=>[D(B,{color:G(Ft)},{default:S(()=>[nt(dt(P),1)]),_:2},1032,["color"])]),default:S(()=>[D(V,{compact:""},{default:S(()=>[D(y,{disabled:"",value:P,style:{width:"10vw","margin-bottom":"5px"}},null,8,["value"]),D(y,{disabled:"",placeholder:"relation",value:"=",style:{width:"8vw"}}),D(y,{disabled:!r.value,placeholder:"value",value:O.parametersValue[P].value,"onUpdate:value":F=>O.parametersValue[P].value=F,style:{width:"15vw"}},null,8,["disabled","value","onUpdate:value"])]),_:2},1024)]),_:2},1024)):(E(),$(N,{key:1,"label-col":{style:{width:"9vw"}}},{label:S(()=>[D(B,{color:G(Ft)},{default:S(()=>[nt(dt(P),1)]),_:2},1032,["color"])]),default:S(()=>[(E(!0),Ct(Wt,null,qt(O.parametersValue[P].arr,(F,ht)=>(E(),$(V,{style:{"margin-bottom":"5px"},compact:""},{default:S(()=>[O.parametersValue[P].type==="arr"?(E(),$(y,{key:0,placeholder:"key",disabled:"",value:P,style:{width:"10vw"}},null,8,["value"])):(E(),$(y,{key:1,placeholder:"key",disabled:!r.value,value:F.key,"onUpdate:value":_t=>F.key=_t,style:{width:"10vw"}},null,8,["disabled","value","onUpdate:value"])),D(y,{disabled:"",placeholder:"relation",value:"=",style:{width:"8vw"}}),D(y,{placeholder:"value",disabled:!r.value,value:F.value,"onUpdate:value":_t=>F.value=_t,style:{width:"15vw"}},null,8,["disabled","value","onUpdate:value"]),r.value?zt("",!0):(E(),$(A,{key:2,disabled:O.parametersValue[P].arr.length===1,onClick:_t=>O.delArrConfig(O.parametersValue,P,ht),style:{"margin-left":"10px",padding:"5px"},danger:""},{default:S(()=>[D(G(ne),{style:{"font-size":"20px","margin-bottom":"-2px"},icon:"mynaui:minus-solid"})]),_:2},1032,["disabled","onClick"])),r.value?zt("",!0):(E(),$(A,{key:3,onClick:_t=>O.addArrConfig(O.parametersValue,P,ht,{relation:"="}),style:{"margin-left":"10px",padding:"5px"},type:"primary"},{default:S(()=>[D(G(ne),{style:{"font-size":"20px","margin-bottom":"-2px"},icon:"mynaui:plus-solid"})]),_:2},1032,["onClick"]))]),_:2},1024))),256))]),_:2},1024))]))),128))]),_:2},1024)])]),_:2},1032,["label"])]),_:2},1024)]),_:2},1024))),256))]),_:1},512)]),_:1},8,["spinning"]),r.value?(E(),$(A,{key:0,style:{"margin-bottom":"20px"},onClick:c},{default:S(()=>[nt(dt(p.$t("dynamicConfigDomain.addConfig")),1)]),_:1})):zt("",!0),D(z,{class:"footer"},{default:S(()=>[r.value?(E(),$(Xt,{key:0},{default:S(()=>[D(A,{type:"primary",onClick:k},{default:S(()=>[nt(dt(p.$t("dynamicConfigDomain.save")),1)]),_:1}),D(A,{style:{"margin-left":"30px"},onClick:b},{default:S(()=>[nt(dt(p.$t("dynamicConfigDomain.reset")),1)]),_:1})]),_:1})):zt("",!0)]),_:1})])}}}),Ls=hn(Es,[["__scopeId","data-v-0dc56252"]]);export{Ls as default}; diff --git a/app/dubbo-ui/dist/admin/assets/formView-94FyHCnm.css b/app/dubbo-ui/dist/admin/assets/formView-94FyHCnm.css deleted file mode 100644 index 1d3077fcb..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView-94FyHCnm.css +++ /dev/null @@ -1 +0,0 @@ -.description-item-content.no-card[data-v-4f4c877f]{padding-left:20px}.description-item-content.with-card[data-v-4f4c877f]:hover{color:var(--0baf33be)} diff --git a/app/dubbo-ui/dist/admin/assets/formView-IqMlu-2J.css b/app/dubbo-ui/dist/admin/assets/formView-IqMlu-2J.css deleted file mode 100644 index 1ada5cb11..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView-IqMlu-2J.css +++ /dev/null @@ -1 +0,0 @@ -.__container_traffic_config_form[data-v-0dc56252]{position:relative;width:100%}.__container_traffic_config_form .dynamic-config-card[data-v-0dc56252]{margin-bottom:20px}.__container_traffic_config_form .dynamic-config-card[data-v-0dc56252] .ant-descriptions-item-label{width:120px;text-align:right}.__container_traffic_config_form .dynamic-config-card[data-v-0dc56252] .ant-card-head-title{overflow:unset!important}.__container_traffic_config_form .dynamic-config-card .desc-config[data-v-0dc56252]{max-width:60vw;display:inline-flex;font-weight:400;font-size:12px;line-height:20px;flex-wrap:wrap;row-gap:2px}.__container_traffic_config_form .dynamic-config-card .description-item-content.no-card[data-v-0dc56252]{padding-left:20px}.__container_traffic_config_form .dynamic-config-card .description-item-content.with-card[data-v-0dc56252]:hover{color:var(--6abd4bde)} diff --git a/app/dubbo-ui/dist/admin/assets/formView-dr6vkirR.js b/app/dubbo-ui/dist/admin/assets/formView-dr6vkirR.js deleted file mode 100644 index a1cf9955c..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView-dr6vkirR.js +++ /dev/null @@ -1 +0,0 @@ -import{u as L}from"./index-Va7nxJVK.js";import{d as F,k as J,a as K,z as D,r as Q,l as U,W as H,c as $,b as o,w as t,e as i,o as s,f as n,t as r,G as c,n as y,a9 as X,aa as Y,j as g,$ as S,Q as v,J as O,K as j,m as Z,p as ee,h as te,_ as oe}from"./index-hmLAZQYT.js";import{g as le}from"./traffic-C2a-KjHH.js";import"./request-8jI_GZey.js";const A=w=>(ee("data-v-2f7b63ed"),w=w(),te(),w),ae={class:"__container_routingRule_detail"},ne=A(()=>g("p",null,"修改时间: 2024/3/20 15:20:31",-1)),se=A(()=>g("p",null,"版本号: xo842xqpx834",-1)),re=F({__name:"formView",setup(w){const{appContext:{config:{globalProperties:x}}}=J(),M=K(),_=D(!1),N=D(8),z=L().toClipboard;function h(e){Z.success(x.$t("messageDomain.success.copy")),z(e)}const l=Q({configVersion:"v3.0",scope:"service",key:"org.apache.dubbo.samples.UserService",enabled:!0,runtime:!0,force:!1,conditions:["=>host!=192.168.0.68"],group:"",version:""}),B=U(()=>{const e=l.key.split(":");return l.version=e[1]||"",l.group=e[2]||"",e[0]?e[0]:""}),W=D([]),R=D([]);async function E(){var a;let e=await le((a=M.params)==null?void 0:a.ruleName);console.log(e),(e==null?void 0:e.code)===200&&(Object.assign(l,(e==null?void 0:e.data)||{}),l.conditions.forEach((p,C)=>{var k,f;const m=p.split(" => "),u=(k=m[1])==null?void 0:k.split(" & "),b=(f=m[0])==null?void 0:f.split(" & ");W.value=W.value.concat(b),R.value=R.value.concat(u)}))}const G=()=>{var a;const e=(a=M.params)==null?void 0:a.ruleName;if(e&&l.scope==="service"){const p=e==null?void 0:e.split(":");l.version=p[1],l.group=p[2].split(".")[0]}};return H(async()=>{await E(),G()}),(e,a)=>{const p=i("a-typography-title"),C=i("a-button"),m=i("a-flex"),u=i("a-descriptions-item"),b=i("a-typography-paragraph"),k=i("a-descriptions"),f=i("a-card"),T=i("a-row"),P=i("a-tag"),V=i("a-space"),q=i("a-col");return s(),$("div",ae,[o(m,{style:{width:"100%"}},{default:t(()=>[o(q,{span:_.value?24-N.value:24,class:"left"},{default:t(()=>[o(T,null,{default:t(()=>[o(m,{justify:"space-between",style:{width:"100%"}},{default:t(()=>[o(p,{level:3},{default:t(()=>[n(" 基础信息")]),_:1}),o(C,{type:"text",style:{color:"#0a90d5"},onClick:a[0]||(a[0]=d=>_.value=!_.value)},{default:t(()=>[n(r(e.$t("flowControlDomain.versionRecords"))+" ",1),_.value?(s(),c(y(Y),{key:1})):(s(),c(y(X),{key:0}))]),_:1})]),_:1}),o(f,{class:"_detail"},{default:t(()=>[o(k,{column:2,layout:"vertical",title:""},{default:t(()=>[o(u,{label:e.$t("flowControlDomain.ruleName"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[g("p",{class:"description-item-content with-card",onClick:a[1]||(a[1]=d=>h(l.key))},[n(r(l.key)+" ",1),o(y(S))])]),_:1},8,["label"]),o(u,{label:e.$t("flowControlDomain.ruleGranularity"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(b,null,{default:t(()=>[n(r(l.scope),1)]),_:1})]),_:1},8,["label"]),l.scope=="service"?(s(),c(u,{key:0,label:"版本",labelStyle:{fontWeight:"bold"}},{default:t(()=>[g("p",{class:"description-item-content with-card",onClick:a[2]||(a[2]=d=>h(l.version))},[n(r(l.version)+" ",1),l.version.length?(s(),c(y(S),{key:0})):v("",!0)])]),_:1})):v("",!0),l.scope=="service"?(s(),c(u,{key:1,label:"分组",labelStyle:{fontWeight:"bold"}},{default:t(()=>[g("p",{class:"description-item-content with-card",onClick:a[3]||(a[3]=d=>h(l.group))},[n(r(l.group)+" ",1),l.group.length?(s(),c(y(S),{key:0})):v("",!0)])]),_:1})):v("",!0),o(u,{label:e.$t("flowControlDomain.actionObject"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[g("p",{class:"description-item-content with-card",onClick:a[4]||(a[4]=d=>h(B.value))},[n(r(B.value)+" ",1),o(y(S))])]),_:1},8,["label"]),o(u,{label:e.$t("flowControlDomain.faultTolerantProtection"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(b,null,{default:t(()=>[n(r(l.force?e.$t("flowControlDomain.opened"):e.$t("flowControlDomain.closed")),1)]),_:1})]),_:1},8,["label"]),o(u,{label:e.$t("flowControlDomain.enabledState"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(b,null,{default:t(()=>[n(r(l.enabled?e.$t("flowControlDomain.enabled"):e.$t("flowControlDomain.disabled")),1)]),_:1})]),_:1},8,["label"]),o(u,{label:e.$t("flowControlDomain.runTimeEffective"),labelStyle:{fontWeight:"bold"}},{default:t(()=>[o(b,null,{default:t(()=>[n(r(l.runtime?e.$t("flowControlDomain.opened"):e.$t("flowControlDomain.closed")),1)]),_:1})]),_:1},8,["label"])]),_:1})]),_:1})]),_:1}),o(f,{style:{"margin-top":"10px"},class:"_detail"},{default:t(()=>[o(V,{align:"start",style:{width:"100%"}},{default:t(()=>[o(p,{level:5},{default:t(()=>[n(r(e.$t("flowControlDomain.requestParameterMatching"))+": ",1)]),_:1}),o(V,{align:"center",direction:"horizontal",size:"middle",wrap:""},{default:t(()=>[(s(!0),$(O,null,j(W.value,(d,I)=>(s(),c(P,{key:I,color:"#2db7f5"},{default:t(()=>[n(r(d),1)]),_:2},1024))),128))]),_:1})]),_:1}),o(V,{align:"start",style:{width:"100%"},wrap:""},{default:t(()=>[o(p,{level:5},{default:t(()=>[n(r(e.$t("flowControlDomain.addressSubsetMatching"))+": ",1)]),_:1}),(s(!0),$(O,null,j(R.value,(d,I)=>(s(),c(P,{key:I,color:"#87d068"},{default:t(()=>[n(r(d),1)]),_:2},1024))),128))]),_:1})]),_:1})]),_:1},8,["span"]),o(q,{span:_.value?N.value:0,class:"right"},{default:t(()=>[_.value?(s(),c(f,{key:0,class:"sliderBox"},{default:t(()=>[(s(),$(O,null,j(2,d=>o(f,{key:d},{default:t(()=>[ne,se,o(m,{justify:"flex-end"},{default:t(()=>[o(C,{type:"text",style:{color:"#0a90d5"}},{default:t(()=>[n("查看")]),_:1}),o(C,{type:"text",style:{color:"#0a90d5"}},{default:t(()=>[n("回滚")]),_:1})]),_:1})]),_:2},1024)),64))]),_:1})):v("",!0)]),_:1},8,["span"])]),_:1})])}}}),pe=oe(re,[["__scopeId","data-v-2f7b63ed"]]);export{pe as default}; diff --git a/app/dubbo-ui/dist/admin/assets/formView-vPzA7v6e.css b/app/dubbo-ui/dist/admin/assets/formView-vPzA7v6e.css deleted file mode 100644 index 83704e22c..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView-vPzA7v6e.css +++ /dev/null @@ -1 +0,0 @@ -.__container_routingRule_detail .sliderBox[data-v-2f7b63ed]{margin-left:5px;max-height:530px;overflow:auto}.__container_routingRule_detail[data-v-2f7b63ed] .left.ant-col,.__container_routingRule_detail[data-v-2f7b63ed] .right.ant-col{transition:all .5s ease} diff --git a/app/dubbo-ui/dist/admin/assets/formView-yOHva0ty.js b/app/dubbo-ui/dist/admin/assets/formView-yOHva0ty.js deleted file mode 100644 index b3f4d4720..000000000 --- a/app/dubbo-ui/dist/admin/assets/formView-yOHva0ty.js +++ /dev/null @@ -1 +0,0 @@ -import{d as P,v as T,a as x,k as A,l as E,r as G,W as L,c as f,b as t,w as a,J as v,K as w,e as l,n as m,P as M,o as c,j as h,f as n,t as o,$ as D,G as $,m as F,_ as J}from"./index-hmLAZQYT.js";import{u as K}from"./index-Va7nxJVK.js";import{e as Y}from"./traffic-C2a-KjHH.js";import"./request-8jI_GZey.js";const q={class:"__container_app_detail"},z=P({__name:"formView",setup(H){T(e=>({"0baf33be":m(M)}));const k=x(),{appContext:{config:{globalProperties:O}}}=A(),R=K().toClipboard;function _(e){F.success(O.$t("messageDomain.success.copy")),R(e)}const b=E(()=>{const e=s.key.split(":");return e[0]?e[0]:""}),s=G({configVersion:"v3.0",scope:"application",key:"shop-user",enabled:!0,runtime:!0,tags:[{name:"gray",match:[{key:"version",value:{exact:"v1"}}]}]}),N=async()=>{var r;const e=await Y((r=k.params)==null?void 0:r.ruleName);e.code===200&&Object.assign(s,e.data||{})};return L(()=>{N()}),(e,r)=>{const i=l("a-descriptions-item"),u=l("a-typography-paragraph"),S=l("a-descriptions"),g=l("a-card"),V=l("a-flex"),j=l("a-typography-text"),y=l("a-typography-title"),C=l("a-space"),W=l("a-tag");return c(),f("div",q,[t(V,null,{default:a(()=>[t(g,{class:"_detail"},{default:a(()=>[t(S,{column:2,layout:"vertical",title:""},{default:a(()=>[t(i,{label:e.$t("flowControlDomain.ruleName"),labelStyle:{fontWeight:"bold"}},{default:a(()=>[h("p",{onClick:r[0]||(r[0]=p=>_(s.key)),class:"description-item-content with-card"},[n(o(s.key)+" ",1),t(m(D))])]),_:1},8,["label"]),t(i,{label:e.$t("flowControlDomain.ruleGranularity"),labelStyle:{fontWeight:"bold"}},{default:a(()=>[t(u,null,{default:a(()=>[n(o(s.scope),1)]),_:1})]),_:1},8,["label"]),t(i,{label:e.$t("flowControlDomain.actionObject"),labelStyle:{fontWeight:"bold"}},{default:a(()=>[h("p",{onClick:r[1]||(r[1]=p=>_(b.value)),class:"description-item-content with-card"},[n(o(b.value)+" ",1),t(m(D))])]),_:1},8,["label"]),t(i,{label:e.$t("flowControlDomain.enabledState"),labelStyle:{fontWeight:"bold"}},{default:a(()=>[t(u,null,{default:a(()=>[n(o(s.enabled?e.$t("flowControlDomain.enabled"):e.$t("flowControlDomain.disabled")),1)]),_:1})]),_:1},8,["label"]),t(i,{label:e.$t("flowControlDomain.runTimeEffective"),labelStyle:{fontWeight:"bold"}},{default:a(()=>[t(u,null,{default:a(()=>[n(o(s.runtime?e.$t("flowControlDomain.opened"):e.$t("flowControlDomain.closed")),1)]),_:1})]),_:1},8,["label"])]),_:1})]),_:1})]),_:1}),(c(!0),f(v,null,w(s.tags,(p,I)=>(c(),$(g,{title:`标签【${I+1}】`,style:{"margin-top":"10px"},class:"_detail"},{default:a(()=>[t(C,{align:"center"},{default:a(()=>[t(y,{level:5},{default:a(()=>[n(o(e.$t("flowControlDomain.labelName"))+": ",1),t(j,{class:"labelName"},{default:a(()=>[n(o(p.name),1)]),_:2},1024)]),_:2},1024)]),_:2},1024),t(C,{align:"start",style:{width:"100%"}},{default:a(()=>[t(y,{level:5},{default:a(()=>[n(o(e.$t("flowControlDomain.actuatingRange"))+": ",1)]),_:1}),(c(!0),f(v,null,w(p.match,(d,B)=>(c(),$(W,{key:B,color:"#2db7f5"},{default:a(()=>[n(o(d.key)+": "+o(Object.keys(d.value)[0])+"="+o(Object.values(d.value)[0]),1)]),_:2},1024))),128))]),_:2},1024)]),_:2},1032,["title"]))),256))])}}}),ee=J(z,[["__scopeId","data-v-4f4c877f"]]);export{ee as default}; diff --git a/app/dubbo-ui/dist/admin/assets/freemarker2-7czNGzoq.js b/app/dubbo-ui/dist/admin/assets/freemarker2-7czNGzoq.js deleted file mode 100644 index aa1c13975..000000000 --- a/app/dubbo-ui/dist/admin/assets/freemarker2-7czNGzoq.js +++ /dev/null @@ -1,8 +0,0 @@ -import{m as F}from"./js-yaml-8Gkz3BRW.js";import"./index-hmLAZQYT.js";/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var b=Object.defineProperty,x=Object.getOwnPropertyDescriptor,$=Object.getOwnPropertyNames,v=Object.prototype.hasOwnProperty,g=(t,n,_,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of $(n))!v.call(t,o)&&o!==_&&b(t,o,{get:()=>n[o],enumerable:!(e=x(n,o))||e.enumerable});return t},E=(t,n,_)=>(g(t,n,"default"),_&&g(_,n,"default")),r={};E(r,F);var d=["assign","flush","ftl","return","global","import","include","break","continue","local","nested","nt","setting","stop","t","lt","rt","fallback"],s=["attempt","autoesc","autoEsc","compress","comment","escape","noescape","function","if","list","items","sep","macro","noparse","noParse","noautoesc","noAutoEsc","outputformat","switch","visit","recurse"],a={close:">",id:"angle",open:"<"},u={close:"\\]",id:"bracket",open:"\\["},D={close:"[>\\]]",id:"auto",open:"[<\\[]"},k={close:"\\}",id:"dollar",open1:"\\$",open2:"\\{"},p={close:"\\]",id:"bracket",open1:"\\[",open2:"="};function l(t){return{brackets:[["<",">"],["[","]"],["(",")"],["{","}"]],comments:{blockComment:[`${t.open}--`,`--${t.close}`]},autoCloseBefore:` -\r }]),.:;=`,autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string"]}],surroundingPairs:[{open:'"',close:'"'},{open:"'",close:"'"},{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"}],folding:{markers:{start:new RegExp(`${t.open}#(?:${s.join("|")})([^/${t.close}]*(?!/)${t.close})[^${t.open}]*$`),end:new RegExp(`${t.open}/#(?:${s.join("|")})[\\r\\n\\t ]*>`)}},onEnterRules:[{beforeText:new RegExp(`${t.open}#(?!(?:${d.join("|")}))([a-zA-Z_]+)([^/${t.close}]*(?!/)${t.close})[^${t.open}]*$`),afterText:new RegExp(`^${t.open}/#([a-zA-Z_]+)[\\r\\n\\t ]*${t.close}$`),action:{indentAction:r.languages.IndentAction.IndentOutdent}},{beforeText:new RegExp(`${t.open}#(?!(?:${d.join("|")}))([a-zA-Z_]+)([^/${t.close}]*(?!/)${t.close})[^${t.open}]*$`),action:{indentAction:r.languages.IndentAction.Indent}}]}}function A(){return{brackets:[["<",">"],["[","]"],["(",")"],["{","}"]],autoCloseBefore:` -\r }]),.:;=`,autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string"]}],surroundingPairs:[{open:'"',close:'"'},{open:"'",close:"'"},{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"}],folding:{markers:{start:new RegExp(`[<\\[]#(?:${s.join("|")})([^/>\\]]*(?!/)[>\\]])[^<\\[]*$`),end:new RegExp(`[<\\[]/#(?:${s.join("|")})[\\r\\n\\t ]*>`)}},onEnterRules:[{beforeText:new RegExp(`[<\\[]#(?!(?:${d.join("|")}))([a-zA-Z_]+)([^/>\\]]*(?!/)[>\\]])[^[<\\[]]*$`),afterText:new RegExp("^[<\\[]/#([a-zA-Z_]+)[\\r\\n\\t ]*[>\\]]$"),action:{indentAction:r.languages.IndentAction.IndentOutdent}},{beforeText:new RegExp(`[<\\[]#(?!(?:${d.join("|")}))([a-zA-Z_]+)([^/>\\]]*(?!/)[>\\]])[^[<\\[]]*$`),action:{indentAction:r.languages.IndentAction.Indent}}]}}function i(t,n){const _=`_${t.id}_${n.id}`,e=c=>c.replace(/__id__/g,_),o=c=>{const f=c.source.replace(/__id__/g,_);return new RegExp(f,c.flags)};return{unicode:!0,includeLF:!1,start:e("default__id__"),ignoreCase:!1,defaultToken:"invalid",tokenPostfix:".freemarker2",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],[e("open__id__")]:new RegExp(t.open),[e("close__id__")]:new RegExp(t.close),[e("iOpen1__id__")]:new RegExp(n.open1),[e("iOpen2__id__")]:new RegExp(n.open2),[e("iClose__id__")]:new RegExp(n.close),[e("startTag__id__")]:o(/(@open__id__)(#)/),[e("endTag__id__")]:o(/(@open__id__)(\/#)/),[e("startOrEndTag__id__")]:o(/(@open__id__)(\/?#)/),[e("closeTag1__id__")]:o(/((?:@blank)*)(@close__id__)/),[e("closeTag2__id__")]:o(/((?:@blank)*\/?)(@close__id__)/),blank:/[ \t\n\r]/,keywords:["false","true","in","as","using"],directiveStartCloseTag1:/attempt|recover|sep|auto[eE]sc|no(?:autoe|AutoE)sc|compress|default|no[eE]scape|comment|no[pP]arse/,directiveStartCloseTag2:/else|break|continue|return|stop|flush|t|lt|rt|nt|nested|recurse|fallback|ftl/,directiveStartBlank:/if|else[iI]f|list|for[eE]ach|switch|case|assign|global|local|include|import|function|macro|transform|visit|stop|return|call|setting|output[fF]ormat|nested|recurse|escape|ftl|items/,directiveEndCloseTag1:/if|list|items|sep|recover|attempt|for[eE]ach|local|global|assign|function|macro|output[fF]ormat|auto[eE]sc|no(?:autoe|AutoE)sc|compress|transform|switch|escape|no[eE]scape/,escapedChar:/\\(?:[ntrfbgla\\'"\{=]|(?:x[0-9A-Fa-f]{1,4}))/,asciiDigit:/[0-9]/,integer:/[0-9]+/,nonEscapedIdStartChar:/[\$@-Z_a-z\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u1FFF\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183-\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3006\u3031-\u3035\u303B-\u303C\u3040-\u318F\u31A0-\u31BA\u31F0-\u31FF\u3300-\u337F\u3400-\u4DB5\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/,escapedIdChar:/\\[\-\.:#]/,idStartChar:/(?:@nonEscapedIdStartChar)|(?:@escapedIdChar)/,id:/(?:@idStartChar)(?:(?:@idStartChar)|(?:@asciiDigit))*/,specialHashKeys:/\*\*|\*|false|true|in|as|using/,namedSymbols:/<=|>=|\\lte|\\lt|<|\\gte|\\gt|>|&&|\\and|->|->|==|!=|\+=|-=|\*=|\/=|%=|\+\+|--|<=|&&|\|\||:|\.\.\.|\.\.\*|\.\.<|\.\.!|\?\?|=|<|\+|-|\*|\/|%|\||\.\.|\?|!|&|\.|,|;/,arrows:["->","->"],delimiters:[";",":",",","."],stringOperators:["lte","lt","gte","gt"],noParseTags:["noparse","noParse","comment"],tokenizer:{[e("default__id__")]:[{include:e("@directive_token__id__")},{include:e("@interpolation_and_text_token__id__")}],[e("fmExpression__id__.directive")]:[{include:e("@blank_and_expression_comment_token__id__")},{include:e("@directive_end_token__id__")},{include:e("@expression_token__id__")}],[e("fmExpression__id__.interpolation")]:[{include:e("@blank_and_expression_comment_token__id__")},{include:e("@expression_token__id__")},{include:e("@greater_operators_token__id__")}],[e("inParen__id__.plain")]:[{include:e("@blank_and_expression_comment_token__id__")},{include:e("@directive_end_token__id__")},{include:e("@expression_token__id__")}],[e("inParen__id__.gt")]:[{include:e("@blank_and_expression_comment_token__id__")},{include:e("@expression_token__id__")},{include:e("@greater_operators_token__id__")}],[e("noSpaceExpression__id__")]:[{include:e("@no_space_expression_end_token__id__")},{include:e("@directive_end_token__id__")},{include:e("@expression_token__id__")}],[e("unifiedCall__id__")]:[{include:e("@unified_call_token__id__")}],[e("singleString__id__")]:[{include:e("@string_single_token__id__")}],[e("doubleString__id__")]:[{include:e("@string_double_token__id__")}],[e("rawSingleString__id__")]:[{include:e("@string_single_raw_token__id__")}],[e("rawDoubleString__id__")]:[{include:e("@string_double_raw_token__id__")}],[e("expressionComment__id__")]:[{include:e("@expression_comment_token__id__")}],[e("noParse__id__")]:[{include:e("@no_parse_token__id__")}],[e("terseComment__id__")]:[{include:e("@terse_comment_token__id__")}],[e("directive_token__id__")]:[[o(/(?:@startTag__id__)(@directiveStartCloseTag1)(?:@closeTag1__id__)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive"},{cases:{"@noParseTags":{token:"tag",next:e("@noParse__id__.$3")},"@default":{token:"tag"}}},{token:"delimiter.directive"},{token:"@brackets.directive"}]],[o(/(?:@startTag__id__)(@directiveStartCloseTag2)(?:@closeTag2__id__)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag"},{token:"delimiter.directive"},{token:"@brackets.directive"}]],[o(/(?:@startTag__id__)(@directiveStartBlank)(@blank)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag"},{token:"",next:e("@fmExpression__id__.directive")}]],[o(/(?:@endTag__id__)(@directiveEndCloseTag1)(?:@closeTag1__id__)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag"},{token:"delimiter.directive"},{token:"@brackets.directive"}]],[o(/(@open__id__)(@)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive",next:e("@unifiedCall__id__")}]],[o(/(@open__id__)(\/@)((?:(?:@id)(?:\.(?:@id))*)?)(?:@closeTag1__id__)/),[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag"},{token:"delimiter.directive"},{token:"@brackets.directive"}]],[o(/(@open__id__)#--/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:{token:"comment",next:e("@terseComment__id__")}],[o(/(?:@startOrEndTag__id__)([a-zA-Z_]+)/),t.id==="auto"?{cases:{"$1==<":{token:"@rematch",switchTo:`@default_angle_${n.id}`},"$1==[":{token:"@rematch",switchTo:`@default_bracket_${n.id}`}}}:[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag.invalid",next:e("@fmExpression__id__.directive")}]]],[e("interpolation_and_text_token__id__")]:[[o(/(@iOpen1__id__)(@iOpen2__id__)/),[{token:n.id==="bracket"?"@brackets.interpolation":"delimiter.interpolation"},{token:n.id==="bracket"?"delimiter.interpolation":"@brackets.interpolation",next:e("@fmExpression__id__.interpolation")}]],[/[\$#<\[\{]|(?:@blank)+|[^\$<#\[\{\n\r\t ]+/,{token:"source"}]],[e("string_single_token__id__")]:[[/[^'\\]/,{token:"string"}],[/@escapedChar/,{token:"string.escape"}],[/'/,{token:"string",next:"@pop"}]],[e("string_double_token__id__")]:[[/[^"\\]/,{token:"string"}],[/@escapedChar/,{token:"string.escape"}],[/"/,{token:"string",next:"@pop"}]],[e("string_single_raw_token__id__")]:[[/[^']+/,{token:"string.raw"}],[/'/,{token:"string.raw",next:"@pop"}]],[e("string_double_raw_token__id__")]:[[/[^"]+/,{token:"string.raw"}],[/"/,{token:"string.raw",next:"@pop"}]],[e("expression_token__id__")]:[[/(r?)(['"])/,{cases:{"r'":[{token:"keyword"},{token:"string.raw",next:e("@rawSingleString__id__")}],'r"':[{token:"keyword"},{token:"string.raw",next:e("@rawDoubleString__id__")}],"'":[{token:"source"},{token:"string",next:e("@singleString__id__")}],'"':[{token:"source"},{token:"string",next:e("@doubleString__id__")}]}}],[/(?:@integer)(?:\.(?:@integer))?/,{cases:{"(?:@integer)":{token:"number"},"@default":{token:"number.float"}}}],[/(\.)(@blank*)(@specialHashKeys)/,[{token:"delimiter"},{token:""},{token:"identifier"}]],[/(?:@namedSymbols)/,{cases:{"@arrows":{token:"meta.arrow"},"@delimiters":{token:"delimiter"},"@default":{token:"operators"}}}],[/@id/,{cases:{"@keywords":{token:"keyword.$0"},"@stringOperators":{token:"operators"},"@default":{token:"identifier"}}}],[/[\[\]\(\)\{\}]/,{cases:{"\\[":{cases:{"$S2==gt":{token:"@brackets",next:e("@inParen__id__.gt")},"@default":{token:"@brackets",next:e("@inParen__id__.plain")}}},"\\]":{cases:{...n.id==="bracket"?{"$S2==interpolation":{token:"@brackets.interpolation",next:"@popall"}}:{},...t.id==="bracket"?{"$S2==directive":{token:"@brackets.directive",next:"@popall"}}:{},[e("$S1==inParen__id__")]:{token:"@brackets",next:"@pop"},"@default":{token:"@brackets"}}},"\\(":{token:"@brackets",next:e("@inParen__id__.gt")},"\\)":{cases:{[e("$S1==inParen__id__")]:{token:"@brackets",next:"@pop"},"@default":{token:"@brackets"}}},"\\{":{cases:{"$S2==gt":{token:"@brackets",next:e("@inParen__id__.gt")},"@default":{token:"@brackets",next:e("@inParen__id__.plain")}}},"\\}":{cases:{...n.id==="bracket"?{}:{"$S2==interpolation":{token:"@brackets.interpolation",next:"@popall"}},[e("$S1==inParen__id__")]:{token:"@brackets",next:"@pop"},"@default":{token:"@brackets"}}}}}],[/\$\{/,{token:"delimiter.invalid"}]],[e("blank_and_expression_comment_token__id__")]:[[/(?:@blank)+/,{token:""}],[/[<\[][#!]--/,{token:"comment",next:e("@expressionComment__id__")}]],[e("directive_end_token__id__")]:[[/>/,t.id==="bracket"?{token:"operators"}:{token:"@brackets.directive",next:"@popall"}],[o(/(\/)(@close__id__)/),[{token:"delimiter.directive"},{token:"@brackets.directive",next:"@popall"}]]],[e("greater_operators_token__id__")]:[[/>/,{token:"operators"}],[/>=/,{token:"operators"}]],[e("no_space_expression_end_token__id__")]:[[/(?:@blank)+/,{token:"",switchTo:e("@fmExpression__id__.directive")}]],[e("unified_call_token__id__")]:[[/(@id)((?:@blank)+)/,[{token:"tag"},{token:"",next:e("@fmExpression__id__.directive")}]],[o(/(@id)(\/?)(@close__id__)/),[{token:"tag"},{token:"delimiter.directive"},{token:"@brackets.directive",next:"@popall"}]],[/./,{token:"@rematch",next:e("@noSpaceExpression__id__")}]],[e("no_parse_token__id__")]:[[o(/(@open__id__)(\/#?)([a-zA-Z]+)((?:@blank)*)(@close__id__)/),{cases:{"$S2==$3":[{token:"@brackets.directive"},{token:"delimiter.directive"},{token:"tag"},{token:""},{token:"@brackets.directive",next:"@popall"}],"$S2==comment":[{token:"comment"},{token:"comment"},{token:"comment"},{token:"comment"},{token:"comment"}],"@default":[{token:"source"},{token:"source"},{token:"source"},{token:"source"},{token:"source"}]}}],[/[^<\[\-]+|[<\[\-]/,{cases:{"$S2==comment":{token:"comment"},"@default":{token:"source"}}}]],[e("expression_comment_token__id__")]:[[/--[>\]]/,{token:"comment",next:"@pop"}],[/[^\->\]]+|[>\]\-]/,{token:"comment"}]],[e("terse_comment_token__id__")]:[[o(/--(?:@close__id__)/),{token:"comment",next:"@popall"}],[/[^<\[\-]+|[<\[\-]/,{token:"comment"}]]}}}function m(t){const n=i(a,t),_=i(u,t),e=i(D,t);return{...n,..._,...e,unicode:!0,includeLF:!1,start:`default_auto_${t.id}`,ignoreCase:!1,defaultToken:"invalid",tokenPostfix:".freemarker2",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],tokenizer:{...n.tokenizer,..._.tokenizer,...e.tokenizer}}}var w={conf:l(a),language:i(a,k)},T={conf:l(u),language:i(u,k)},h={conf:l(a),language:i(a,p)},S={conf:l(u),language:i(u,p)},P={conf:A(),language:m(k)},y={conf:A(),language:m(p)};export{h as TagAngleInterpolationBracket,w as TagAngleInterpolationDollar,y as TagAutoInterpolationBracket,P as TagAutoInterpolationDollar,S as TagBracketInterpolationBracket,T as TagBracketInterpolationDollar}; diff --git a/app/dubbo-ui/dist/admin/assets/fsharp-bDkC0eEG.js b/app/dubbo-ui/dist/admin/assets/fsharp-bDkC0eEG.js deleted file mode 100644 index ce57a8942..000000000 --- a/app/dubbo-ui/dist/admin/assets/fsharp-bDkC0eEG.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["(*","*)"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*//\\s*#region\\b|^\\s*\\(\\*\\s*#region(.*)\\*\\)"),end:new RegExp("^\\s*//\\s*#endregion\\b|^\\s*\\(\\*\\s*#endregion\\s*\\*\\)")}}},n={defaultToken:"",tokenPostfix:".fs",keywords:["abstract","and","atomic","as","assert","asr","base","begin","break","checked","component","const","constraint","constructor","continue","class","default","delegate","do","done","downcast","downto","elif","else","end","exception","eager","event","external","extern","false","finally","for","fun","function","fixed","functor","global","if","in","include","inherit","inline","interface","internal","land","lor","lsl","lsr","lxor","lazy","let","match","member","mod","module","mutable","namespace","method","mixin","new","not","null","of","open","or","object","override","private","parallel","process","protected","pure","public","rec","return","static","sealed","struct","sig","then","to","true","tailcall","trait","try","type","upcast","use","val","void","virtual","volatile","when","while","with","yield"],symbols:/[=>\]/,"annotation"],[/^#(if|else|endif)/,"keyword"],[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,"delimiter"],[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/,"number.float"],[/0x[0-9a-fA-F]+LF/,"number.float"],[/0x[0-9a-fA-F]+(@integersuffix)/,"number.hex"],[/0b[0-1]+(@integersuffix)/,"number.bin"],[/\d+(@integersuffix)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"""/,"string",'@string."""'],[/"/,"string",'@string."'],[/\@"/,{token:"string.quote",next:"@litstring"}],[/'[^\\']'B?/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\(\*(?!\))/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^*(]+/,"comment"],[/\*\)/,"comment","@pop"],[/\*/,"comment"],[/\(\*\)/,"comment"],[/\(/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/("""|"B?)/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]],litstring:[[/[^"]+/,"string"],[/""/,"string.escape"],[/"/,{token:"string.quote",next:"@pop"}]]}};export{e as conf,n as language}; diff --git a/app/dubbo-ui/dist/admin/assets/go-B7tkULuP.js b/app/dubbo-ui/dist/admin/assets/go-B7tkULuP.js deleted file mode 100644 index 4f410b21b..000000000 --- a/app/dubbo-ui/dist/admin/assets/go-B7tkULuP.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"`",close:"`",notIn:["string"]},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"`",close:"`"},{open:'"',close:'"'},{open:"'",close:"'"}]},n={defaultToken:"",tokenPostfix:".go",keywords:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var","bool","true","false","uint8","uint16","uint32","uint64","int8","int16","int32","int64","float32","float64","complex64","complex128","byte","rune","uint","int","uintptr","string","nil"],operators:["+","-","*","/","%","&","|","^","<<",">>","&^","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=","&^=","&&","||","<-","++","--","==","<",">","=","!","!=","<=",">=",":=","...","(",")","","]","{","}",",",";",".",":"],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F']*[0-9a-fA-F]/,"number.hex"],[/0[0-7']*[0-7]/,"number.octal"],[/0[bB][0-1']*[0-1]/,"number.binary"],[/\d[\d']*/,"number"],[/\d/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/`/,"string","@rawstring"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@doccomment"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],doccomment:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],rawstring:[[/[^\`]/,"string"],[/`/,"string","@pop"]]}};export{e as conf,n as language}; diff --git a/app/dubbo-ui/dist/admin/assets/graphql-CtVT9S5J.js b/app/dubbo-ui/dist/admin/assets/graphql-CtVT9S5J.js deleted file mode 100644 index a6a4e77ad..000000000 --- a/app/dubbo-ui/dist/admin/assets/graphql-CtVT9S5J.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""',notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""'},{open:'"',close:'"'}],folding:{offSide:!0}},n={defaultToken:"invalid",tokenPostfix:".gql",keywords:["null","true","false","query","mutation","subscription","extend","schema","directive","scalar","type","interface","union","enum","input","implements","fragment","on"],typeKeywords:["Int","Float","String","Boolean","ID"],directiveLocations:["SCHEMA","SCALAR","OBJECT","FIELD_DEFINITION","ARGUMENT_DEFINITION","INTERFACE","UNION","ENUM","ENUM_VALUE","INPUT_OBJECT","INPUT_FIELD_DEFINITION","QUERY","MUTATION","SUBSCRIPTION","FIELD","FRAGMENT_DEFINITION","FRAGMENT_SPREAD","INLINE_FRAGMENT","VARIABLE_DEFINITION"],operators:["=","!","?",":","&","|"],symbols:/[=!?:&|]+/,escapes:/\\(?:["\\\/bfnrt]|u[0-9A-Fa-f]{4})/,tokenizer:{root:[[/[a-z_][\w$]*/,{cases:{"@keywords":"keyword","@default":"key.identifier"}}],[/[$][\w$]*/,{cases:{"@keywords":"keyword","@default":"argument.identifier"}}],[/[A-Z][\w\$]*/,{cases:{"@typeKeywords":"keyword","@default":"type.identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,{token:"annotation",log:"annotation token: $0"}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"""/,{token:"string",next:"@mlstring",nextEmbedded:"markdown"}],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",bracket:"@open",next:"@string"}]],mlstring:[[/[^"]+/,"string"],['"""',{token:"string",next:"@pop",nextEmbedded:"@pop"}]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/#.*$/,"comment"]]}};export{e as conf,n as language}; diff --git a/app/dubbo-ui/dist/admin/assets/handlebars-WxO52qam.js b/app/dubbo-ui/dist/admin/assets/handlebars-WxO52qam.js deleted file mode 100644 index f7c544033..000000000 --- a/app/dubbo-ui/dist/admin/assets/handlebars-WxO52qam.js +++ /dev/null @@ -1,6 +0,0 @@ -import{m as i}from"./js-yaml-8Gkz3BRW.js";import"./index-hmLAZQYT.js";/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var s=Object.defineProperty,d=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,p=Object.prototype.hasOwnProperty,o=(t,e,r,m)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of c(e))!p.call(t,n)&&n!==r&&s(t,n,{get:()=>e[n],enumerable:!(m=d(e,n))||m.enumerable});return t},h=(t,e,r)=>(o(t,e,"default"),r&&o(r,e,"default")),a={};h(a,i);var l=["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"],y={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,comments:{blockComment:["{{!--","--}}"]},brackets:[[""],["<",">"],["{{","}}"],["{","}"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"<",close:">"},{open:'"',close:'"'},{open:"'",close:"'"}],onEnterRules:[{beforeText:new RegExp(`<(?!(?:${l.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),afterText:/^<\/(\w[\w\d]*)\s*>$/i,action:{indentAction:a.languages.IndentAction.IndentOutdent}},{beforeText:new RegExp(`<(?!(?:${l.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),action:{indentAction:a.languages.IndentAction.Indent}}]},k={defaultToken:"",tokenPostfix:"",tokenizer:{root:[[/\{\{!--/,"comment.block.start.handlebars","@commentBlock"],[/\{\{!/,"comment.start.handlebars","@comment"],[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.root"}],[/)/,["delimiter.html","tag.html","delimiter.html"]],[/(<)(script)/,["delimiter.html",{token:"tag.html",next:"@script"}]],[/(<)(style)/,["delimiter.html",{token:"tag.html",next:"@style"}]],[/(<)([:\w]+)/,["delimiter.html",{token:"tag.html",next:"@otherTag"}]],[/(<\/)(\w+)/,["delimiter.html",{token:"tag.html",next:"@otherTag"}]],[/]+/,"metatag.content.html"],[/>/,"metatag.html","@pop"]],comment:[[/\}\}/,"comment.end.handlebars","@pop"],[/./,"comment.content.handlebars"]],commentBlock:[[/--\}\}/,"comment.block.end.handlebars","@pop"],[/./,"comment.content.handlebars"]],commentHtml:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.comment"}],[/-->/,"comment.html","@pop"],[/[^-]+/,"comment.content.html"],[/./,"comment.content.html"]],otherTag:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.otherTag"}],[/\/?>/,"delimiter.html","@pop"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/]],script:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.script"}],[/type/,"attribute.name","@scriptAfterType"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/>/,{token:"delimiter.html",next:"@scriptEmbedded.text/javascript",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/(<\/)(script\s*)(>)/,["delimiter.html","tag.html",{token:"delimiter.html",next:"@pop"}]]],scriptAfterType:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.scriptAfterType"}],[/=/,"delimiter","@scriptAfterTypeEquals"],[/>/,{token:"delimiter.html",next:"@scriptEmbedded.text/javascript",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptAfterTypeEquals:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.scriptAfterTypeEquals"}],[/"([^"]*)"/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/>/,{token:"delimiter.html",next:"@scriptEmbedded.text/javascript",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptWithCustomType:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.scriptWithCustomType.$S2"}],[/>/,{token:"delimiter.html",next:"@scriptEmbedded.$S2",nextEmbedded:"$S2"}],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptEmbedded:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInEmbeddedState.scriptEmbedded.$S2",nextEmbedded:"@pop"}],[/<\/script/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}]],style:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.style"}],[/type/,"attribute.name","@styleAfterType"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/>/,{token:"delimiter.html",next:"@styleEmbedded.text/css",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/(<\/)(style\s*)(>)/,["delimiter.html","tag.html",{token:"delimiter.html",next:"@pop"}]]],styleAfterType:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.styleAfterType"}],[/=/,"delimiter","@styleAfterTypeEquals"],[/>/,{token:"delimiter.html",next:"@styleEmbedded.text/css",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleAfterTypeEquals:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.styleAfterTypeEquals"}],[/"([^"]*)"/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/>/,{token:"delimiter.html",next:"@styleEmbedded.text/css",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleWithCustomType:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInSimpleState.styleWithCustomType.$S2"}],[/>/,{token:"delimiter.html",next:"@styleEmbedded.$S2",nextEmbedded:"$S2"}],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleEmbedded:[[/\{\{/,{token:"@rematch",switchTo:"@handlebarsInEmbeddedState.styleEmbedded.$S2",nextEmbedded:"@pop"}],[/<\/style/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}]],handlebarsInSimpleState:[[/\{\{\{?/,"delimiter.handlebars"],[/\}\}\}?/,{token:"delimiter.handlebars",switchTo:"@$S2.$S3"}],{include:"handlebarsRoot"}],handlebarsInEmbeddedState:[[/\{\{\{?/,"delimiter.handlebars"],[/\}\}\}?/,{token:"delimiter.handlebars",switchTo:"@$S2.$S3",nextEmbedded:"$S3"}],{include:"handlebarsRoot"}],handlebarsRoot:[[/"[^"]*"/,"string.handlebars"],[/[#/][^\s}]+/,"keyword.helper.handlebars"],[/else\b/,"keyword.helper.handlebars"],[/[\s]+/],[/[^}]/,"variable.parameter.handlebars"]]}};export{y as conf,k as language}; diff --git a/app/dubbo-ui/dist/admin/assets/hcl-rcnRcHhv.js b/app/dubbo-ui/dist/admin/assets/hcl-rcnRcHhv.js deleted file mode 100644 index 8f23e8f53..000000000 --- a/app/dubbo-ui/dist/admin/assets/hcl-rcnRcHhv.js +++ /dev/null @@ -1,6 +0,0 @@ -/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var e={comments:{lineComment:"#",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"',notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}]},t={defaultToken:"",tokenPostfix:".hcl",keywords:["var","local","path","for_each","any","string","number","bool","true","false","null","if ","else ","endif ","for ","in","endfor"],operators:["=",">=","<=","==","!=","+","-","*","/","%","&&","||","!","<",">","?","...",":"],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\d[\d']*/,"number"],[/\d/,"number"],[/[;,.]/,"delimiter"],[/"/,"string","@string"],[/'/,"invalid"]],heredoc:[[/<<[-]*\s*["]?([\w\-]+)["]?/,{token:"string.heredoc.delimiter",next:"@heredocBody.$1"}]],heredocBody:[[/([\w\-]+)$/,{cases:{"$1==$S2":[{token:"string.heredoc.delimiter",next:"@popall"}],"@default":"string.heredoc"}}],[/./,"string.heredoc"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"],[/#.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/\$\{/,{token:"delimiter",next:"@stringExpression"}],[/[^\\"\$]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@popall"]],stringInsideExpression:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],stringExpression:[[/\}/,{token:"delimiter",next:"@pop"}],[/"/,"string","@stringInsideExpression"],{include:"@terraform"}]}};export{e as conf,t as language}; diff --git a/app/dubbo-ui/dist/admin/assets/html-uljtN73o.js b/app/dubbo-ui/dist/admin/assets/html-uljtN73o.js deleted file mode 100644 index 059dc5488..000000000 --- a/app/dubbo-ui/dist/admin/assets/html-uljtN73o.js +++ /dev/null @@ -1,6 +0,0 @@ -import{m as p}from"./js-yaml-8Gkz3BRW.js";import"./index-hmLAZQYT.js";/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var d=Object.defineProperty,m=Object.getOwnPropertyDescriptor,l=Object.getOwnPropertyNames,c=Object.prototype.hasOwnProperty,a=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of l(e))!c.call(t,r)&&r!==n&&d(t,r,{get:()=>e[r],enumerable:!(o=m(e,r))||o.enumerable});return t},u=(t,e,n)=>(a(t,e,"default"),n&&a(n,e,"default")),i={};u(i,p);var s=["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"],y={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,comments:{blockComment:[""]},brackets:[[""],["<",">"],["{","}"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:'"',close:'"'},{open:"'",close:"'"},{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"}],onEnterRules:[{beforeText:new RegExp(`<(?!(?:${s.join("|")}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:i.languages.IndentAction.IndentOutdent}},{beforeText:new RegExp(`<(?!(?:${s.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),action:{indentAction:i.languages.IndentAction.Indent}}],folding:{markers:{start:new RegExp("^\\s*"),end:new RegExp("^\\s*")}}},k={defaultToken:"",tokenPostfix:".html",ignoreCase:!0,tokenizer:{root:[[/)/,["delimiter","tag","","delimiter"]],[/(<)(script)/,["delimiter",{token:"tag",next:"@script"}]],[/(<)(style)/,["delimiter",{token:"tag",next:"@style"}]],[/(<)((?:[\w\-]+:)?[\w\-]+)/,["delimiter",{token:"tag",next:"@otherTag"}]],[/(<\/)((?:[\w\-]+:)?[\w\-]+)/,["delimiter",{token:"tag",next:"@otherTag"}]],[/]+/,"metatag.content"],[/>/,"metatag","@pop"]],comment:[[/-->/,"comment","@pop"],[/[^-]+/,"comment.content"],[/./,"comment.content"]],otherTag:[[/\/?>/,"delimiter","@pop"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/]],script:[[/type/,"attribute.name","@scriptAfterType"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/(<\/)(script\s*)(>)/,["delimiter","tag",{token:"delimiter",next:"@pop"}]]],scriptAfterType:[[/=/,"delimiter","@scriptAfterTypeEquals"],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptAfterTypeEquals:[[/"module"/,{token:"attribute.value",switchTo:"@scriptWithCustomType.text/javascript"}],[/'module'/,{token:"attribute.value",switchTo:"@scriptWithCustomType.text/javascript"}],[/"([^"]*)"/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptWithCustomType:[[/>/,{token:"delimiter",next:"@scriptEmbedded.$S2",nextEmbedded:"$S2"}],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptEmbedded:[[/<\/script/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}],[/[^<]+/,""]],style:[[/type/,"attribute.name","@styleAfterType"],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/(<\/)(style\s*)(>)/,["delimiter","tag",{token:"delimiter",next:"@pop"}]]],styleAfterType:[[/=/,"delimiter","@styleAfterTypeEquals"],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleAfterTypeEquals:[[/"([^"]*)"/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleWithCustomType:[[/>/,{token:"delimiter",next:"@styleEmbedded.$S2",nextEmbedded:"$S2"}],[/"([^"]*)"/,"attribute.value"],[/'([^']*)'/,"attribute.value"],[/[\w\-]+/,"attribute.name"],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleEmbedded:[[/<\/style/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}],[/[^<]+/,""]]}};export{y as conf,k as language}; diff --git a/app/dubbo-ui/dist/admin/assets/htmlMode-X6nY_fAl.js b/app/dubbo-ui/dist/admin/assets/htmlMode-X6nY_fAl.js deleted file mode 100644 index c150c2acd..000000000 --- a/app/dubbo-ui/dist/admin/assets/htmlMode-X6nY_fAl.js +++ /dev/null @@ -1,9 +0,0 @@ -import{m as ft}from"./js-yaml-8Gkz3BRW.js";import"./index-hmLAZQYT.js";/*!----------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt - *-----------------------------------------------------------------------------*/var gt=Object.defineProperty,ht=Object.getOwnPropertyDescriptor,vt=Object.getOwnPropertyNames,pt=Object.prototype.hasOwnProperty,T=(e,n,i,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of vt(n))!pt.call(e,t)&&t!==i&>(e,t,{get:()=>n[t],enumerable:!(r=ht(n,t))||r.enumerable});return e},mt=(e,n,i)=>(T(e,n,"default"),i&&T(i,n,"default")),c={};mt(c,ft);var _t=2*60*1e3,Ge=class{constructor(e){this._defaults=e,this._worker=null,this._client=null,this._idleCheckInterval=window.setInterval(()=>this._checkIfIdle(),30*1e3),this._lastUsedTime=0,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker())}_stopWorker(){this._worker&&(this._worker.dispose(),this._worker=null),this._client=null}dispose(){clearInterval(this._idleCheckInterval),this._configChangeListener.dispose(),this._stopWorker()}_checkIfIdle(){if(!this._worker)return;Date.now()-this._lastUsedTime>_t&&this._stopWorker()}_getClient(){return this._lastUsedTime=Date.now(),this._client||(this._worker=c.editor.createWebWorker({moduleId:"vs/language/html/htmlWorker",createData:{languageSettings:this._defaults.options,languageId:this._defaults.languageId},label:this._defaults.languageId}),this._client=this._worker.getProxy()),this._client}getLanguageServiceWorker(...e){let n;return this._getClient().then(i=>{n=i}).then(i=>{if(this._worker)return this._worker.withSyncedResources(e)}).then(i=>n)}},Y;(function(e){function n(i){return typeof i=="string"}e.is=n})(Y||(Y={}));var S;(function(e){function n(i){return typeof i=="string"}e.is=n})(S||(S={}));var Z;(function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647;function n(i){return typeof i=="number"&&e.MIN_VALUE<=i&&i<=e.MAX_VALUE}e.is=n})(Z||(Z={}));var M;(function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647;function n(i){return typeof i=="number"&&e.MIN_VALUE<=i&&i<=e.MAX_VALUE}e.is=n})(M||(M={}));var b;(function(e){function n(r,t){return r===Number.MAX_VALUE&&(r=M.MAX_VALUE),t===Number.MAX_VALUE&&(t=M.MAX_VALUE),{line:r,character:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&a.uinteger(t.line)&&a.uinteger(t.character)}e.is=i})(b||(b={}));var h;(function(e){function n(r,t,o,s){if(a.uinteger(r)&&a.uinteger(t)&&a.uinteger(o)&&a.uinteger(s))return{start:b.create(r,t),end:b.create(o,s)};if(b.is(r)&&b.is(t))return{start:r,end:t};throw new Error(`Range#create called with invalid arguments[${r}, ${t}, ${o}, ${s}]`)}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&b.is(t.start)&&b.is(t.end)}e.is=i})(h||(h={}));var C;(function(e){function n(r,t){return{uri:r,range:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.range)&&(a.string(t.uri)||a.undefined(t.uri))}e.is=i})(C||(C={}));var K;(function(e){function n(r,t,o,s){return{targetUri:r,targetRange:t,targetSelectionRange:o,originSelectionRange:s}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.targetRange)&&a.string(t.targetUri)&&h.is(t.targetSelectionRange)&&(h.is(t.originSelectionRange)||a.undefined(t.originSelectionRange))}e.is=i})(K||(K={}));var O;(function(e){function n(r,t,o,s){return{red:r,green:t,blue:o,alpha:s}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.numberRange(t.red,0,1)&&a.numberRange(t.green,0,1)&&a.numberRange(t.blue,0,1)&&a.numberRange(t.alpha,0,1)}e.is=i})(O||(O={}));var ee;(function(e){function n(r,t){return{range:r,color:t}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&h.is(t.range)&&O.is(t.color)}e.is=i})(ee||(ee={}));var te;(function(e){function n(r,t,o){return{label:r,textEdit:t,additionalTextEdits:o}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.string(t.label)&&(a.undefined(t.textEdit)||E.is(t))&&(a.undefined(t.additionalTextEdits)||a.typedArray(t.additionalTextEdits,E.is))}e.is=i})(te||(te={}));var A;(function(e){e.Comment="comment",e.Imports="imports",e.Region="region"})(A||(A={}));var re;(function(e){function n(r,t,o,s,u,f){const d={startLine:r,endLine:t};return a.defined(o)&&(d.startCharacter=o),a.defined(s)&&(d.endCharacter=s),a.defined(u)&&(d.kind=u),a.defined(f)&&(d.collapsedText=f),d}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.uinteger(t.startLine)&&a.uinteger(t.startLine)&&(a.undefined(t.startCharacter)||a.uinteger(t.startCharacter))&&(a.undefined(t.endCharacter)||a.uinteger(t.endCharacter))&&(a.undefined(t.kind)||a.string(t.kind))}e.is=i})(re||(re={}));var U;(function(e){function n(r,t){return{location:r,message:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&C.is(t.location)&&a.string(t.message)}e.is=i})(U||(U={}));var x;(function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4})(x||(x={}));var ne;(function(e){e.Unnecessary=1,e.Deprecated=2})(ne||(ne={}));var ie;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&a.string(r.href)}e.is=n})(ie||(ie={}));var F;(function(e){function n(r,t,o,s,u,f){let d={range:r,message:t};return a.defined(o)&&(d.severity=o),a.defined(s)&&(d.code=s),a.defined(u)&&(d.source=u),a.defined(f)&&(d.relatedInformation=f),d}e.create=n;function i(r){var t;let o=r;return a.defined(o)&&h.is(o.range)&&a.string(o.message)&&(a.number(o.severity)||a.undefined(o.severity))&&(a.integer(o.code)||a.string(o.code)||a.undefined(o.code))&&(a.undefined(o.codeDescription)||a.string((t=o.codeDescription)===null||t===void 0?void 0:t.href))&&(a.string(o.source)||a.undefined(o.source))&&(a.undefined(o.relatedInformation)||a.typedArray(o.relatedInformation,U.is))}e.is=i})(F||(F={}));var I;(function(e){function n(r,t,...o){let s={title:r,command:t};return a.defined(o)&&o.length>0&&(s.arguments=o),s}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.title)&&a.string(t.command)}e.is=i})(I||(I={}));var E;(function(e){function n(o,s){return{range:o,newText:s}}e.replace=n;function i(o,s){return{range:{start:o,end:o},newText:s}}e.insert=i;function r(o){return{range:o,newText:""}}e.del=r;function t(o){const s=o;return a.objectLiteral(s)&&a.string(s.newText)&&h.is(s.range)}e.is=t})(E||(E={}));var V;(function(e){function n(r,t,o){const s={label:r};return t!==void 0&&(s.needsConfirmation=t),o!==void 0&&(s.description=o),s}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&a.string(t.label)&&(a.boolean(t.needsConfirmation)||t.needsConfirmation===void 0)&&(a.string(t.description)||t.description===void 0)}e.is=i})(V||(V={}));var L;(function(e){function n(i){const r=i;return a.string(r)}e.is=n})(L||(L={}));var oe;(function(e){function n(o,s,u){return{range:o,newText:s,annotationId:u}}e.replace=n;function i(o,s,u){return{range:{start:o,end:o},newText:s,annotationId:u}}e.insert=i;function r(o,s){return{range:o,newText:"",annotationId:s}}e.del=r;function t(o){const s=o;return E.is(s)&&(V.is(s.annotationId)||L.is(s.annotationId))}e.is=t})(oe||(oe={}));var W;(function(e){function n(r,t){return{textDocument:r,edits:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&B.is(t.textDocument)&&Array.isArray(t.edits)}e.is=i})(W||(W={}));var H;(function(e){function n(r,t,o){let s={kind:"create",uri:r};return t!==void 0&&(t.overwrite!==void 0||t.ignoreIfExists!==void 0)&&(s.options=t),o!==void 0&&(s.annotationId=o),s}e.create=n;function i(r){let t=r;return t&&t.kind==="create"&&a.string(t.uri)&&(t.options===void 0||(t.options.overwrite===void 0||a.boolean(t.options.overwrite))&&(t.options.ignoreIfExists===void 0||a.boolean(t.options.ignoreIfExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})(H||(H={}));var X;(function(e){function n(r,t,o,s){let u={kind:"rename",oldUri:r,newUri:t};return o!==void 0&&(o.overwrite!==void 0||o.ignoreIfExists!==void 0)&&(u.options=o),s!==void 0&&(u.annotationId=s),u}e.create=n;function i(r){let t=r;return t&&t.kind==="rename"&&a.string(t.oldUri)&&a.string(t.newUri)&&(t.options===void 0||(t.options.overwrite===void 0||a.boolean(t.options.overwrite))&&(t.options.ignoreIfExists===void 0||a.boolean(t.options.ignoreIfExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})(X||(X={}));var $;(function(e){function n(r,t,o){let s={kind:"delete",uri:r};return t!==void 0&&(t.recursive!==void 0||t.ignoreIfNotExists!==void 0)&&(s.options=t),o!==void 0&&(s.annotationId=o),s}e.create=n;function i(r){let t=r;return t&&t.kind==="delete"&&a.string(t.uri)&&(t.options===void 0||(t.options.recursive===void 0||a.boolean(t.options.recursive))&&(t.options.ignoreIfNotExists===void 0||a.boolean(t.options.ignoreIfNotExists)))&&(t.annotationId===void 0||L.is(t.annotationId))}e.is=i})($||($={}));var z;(function(e){function n(i){let r=i;return r&&(r.changes!==void 0||r.documentChanges!==void 0)&&(r.documentChanges===void 0||r.documentChanges.every(t=>a.string(t.kind)?H.is(t)||X.is(t)||$.is(t):W.is(t)))}e.is=n})(z||(z={}));var ae;(function(e){function n(r){return{uri:r}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)}e.is=i})(ae||(ae={}));var se;(function(e){function n(r,t){return{uri:r,version:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&a.integer(t.version)}e.is=i})(se||(se={}));var B;(function(e){function n(r,t){return{uri:r,version:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&(t.version===null||a.integer(t.version))}e.is=i})(B||(B={}));var ue;(function(e){function n(r,t,o,s){return{uri:r,languageId:t,version:o,text:s}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.string(t.uri)&&a.string(t.languageId)&&a.integer(t.version)&&a.string(t.text)}e.is=i})(ue||(ue={}));var q;(function(e){e.PlainText="plaintext",e.Markdown="markdown";function n(i){const r=i;return r===e.PlainText||r===e.Markdown}e.is=n})(q||(q={}));var P;(function(e){function n(i){const r=i;return a.objectLiteral(i)&&q.is(r.kind)&&a.string(r.value)}e.is=n})(P||(P={}));var v;(function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25})(v||(v={}));var Q;(function(e){e.PlainText=1,e.Snippet=2})(Q||(Q={}));var ce;(function(e){e.Deprecated=1})(ce||(ce={}));var de;(function(e){function n(r,t,o){return{newText:r,insert:t,replace:o}}e.create=n;function i(r){const t=r;return t&&a.string(t.newText)&&h.is(t.insert)&&h.is(t.replace)}e.is=i})(de||(de={}));var le;(function(e){e.asIs=1,e.adjustIndentation=2})(le||(le={}));var fe;(function(e){function n(i){const r=i;return r&&(a.string(r.detail)||r.detail===void 0)&&(a.string(r.description)||r.description===void 0)}e.is=n})(fe||(fe={}));var ge;(function(e){function n(i){return{label:i}}e.create=n})(ge||(ge={}));var he;(function(e){function n(i,r){return{items:i||[],isIncomplete:!!r}}e.create=n})(he||(he={}));var y;(function(e){function n(r){return r.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}e.fromPlainText=n;function i(r){const t=r;return a.string(t)||a.objectLiteral(t)&&a.string(t.language)&&a.string(t.value)}e.is=i})(y||(y={}));var ve;(function(e){function n(i){let r=i;return!!r&&a.objectLiteral(r)&&(P.is(r.contents)||y.is(r.contents)||a.typedArray(r.contents,y.is))&&(i.range===void 0||h.is(i.range))}e.is=n})(ve||(ve={}));var pe;(function(e){function n(i,r){return r?{label:i,documentation:r}:{label:i}}e.create=n})(pe||(pe={}));var me;(function(e){function n(i,r,...t){let o={label:i};return a.defined(r)&&(o.documentation=r),a.defined(t)?o.parameters=t:o.parameters=[],o}e.create=n})(me||(me={}));var R;(function(e){e.Text=1,e.Read=2,e.Write=3})(R||(R={}));var _e;(function(e){function n(i,r){let t={range:i};return a.number(r)&&(t.kind=r),t}e.create=n})(_e||(_e={}));var p;(function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26})(p||(p={}));var we;(function(e){e.Deprecated=1})(we||(we={}));var be;(function(e){function n(i,r,t,o,s){let u={name:i,kind:r,location:{uri:o,range:t}};return s&&(u.containerName=s),u}e.create=n})(be||(be={}));var ke;(function(e){function n(i,r,t,o){return o!==void 0?{name:i,kind:r,location:{uri:t,range:o}}:{name:i,kind:r,location:{uri:t}}}e.create=n})(ke||(ke={}));var xe;(function(e){function n(r,t,o,s,u,f){let d={name:r,detail:t,kind:o,range:s,selectionRange:u};return f!==void 0&&(d.children=f),d}e.create=n;function i(r){let t=r;return t&&a.string(t.name)&&a.number(t.kind)&&h.is(t.range)&&h.is(t.selectionRange)&&(t.detail===void 0||a.string(t.detail))&&(t.deprecated===void 0||a.boolean(t.deprecated))&&(t.children===void 0||Array.isArray(t.children))&&(t.tags===void 0||Array.isArray(t.tags))}e.is=i})(xe||(xe={}));var Ie;(function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"})(Ie||(Ie={}));var j;(function(e){e.Invoked=1,e.Automatic=2})(j||(j={}));var Ee;(function(e){function n(r,t,o){let s={diagnostics:r};return t!=null&&(s.only=t),o!=null&&(s.triggerKind=o),s}e.create=n;function i(r){let t=r;return a.defined(t)&&a.typedArray(t.diagnostics,F.is)&&(t.only===void 0||a.typedArray(t.only,a.string))&&(t.triggerKind===void 0||t.triggerKind===j.Invoked||t.triggerKind===j.Automatic)}e.is=i})(Ee||(Ee={}));var Le;(function(e){function n(r,t,o){let s={title:r},u=!0;return typeof t=="string"?(u=!1,s.kind=t):I.is(t)?s.command=t:s.edit=t,u&&o!==void 0&&(s.kind=o),s}e.create=n;function i(r){let t=r;return t&&a.string(t.title)&&(t.diagnostics===void 0||a.typedArray(t.diagnostics,F.is))&&(t.kind===void 0||a.string(t.kind))&&(t.edit!==void 0||t.command!==void 0)&&(t.command===void 0||I.is(t.command))&&(t.isPreferred===void 0||a.boolean(t.isPreferred))&&(t.edit===void 0||z.is(t.edit))}e.is=i})(Le||(Le={}));var Ae;(function(e){function n(r,t){let o={range:r};return a.defined(t)&&(o.data=t),o}e.create=n;function i(r){let t=r;return a.defined(t)&&h.is(t.range)&&(a.undefined(t.command)||I.is(t.command))}e.is=i})(Ae||(Ae={}));var Re;(function(e){function n(r,t){return{tabSize:r,insertSpaces:t}}e.create=n;function i(r){let t=r;return a.defined(t)&&a.uinteger(t.tabSize)&&a.boolean(t.insertSpaces)}e.is=i})(Re||(Re={}));var Pe;(function(e){function n(r,t,o){return{range:r,target:t,data:o}}e.create=n;function i(r){let t=r;return a.defined(t)&&h.is(t.range)&&(a.undefined(t.target)||a.string(t.target))}e.is=i})(Pe||(Pe={}));var De;(function(e){function n(r,t){return{range:r,parent:t}}e.create=n;function i(r){let t=r;return a.objectLiteral(t)&&h.is(t.range)&&(t.parent===void 0||e.is(t.parent))}e.is=i})(De||(De={}));var Me;(function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"})(Me||(Me={}));var Ce;(function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"})(Ce||(Ce={}));var Fe;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&(r.resultId===void 0||typeof r.resultId=="string")&&Array.isArray(r.data)&&(r.data.length===0||typeof r.data[0]=="number")}e.is=n})(Fe||(Fe={}));var ye;(function(e){function n(r,t){return{range:r,text:t}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&a.string(t.text)}e.is=i})(ye||(ye={}));var je;(function(e){function n(r,t,o){return{range:r,variableName:t,caseSensitiveLookup:o}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&a.boolean(t.caseSensitiveLookup)&&(a.string(t.variableName)||t.variableName===void 0)}e.is=i})(je||(je={}));var Ne;(function(e){function n(r,t){return{range:r,expression:t}}e.create=n;function i(r){const t=r;return t!=null&&h.is(t.range)&&(a.string(t.expression)||t.expression===void 0)}e.is=i})(Ne||(Ne={}));var Se;(function(e){function n(r,t){return{frameId:r,stoppedLocation:t}}e.create=n;function i(r){const t=r;return a.defined(t)&&h.is(r.stoppedLocation)}e.is=i})(Se||(Se={}));var G;(function(e){e.Type=1,e.Parameter=2;function n(i){return i===1||i===2}e.is=n})(G||(G={}));var J;(function(e){function n(r){return{value:r}}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&(t.tooltip===void 0||a.string(t.tooltip)||P.is(t.tooltip))&&(t.location===void 0||C.is(t.location))&&(t.command===void 0||I.is(t.command))}e.is=i})(J||(J={}));var Oe;(function(e){function n(r,t,o){const s={position:r,label:t};return o!==void 0&&(s.kind=o),s}e.create=n;function i(r){const t=r;return a.objectLiteral(t)&&b.is(t.position)&&(a.string(t.label)||a.typedArray(t.label,J.is))&&(t.kind===void 0||G.is(t.kind))&&t.textEdits===void 0||a.typedArray(t.textEdits,E.is)&&(t.tooltip===void 0||a.string(t.tooltip)||P.is(t.tooltip))&&(t.paddingLeft===void 0||a.boolean(t.paddingLeft))&&(t.paddingRight===void 0||a.boolean(t.paddingRight))}e.is=i})(Oe||(Oe={}));var Ue;(function(e){function n(i){return{kind:"snippet",value:i}}e.createSnippet=n})(Ue||(Ue={}));var Ve;(function(e){function n(i,r,t,o){return{insertText:i,filterText:r,range:t,command:o}}e.create=n})(Ve||(Ve={}));var We;(function(e){function n(i){return{items:i}}e.create=n})(We||(We={}));var He;(function(e){e.Invoked=0,e.Automatic=1})(He||(He={}));var Xe;(function(e){function n(i,r){return{range:i,text:r}}e.create=n})(Xe||(Xe={}));var $e;(function(e){function n(i,r){return{triggerKind:i,selectedCompletionInfo:r}}e.create=n})($e||($e={}));var ze;(function(e){function n(i){const r=i;return a.objectLiteral(r)&&S.is(r.uri)&&a.string(r.name)}e.is=n})(ze||(ze={}));var Be;(function(e){function n(o,s,u,f){return new wt(o,s,u,f)}e.create=n;function i(o){let s=o;return!!(a.defined(s)&&a.string(s.uri)&&(a.undefined(s.languageId)||a.string(s.languageId))&&a.uinteger(s.lineCount)&&a.func(s.getText)&&a.func(s.positionAt)&&a.func(s.offsetAt))}e.is=i;function r(o,s){let u=o.getText(),f=t(s,(g,_)=>{let w=g.range.start.line-_.range.start.line;return w===0?g.range.start.character-_.range.start.character:w}),d=u.length;for(let g=f.length-1;g>=0;g--){let _=f[g],w=o.offsetAt(_.range.start),l=o.offsetAt(_.range.end);if(l<=d)u=u.substring(0,w)+_.newText+u.substring(l,u.length);else throw new Error("Overlapping edit");d=w}return u}e.applyEdits=r;function t(o,s){if(o.length<=1)return o;const u=o.length/2|0,f=o.slice(0,u),d=o.slice(u);t(f,s),t(d,s);let g=0,_=0,w=0;for(;g0&&e.push(n.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let n=this.getLineOffsets(),i=0,r=n.length;if(r===0)return b.create(0,e);for(;ie?r=o:i=o+1}let t=i-1;return b.create(t,e-n[t])}offsetAt(e){let n=this.getLineOffsets();if(e.line>=n.length)return this._content.length;if(e.line<0)return 0;let i=n[e.line],r=e.line+1"u"}e.undefined=r;function t(l){return l===!0||l===!1}e.boolean=t;function o(l){return n.call(l)==="[object String]"}e.string=o;function s(l){return n.call(l)==="[object Number]"}e.number=s;function u(l,N,lt){return n.call(l)==="[object Number]"&&N<=l&&l<=lt}e.numberRange=u;function f(l){return n.call(l)==="[object Number]"&&-2147483648<=l&&l<=2147483647}e.integer=f;function d(l){return n.call(l)==="[object Number]"&&0<=l&&l<=2147483647}e.uinteger=d;function g(l){return n.call(l)==="[object Function]"}e.func=g;function _(l){return l!==null&&typeof l=="object"}e.objectLiteral=_;function w(l,N){return Array.isArray(l)&&l.every(N)}e.typedArray=w})(a||(a={}));var jt=class{constructor(e,n,i){this._languageId=e,this._worker=n,this._disposables=[],this._listener=Object.create(null);const r=o=>{let s=o.getLanguageId();if(s!==this._languageId)return;let u;this._listener[o.uri.toString()]=o.onDidChangeContent(()=>{window.clearTimeout(u),u=window.setTimeout(()=>this._doValidate(o.uri,s),500)}),this._doValidate(o.uri,s)},t=o=>{c.editor.setModelMarkers(o,this._languageId,[]);let s=o.uri.toString(),u=this._listener[s];u&&(u.dispose(),delete this._listener[s])};this._disposables.push(c.editor.onDidCreateModel(r)),this._disposables.push(c.editor.onWillDisposeModel(t)),this._disposables.push(c.editor.onDidChangeModelLanguage(o=>{t(o.model),r(o.model)})),this._disposables.push(i(o=>{c.editor.getModels().forEach(s=>{s.getLanguageId()===this._languageId&&(t(s),r(s))})})),this._disposables.push({dispose:()=>{c.editor.getModels().forEach(t);for(let o in this._listener)this._listener[o].dispose()}}),c.editor.getModels().forEach(r)}dispose(){this._disposables.forEach(e=>e&&e.dispose()),this._disposables.length=0}_doValidate(e,n){this._worker(e).then(i=>i.doValidation(e.toString())).then(i=>{const r=i.map(o=>kt(e,o));let t=c.editor.getModel(e);t&&t.getLanguageId()===n&&c.editor.setModelMarkers(t,n,r)}).then(void 0,i=>{console.error(i)})}};function bt(e){switch(e){case x.Error:return c.MarkerSeverity.Error;case x.Warning:return c.MarkerSeverity.Warning;case x.Information:return c.MarkerSeverity.Info;case x.Hint:return c.MarkerSeverity.Hint;default:return c.MarkerSeverity.Info}}function kt(e,n){let i=typeof n.code=="number"?String(n.code):n.code;return{severity:bt(n.severity),startLineNumber:n.range.start.line+1,startColumn:n.range.start.character+1,endLineNumber:n.range.end.line+1,endColumn:n.range.end.character+1,message:n.message,code:i,source:n.source}}var xt=class{constructor(e,n){this._worker=e,this._triggerCharacters=n}get triggerCharacters(){return this._triggerCharacters}provideCompletionItems(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.doComplete(t.toString(),k(n))).then(o=>{if(!o)return;const s=e.getWordUntilPosition(n),u=new c.Range(n.lineNumber,s.startColumn,n.lineNumber,s.endColumn),f=o.items.map(d=>{const g={label:d.label,insertText:d.insertText||d.label,sortText:d.sortText,filterText:d.filterText,documentation:d.documentation,detail:d.detail,command:Lt(d.command),range:u,kind:Et(d.kind)};return d.textEdit&&(It(d.textEdit)?g.range={insert:m(d.textEdit.insert),replace:m(d.textEdit.replace)}:g.range=m(d.textEdit.range),g.insertText=d.textEdit.newText),d.additionalTextEdits&&(g.additionalTextEdits=d.additionalTextEdits.map(D)),d.insertTextFormat===Q.Snippet&&(g.insertTextRules=c.languages.CompletionItemInsertTextRule.InsertAsSnippet),g});return{isIncomplete:o.isIncomplete,suggestions:f}})}};function k(e){if(e)return{character:e.column-1,line:e.lineNumber-1}}function Je(e){if(e)return{start:{line:e.startLineNumber-1,character:e.startColumn-1},end:{line:e.endLineNumber-1,character:e.endColumn-1}}}function m(e){if(e)return new c.Range(e.start.line+1,e.start.character+1,e.end.line+1,e.end.character+1)}function It(e){return typeof e.insert<"u"&&typeof e.replace<"u"}function Et(e){const n=c.languages.CompletionItemKind;switch(e){case v.Text:return n.Text;case v.Method:return n.Method;case v.Function:return n.Function;case v.Constructor:return n.Constructor;case v.Field:return n.Field;case v.Variable:return n.Variable;case v.Class:return n.Class;case v.Interface:return n.Interface;case v.Module:return n.Module;case v.Property:return n.Property;case v.Unit:return n.Unit;case v.Value:return n.Value;case v.Enum:return n.Enum;case v.Keyword:return n.Keyword;case v.Snippet:return n.Snippet;case v.Color:return n.Color;case v.File:return n.File;case v.Reference:return n.Reference}return n.Property}function D(e){if(e)return{range:m(e.range),text:e.newText}}function Lt(e){return e&&e.command==="editor.action.triggerSuggest"?{id:e.command,title:e.title,arguments:e.arguments}:void 0}var Te=class{constructor(e){this._worker=e}provideHover(e,n,i){let r=e.uri;return this._worker(r).then(t=>t.doHover(r.toString(),k(n))).then(t=>{if(t)return{range:m(t.range),contents:Rt(t.contents)}})}};function At(e){return e&&typeof e=="object"&&typeof e.kind=="string"}function qe(e){return typeof e=="string"?{value:e}:At(e)?e.kind==="plaintext"?{value:e.value.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}:{value:e.value}:{value:"```"+e.language+` -`+e.value+"\n```\n"}}function Rt(e){if(e)return Array.isArray(e)?e.map(qe):[qe(e)]}var Ye=class{constructor(e){this._worker=e}provideDocumentHighlights(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.findDocumentHighlights(r.toString(),k(n))).then(t=>{if(t)return t.map(o=>({range:m(o.range),kind:Pt(o.kind)}))})}};function Pt(e){switch(e){case R.Read:return c.languages.DocumentHighlightKind.Read;case R.Write:return c.languages.DocumentHighlightKind.Write;case R.Text:return c.languages.DocumentHighlightKind.Text}return c.languages.DocumentHighlightKind.Text}var Nt=class{constructor(e){this._worker=e}provideDefinition(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.findDefinition(r.toString(),k(n))).then(t=>{if(t)return[Ze(t)]})}};function Ze(e){return{uri:c.Uri.parse(e.uri),range:m(e.range)}}var St=class{constructor(e){this._worker=e}provideReferences(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.findReferences(t.toString(),k(n))).then(o=>{if(o)return o.map(Ze)})}},Ke=class{constructor(e){this._worker=e}provideRenameEdits(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.doRename(t.toString(),k(n),i)).then(o=>Dt(o))}};function Dt(e){if(!e||!e.changes)return;let n=[];for(let i in e.changes){const r=c.Uri.parse(i);for(let t of e.changes[i])n.push({resource:r,versionId:void 0,textEdit:{range:m(t.range),text:t.newText}})}return{edits:n}}var et=class{constructor(e){this._worker=e}provideDocumentSymbols(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentSymbols(i.toString())).then(r=>{if(r)return r.map(t=>Mt(t)?tt(t):{name:t.name,detail:"",containerName:t.containerName,kind:rt(t.kind),range:m(t.location.range),selectionRange:m(t.location.range),tags:[]})})}};function Mt(e){return"children"in e}function tt(e){return{name:e.name,detail:e.detail??"",kind:rt(e.kind),range:m(e.range),selectionRange:m(e.selectionRange),tags:e.tags??[],children:(e.children??[]).map(n=>tt(n))}}function rt(e){let n=c.languages.SymbolKind;switch(e){case p.File:return n.File;case p.Module:return n.Module;case p.Namespace:return n.Namespace;case p.Package:return n.Package;case p.Class:return n.Class;case p.Method:return n.Method;case p.Property:return n.Property;case p.Field:return n.Field;case p.Constructor:return n.Constructor;case p.Enum:return n.Enum;case p.Interface:return n.Interface;case p.Function:return n.Function;case p.Variable:return n.Variable;case p.Constant:return n.Constant;case p.String:return n.String;case p.Number:return n.Number;case p.Boolean:return n.Boolean;case p.Array:return n.Array}return n.Function}var nt=class{constructor(e){this._worker=e}provideLinks(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentLinks(i.toString())).then(r=>{if(r)return{links:r.map(t=>({range:m(t.range),url:t.target}))}})}},it=class{constructor(e){this._worker=e}provideDocumentFormattingEdits(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.format(r.toString(),null,at(n)).then(o=>{if(!(!o||o.length===0))return o.map(D)}))}},ot=class{constructor(e){this._worker=e,this.canFormatMultipleRanges=!1}provideDocumentRangeFormattingEdits(e,n,i,r){const t=e.uri;return this._worker(t).then(o=>o.format(t.toString(),Je(n),at(i)).then(s=>{if(!(!s||s.length===0))return s.map(D)}))}};function at(e){return{tabSize:e.tabSize,insertSpaces:e.insertSpaces}}var Ot=class{constructor(e){this._worker=e}provideDocumentColors(e,n){const i=e.uri;return this._worker(i).then(r=>r.findDocumentColors(i.toString())).then(r=>{if(r)return r.map(t=>({color:t.color,range:m(t.range)}))})}provideColorPresentations(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getColorPresentations(r.toString(),n.color,Je(n.range))).then(t=>{if(t)return t.map(o=>{let s={label:o.label};return o.textEdit&&(s.textEdit=D(o.textEdit)),o.additionalTextEdits&&(s.additionalTextEdits=o.additionalTextEdits.map(D)),s})})}},st=class{constructor(e){this._worker=e}provideFoldingRanges(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getFoldingRanges(r.toString(),n)).then(t=>{if(t)return t.map(o=>{const s={start:o.startLine+1,end:o.endLine+1};return typeof o.kind<"u"&&(s.kind=Ct(o.kind)),s})})}};function Ct(e){switch(e){case A.Comment:return c.languages.FoldingRangeKind.Comment;case A.Imports:return c.languages.FoldingRangeKind.Imports;case A.Region:return c.languages.FoldingRangeKind.Region}}var ut=class{constructor(e){this._worker=e}provideSelectionRanges(e,n,i){const r=e.uri;return this._worker(r).then(t=>t.getSelectionRanges(r.toString(),n.map(k))).then(t=>{if(t)return t.map(o=>{const s=[];for(;o;)s.push({range:m(o.range)}),o=o.parent;return s})})}},ct=class extends xt{constructor(e){super(e,[".",":","<",'"',"=","/"])}};function Ut(e){const n=new Ge(e),i=(...t)=>n.getLanguageServiceWorker(...t);let r=e.languageId;c.languages.registerCompletionItemProvider(r,new ct(i)),c.languages.registerHoverProvider(r,new Te(i)),c.languages.registerDocumentHighlightProvider(r,new Ye(i)),c.languages.registerLinkProvider(r,new nt(i)),c.languages.registerFoldingRangeProvider(r,new st(i)),c.languages.registerDocumentSymbolProvider(r,new et(i)),c.languages.registerSelectionRangeProvider(r,new ut(i)),c.languages.registerRenameProvider(r,new Ke(i)),r==="html"&&(c.languages.registerDocumentFormattingEditProvider(r,new it(i)),c.languages.registerDocumentRangeFormattingEditProvider(r,new ot(i)))}function Vt(e){const n=[],i=[],r=new Ge(e);n.push(r);const t=(...s)=>r.getLanguageServiceWorker(...s);function o(){const{languageId:s,modeConfiguration:u}=e;dt(i),u.completionItems&&i.push(c.languages.registerCompletionItemProvider(s,new ct(t))),u.hovers&&i.push(c.languages.registerHoverProvider(s,new Te(t))),u.documentHighlights&&i.push(c.languages.registerDocumentHighlightProvider(s,new Ye(t))),u.links&&i.push(c.languages.registerLinkProvider(s,new nt(t))),u.documentSymbols&&i.push(c.languages.registerDocumentSymbolProvider(s,new et(t))),u.rename&&i.push(c.languages.registerRenameProvider(s,new Ke(t))),u.foldingRanges&&i.push(c.languages.registerFoldingRangeProvider(s,new st(t))),u.selectionRanges&&i.push(c.languages.registerSelectionRangeProvider(s,new ut(t))),u.documentFormattingEdits&&i.push(c.languages.registerDocumentFormattingEditProvider(s,new it(t))),u.documentRangeFormattingEdits&&i.push(c.languages.registerDocumentRangeFormattingEditProvider(s,new ot(t)))}return o(),n.push(Qe(i)),Qe(n)}function Qe(e){return{dispose:()=>dt(e)}}function dt(e){for(;e.length;)e.pop().dispose()}export{xt as CompletionAdapter,Nt as DefinitionAdapter,jt as DiagnosticsAdapter,Ot as DocumentColorAdapter,it as DocumentFormattingEditProvider,Ye as DocumentHighlightAdapter,nt as DocumentLinkAdapter,ot as DocumentRangeFormattingEditProvider,et as DocumentSymbolAdapter,st as FoldingRangeAdapter,Te as HoverAdapter,St as ReferenceAdapter,Ke as RenameAdapter,ut as SelectionRangeAdapter,Ge as WorkerManager,k as fromPosition,Je as fromRange,Vt as setupMode,Ut as setupMode1,m as toRange,D as toTextEdit}; diff --git a/app/dubbo-ui/dist/admin/assets/index-1-DS2ySp.js b/app/dubbo-ui/dist/admin/assets/index-1-DS2ySp.js deleted file mode 100644 index e9989d33c..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-1-DS2ySp.js +++ /dev/null @@ -1 +0,0 @@ -import{d as N,v as g,a as w,r as b,W as D,D as S,c as n,b as _,w as l,n as p,P as v,R,e as V,o as t,J as y,K as C,G as h,f as d,t as c,X as q,j as A,I as E,Q as B,y as O,_ as M}from"./index-hmLAZQYT.js";import{s as P}from"./app-duU6O0cq.js";import{S as T,a as Y,s as x}from"./SearchUtil-sOWd6ofa.js";import"./request-8jI_GZey.js";const F={class:"__container_resources_application_index"},J=["onClick"],K=N({__name:"index",setup(L){g(e=>({d89413de:p(v)}));let u=w(),k=u.query.query,f=[{title:"appName",key:"appName",dataIndex:"appName",sorter:(e,s)=>x(e.appName,s.appName),width:140,ellipsis:!0},{title:"applicationDomain.instanceCount",key:"instanceCount",dataIndex:"instanceCount",width:100,sorter:(e,s)=>x(e.instanceCount,s.instanceCount)},{title:"applicationDomain.deployClusters",key:"deployClusters",dataIndex:"deployClusters",width:120},{title:"applicationDomain.registryClusters",key:"registryClusters",dataIndex:"registryClusters",width:200}];const a=b(new T([{label:"appName",param:"keywords",defaultValue:k,placeholder:"typeAppName",style:{width:"200px"}}],P,f));return D(()=>{a.onSearch(),a.tableStyle={scrollX:"100",scrollY:"367px"}}),R(O.SEARCH_DOMAIN,a),S(u,(e,s)=>{a.queryForm.keywords=e.query.query,a.onSearch(),console.log(e)}),(e,s)=>{const m=V("a-tag");return t(),n("div",F,[_(Y,{"search-domain":a},{bodyCell:l(({text:i,record:I,index:X,column:r})=>[r.dataIndex==="registryClusters"?(t(!0),n(y,{key:0},C(i,o=>(t(),h(m,null,{default:l(()=>[d(c(o),1)]),_:2},1024))),256)):r.dataIndex==="deployClusters"?(t(!0),n(y,{key:1},C(i,o=>(t(),h(m,null,{default:l(()=>[d(c(o),1)]),_:2},1024))),256)):r.dataIndex==="appName"?(t(),n("span",{key:2,class:"app-link",onClick:o=>p(q).push(`/resources/applications/detail/${I[r.key]}`)},[A("b",null,[_(p(E),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),d(" "+c(i),1)])],8,J)):B("",!0)]),_:1},8,["search-domain"])])}}}),Q=M(K,[["__scopeId","data-v-2d6e7df7"]]);export{Q as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-1FKHxc4J.css b/app/dubbo-ui/dist/admin/assets/index-1FKHxc4J.css deleted file mode 100644 index 136a93cc5..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-1FKHxc4J.css +++ /dev/null @@ -1 +0,0 @@ -.__container_menu .icon-wrapper .icon[data-v-0c21c672]{font-size:20px;margin-right:5px;margin-bottom:-4px;font-weight:700}.__container_layout_header .header[data-v-8929dc94]{background:var(--5b012264);padding:0}.__container_layout_header .header .search-group[data-v-8929dc94]{display:flex;align-items:center}.__container_layout_header .header .search-group .select-type[data-v-8929dc94]{width:120px}.__container_layout_header .header .search-group .input-keywords[data-v-8929dc94]{width:20vw}.__container_layout_header .header .search-group .input-keywords[data-v-8929dc94]:hover,.__container_layout_header .header .search-group .input-keywords[data-v-8929dc94]:hover .ant-select-selector{border-color:#d9d9d9}.__container_layout_header .header .search-group .input-keywords[data-v-8929dc94] .ant-select-selector,.__container_layout_header .header .search-group .input-keywords[data-v-8929dc94] .ant-select-selector:hover{border-color:#d9d9d9;box-shadow:none}.__container_layout_header .header .search-group .search-icon[data-v-8929dc94]{width:32px}.__container_layout_header .trigger[data-v-8929dc94]{font-size:20px;margin-left:20px;color:#fff}.__container_layout_header .username[data-v-8929dc94]{color:#fff;padding:5px}.__container_layout_header .reset-icon[data-v-8929dc94]{font-size:25px;color:#fff}.__container_layout_bread[data-v-97925c3f]{padding-left:20px;padding-top:10px}.__container_layout_index[data-v-bf34dde3] .ant-layout-content{padding:16px!important}.__container_layout_index .logo[data-v-bf34dde3]{height:40px;width:auto;margin:10px 15px;padding-left:10px;padding-right:10px;border-radius:8px;background:var(--0345b33d);line-height:40px;vertical-align:middle;font-size:22px;color:#fff}.__container_layout_index .logo img[data-v-bf34dde3]{width:28px;height:28px;margin-bottom:5px;margin-right:5px}.__container_layout_index .layout-content[data-v-bf34dde3]{margin:16px;padding:16px 16px 24px;overflow:hidden;height:calc(100vh - 140px)}.__container_layout_index .layout-footer[data-v-bf34dde3]{height:30px;text-align:center}.slide-fade-enter-active{animation:slide-fade-in .5s}@keyframes slide-fade-in{0%{transform:translate(80px);opacity:0}50%{transform:translate(-2px);opacity:20}to{transform:translate(0);opacity:100}}.fade-enter-active{animation:fade-in .6s ease-in-out}.fade-leave-active{animation:fade-in .6s reverse}@keyframes fade-in{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:100}} diff --git a/app/dubbo-ui/dist/admin/assets/index-3ObQClF5.js b/app/dubbo-ui/dist/admin/assets/index-3ObQClF5.js deleted file mode 100644 index 66defbb73..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-3ObQClF5.js +++ /dev/null @@ -1 +0,0 @@ -import{d as w,v as S,x as T,y as h,r as g,W as E,c as l,b as n,w as o,n as r,P as V,R as $,e as C,o as c,X as p,f as a,j as D,I as A,t as _,Q as u,J as f,_ as B}from"./index-hmLAZQYT.js";import{s as G,d as O}from"./traffic-C2a-KjHH.js";import{S as P,a as Y,s as y}from"./SearchUtil-sOWd6ofa.js";import{f as F}from"./DateUtil-BI1mUH_z.js";import"./request-8jI_GZey.js";const J={class:"routing-rule-container"},M=["onClick"],j=w({__name:"index",setup(K){S(e=>({"5abc36e7":r(V)}));const N=T(h.PROVIDE_INJECT_KEY);let I=[{title:"ruleName",key:"ruleName",dataIndex:"ruleName",sorter:(e,t)=>y(e.appName,t.appName),width:140},{title:"ruleGranularity",key:"ruleGranularity",dataIndex:"ruleGranularity",render:(e,t)=>t.isService?"服务":"应用",width:100,sorter:(e,t)=>y(e.instanceNum,t.instanceNum)},{title:"createTime",key:"createTime",dataIndex:"createTime",width:120,sorter:(e,t)=>y(e.instanceNum,t.instanceNum)},{title:"enabled",key:"enabled",dataIndex:"enabled",width:120,sorter:(e,t)=>y(e.instanceNum,t.instanceNum)},{title:"operation",key:"operation",dataIndex:"operation",width:200}];const d=g(new P([{label:"serviceGovernance",param:"serviceGovernance",placeholder:"typeRoutingRules",style:{width:"200px"}}],G,I)),v=async e=>{(await O(e)).code===200&&await d.onSearch()};E(()=>{N.conditionRule=null,N.addConditionRuleSate=null,d.onSearch(),d.tableStyle={scrollX:"100",scrollY:"367px"}});const R=e=>{v(e)};return $(h.SEARCH_DOMAIN,d),(e,t)=>{const m=C("a-button"),b=C("a-popconfirm");return c(),l("div",J,[n(Y,{"search-domain":d},{customOperation:o(()=>[n(m,{type:"primary",onClick:t[0]||(t[0]=k=>r(p).push("/traffic/addRoutingRule/addByFormView"))},{default:o(()=>[a("新增条件路由规则 ")]),_:1})]),bodyCell:o(({text:k,column:i,record:s})=>[i.dataIndex==="ruleName"?(c(),l("span",{key:0,class:"rule-link",onClick:x=>r(p).push(`formview/${s[i.key]}`)},[D("b",null,[n(r(A),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),a(" "+_(k),1)])],8,M)):u("",!0),i.dataIndex==="ruleGranularity"?(c(),l(f,{key:1},[a(_(s.scope==="service"?"服务":"应用"),1)],64)):u("",!0),i.dataIndex==="enabled"?(c(),l(f,{key:2},[a(_(k?"启用":"禁用"),1)],64)):u("",!0),i.dataIndex==="createTime"?(c(),l(f,{key:3},[a(_(r(F)(s.createTime)),1)],64)):u("",!0),i.dataIndex==="operation"?(c(),l(f,{key:4},[n(m,{type:"link",onClick:x=>r(p).push(`formview/${s.ruleName}`)},{default:o(()=>[a(" 查看 ")]),_:2},1032,["onClick"]),n(m,{type:"link",onClick:x=>r(p).push(`/traffic/updateRoutingRule/updateByFormView/${s.ruleName}`)},{default:o(()=>[a(" 修改 ")]),_:2},1032,["onClick"]),n(b,{title:"确认删除该条件路由规则?","ok-text":"Yes","cancel-text":"No",onConfirm:x=>R(s.ruleName)},{default:o(()=>[n(m,{type:"link"},{default:o(()=>[a(" 删除")]),_:1})]),_:2},1032,["onConfirm"])],64)):u("",!0)]),_:1},8,["search-domain"])])}}}),q=B(j,[["__scopeId","data-v-142b26f8"]]);export{q as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-6mDJigRo.js b/app/dubbo-ui/dist/admin/assets/index-6mDJigRo.js deleted file mode 100644 index 9def9d6da..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-6mDJigRo.js +++ /dev/null @@ -1 +0,0 @@ -import{d as D,v as R,u as S,x as T,y as N,r as k,W as E,c as o,b as t,w as n,n as r,P as V,R as $,e as x,o as s,f as i,j as G,I as O,t as C,Q as p,J as h,_ as A}from"./index-hmLAZQYT.js";import{i as B,j as P}from"./traffic-C2a-KjHH.js";import{S as Y,a as j,s as f}from"./SearchUtil-sOWd6ofa.js";import"./request-8jI_GZey.js";const J={class:"__container_traffic_config_index"},M=["onClick"],F=D({__name:"index",setup(K){R(e=>({"2f10a2da":r(V)}));const c=S(),v=T(N.PROVIDE_INJECT_KEY);v.dynamicConfigForm=k({});let I=[{title:"ruleName",key:"ruleName",dataIndex:"ruleName",sorter:(e,a)=>f(e.appName,a.appName),width:200,ellipsis:!0},{title:"ruleGranularity",key:"ruleGranularity",dataIndex:"ruleGranularity",render:(e,a)=>a.isService?"服务":"应用",width:100,sorter:(e,a)=>f(e.instanceNum,a.instanceNum)},{title:"createTime",key:"createTime",dataIndex:"createTime",width:200,sorter:(e,a)=>f(e.instanceNum,a.instanceNum)},{title:"enabled",key:"enabled",dataIndex:"enabled",render:(e,a)=>a.enabled?"是":"否",width:120,sorter:(e,a)=>f(e.instanceNum,a.instanceNum)},{title:"operation",key:"operation",dataIndex:"operation",width:200}];const l=k(new Y([{label:"serviceGovernance",param:"serviceGovernance",placeholder:"typeRoutingRules",style:{width:"200px"}}],B,I)),g=()=>{c.push("/traffic/dynamicConfig/formview/_tmp/1")};E(async()=>{await l.onSearch()});const w=async e=>{await P({name:e.ruleName}),await l.onSearch()};return $(N.SEARCH_DOMAIN,l),(e,a)=>{const d=x("a-button"),b=x("a-popconfirm");return s(),o("div",J,[t(j,{"search-domain":l},{customOperation:n(()=>[t(d,{type:"primary",onClick:g},{default:n(()=>[i("新增动态配置")]),_:1})]),bodyCell:n(({text:_,column:m,record:u})=>[m.dataIndex==="ruleName"?(s(),o("span",{key:0,class:"config-link",onClick:y=>r(c).push(`/traffic/dynamicConfig/formview/${u.ruleName}/0`)},[G("b",null,[t(r(O),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),i(" "+C(_),1)])],8,M)):p("",!0),m.dataIndex==="ruleGranularity"?(s(),o(h,{key:1},[i(C(_?"服务":"应用"),1)],64)):p("",!0),m.dataIndex==="enabled"?(s(),o(h,{key:2},[i(C(_?"启用":"禁用"),1)],64)):p("",!0),m.dataIndex==="operation"?(s(),o(h,{key:3},[t(d,{type:"link",onClick:y=>r(c).push(`/traffic/dynamicConfig/formview/${u.ruleName}/0`)},{default:n(()=>[i("查看")]),_:2},1032,["onClick"]),t(d,{type:"link",onClick:y=>r(c).push(`/traffic/dynamicConfig/formview/${u.ruleName}/1`)},{default:n(()=>[i(" 修改 ")]),_:2},1032,["onClick"]),t(b,{title:"确认删除该动态配置?","ok-text":"Yes","cancel-text":"No",onConfirm:y=>w(u)},{default:n(()=>[t(d,{type:"link"},{default:n(()=>[i("删除")]),_:1})]),_:2},1032,["onConfirm"])],64)):p("",!0)]),_:1},8,["search-domain"])])}}}),q=A(F,[["__scopeId","data-v-25acc517"]]);export{q as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-BItwxFIb.js b/app/dubbo-ui/dist/admin/assets/index-BItwxFIb.js deleted file mode 100644 index d032dcd26..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-BItwxFIb.js +++ /dev/null @@ -1 +0,0 @@ -import{d as b,u as d,c as u,f as o,b as s,w as r,n as _,j as t,e as c,o as i}from"./index-hmLAZQYT.js";const h={class:"__container_tab_index"},p=t("br",null,null,-1),f=t("a",{href:"/admin/common/tab/tab1/pathId1"},"to tab1 by href",-1),m=t("br",null,null,-1),x=t("a",{href:"tab2/pathId1"},"to tab2 by href",-1),C=t("br",null,null,-1),k=t("br",null,null,-1),B=b({__name:"index",setup(v){const n=d();return(y,e)=>{const a=c("a-button");return i(),u("div",h,[o(" tab page "),p,f,m,x,C,s(a,{onClick:e[0]||(e[0]=l=>_(n).push("/common/tab/tab1/pathId1"))},{default:r(()=>[o("to tab1 by href")]),_:1}),k,s(a,{onClick:e[1]||(e[1]=l=>_(n).push("tab2/pathId1"))},{default:r(()=>[o("to tab2 by href")]),_:1})])}}});export{B as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-DgO44mZ7.css b/app/dubbo-ui/dist/admin/assets/index-DgO44mZ7.css deleted file mode 100644 index 96092a4de..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-DgO44mZ7.css +++ /dev/null @@ -1 +0,0 @@ -.tag-rule-container[data-v-8b7bd8e7]{height:100%}.tag-rule-container .search-table-container[data-v-8b7bd8e7]{min-height:60vh}.tag-rule-container .search-table-container .rule-link[data-v-8b7bd8e7]{padding:4px 10px 4px 4px;border-radius:4px;color:var(--c2298156)}.tag-rule-container .search-table-container .rule-link[data-v-8b7bd8e7]:hover{cursor:pointer;background:#85838321} diff --git a/app/dubbo-ui/dist/admin/assets/index-JAGQH17O.js b/app/dubbo-ui/dist/admin/assets/index-JAGQH17O.js deleted file mode 100644 index 2d1456cbb..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-JAGQH17O.js +++ /dev/null @@ -1 +0,0 @@ -import{d as T,v as g,x as S,y as C,W as N,a as $,r as D,c as l,b as t,w as n,n as o,P as E,R as V,e as b,o as c,X as p,f as r,j as A,I as B,t as y,Q as f,J as k,_ as O}from"./index-hmLAZQYT.js";import{b as P,c as Y}from"./traffic-C2a-KjHH.js";import{S as F,a as J,s as h}from"./SearchUtil-sOWd6ofa.js";import{f as M}from"./DateUtil-BI1mUH_z.js";import"./request-8jI_GZey.js";const j={class:"tag-rule-container"},G=["onClick"],K=T({__name:"index",setup(X){g(e=>({c2298156:o(E)}));const x=S(C.PROVIDE_INJECT_KEY);N(()=>{x.tagRule=null}),$();let I=[{title:"ruleName",key:"ruleName",dataIndex:"ruleName",sorter:(e,a)=>h(e.appName,a.appName),width:140},{title:"createTime",key:"createTime",dataIndex:"createTime",width:120,sorter:(e,a)=>h(e.instanceNum,a.instanceNum)},{title:"enable",key:"enabled",dataIndex:"enabled",width:120,sorter:(e,a)=>h(e.instanceNum,a.instanceNum)},{title:"operation",key:"operation",dataIndex:"operation",width:200}];const s=D(new F([{label:"serviceGovernance",param:"serviceGovernance",placeholder:"typeRoutingRules",style:{width:"200px"}}],P,I)),v=async e=>{(await Y(e)).code===200&&await s.onSearch()};N(()=>{s.onSearch(),s.tableStyle={scrollX:"100",scrollY:"367px"}});const R=e=>{v(e)};return V(C.SEARCH_DOMAIN,s),(e,a)=>{const d=b("a-button"),w=b("a-popconfirm");return c(),l("div",j,[t(J,{"search-domain":s},{customOperation:n(()=>[t(d,{type:"primary",onClick:a[0]||(a[0]=m=>o(p).push("/traffic/addTagRule/addByFormView"))},{default:n(()=>[r(" 新增标签路由规则 ")]),_:1})]),bodyCell:n(({text:m,column:i,record:u})=>[i.dataIndex==="ruleName"?(c(),l("span",{key:0,class:"rule-link",onClick:_=>o(p).push(`/traffic/tagRule/formview/${u[i.key]}`)},[A("b",null,[t(o(B),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),r(" "+y(m),1)])],8,G)):f("",!0),i.dataIndex==="createTime"?(c(),l(k,{key:1},[r(y(o(M)(m)),1)],64)):f("",!0),i.dataIndex==="enabled"?(c(),l(k,{key:2},[r(y(m?e.$t("flowControlDomain.enabled"):e.$t("flowControlDomain.disabled")),1)],64)):f("",!0),i.dataIndex==="operation"?(c(),l(k,{key:3},[t(d,{type:"link",onClick:_=>o(p).push(`formview/${u.ruleName}`)},{default:n(()=>[r(" 查看 ")]),_:2},1032,["onClick"]),t(d,{onClick:_=>o(p).push(`/traffic/updateTagRule/updateByFormView/${u.ruleName}`),type:"link"},{default:n(()=>[r(" 修改 ")]),_:2},1032,["onClick"]),t(w,{title:"确认删除该标签路由规则?","ok-text":"Yes","cancel-text":"No",onConfirm:_=>R(u.ruleName)},{default:n(()=>[t(d,{type:"link"},{default:n(()=>[r(" 删除 ")]),_:1})]),_:2},1032,["onConfirm"])],64)):f("",!0)]),_:1},8,["search-domain"])])}}}),z=O(K,[["__scopeId","data-v-8b7bd8e7"]]);export{z as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-PRmcKXGy.js b/app/dubbo-ui/dist/admin/assets/index-PRmcKXGy.js deleted file mode 100644 index 191a05a80..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-PRmcKXGy.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c,o}from"./index-hmLAZQYT.js";const n={},_={class:"__container_common_index"};function t(r,s){return o(),c("div",_,"placeholder demo")}const d=e(n,[["render",t]]);export{d as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-VJs-1Ntn.js b/app/dubbo-ui/dist/admin/assets/index-VJs-1Ntn.js deleted file mode 100644 index b1f7b77b7..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-VJs-1Ntn.js +++ /dev/null @@ -1,4 +0,0 @@ -import{d as w,v as b,a as D,r as N,W as T,D as E,c as _,b as I,w as l,n as p,P as R,F as O,R as q,e as v,o,X as V,j as A,I as L,f as c,t as m,Q as u,G as y,a1 as P,a2 as $,J as B,K as F,y as M,_ as Y}from"./index-hmLAZQYT.js";import{s as U}from"./instance-9-P3Wy8N.js";import{S as G,a as H,s as r}from"./SearchUtil-sOWd6ofa.js";import{p as J,q as f}from"./PromQueryUtil-2EbGMcmH.js";import{b as K}from"./ByteUtil-YdHlSEeW.js";import"./request-8jI_GZey.js";const Q={class:"instances-container"},X=["onClick"],j=w({__name:"index",setup(W){b(e=>({"2ab83322":p(R)}));let C=D(),g=C.query.query,S=[{title:"instanceDomain.instanceIP",key:"ip",dataIndex:"ip",sorter:(e,t)=>r(e.ip,t.ip),width:200},{title:"instanceDomain.instanceName",key:"name",dataIndex:"name",sorter:(e,t)=>r(e.name,t.name),width:140},{title:"instanceDomain.deployState",key:"deployState",dataIndex:"deployState",width:120,sorter:(e,t)=>r(e.deployState,t.deployState)},{title:"instanceDomain.deployCluster",key:"deployCluster",dataIndex:"deployCluster",sorter:(e,t)=>r(e.deployCluster,t.deployCluster),width:120},{title:"instanceDomain.registerState",key:"registerState",dataIndex:"registerState",sorter:(e,t)=>r(e.registerState,t.registerState),width:120},{title:"instanceDomain.registerCluster",key:"registerClusters",dataIndex:"registerClusters",sorter:(e,t)=>r(e.registerClusters,t.registerClusters),width:140},{title:"instanceDomain.CPU",key:"cpu",dataIndex:"cpu",sorter:(e,t)=>r(e.cpu,t.cpu),width:140},{title:"instanceDomain.memory",key:"memory",dataIndex:"memory",sorter:(e,t)=>r(e.memory,t.memory),width:100},{title:"instanceDomain.startTime_k8s",key:"startTime_k8s",dataIndex:"startTime",sorter:(e,t)=>r(e.startTime,t.startTime),width:200}];function x(e){return U(e).then(async t=>J(t,["cpu","memory"],async s=>{let a=s.ip.split(":")[0],i=await f(`sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=""}) by (pod) * on (pod) group_left(pod_ip) - kube_pod_info{pod_ip="${a}"}`),h=await f(`sum(container_memory_working_set_bytes{container!=""}) by (pod) -* on (pod) group_left(pod_ip) -kube_pod_info{pod_ip="${a}"}`);s.cpu=O.isNumber(i)?i.toFixed(3)+"u":i,s.memory=K(h)}))}const n=N(new G([{label:"appName",param:"keywords",defaultValue:g,placeholder:"typeAppName",style:{width:"200px"}}],x,S));return T(()=>{n.tableStyle={scrollX:"100",scrollY:"367px"},n.onSearch()}),q(M.SEARCH_DOMAIN,n),E(C,(e,t)=>{n.queryForm.keywords=e.query.query,n.onSearch(),console.log(e)}),(e,t)=>{const s=v("a-tag");return o(),_("div",Q,[I(H,{"search-domain":n},{bodyCell:l(({text:a,record:i,index:h,column:d})=>[d.dataIndex==="ip"?(o(),_("span",{key:0,class:"app-link",onClick:k=>p(V).push(`/resources/instances/detail/${i.name}/${i[d.key]}`)},[A("b",null,[I(p(L),{style:{"margin-bottom":"-2px"},icon:"material-symbols:attach-file-rounded"}),c(" "+m(a),1)])],8,X)):u("",!0),d.dataIndex==="deployState"?(o(),y(s,{key:1,color:p(P)[a.toUpperCase()]},{default:l(()=>[c(m(a),1)]),_:2},1032,["color"])):u("",!0),d.dataIndex==="deployCluster"?(o(),y(s,{key:2,color:"grey"},{default:l(()=>[c(m(a),1)]),_:2},1024)):u("",!0),d.dataIndex==="registerState"?(o(),y(s,{key:3,color:p($)[a.toUpperCase()]},{default:l(()=>[c(m(a),1)]),_:2},1032,["color"])):u("",!0),d.dataIndex==="registerClusters"?(o(!0),_(B,{key:4},F(a,k=>(o(),y(s,{color:"grey"},{default:l(()=>[c(m(k),1)]),_:2},1024))),256)):u("",!0)]),_:1},8,["search-domain"])])}}}),se=Y(j,[["__scopeId","data-v-2f938e3f"]]);export{se as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-Va7nxJVK.js b/app/dubbo-ui/dist/admin/assets/index-Va7nxJVK.js deleted file mode 100644 index 1d9af79aa..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-Va7nxJVK.js +++ /dev/null @@ -1,6 +0,0 @@ -import{V as $,ac as J}from"./index-hmLAZQYT.js";var M={exports:{}};/*! - * clipboard.js v2.0.11 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */(function(x,O){(function(_,g){x.exports=g()})(J,function(){return function(){var T={686:function(s,u,t){t.d(u,{default:function(){return X}});var a=t(279),f=t.n(a),l=t(370),h=t.n(l),y=t(817),m=t.n(y);function d(i){try{return document.execCommand(i)}catch{return!1}}var v=function(n){var e=m()(n);return d("cut"),e},p=v;function E(i){var n=document.documentElement.getAttribute("dir")==="rtl",e=document.createElement("textarea");e.style.fontSize="12pt",e.style.border="0",e.style.padding="0",e.style.margin="0",e.style.position="absolute",e.style[n?"right":"left"]="-9999px";var r=window.pageYOffset||document.documentElement.scrollTop;return e.style.top="".concat(r,"px"),e.setAttribute("readonly",""),e.value=i,e}var R=function(n,e){var r=E(n);e.container.appendChild(r);var o=m()(r);return d("copy"),r.remove(),o},j=function(n){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},r="";return typeof n=="string"?r=R(n,e):n instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(n==null?void 0:n.type)?r=R(n.value,e):(r=m()(n),d("copy")),r},L=j;function w(i){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?w=function(e){return typeof e}:w=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},w(i)}var D=function(){var n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},e=n.action,r=e===void 0?"copy":e,o=n.container,c=n.target,b=n.text;if(r!=="copy"&&r!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(c!==void 0)if(c&&w(c)==="object"&&c.nodeType===1){if(r==="copy"&&c.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(r==="cut"&&(c.hasAttribute("readonly")||c.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(b)return L(b,{container:o});if(c)return r==="cut"?p(c):L(c,{container:o})},F=D;function S(i){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?S=function(e){return typeof e}:S=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},S(i)}function H(i,n){if(!(i instanceof n))throw new TypeError("Cannot call a class as a function")}function N(i,n){for(var e=0;e"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch{return!1}}function A(i){return A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},A(i)}function P(i,n){var e="data-clipboard-".concat(i);if(n.hasAttribute(e))return n.getAttribute(e)}var G=function(i){z(e,i);var n=B(e);function e(r,o){var c;return H(this,e),c=n.call(this),c.resolveOptions(o),c.listenClick(r),c}return I(e,[{key:"resolveOptions",value:function(){var o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof o.action=="function"?o.action:this.defaultAction,this.target=typeof o.target=="function"?o.target:this.defaultTarget,this.text=typeof o.text=="function"?o.text:this.defaultText,this.container=S(o.container)==="object"?o.container:document.body}},{key:"listenClick",value:function(o){var c=this;this.listener=h()(o,"click",function(b){return c.onClick(b)})}},{key:"onClick",value:function(o){var c=o.delegateTarget||o.currentTarget,b=this.action(c)||"copy",C=F({action:b,container:this.container,target:this.target(c),text:this.text(c)});this.emit(C?"success":"error",{action:b,text:C,trigger:c,clearSelection:function(){c&&c.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(o){return P("action",o)}},{key:"defaultTarget",value:function(o){var c=P("target",o);if(c)return document.querySelector(c)}},{key:"defaultText",value:function(o){return P("text",o)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(o){var c=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return L(o,c)}},{key:"cut",value:function(o){return p(o)}},{key:"isSupported",value:function(){var o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],c=typeof o=="string"?[o]:o,b=!!document.queryCommandSupported;return c.forEach(function(C){b=b&&!!document.queryCommandSupported(C)}),b}}]),e}(f()),X=G},828:function(s){var u=9;if(typeof Element<"u"&&!Element.prototype.matches){var t=Element.prototype;t.matches=t.matchesSelector||t.mozMatchesSelector||t.msMatchesSelector||t.oMatchesSelector||t.webkitMatchesSelector}function a(f,l){for(;f&&f.nodeType!==u;){if(typeof f.matches=="function"&&f.matches(l))return f;f=f.parentNode}}s.exports=a},438:function(s,u,t){var a=t(828);function f(y,m,d,v,p){var E=h.apply(this,arguments);return y.addEventListener(d,E,p),{destroy:function(){y.removeEventListener(d,E,p)}}}function l(y,m,d,v,p){return typeof y.addEventListener=="function"?f.apply(null,arguments):typeof d=="function"?f.bind(null,document).apply(null,arguments):(typeof y=="string"&&(y=document.querySelectorAll(y)),Array.prototype.map.call(y,function(E){return f(E,m,d,v,p)}))}function h(y,m,d,v){return function(p){p.delegateTarget=a(p.target,m),p.delegateTarget&&v.call(y,p)}}s.exports=l},879:function(s,u){u.node=function(t){return t!==void 0&&t instanceof HTMLElement&&t.nodeType===1},u.nodeList=function(t){var a=Object.prototype.toString.call(t);return t!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in t&&(t.length===0||u.node(t[0]))},u.string=function(t){return typeof t=="string"||t instanceof String},u.fn=function(t){var a=Object.prototype.toString.call(t);return a==="[object Function]"}},370:function(s,u,t){var a=t(879),f=t(438);function l(d,v,p){if(!d&&!v&&!p)throw new Error("Missing required arguments");if(!a.string(v))throw new TypeError("Second argument must be a String");if(!a.fn(p))throw new TypeError("Third argument must be a Function");if(a.node(d))return h(d,v,p);if(a.nodeList(d))return y(d,v,p);if(a.string(d))return m(d,v,p);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function h(d,v,p){return d.addEventListener(v,p),{destroy:function(){d.removeEventListener(v,p)}}}function y(d,v,p){return Array.prototype.forEach.call(d,function(E){E.addEventListener(v,p)}),{destroy:function(){Array.prototype.forEach.call(d,function(E){E.removeEventListener(v,p)})}}}function m(d,v,p){return f(document.body,d,v,p)}s.exports=l},817:function(s){function u(t){var a;if(t.nodeName==="SELECT")t.focus(),a=t.value;else if(t.nodeName==="INPUT"||t.nodeName==="TEXTAREA"){var f=t.hasAttribute("readonly");f||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),f||t.removeAttribute("readonly"),a=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var l=window.getSelection(),h=document.createRange();h.selectNodeContents(t),l.removeAllRanges(),l.addRange(h),a=l.toString()}return a}s.exports=u},279:function(s){function u(){}u.prototype={on:function(t,a,f){var l=this.e||(this.e={});return(l[t]||(l[t]=[])).push({fn:a,ctx:f}),this},once:function(t,a,f){var l=this;function h(){l.off(t,h),a.apply(f,arguments)}return h._=a,this.on(t,h,f)},emit:function(t){var a=[].slice.call(arguments,1),f=((this.e||(this.e={}))[t]||[]).slice(),l=0,h=f.length;for(l;l{const O=(x==null?void 0:x.appendToBody)===void 0?!0:x.appendToBody;return{toClipboard(T,_){return new Promise((g,s)=>{const u=document.createElement("button"),t=new Q(u,{text:()=>T,action:()=>"copy",container:_!==void 0?_:document.body});t.on("success",a=>{t.destroy(),g(a)}),t.on("error",a=>{t.destroy(),s(a)}),O&&document.body.appendChild(u),u.click(),O&&document.body.removeChild(u)})}}};export{q as u}; diff --git a/app/dubbo-ui/dist/admin/assets/index-YSfCu-V6.css b/app/dubbo-ui/dist/admin/assets/index-YSfCu-V6.css deleted file mode 100644 index 12d4ffbb6..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-YSfCu-V6.css +++ /dev/null @@ -1 +0,0 @@ -.__container_router_tab_index[data-v-e3c1cda1] .tab-spin{margin-top:20vh}.__container_router_tab_index[data-v-e3c1cda1] .ant-tabs-nav{margin:0}.__container_router_tab_index .header[data-v-e3c1cda1]{background:#fafafa;padding:20px 20px 0;border-radius:10px;margin-bottom:20px}.__container_router_tab_index .back[data-v-e3c1cda1]{font-size:24px;margin-bottom:-2px;color:var(--6b871b3a)}.__container_AppTabHeaderSlot .header-desc[data-v-d9202124],.__container_ServiceTabHeaderSlot .header-desc[data-v-3de51f62],.__container_AppTabHeaderSlot .header-desc[data-v-945638c8],.__container_AppTabHeaderSlot .header-desc[data-v-0f2e35af],.__container_AppTabHeaderSlot .header-desc[data-v-8b847dc2],.__container_AppTabHeaderSlot .header-desc[data-v-9e571c17],.__container_AppTabHeaderSlot .header-desc[data-v-0f780945],.__container_AppTabHeaderSlot .header-desc[data-v-49f86476],.__container_AppTabHeaderSlot .header-desc[data-v-91777569],.__container_AppTabHeaderSlot .header-desc[data-v-e3a937b1],.__container_AppTabHeaderSlot .header-desc[data-v-4d4ee463]{line-height:30px;vertical-align:center}.__global_float_button_question{right:24px}#nprogress .bar{background:#000!important}._detail{box-shadow:8px 8px 4px #a2a2a230}.description-item-card{width:80%;margin-left:20px;border:1px dashed rgba(162,162,162,.19)}.description-item-card :deep(.ant-card-body){padding:10px}.description-item-content.no-card{padding-left:20px}.description-item-content.with-card:hover{color:var(--74d14fde)}.__container_tabDemo3 .option{padding-left:16px}.__container_tabDemo3 .option .btn{margin-right:10px}.__container_tabDemo3 :deep(.spin){margin-top:30px}html,body{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,*:before,*:after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{margin:0}[tabindex="-1"]:focus{outline:none}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[title],abbr[data-original-title]{-webkit-text-decoration:underline dotted;text-decoration:underline;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=text],input[type=password],input[type=number],textarea{-webkit-appearance:none}ol,ul,dl{margin-top:0;margin-bottom:1em}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}pre,code,kbd,samp{font-size:1em;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}a,area,button,[role=button],input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;text-align:left;caption-side:bottom}input,button,select,optgroup,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}.small-alpha-slider{height:10px!important}.small-alpha-slider .small-bar{height:10px!important;width:10px!important}.small-alpha-slider .small-bar div{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.bee-alpha-slider{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.bee-alpha-slider.is-vertical{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.bee-alpha-slider.transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-alpha-slider__bar{position:relative;width:100%;height:100%;border-radius:15px}.bee-alpha-slider__bar-pointer{position:absolute;width:14px;height:14px}.bee-alpha-slider__bar-handle{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.bee-alpha-slider__bar-handle.vertical{transform:translateY(-7px);margin-top:0}.bee-compact{margin-bottom:15px;width:auto;box-shadow:3px 0 5px #00000014;display:inline-block}.bee-compact__row{position:relative;width:100%;margin:0}.bee-compact__row>*{display:inline-block;vertical-align:middle}.bee-compact__color_cube{width:100%;height:100%}.bee-compact__color_cube.transparent:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:#fff}.bee-compact__color_cube.transparent:after{content:"";position:absolute;top:100%;left:0;transform:rotate(-45deg);transform-origin:0 0;width:35px;height:1px;background:red}.bee-compact__color_cube.advance{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABqVJREFUeNrEl11yHDUQx1ua2Zlde2M7jqESqnjg45kjcBwOwQG4BY+8cwWK17xBUUARICQhTmI7tte7Ozs7o+bXLTleuACpKNJqJP3789+doKoSPxfVGxFZioS1iK5Yd0nCJko9iLTVVvZSlCOp5FBF7vP5RFTelyDHvmYvMPPtiP19fu+HIHPetrllX2TLMJAOgEehti3ZY/Axap51ZB5ZDEnGMUoCNCmDbRv+2Q4CDJ5Mymj4OmE0CNj6b5WJlkel3xkiGXjOc0imDH/JDid1AXQEfKgccHg3lN+uhh+v2WkkOvCUnT3GjP2WOfrJzjUNPq/ugPUej1TiwME3+DfVUhWkEQF6LZraJxsp6xHLIzW/DNyAW75PGJVrOxbQFSeWzOsdjQ/tZHTxtSgdzAimMfOAdbas7crUvIWAqZg5+gg8FBzYTOygbo1tAb1xTYMs/q1xAFgnvBx5JrKO2X9pzJrJhr+b5BaY8vjG3O+w7HFnypkZ+zP3K8AWL7FHiRsJappe4knA9fo/pj7WrIrdshBs8cukcu0ljhK2lZt1Q8B1msMj5WCQKoibd8q8p1J8i6aWJnrJCcDljDX2Cm8Jn2WJC9PtIHpYeowza125Dc3c6CQ1MbEdooxoPQw54Ak9jigaKcAMk9ddgUi68ZxMmNbNG8hTXXjOZrPf+vg4C+RpRRJqO0ps8FxtzhoJLiSIHCWtLi9u5LiZyqKv0UvlHmaccukoVjJLFu2YUy946FRidS7beCXN9i3gKzd1Yo53ps7ppTnqEYD0mYNldpuxnvIo2nZb/L+ay9tulA/sJpE/Tfchj1H2kW2KpsFYSK4YgI1vZDJe57XmIAu642N5kCxUJfQ8bA48IKpWGNKi/T7rPWRMBMkp5lhz5mUlV0O+fGAGC5XMkTzoG349I/D+Qis0jpeZBt0CXaZGnwtwdcS7A/4ycOIi3bNI0pzfxoVHQYYDIu+A9djJ5bKX+c2BVKnHS5Xcw8QTecWlXxi/khgvYMFzHlp4/g74WREshg3zpuS9mfowShxyrnv6wFS2Dl12QUDwaO54xIWTKZem8up7M0ojn5BzdftEdPMzII9ljE8kVde8Z5y89PSJYcACAJhWTigFOO1rpqRbWs0pKjp4Nkl6OMiGQiFnKsOnLQNqJNe33yV5iFml/4YLfzB+wwpvuNoT+eq0F+JWYtp50MlXLBvUAkLlXXbdloHkUsREDsc6y9LDvs2pTNJD6eM5+x/KAslqWK/pOo/WEIvw3PC3q8rZz3IzWBqqp2CpTvjAACIVyFhLMQmlwXPU9gYrC+lCZs0VtPkc0Jfc+Va+XK/lK3Pr10XhF8ToAjf1VKktAH0hd3srqesSMmCJaiNwJB/IzNviF9Uor8NnndSkyRBfExbPpdHfKRg/yqH8JCPxdvbZVE6+6GTzmCD9Af45RfhzLGZZtEaIVQVdDpLwVByAHeIu8DXWGTySUil8wSNw6fMoliZnfHsqfXiC2M+gjJXX7wuEOvm4gWUBa9h4xrAAtwy6hHyWo1QQGc9gDkD7sAt8VjqETSnUHaArd0Gupc8ZBv4n4ymUfiEPxEu4/A3eyayX+x+ZZjjoIEl6D+2zrJJgyOoKf68RCKJXOpt4B3xZQNclwVeSbXVd2hXzKXlpqsC3c0ttyR3La6rTW2yyP1dpSbdowUtBji1+aAioxTZXD+ORZcrs+A5YF9kWnnfWeJUSZgnswKeZ7FNHkaeXgjTmowVhkhuQ1pQxCE1aik2A16OVVwtvayxmW6fdeDNKKcs79Zhy5eaFwIOXsxu3grolVsUVS0y0pAKN3tpMStdlheJajZ1V5rxWHxoJjR6crr51frlg59K73AFWf7h3gs8BlWtpsHpqwrioa6nJj5lphgim1C3XdPGuuZm2hYIB90QCrKqxDnPkm81hN6pvAyqElRdvN3exjdXeYGQS8oXGmjgoICQjhUh6jdSYmvQdpakSFArIfg6bqiqZW6t3N6HaNbUX7M4Lt4NK8bX3SblJM9Mas+65xuodpVFRj58HfLyAdPZjftCittnLXaHWKQdczNE4trkfK8GFiT3RVqU523gaBbeC04/3zW3pp0yJWFqfofjZejBfw3bGE3WNO8jrmLtDt5ahVyHt+DiUDv/WtFpAQ+4MrDFvC3Bb+uXiI2f1TXGURfesNPc11mjacki1dK/JKTnsUmYGLnnM/2MycWRt7dCtedrSyhqPe39tPBecjV3rrTWDweqzSl2hsfVwM3lX+UL+f0CuTv/Hn38EGAAvCnNy1JKVIQAAAABJRU5ErkJggg==)}.bee-compact__color_cube .alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-compact__color-cube--wrap{position:relative;width:25px;height:25px;cursor:pointer;overflow:hidden}.bee-compact__color-cube--wrap:hover{transform:scale(1.2);z-index:299;transition:transform .2s}.bee-colorPicker__record{display:flex;align-items:center;margin-top:20px}.bee-colorPicker__record .text{width:48px;margin-right:10px;text-align:right;font-size:12px;color:#666}.bee-colorPicker__record .color-list{width:auto;display:flex;position:relative;margin:0}.bee-colorPicker__record .color-list .color-item{position:relative;width:25px;height:25px;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle;margin-right:1px;box-shadow:3px 0 5px #00000014}.bee-colorPicker__record .color-list .color-item__round{border-radius:50%}.bee-colorPicker__record .color-list .color-item.transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-colorPicker__record .color-list .color-item:hover{transform:scale(1.2);z-index:299;transition:transform .2s}.bee-colorPicker__record .color-list .color-item__display{width:100%;height:100%}.small-hue-slider{height:10px!important}.small-hue-slider .small-bar{height:10px!important;width:10px!important}.small-hue-slider .small-bar div{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.bee-hue-colorPicker{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.bee-hue-colorPicker.is-vertical{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.bee-hue-colorPicker.transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-hue-colorPicker__inner{position:relative;width:100%;height:100%;border-radius:15px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMkAAAAdCAYAAAAAaUg8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKtJREFUeNrs09EKgjAUgOGzEFfv/7CVBceiLiJiLnf7fSAbDoUj/iWnyKgRcXxf9Wtt7Vvntf8854jLY3uN19qzf67nH/e2nmmdZ8xjg2x+sI533qf9g4wM/3GvLPumOHVMWf/4SiWWsUG6/6bG+/NWDgE0iQREAiIBkYBIQCQgEhAJiAQQCYgERAIiAZGASEAkIBJAJCASEAmIBEQCIgGRgEgAkYBIYNAqwAD5oWo3bpsiKwAAAABJRU5ErkJggg==);background-size:100%}.bee-hue-colorPicker__inner-pointer{position:absolute;width:14px;height:14px}.bee-hue-colorPicker__inner-handle{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.bee-hue-colorPicker__inner-handle.vertical{transform:translate(-1px,-7px);margin-top:0}.small-light-slider{height:10px!important}.small-light-slider .small-bar{height:10px!important;width:10px!important}.small-light-slider .small-bar div{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.bee-light-colorPicker{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.bee-light-colorPicker.is-vertical{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.bee-light-colorPicker.transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-light-colorPicker__inner{position:relative;width:100%;height:100%;border-radius:15px}.bee-light-colorPicker__inner-pointer{position:absolute;width:14px;height:14px}.bee-light-colorPicker__inner-handle{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.bee-light-colorPicker__inner-handle.vertical{transform:translateY(-7px);margin-top:0}.bee-saturation{position:relative;margin-bottom:15px;width:100%;height:125px}.bee-saturation__chrome{border-top-left-radius:5px;border-top-right-radius:5px;border-color:transparent}.bee-saturation__hidden{overflow:hidden}.bee-saturation__white,.bee-saturation__black{position:absolute;top:0;left:0;right:0;bottom:0}.bee-saturation__black{background:linear-gradient(0deg,#000,transparent)}.bee-saturation__white{background:linear-gradient(90deg,#fff,#fff0)}.bee-saturation__cursor{position:absolute}.bee-saturation__cursor div{transform:translate(-5px,-5px);box-shadow:0 1px 4px #0000005e;width:10px;height:10px;border:1px solid white;border-radius:50%;cursor:pointer}.inputs-controls{display:flex;font-size:16px;margin-bottom:5px}.inputs-controls .formatBtn{position:relative;display:inline-flex;justify-content:center;align-items:center;padding:1px;border:0;text-align:center;cursor:pointer;background-color:transparent;font-weight:700;outline:none;margin-right:5px}.inputs-controls .formatBtn:hover{color:#1a3aff}.inputs-controls .format-group{display:flex;flex-grow:1}.inputs-controls .format-group input{padding:5px;margin:0 3px;min-width:0;text-align:center;border-width:0 0 1px 0;-webkit-appearance:none;appearance:none;-moz-appearance:textfield;outline:none;flex:1}.inputs-controls .format-group input::-webkit-outer-spin-button,.inputs-controls .format-group input::-webkit-inner-spin-button{-webkit-appearance:none!important;margin:0}.bee-fk-colorPicker{position:relative;box-sizing:border-box;border-radius:3px;box-shadow:0 0 10px #00000026;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;width:249px;padding-bottom:10px}.bee-fk-colorPicker__inner{padding:12px}.bee-fk-colorPicker__header{margin-bottom:12px;z-index:999;text-align:left}.bee-fk-colorPicker__header .back{border:solid black;border-width:0 1px 1px 0;display:inline-block;padding:4px;margin-left:2px;transform:rotate(135deg);-webkit-transform:rotate(135deg)}.bee-fk-colorPicker__display{position:relative;width:100%;margin:0;text-align:left}.bee-fk-colorPicker__display .transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-fk-colorPicker__display .current-color{margin-right:10px;width:50px;height:24px;box-shadow:3px 0 5px #00000014;position:relative;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle}.bee-fk-colorPicker__display .current-color .color-cube{width:100%;height:100%}.bee-fk-colorPicker__display .hexColor-prefix{position:relative;padding:0 4px;font-size:14px;display:inline-block;vertical-align:middle}.bee-fk-colorPicker__display input{width:25px;text-align:center;outline:0;border-top:0;border-right:0;border-left:none;display:inline-block;vertical-align:middle;padding-bottom:3px;border-bottom:1px solid #e3e2e8}.bee-fk-colorPicker__display .hexColor-input{width:64px}.bee-fk-colorPicker__display .action{float:right;vertical-align:middle}.bee-fk-colorPicker__display .action .clear-btn{border-color:transparent;color:#409eff;background:transparent;padding-left:0;padding-right:0;display:inline-block;vertical-align:middle;cursor:pointer}.bee-fk-colorPicker__display .action .copy-btn{border-color:transparent;color:#13ce66cc;background:transparent;padding-left:0;padding-right:0;display:inline-block;margin-left:10px;vertical-align:middle;cursor:pointer}.bee-ele-colorPicker{position:relative;box-sizing:border-box;border-radius:3px;box-shadow:0 0 10px #00000026;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;padding:10px;width:300px}.bee-ele-colorPicker .bee-ele-row{display:flex}.bee-ele-colorPicker .bee-ele-row .bee-ele-saturation{width:280px;height:180px}.bee-ele-colorPicker .bee-ele-row .bee-ele-hue{margin-left:10px;height:180px}.bee-chrome-colorPicker{position:relative;box-sizing:border-box;border-radius:3px;box-shadow:0 0 10px #00000026;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;width:250px;padding-bottom:20px}.bee-chrome-colorPicker-body{padding:0 12px;background-color:#fff}.bee-chrome-colorPicker-body .chrome-controls{display:flex}.bee-chrome-colorPicker-body .chrome-controls .chrome-color-wrap{position:relative;width:36px;height:36px;border-radius:50%;overflow:hidden;z-index:1}.bee-chrome-colorPicker-body .chrome-controls .chrome-color-wrap .current-color{width:100%;height:100%}.bee-chrome-colorPicker-body .chrome-controls .chrome-sliders{flex:1;margin-left:10px}.bee-color-wrap{margin-right:10px;width:50px;height:24px;box-shadow:3px 0 5px #00000014;position:relative;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle}.bee-color-wrap.transparent{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.bee-color-wrap.round{width:22px;height:22px;border-radius:50%;border:1px solid #d8d8d8}.bee-color-wrap .current-color{width:100%;height:100%}.vc-alpha-slider[data-v-18925ba6]{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.vc-alpha-slider.is-vertical[data-v-18925ba6]{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.vc-alpha-slider.transparent[data-v-18925ba6]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-alpha-slider__bar[data-v-18925ba6]{position:relative;width:100%;height:100%;border-radius:15px}.vc-alpha-slider__bar-pointer[data-v-18925ba6]{position:absolute;width:14px;height:14px}.vc-alpha-slider__bar-handle[data-v-18925ba6]{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.vc-alpha-slider__bar-handle.vertical[data-v-18925ba6]{transform:translateY(-7px);margin-top:0}.vc-alpha-slider.small-slider[data-v-18925ba6]{height:10px!important}.vc-alpha-slider.small-slider .small-bar[data-v-18925ba6]{height:10px!important;width:10px!important}.vc-alpha-slider.small-slider .small-bar div[data-v-18925ba6]{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.vc-compact[data-v-b969fd48]{margin-bottom:15px;width:auto;box-shadow:3px 0 5px #00000014;display:inline-block}.vc-compact__row[data-v-b969fd48]{position:relative;width:100%;margin:0;height:27px}.vc-compact__row>*[data-v-b969fd48]{display:inline-block;vertical-align:middle}.vc-compact__color_cube[data-v-b969fd48]{width:100%;height:100%}.vc-compact__color_cube.transparent[data-v-b969fd48]:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:#fff}.vc-compact__color_cube.transparent[data-v-b969fd48]:after{content:"";position:absolute;top:100%;left:0;transform:rotate(-45deg);transform-origin:0 0;width:35px;height:1px;background:red}.vc-compact__color_cube.advance[data-v-b969fd48]{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABqVJREFUeNrEl11yHDUQx1ua2Zlde2M7jqESqnjg45kjcBwOwQG4BY+8cwWK17xBUUARICQhTmI7tte7Ozs7o+bXLTleuACpKNJqJP3789+doKoSPxfVGxFZioS1iK5Yd0nCJko9iLTVVvZSlCOp5FBF7vP5RFTelyDHvmYvMPPtiP19fu+HIHPetrllX2TLMJAOgEehti3ZY/Axap51ZB5ZDEnGMUoCNCmDbRv+2Q4CDJ5Mymj4OmE0CNj6b5WJlkel3xkiGXjOc0imDH/JDid1AXQEfKgccHg3lN+uhh+v2WkkOvCUnT3GjP2WOfrJzjUNPq/ugPUej1TiwME3+DfVUhWkEQF6LZraJxsp6xHLIzW/DNyAW75PGJVrOxbQFSeWzOsdjQ/tZHTxtSgdzAimMfOAdbas7crUvIWAqZg5+gg8FBzYTOygbo1tAb1xTYMs/q1xAFgnvBx5JrKO2X9pzJrJhr+b5BaY8vjG3O+w7HFnypkZ+zP3K8AWL7FHiRsJappe4knA9fo/pj7WrIrdshBs8cukcu0ljhK2lZt1Q8B1msMj5WCQKoibd8q8p1J8i6aWJnrJCcDljDX2Cm8Jn2WJC9PtIHpYeowza125Dc3c6CQ1MbEdooxoPQw54Ak9jigaKcAMk9ddgUi68ZxMmNbNG8hTXXjOZrPf+vg4C+RpRRJqO0ps8FxtzhoJLiSIHCWtLi9u5LiZyqKv0UvlHmaccukoVjJLFu2YUy946FRidS7beCXN9i3gKzd1Yo53ps7ppTnqEYD0mYNldpuxnvIo2nZb/L+ay9tulA/sJpE/Tfchj1H2kW2KpsFYSK4YgI1vZDJe57XmIAu642N5kCxUJfQ8bA48IKpWGNKi/T7rPWRMBMkp5lhz5mUlV0O+fGAGC5XMkTzoG349I/D+Qis0jpeZBt0CXaZGnwtwdcS7A/4ycOIi3bNI0pzfxoVHQYYDIu+A9djJ5bKX+c2BVKnHS5Xcw8QTecWlXxi/khgvYMFzHlp4/g74WREshg3zpuS9mfowShxyrnv6wFS2Dl12QUDwaO54xIWTKZem8up7M0ojn5BzdftEdPMzII9ljE8kVde8Z5y89PSJYcACAJhWTigFOO1rpqRbWs0pKjp4Nkl6OMiGQiFnKsOnLQNqJNe33yV5iFml/4YLfzB+wwpvuNoT+eq0F+JWYtp50MlXLBvUAkLlXXbdloHkUsREDsc6y9LDvs2pTNJD6eM5+x/KAslqWK/pOo/WEIvw3PC3q8rZz3IzWBqqp2CpTvjAACIVyFhLMQmlwXPU9gYrC+lCZs0VtPkc0Jfc+Va+XK/lK3Pr10XhF8ToAjf1VKktAH0hd3srqesSMmCJaiNwJB/IzNviF9Uor8NnndSkyRBfExbPpdHfKRg/yqH8JCPxdvbZVE6+6GTzmCD9Af45RfhzLGZZtEaIVQVdDpLwVByAHeIu8DXWGTySUil8wSNw6fMoliZnfHsqfXiC2M+gjJXX7wuEOvm4gWUBa9h4xrAAtwy6hHyWo1QQGc9gDkD7sAt8VjqETSnUHaArd0Gupc8ZBv4n4ymUfiEPxEu4/A3eyayX+x+ZZjjoIEl6D+2zrJJgyOoKf68RCKJXOpt4B3xZQNclwVeSbXVd2hXzKXlpqsC3c0ttyR3La6rTW2yyP1dpSbdowUtBji1+aAioxTZXD+ORZcrs+A5YF9kWnnfWeJUSZgnswKeZ7FNHkaeXgjTmowVhkhuQ1pQxCE1aik2A16OVVwtvayxmW6fdeDNKKcs79Zhy5eaFwIOXsxu3grolVsUVS0y0pAKN3tpMStdlheJajZ1V5rxWHxoJjR6crr51frlg59K73AFWf7h3gs8BlWtpsHpqwrioa6nJj5lphgim1C3XdPGuuZm2hYIB90QCrKqxDnPkm81hN6pvAyqElRdvN3exjdXeYGQS8oXGmjgoICQjhUh6jdSYmvQdpakSFArIfg6bqiqZW6t3N6HaNbUX7M4Lt4NK8bX3SblJM9Mas+65xuodpVFRj58HfLyAdPZjftCittnLXaHWKQdczNE4trkfK8GFiT3RVqU523gaBbeC04/3zW3pp0yJWFqfofjZejBfw3bGE3WNO8jrmLtDt5ahVyHt+DiUDv/WtFpAQ+4MrDFvC3Bb+uXiI2f1TXGURfesNPc11mjacki1dK/JKTnsUmYGLnnM/2MycWRt7dCtedrSyhqPe39tPBecjV3rrTWDweqzSl2hsfVwM3lX+UL+f0CuTv/Hn38EGAAvCnNy1JKVIQAAAABJRU5ErkJggg==)}.vc-compact__color_cube .alpha[data-v-b969fd48]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-compact__color-cube--wrap[data-v-b969fd48]{position:relative;width:27px;height:27px;cursor:pointer;overflow:hidden}.vc-compact__color-cube--wrap[data-v-b969fd48]:hover{transform:scale(1.2);z-index:299;transition:transform .2s}.vc-saturation[data-v-058e5db2]{position:relative;margin-bottom:15px;width:100%;height:125px}.vc-saturation__chrome[data-v-058e5db2]{border-top-left-radius:5px;border-top-right-radius:5px;border-color:transparent}.vc-saturation__hidden[data-v-058e5db2]{overflow:hidden}.vc-saturation__white[data-v-058e5db2],.vc-saturation__black[data-v-058e5db2]{position:absolute;top:0;left:0;right:0;bottom:0}.vc-saturation__black[data-v-058e5db2]{background:linear-gradient(0deg,#000,transparent)}.vc-saturation__white[data-v-058e5db2]{background:linear-gradient(90deg,#fff,#fff0)}.vc-saturation__cursor[data-v-058e5db2]{position:absolute}.vc-saturation__cursor div[data-v-058e5db2]{transform:translate(-5px,-5px);box-shadow:0 1px 4px #0000005e;width:10px;height:10px;border:1px solid white;border-radius:50%;cursor:pointer}.vc-hue-slider[data-v-e1a08576]{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.vc-hue-slider.is-vertical[data-v-e1a08576]{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.vc-hue-slider.transparent[data-v-e1a08576]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-hue-slider__bar[data-v-e1a08576]{position:relative;width:100%;height:100%;border-radius:15px;background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red);background:-webkit-linear-gradient(left,rgb(255,0,0) 0%,rgb(255,255,0) 16.66%,rgb(0,255,0) 33.33%,rgb(0,255,255) 50%,rgb(0,0,255) 66.66%,rgb(255,0,255) 83.33%,rgb(255,0,0) 100%);background:-moz-linear-gradient(left,rgb(255,0,0) 0%,rgb(255,255,0) 16.66%,rgb(0,255,0) 33.33%,rgb(0,255,255) 50%,rgb(0,0,255) 66.66%,rgb(255,0,255) 83.33%,rgb(255,0,0) 100%);background:-ms-linear-gradient(left,rgb(255,0,0) 0%,rgb(255,255,0) 16.66%,rgb(0,255,0) 33.33%,rgb(0,255,255) 50%,rgb(0,0,255) 66.66%,rgb(255,0,255) 83.33%,rgb(255,0,0) 100%)}.vc-hue-slider__bar-pointer[data-v-e1a08576]{position:absolute;width:14px;height:14px}.vc-hue-slider__bar-handle[data-v-e1a08576]{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.vc-hue-slider__bar-handle.vertical[data-v-e1a08576]{transform:translateY(-7px);margin-top:0}.vc-hue-slider.small-slider[data-v-e1a08576]{height:10px!important}.vc-hue-slider.small-slider .small-bar[data-v-e1a08576]{height:10px!important;width:10px!important}.vc-hue-slider.small-slider .small-bar div[data-v-e1a08576]{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.vc-lightness-slider[data-v-94a50a9e]{position:relative;margin-bottom:15px;width:100%;height:14px;box-shadow:2px 0 8px #00000014;border-radius:15px}.vc-lightness-slider.is-vertical[data-v-94a50a9e]{width:14px;height:100%;display:inline-block;transform:rotate(180deg)}.vc-lightness-slider.transparent[data-v-94a50a9e]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-lightness-slider__bar[data-v-94a50a9e]{position:relative;width:100%;height:100%;border-radius:15px}.vc-lightness-slider__bar-pointer[data-v-94a50a9e]{position:absolute;width:14px;height:14px}.vc-lightness-slider__bar-handle[data-v-94a50a9e]{width:14px;height:14px;border-radius:6px;transform:translate(-7px,-2px);background-color:#f8f8f8;margin-top:2px;box-shadow:0 1px 4px #0000005e;cursor:pointer}.vc-lightness-slider__bar-handle.vertical[data-v-94a50a9e]{transform:translateY(-7px);margin-top:0}.vc-lightness-slider.small-slider[data-v-94a50a9e]{height:10px!important}.vc-lightness-slider.small-slider .small-bar[data-v-94a50a9e]{height:10px!important;width:10px!important}.vc-lightness-slider.small-slider .small-bar div[data-v-94a50a9e]{width:12px!important;height:12px!important;border-radius:5px!important;transform:translate(-6px,-2px);margin-top:1px!important}.vc-colorPicker__record[data-v-0f657238]{display:flex;align-items:center;margin-top:15px}.vc-colorPicker__record .text[data-v-0f657238]{width:48px;margin-right:10px;text-align:right;font-size:12px;color:#666}.vc-colorPicker__record .color-list[data-v-0f657238]{width:100%;display:flex;position:relative;margin:0;gap:2px}.vc-colorPicker__record .color-list .color-item[data-v-0f657238]{position:relative;flex:1;max-width:26px;height:26px;border-radius:2px;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle;box-shadow:3px 0 5px #0000001a}.vc-colorPicker__record .color-list .color-item__round[data-v-0f657238]{border-radius:50%}.vc-colorPicker__record .color-list .color-item.transparent[data-v-0f657238]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-colorPicker__record .color-list .color-item[data-v-0f657238]:hover{transform:scale(1.2);z-index:299;transition:transform .2s}.vc-colorPicker__record .color-list .color-item__display[data-v-0f657238]{width:100%;height:100%}.vc-display[data-v-80d589ba]{height:28px;display:flex;align-items:center;gap:8px}.vc-display .vc-current-color[data-v-80d589ba]{width:50px;height:100%;box-shadow:3px 0 5px #00000014;border-radius:2px;position:relative;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle}.vc-display .vc-current-color.vc-transparent[data-v-80d589ba]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-display .vc-current-color .color-cube[data-v-80d589ba]{width:100%;height:100%}.vc-display .vc-color-input[data-v-80d589ba]{height:100%;flex:1;flex-shrink:0;box-sizing:border-box;position:relative}.vc-display .vc-color-input input[data-v-80d589ba]{padding:0;border:0;outline:none;cursor:pointer;font-size:14px;text-align:center;box-sizing:border-box;background-color:#c8c8c840;color:#666;border-radius:2px;height:100%;width:100%}.vc-display .vc-rgb-input[data-v-80d589ba]{flex:1;font-size:12px;color:#666;text-align:center}.vc-display .vc-rgb-input input[data-v-80d589ba]{padding:4px 0;margin-bottom:2px;border:0;outline:none;cursor:pointer;font-size:14px;text-align:center;background-color:#c8c8c840;color:#666;border-radius:2px;width:100%}.vc-display .vc-alpha-input[data-v-80d589ba]{width:56px;height:100%;border:none;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;border-radius:2px;font-size:14px}.vc-display .vc-alpha-input>input[data-v-80d589ba]{width:100%;height:100%;padding:0;text-align:center;background-color:#c8c8c840;color:#666;font-size:inherit}.vc-display .vc-alpha-input__inner[data-v-80d589ba]{padding:10px 16px;border-radius:4px;color:#000;font-size:14px;line-height:20px;outline:none;border:none;display:block;box-sizing:border-box;cursor:pointer}.vc-display .vc-input-toggle[data-v-80d589ba]{cursor:pointer;font-size:12px;line-height:12px;width:24px;border-radius:4px;padding:2px}.vc-display .vc-input-toggle[data-v-80d589ba]:hover{background-color:#efefef}.vc-display .vc-input-toggle[data-v-80d589ba]:before{height:0;width:0;margin:auto auto 2px;content:"";display:block;border-bottom:4px solid #888;border-left:4px solid transparent;border-right:4px solid transparent}.vc-display .vc-input-toggle[data-v-80d589ba]:after{height:0;width:0;margin:2px auto auto;content:"";display:block;border-top:4px solid #888;border-left:4px solid transparent;border-right:4px solid transparent}.vc-fk-colorPicker[data-v-0d5bef46]{position:relative;box-sizing:border-box;border-radius:3px;-webkit-user-select:none;user-select:none;background-color:initial}.vc-fk-colorPicker__inner[data-v-0d5bef46]{position:relative}.vc-fk-colorPicker__header[data-v-0d5bef46]{margin-bottom:12px;z-index:999;text-align:left}.vc-fk-colorPicker__header .back[data-v-0d5bef46]{border:2px solid rgba(150,150,150,.6);border-width:0 1px 1px 0;display:inline-block;padding:4px;margin-left:2px;transform:rotate(135deg)}.vc-fk-colorPicker__display[data-v-0d5bef46]{position:relative;width:100%;margin:0;text-align:left}.vc-fk-colorPicker__display .transparent[data-v-0d5bef46]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-fk-colorPicker__display .current-color[data-v-0d5bef46]{margin-right:10px;width:50px;height:24px;box-shadow:3px 0 5px #00000014;position:relative;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle}.vc-fk-colorPicker__display .current-color .color-cube[data-v-0d5bef46]{width:100%;height:100%}.vc-fk-colorPicker__display .hexColor-prefix[data-v-0d5bef46]{position:relative;padding:0 4px;font-size:14px;display:inline-block;vertical-align:middle}.vc-fk-colorPicker__display input[data-v-0d5bef46]{width:25px;text-align:center;outline:0;border-top:0;border-right:0;border-left:none;display:inline-block;vertical-align:middle;padding-bottom:3px;border-bottom:1px solid #e3e2e8}.vc-fk-colorPicker__display .hexColor-input[data-v-0d5bef46]{width:64px}.vc-fk-colorPicker__display .action[data-v-0d5bef46]{float:right;vertical-align:middle}.vc-fk-colorPicker__display .action .clear-btn[data-v-0d5bef46]{border-color:transparent;color:#409eff;background:transparent;padding-left:0;padding-right:0;display:inline-block;vertical-align:middle;cursor:pointer}.vc-fk-colorPicker__display .action .copy-btn[data-v-0d5bef46]{border-color:transparent;color:#13ce66cc;background:transparent;padding-left:0;padding-right:0;display:inline-block;margin-left:10px;vertical-align:middle;cursor:pointer}.vc-chrome-colorPicker[data-v-33636434]{position:relative;box-sizing:border-box;border-radius:3px;-webkit-user-select:none;user-select:none;background-color:initial}.vc-chrome-colorPicker-body[data-v-33636434]{position:relative}.vc-chrome-colorPicker-body .chrome-controls[data-v-33636434]{display:flex}.vc-chrome-colorPicker-body .chrome-controls .chrome-color-wrap[data-v-33636434]{position:relative;width:36px;height:36px;border-radius:50%;overflow:hidden;z-index:1}.vc-chrome-colorPicker-body .chrome-controls .chrome-color-wrap.transparent[data-v-33636434]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-chrome-colorPicker-body .chrome-controls .chrome-color-wrap .current-color[data-v-33636434]{width:100%;height:100%}.vc-chrome-colorPicker-body .chrome-controls .chrome-sliders[data-v-33636434]{flex:1;margin-left:10px}.bee-angle{transform:rotate(90deg)}.bee-angle>*{display:inline-block;vertical-align:middle}.bee-angle.zero-right{transform:rotate(180deg)}.bee-angle.zero-bottom{transform:rotate(270deg)}.bee-angle__round{position:relative;width:16px;height:16px;border:1px solid #666;border-radius:50%;cursor:pointer;display:inline-block;vertical-align:middle}.bee-angle__round:before{content:"";position:absolute;top:50%;left:0;transform:translateY(-50%);width:50%;height:1px;background-color:#666}.vc-gradient-picker[data-v-431cadee]{position:relative}.vc-gradient-picker__header[data-v-431cadee]{margin-bottom:12px;z-index:999;text-align:left;display:flex;justify-content:space-between;align-items:center}.vc-gradient-picker__header .back[data-v-431cadee]{border:2px solid rgba(150,150,150,.65);border-width:0 1px 1px 0;display:inline-block;padding:4px;margin-left:2px;transform:rotate(135deg);margin-right:8px}.vc-gradient-picker .vc-gradient__types[data-v-431cadee]{display:flex;width:100%;justify-content:space-between}.vc-gradient-picker .vc-gradient__types .vc-gradient-wrap__types[data-v-431cadee]{display:flex;background-color:#c8c8c840;border-radius:4px;overflow:hidden;align-items:center}.vc-gradient-picker .vc-gradient__types .vc-gradient__type[data-v-431cadee]{padding:4px 8px;color:#666;cursor:pointer;font-size:12px}.vc-gradient-picker .vc-gradient__types .vc-gradient__type.active[data-v-431cadee]{color:#000;background-color:#c8c8c8cc}.vc-gradient-picker__body[data-v-431cadee]{margin-bottom:12px;display:-ms-flexbox;display:flex;align-items:center}.vc-gradient-picker__body .vc-color-range[data-v-431cadee]{flex:1}.vc-gradient-picker__body .vc-color-range__container[data-v-431cadee]{position:relative;height:16px;border-radius:5px}.vc-gradient-picker__body .vc-color-range__container .vc-background[data-v-431cadee]{height:100%;border-radius:4px;box-shadow:inset 0 0 0 1px #0000000f}.vc-gradient-picker__body .vc-color-range__container .vc-gradient__stop__container[data-v-431cadee]{position:absolute;width:100%;top:0;height:100%;left:0}.vc-gradient-picker__body .vc-color-range__container .vc-gradient__stop__container .vc-gradient__stop[data-v-431cadee]{position:absolute;top:-2px;width:14px;height:16px;overflow:hidden;border:2px solid #fff;border-radius:2px;cursor:pointer;box-shadow:0 0 2px 1px #00000059;box-sizing:content-box;transform:translate(-9px)}.vc-gradient-picker__body .vc-color-range__container .vc-gradient__stop__container .vc-gradient__stop--inner[data-v-431cadee]{display:inline-block;height:100%}.vc-gradient-picker__body .vc-color-range__container .vc-gradient__stop__container .vc-gradient__stop--current[data-v-431cadee]{position:relative;z-index:1;box-shadow:0 0 2px 2px #2253f4,0 0 1px 1px #2253f480}.vc-gradient-picker .vc-degree-input[data-v-431cadee]{position:relative;z-index:2;font-size:12px;border-radius:4px;display:flex}.vc-gradient-picker .vc-degree-input:hover .vc-degree-input__panel[data-v-431cadee]{display:block}.vc-gradient-picker .vc-degree-input__control[data-v-431cadee]{width:100%;height:100%;display:flex;justify-content:center;align-items:center;border-radius:4px;background-color:#c8c8c840;color:#666;padding:0 6px 0 0}.vc-gradient-picker .vc-degree-input__control input[data-v-431cadee]{max-width:28px;text-align:center;border:none;outline:none;background-color:transparent;color:#666;font-size:inherit;overflow:visible}.vc-gradient-picker .vc-degree-input__panel[data-v-431cadee]{display:none;z-index:10;position:absolute;top:20px;left:0}.vc-gradient-picker .vc-degree-input__panel .vc-degree-input__disk[data-v-431cadee]{padding:4px;background-color:#f1f1f1;box-shadow:0 0 2px #00000029,0 1px 8px #0000000f,0 4px 12px #00000014;border-radius:4px;display:flex;justify-content:center;align-items:center;position:relative;transform:translate(0)}.vc-gradient-picker .vc-picker-degree-input[data-v-431cadee]{margin-left:8px}.vc-colorpicker[data-v-0492277d]{position:relative;box-sizing:border-box;border-radius:3px;box-shadow:0 0 10px #00000026;-webkit-user-select:none;user-select:none;width:276px;z-index:10000}.vc-colorpicker *[data-v-0492277d]{outline:none;line-height:1}.vc-colorpicker--container[data-v-0492277d]{padding:16px}.vc-colorpicker--tabs[data-v-0492277d]{padding:2px;background:#f6f7f9;border-radius:6px;position:relative;margin-bottom:12px}.vc-colorpicker--tabs__inner[data-v-0492277d]{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;padding:0;background:#f6f7f9;border-bottom:none;position:relative;box-sizing:border-box}.vc-colorpicker--tabs__btn[data-v-0492277d]{-ms-flex:1;flex:1;z-index:2;color:#636c78;font-size:14px;border-radius:4px;cursor:pointer}.vc-colorpicker--tabs__btn.vc-btn-active[data-v-0492277d]{color:#33383e;font-weight:600}.vc-colorpicker--tabs__btn button[data-v-0492277d]{width:100%;background-color:initial;padding:6px 0;font-size:14px;line-height:20px;color:#636c78;border:0;border-radius:0;outline:0;cursor:pointer;-moz-appearance:none;appearance:none;-webkit-appearance:none;font-weight:inherit}.vc-colorpicker--tabs__btn button .vc-btn__content[data-v-0492277d]{position:relative;white-space:nowrap}.vc-colorpicker--tabs__bg[data-v-0492277d]{position:absolute;top:0;bottom:0;background:#fff;box-shadow:0 1px 4px #0000001f;border-radius:4px;z-index:1;transition:left .2s ease-in-out}.vc-colorpicker.black[data-v-0492277d]{background-color:#000;color:#fff}.vc-colorpicker.white[data-v-0492277d]{background-color:#fff;color:#333}.vc-color-wrap[data-v-3ba84123]{margin-right:10px;width:50px;height:24px;box-shadow:3px 0 5px #00000014;position:relative;cursor:pointer;overflow:hidden;display:inline-block;vertical-align:middle}.vc-color-wrap.transparent[data-v-3ba84123]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);background-repeat:repeat}.vc-color-wrap.round[data-v-3ba84123]{width:22px;height:22px;border-radius:50%;border:1px solid #d8d8d8}.vc-color-wrap .current-color[data-v-3ba84123]{width:100%;height:100%}#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:solid 2px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .spinner,.nprogress-custom-parent #nprogress .bar{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}} diff --git a/app/dubbo-ui/dist/admin/assets/index-ZwzA_cjG.css b/app/dubbo-ui/dist/admin/assets/index-ZwzA_cjG.css deleted file mode 100644 index 568ae9b18..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-ZwzA_cjG.css +++ /dev/null @@ -1 +0,0 @@ -.instances-container[data-v-2f938e3f]{width:100%;height:100%}.instances-container .search-table-container[data-v-2f938e3f]{min-height:60vh}.instances-container .search-table-container .app-link[data-v-2f938e3f]{padding:4px 10px 4px 4px;border-radius:4px;color:var(--2ab83322)}.instances-container .search-table-container .app-link[data-v-2f938e3f]:hover{cursor:pointer;background:#85838321} diff --git a/app/dubbo-ui/dist/admin/assets/index-bVXendlO.css b/app/dubbo-ui/dist/admin/assets/index-bVXendlO.css deleted file mode 100644 index ee4ab4071..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-bVXendlO.css +++ /dev/null @@ -1 +0,0 @@ -.__container_home_index[data-v-a6d34c3f]{max-height:calc(100vh - 60px);overflow:auto}.__container_home_index .statistic[data-v-a6d34c3f]{width:16vw}.__container_home_index .statistic-card[data-v-a6d34c3f]{border:1px solid var(--a8c0aff4)}.__container_home_index .statistic-icon[data-v-a6d34c3f]{color:var(--db6f68ac);margin-bottom:-3px}.__container_home_index .statistic-icon-big[data-v-a6d34c3f]{width:40px;height:40px;background:var(--db6f68ac);line-height:44px;vertical-align:middle;text-align:center;border-radius:5px;font-size:56px;color:#fff}.__container_home_index .card[data-v-a6d34c3f]{margin-top:10px} diff --git a/app/dubbo-ui/dist/admin/assets/index-bidvosE-.js b/app/dubbo-ui/dist/admin/assets/index-bidvosE-.js deleted file mode 100644 index 2400ed2e7..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-bidvosE-.js +++ /dev/null @@ -1,51 +0,0 @@ -import{V as ip,d as vk,v as gk,a as yk,r as Bv,W as mk,c as bf,j as Qo,t as xf,n as yi,b as Fn,w as On,e as ho,P as Fv,o as po,J as zv,K as Gv,G as Yv,I as Wv,f as Hv,p as bk,h as xk,_ as wk}from"./index-hmLAZQYT.js";import{g as Ok,a as Sk}from"./serverInfo-j8z5RY-E.js";import"./request-8jI_GZey.js";const _b=()=>[["cartesian"]];_b.props={};function _k(t,e){return t=t%(2*Math.PI),e=e%(2*Math.PI),t<0&&(t=2*Math.PI+t),e<0&&(e=2*Math.PI+e),t>=e&&(e=e+2*Math.PI),{startAngle:t,endAngle:e}}const Mb=(t={})=>{const e={startAngle:-Math.PI/2,endAngle:Math.PI*3/2,innerRadius:0,outerRadius:1},n=Object.assign(Object.assign({},e),t);return Object.assign(Object.assign({},n),_k(n.startAngle,n.endAngle))},Cs=t=>{const{startAngle:e,endAngle:n,innerRadius:r,outerRadius:i}=Mb(t);return[["translate",0,.5],["reflect.y"],["translate",0,-.5],["polar",e,n,r,i]]};Cs.props={};const ap=()=>[["transpose"],["translate",.5,.5],["reflect.x"],["translate",-.5,-.5]];ap.props={transform:!0};const Mk=(t={})=>{const e={startAngle:-Math.PI/2,endAngle:Math.PI*3/2,innerRadius:0,outerRadius:1};return Object.assign(Object.assign({},e),t)},Eb=t=>{const{startAngle:e,endAngle:n,innerRadius:r,outerRadius:i}=Mk(t);return[...ap(),...Cs({startAngle:e,endAngle:n,innerRadius:r,outerRadius:i})]};Eb.props={};const Pb=(t={})=>{const e={startAngle:-Math.PI/2,endAngle:Math.PI*3/2,innerRadius:0,outerRadius:1};return Object.assign(Object.assign({},e),t)},op=t=>{const{startAngle:e,endAngle:n,innerRadius:r,outerRadius:i}=Pb(t);return[["transpose"],["translate",.5,.5],["reflect"],["translate",-.5,-.5],...Cs({startAngle:e,endAngle:n,innerRadius:r,outerRadius:i})]};op.props={};const sp=()=>[["parallel",0,1,0,1]];sp.props={};const Ab=({focusX:t=0,focusY:e=0,distortionX:n=2,distortionY:r=2,visual:i=!1})=>[["fisheye",t,e,n,r,i]];Ab.props={transform:!0};const kb=t=>{const{startAngle:e=-Math.PI/2,endAngle:n=Math.PI*3/2,innerRadius:r=0,outerRadius:i=1}=t;return[...sp(),...Cs({startAngle:e,endAngle:n,innerRadius:r,outerRadius:i})]};kb.props={};const Tb=({value:t})=>e=>e.map(()=>t);Tb.props={};const Cb=({value:t})=>e=>e.map(t);Cb.props={};const Lb=({value:t})=>e=>e.map(n=>n[t]);Lb.props={};const Nb=({value:t})=>()=>t;Nb.props={};var fl=function(t){return t!==null&&typeof t!="function"&&isFinite(t.length)};const Ve=function(t){return typeof t=="function"};var nt=function(t){return t==null},Ek={}.toString,Ls=function(t,e){return Ek.call(t)==="[object "+e+"]"};const Le=function(t){return Array.isArray?Array.isArray(t):Ls(t,"Array")},ki=function(t){var e=typeof t;return t!==null&&e==="object"||e==="function"};function cp(t,e){if(t){var n;if(Le(t))for(var r=0,i=t.length;rn?n:t},de=function(t){return Ls(t,"Number")},Tk=1e-5;function Fo(t,e,n){return n===void 0&&(n=Tk),Math.abs(t-e)r&&(n=a,r=o)}return n}},Lk=function(t,e){if(Le(t)){for(var n,r=1/0,i=0;ii&&(r=n,o(1),++e),n[s]=c}function o(s){e=0,n=Object.create(null),s||(r=Object.create(null))}return o(),{clear:o,has:function(s){return n[s]!==void 0||r[s]!==void 0},get:function(s){var c=n[s];if(c!==void 0)return c;if((c=r[s])!==void 0)return a(s,c),c},set:function(s,c){n[s]!==void 0?n[s]=c:a(s,c)}}}const Ik=function(t,e,n){if(n===void 0&&(n=128),!Ve(t))throw new TypeError("Expected a function");var r=function(){for(var i=[],a=0;ae?(r&&(clearTimeout(r),r=null),s=u,o=t.apply(i,a),r||(i=a=null)):!r&&n.trailing!==!1&&(r=setTimeout(c,f)),o};return l.cancel=function(){clearTimeout(r),s=0,r=i=a=null},l},wf=function(){};function Uv(t){return nt(t)?0:fl(t)?t.length:Object.keys(t).length}var Zt=1e-6,he=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});function Ja(){var t=new he(9);return he!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0),t[0]=1,t[4]=1,t[8]=1,t}function zk(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t}function Gk(t){var e=new he(9);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e}function Yk(t,e,n,r,i,a,o,s,c){var l=new he(9);return l[0]=t,l[1]=e,l[2]=n,l[3]=r,l[4]=i,l[5]=a,l[6]=o,l[7]=s,l[8]=c,l}function Wk(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],f=u*o-s*l,d=-u*a+s*c,h=l*a-o*c,p=n*f+r*d+i*h;return p?(p=1/p,t[0]=f*p,t[1]=(-u*r+i*l)*p,t[2]=(s*r-i*o)*p,t[3]=d*p,t[4]=(u*n-i*c)*p,t[5]=(-s*n+i*a)*p,t[6]=h*p,t[7]=(-l*n+r*c)*p,t[8]=(o*n-r*a)*p,t):null}function Hk(t,e,n){var r=e[0],i=e[1],a=e[2],o=e[3],s=e[4],c=e[5],l=e[6],u=e[7],f=e[8],d=n[0],h=n[1],p=n[2],v=n[3],g=n[4],y=n[5],m=n[6],b=n[7],x=n[8];return t[0]=d*r+h*o+p*l,t[1]=d*i+h*s+p*u,t[2]=d*a+h*c+p*f,t[3]=v*r+g*o+y*l,t[4]=v*i+g*s+y*u,t[5]=v*a+g*c+y*f,t[6]=m*r+b*o+x*l,t[7]=m*i+b*s+x*u,t[8]=m*a+b*c+x*f,t}function Vk(t,e){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=e[0],t[7]=e[1],t[8]=1,t}function Xk(t,e){var n=Math.sin(e),r=Math.cos(e);return t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function Uk(t,e){return t[0]=e[0],t[1]=0,t[2]=0,t[3]=0,t[4]=e[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}var qk=Hk;function Nt(){var t=new he(16);return he!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t}function lp(t){var e=new he(16);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function Ri(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t}function Kk(t,e,n,r,i,a,o,s,c,l,u,f,d,h,p,v){var g=new he(16);return g[0]=t,g[1]=e,g[2]=n,g[3]=r,g[4]=i,g[5]=a,g[6]=o,g[7]=s,g[8]=c,g[9]=l,g[10]=u,g[11]=f,g[12]=d,g[13]=h,g[14]=p,g[15]=v,g}function Td(t,e,n,r,i,a,o,s,c,l,u,f,d,h,p,v,g){return t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s,t[7]=c,t[8]=l,t[9]=u,t[10]=f,t[11]=d,t[12]=h,t[13]=p,t[14]=v,t[15]=g,t}function Rs(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function zb(t,e){if(t===e){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],s=e[11];t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[11]=e[14],t[12]=i,t[13]=o,t[14]=s}else t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15];return t}function Wn(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],f=e[9],d=e[10],h=e[11],p=e[12],v=e[13],g=e[14],y=e[15],m=n*s-r*o,b=n*c-i*o,x=n*l-a*o,w=r*c-i*s,O=r*l-a*s,S=i*l-a*c,_=u*v-f*p,M=u*g-d*p,E=u*y-h*p,P=f*g-d*v,T=f*y-h*v,A=d*y-h*g,k=m*A-b*T+x*P+w*E-O*M+S*_;return k?(k=1/k,t[0]=(s*A-c*T+l*P)*k,t[1]=(i*T-r*A-a*P)*k,t[2]=(v*S-g*O+y*w)*k,t[3]=(d*O-f*S-h*w)*k,t[4]=(c*E-o*A-l*M)*k,t[5]=(n*A-i*E+a*M)*k,t[6]=(g*x-p*S-y*b)*k,t[7]=(u*S-d*x+h*b)*k,t[8]=(o*T-s*E+l*_)*k,t[9]=(r*E-n*T-a*_)*k,t[10]=(p*O-v*x+y*m)*k,t[11]=(f*x-u*O-h*m)*k,t[12]=(s*M-o*P-c*_)*k,t[13]=(n*P-r*M+i*_)*k,t[14]=(v*b-p*w-g*m)*k,t[15]=(u*w-f*b+d*m)*k,t):null}function Zk(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],f=e[9],d=e[10],h=e[11],p=e[12],v=e[13],g=e[14],y=e[15];return t[0]=s*(d*y-h*g)-f*(c*y-l*g)+v*(c*h-l*d),t[1]=-(r*(d*y-h*g)-f*(i*y-a*g)+v*(i*h-a*d)),t[2]=r*(c*y-l*g)-s*(i*y-a*g)+v*(i*l-a*c),t[3]=-(r*(c*h-l*d)-s*(i*h-a*d)+f*(i*l-a*c)),t[4]=-(o*(d*y-h*g)-u*(c*y-l*g)+p*(c*h-l*d)),t[5]=n*(d*y-h*g)-u*(i*y-a*g)+p*(i*h-a*d),t[6]=-(n*(c*y-l*g)-o*(i*y-a*g)+p*(i*l-a*c)),t[7]=n*(c*h-l*d)-o*(i*h-a*d)+u*(i*l-a*c),t[8]=o*(f*y-h*v)-u*(s*y-l*v)+p*(s*h-l*f),t[9]=-(n*(f*y-h*v)-u*(r*y-a*v)+p*(r*h-a*f)),t[10]=n*(s*y-l*v)-o*(r*y-a*v)+p*(r*l-a*s),t[11]=-(n*(s*h-l*f)-o*(r*h-a*f)+u*(r*l-a*s)),t[12]=-(o*(f*g-d*v)-u*(s*g-c*v)+p*(s*d-c*f)),t[13]=n*(f*g-d*v)-u*(r*g-i*v)+p*(r*d-i*f),t[14]=-(n*(s*g-c*v)-o*(r*g-i*v)+p*(r*c-i*s)),t[15]=n*(s*d-c*f)-o*(r*d-i*f)+u*(r*c-i*s),t}function Gb(t){var e=t[0],n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6],c=t[7],l=t[8],u=t[9],f=t[10],d=t[11],h=t[12],p=t[13],v=t[14],g=t[15],y=e*o-n*a,m=e*s-r*a,b=e*c-i*a,x=n*s-r*o,w=n*c-i*o,O=r*c-i*s,S=l*p-u*h,_=l*v-f*h,M=l*g-d*h,E=u*v-f*p,P=u*g-d*p,T=f*g-d*v;return y*T-m*P+b*E+x*M-w*_+O*S}function $e(t,e,n){var r=e[0],i=e[1],a=e[2],o=e[3],s=e[4],c=e[5],l=e[6],u=e[7],f=e[8],d=e[9],h=e[10],p=e[11],v=e[12],g=e[13],y=e[14],m=e[15],b=n[0],x=n[1],w=n[2],O=n[3];return t[0]=b*r+x*s+w*f+O*v,t[1]=b*i+x*c+w*d+O*g,t[2]=b*a+x*l+w*h+O*y,t[3]=b*o+x*u+w*p+O*m,b=n[4],x=n[5],w=n[6],O=n[7],t[4]=b*r+x*s+w*f+O*v,t[5]=b*i+x*c+w*d+O*g,t[6]=b*a+x*l+w*h+O*y,t[7]=b*o+x*u+w*p+O*m,b=n[8],x=n[9],w=n[10],O=n[11],t[8]=b*r+x*s+w*f+O*v,t[9]=b*i+x*c+w*d+O*g,t[10]=b*a+x*l+w*h+O*y,t[11]=b*o+x*u+w*p+O*m,b=n[12],x=n[13],w=n[14],O=n[15],t[12]=b*r+x*s+w*f+O*v,t[13]=b*i+x*c+w*d+O*g,t[14]=b*a+x*l+w*h+O*y,t[15]=b*o+x*u+w*p+O*m,t}function Ur(t,e,n){var r=n[0],i=n[1],a=n[2],o,s,c,l,u,f,d,h,p,v,g,y;return e===t?(t[12]=e[0]*r+e[4]*i+e[8]*a+e[12],t[13]=e[1]*r+e[5]*i+e[9]*a+e[13],t[14]=e[2]*r+e[6]*i+e[10]*a+e[14],t[15]=e[3]*r+e[7]*i+e[11]*a+e[15]):(o=e[0],s=e[1],c=e[2],l=e[3],u=e[4],f=e[5],d=e[6],h=e[7],p=e[8],v=e[9],g=e[10],y=e[11],t[0]=o,t[1]=s,t[2]=c,t[3]=l,t[4]=u,t[5]=f,t[6]=d,t[7]=h,t[8]=p,t[9]=v,t[10]=g,t[11]=y,t[12]=o*r+u*i+p*a+e[12],t[13]=s*r+f*i+v*a+e[13],t[14]=c*r+d*i+g*a+e[14],t[15]=l*r+h*i+y*a+e[15]),t}function vl(t,e,n){var r=n[0],i=n[1],a=n[2];return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t[4]=e[4]*i,t[5]=e[5]*i,t[6]=e[6]*i,t[7]=e[7]*i,t[8]=e[8]*a,t[9]=e[9]*a,t[10]=e[10]*a,t[11]=e[11]*a,t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t}function Qk(t,e,n,r){var i=r[0],a=r[1],o=r[2],s=Math.hypot(i,a,o),c,l,u,f,d,h,p,v,g,y,m,b,x,w,O,S,_,M,E,P,T,A,k,C;return s0?(n[0]=(s*o+u*r+c*a-l*i)*2/f,n[1]=(c*o+u*i+l*r-s*a)*2/f,n[2]=(l*o+u*a+s*i-c*r)*2/f):(n[0]=(s*o+u*r+c*a-l*i)*2,n[1]=(c*o+u*i+l*r-s*a)*2,n[2]=(l*o+u*a+s*i-c*r)*2),Hb(t,e,n),t}function gl(t,e){return t[0]=e[12],t[1]=e[13],t[2]=e[14],t}function Aa(t,e){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],s=e[6],c=e[8],l=e[9],u=e[10];return t[0]=Math.hypot(n,r,i),t[1]=Math.hypot(a,o,s),t[2]=Math.hypot(c,l,u),t}function yl(t,e){var n=new he(3);Aa(n,e);var r=1/n[0],i=1/n[1],a=1/n[2],o=e[0]*r,s=e[1]*i,c=e[2]*a,l=e[4]*r,u=e[5]*i,f=e[6]*a,d=e[8]*r,h=e[9]*i,p=e[10]*a,v=o+u+p,g=0;return v>0?(g=Math.sqrt(v+1)*2,t[3]=.25*g,t[0]=(f-h)/g,t[1]=(d-c)/g,t[2]=(s-l)/g):o>u&&o>p?(g=Math.sqrt(1+o-u-p)*2,t[3]=(f-h)/g,t[0]=.25*g,t[1]=(s+l)/g,t[2]=(d+c)/g):u>p?(g=Math.sqrt(1+u-o-p)*2,t[3]=(d-c)/g,t[0]=(s+l)/g,t[1]=.25*g,t[2]=(f+h)/g):(g=Math.sqrt(1+p-o-u)*2,t[3]=(s-l)/g,t[0]=(d+c)/g,t[1]=(f+h)/g,t[2]=.25*g),t}function aT(t,e,n,r){var i=e[0],a=e[1],o=e[2],s=e[3],c=i+i,l=a+a,u=o+o,f=i*c,d=i*l,h=i*u,p=a*l,v=a*u,g=o*u,y=s*c,m=s*l,b=s*u,x=r[0],w=r[1],O=r[2];return t[0]=(1-(p+g))*x,t[1]=(d+b)*x,t[2]=(h-m)*x,t[3]=0,t[4]=(d-b)*w,t[5]=(1-(f+g))*w,t[6]=(v+y)*w,t[7]=0,t[8]=(h+m)*O,t[9]=(v-y)*O,t[10]=(1-(f+p))*O,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t}function zo(t,e,n,r,i){var a=e[0],o=e[1],s=e[2],c=e[3],l=a+a,u=o+o,f=s+s,d=a*l,h=a*u,p=a*f,v=o*u,g=o*f,y=s*f,m=c*l,b=c*u,x=c*f,w=r[0],O=r[1],S=r[2],_=i[0],M=i[1],E=i[2],P=(1-(v+y))*w,T=(h+x)*w,A=(p-b)*w,k=(h-x)*O,C=(1-(d+y))*O,L=(g+m)*O,I=(p+b)*S,R=(g-m)*S,j=(1-(d+v))*S;return t[0]=P,t[1]=T,t[2]=A,t[3]=0,t[4]=k,t[5]=C,t[6]=L,t[7]=0,t[8]=I,t[9]=R,t[10]=j,t[11]=0,t[12]=n[0]+_-(P*_+k*M+I*E),t[13]=n[1]+M-(T*_+C*M+R*E),t[14]=n[2]+E-(A*_+L*M+j*E),t[15]=1,t}function dp(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=n+n,s=r+r,c=i+i,l=n*o,u=r*o,f=r*s,d=i*o,h=i*s,p=i*c,v=a*o,g=a*s,y=a*c;return t[0]=1-f-p,t[1]=u+y,t[2]=d-g,t[3]=0,t[4]=u-y,t[5]=1-l-p,t[6]=h+v,t[7]=0,t[8]=d+g,t[9]=h-v,t[10]=1-l-f,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function oT(t,e,n,r,i,a,o){var s=1/(n-e),c=1/(i-r),l=1/(a-o);return t[0]=a*2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a*2*c,t[6]=0,t[7]=0,t[8]=(n+e)*s,t[9]=(i+r)*c,t[10]=(o+a)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*a*2*l,t[15]=0,t}function Vb(t,e,n,r,i){var a=1/Math.tan(e/2),o;return t[0]=a/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,i!=null&&i!==1/0?(o=1/(r-i),t[10]=(i+r)*o,t[14]=2*i*r*o):(t[10]=-1,t[14]=-2*r),t}var sT=Vb;function cT(t,e,n,r,i){var a=1/Math.tan(e/2),o;return t[0]=a/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,i!=null&&i!==1/0?(o=1/(r-i),t[10]=i*o,t[14]=i*r*o):(t[10]=-1,t[14]=-r),t}function lT(t,e,n,r){var i=Math.tan(e.upDegrees*Math.PI/180),a=Math.tan(e.downDegrees*Math.PI/180),o=Math.tan(e.leftDegrees*Math.PI/180),s=Math.tan(e.rightDegrees*Math.PI/180),c=2/(o+s),l=2/(i+a);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=l,t[6]=0,t[7]=0,t[8]=-((o-s)*c*.5),t[9]=(i-a)*l*.5,t[10]=r/(n-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*n/(n-r),t[15]=0,t}function Xb(t,e,n,r,i,a,o){var s=1/(e-n),c=1/(r-i),l=1/(a-o);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*l,t[11]=0,t[12]=(e+n)*s,t[13]=(i+r)*c,t[14]=(o+a)*l,t[15]=1,t}var Ub=Xb;function qb(t,e,n,r,i,a,o){var s=1/(e-n),c=1/(r-i),l=1/(a-o);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=l,t[11]=0,t[12]=(e+n)*s,t[13]=(i+r)*c,t[14]=a*l,t[15]=1,t}function Kb(t,e,n,r){var i,a,o,s,c,l,u,f,d,h,p=e[0],v=e[1],g=e[2],y=r[0],m=r[1],b=r[2],x=n[0],w=n[1],O=n[2];return Math.abs(p-x)0&&(h=1/Math.sqrt(h),u*=h,f*=h,d*=h);var p=c*d-l*f,v=l*u-s*d,g=s*f-c*u;return h=p*p+v*v+g*g,h>0&&(h=1/Math.sqrt(h),p*=h,v*=h,g*=h),t[0]=p,t[1]=v,t[2]=g,t[3]=0,t[4]=f*g-d*v,t[5]=d*p-u*g,t[6]=u*v-f*p,t[7]=0,t[8]=u,t[9]=f,t[10]=d,t[11]=0,t[12]=i,t[13]=a,t[14]=o,t[15]=1,t}function fT(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"}function dT(t){return Math.hypot(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}function hT(t,e,n){return t[0]=e[0]+n[0],t[1]=e[1]+n[1],t[2]=e[2]+n[2],t[3]=e[3]+n[3],t[4]=e[4]+n[4],t[5]=e[5]+n[5],t[6]=e[6]+n[6],t[7]=e[7]+n[7],t[8]=e[8]+n[8],t[9]=e[9]+n[9],t[10]=e[10]+n[10],t[11]=e[11]+n[11],t[12]=e[12]+n[12],t[13]=e[13]+n[13],t[14]=e[14]+n[14],t[15]=e[15]+n[15],t}function Zb(t,e,n){return t[0]=e[0]-n[0],t[1]=e[1]-n[1],t[2]=e[2]-n[2],t[3]=e[3]-n[3],t[4]=e[4]-n[4],t[5]=e[5]-n[5],t[6]=e[6]-n[6],t[7]=e[7]-n[7],t[8]=e[8]-n[8],t[9]=e[9]-n[9],t[10]=e[10]-n[10],t[11]=e[11]-n[11],t[12]=e[12]-n[12],t[13]=e[13]-n[13],t[14]=e[14]-n[14],t[15]=e[15]-n[15],t}function pT(t,e,n){return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t[3]=e[3]*n,t[4]=e[4]*n,t[5]=e[5]*n,t[6]=e[6]*n,t[7]=e[7]*n,t[8]=e[8]*n,t[9]=e[9]*n,t[10]=e[10]*n,t[11]=e[11]*n,t[12]=e[12]*n,t[13]=e[13]*n,t[14]=e[14]*n,t[15]=e[15]*n,t}function vT(t,e,n,r){return t[0]=e[0]+n[0]*r,t[1]=e[1]+n[1]*r,t[2]=e[2]+n[2]*r,t[3]=e[3]+n[3]*r,t[4]=e[4]+n[4]*r,t[5]=e[5]+n[5]*r,t[6]=e[6]+n[6]*r,t[7]=e[7]+n[7]*r,t[8]=e[8]+n[8]*r,t[9]=e[9]+n[9]*r,t[10]=e[10]+n[10]*r,t[11]=e[11]+n[11]*r,t[12]=e[12]+n[12]*r,t[13]=e[13]+n[13]*r,t[14]=e[14]+n[14]*r,t[15]=e[15]+n[15]*r,t}function gT(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[11]===e[11]&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[15]===e[15]}function yT(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],s=t[5],c=t[6],l=t[7],u=t[8],f=t[9],d=t[10],h=t[11],p=t[12],v=t[13],g=t[14],y=t[15],m=e[0],b=e[1],x=e[2],w=e[3],O=e[4],S=e[5],_=e[6],M=e[7],E=e[8],P=e[9],T=e[10],A=e[11],k=e[12],C=e[13],L=e[14],I=e[15];return Math.abs(n-m)<=Zt*Math.max(1,Math.abs(n),Math.abs(m))&&Math.abs(r-b)<=Zt*Math.max(1,Math.abs(r),Math.abs(b))&&Math.abs(i-x)<=Zt*Math.max(1,Math.abs(i),Math.abs(x))&&Math.abs(a-w)<=Zt*Math.max(1,Math.abs(a),Math.abs(w))&&Math.abs(o-O)<=Zt*Math.max(1,Math.abs(o),Math.abs(O))&&Math.abs(s-S)<=Zt*Math.max(1,Math.abs(s),Math.abs(S))&&Math.abs(c-_)<=Zt*Math.max(1,Math.abs(c),Math.abs(_))&&Math.abs(l-M)<=Zt*Math.max(1,Math.abs(l),Math.abs(M))&&Math.abs(u-E)<=Zt*Math.max(1,Math.abs(u),Math.abs(E))&&Math.abs(f-P)<=Zt*Math.max(1,Math.abs(f),Math.abs(P))&&Math.abs(d-T)<=Zt*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(h-A)<=Zt*Math.max(1,Math.abs(h),Math.abs(A))&&Math.abs(p-k)<=Zt*Math.max(1,Math.abs(p),Math.abs(k))&&Math.abs(v-C)<=Zt*Math.max(1,Math.abs(v),Math.abs(C))&&Math.abs(g-L)<=Zt*Math.max(1,Math.abs(g),Math.abs(L))&&Math.abs(y-I)<=Zt*Math.max(1,Math.abs(y),Math.abs(I))}var Qb=$e,mT=Zb;const bT=Object.freeze(Object.defineProperty({__proto__:null,add:hT,adjoint:Zk,clone:lp,copy:Ri,create:Nt,determinant:Gb,equals:yT,exactEquals:gT,frob:dT,fromQuat:dp,fromQuat2:iT,fromRotation:tT,fromRotationTranslation:Hb,fromRotationTranslationScale:aT,fromRotationTranslationScaleOrigin:zo,fromScaling:fp,fromTranslation:up,fromValues:Kk,fromXRotation:eT,fromYRotation:nT,fromZRotation:rT,frustum:oT,getRotation:yl,getScaling:Aa,getTranslation:gl,identity:Rs,invert:Wn,lookAt:Kb,mul:Qb,multiply:$e,multiplyScalar:pT,multiplyScalarAndAdd:vT,ortho:Ub,orthoNO:Xb,orthoZO:qb,perspective:sT,perspectiveFromFieldOfView:lT,perspectiveNO:Vb,perspectiveZO:cT,rotate:Qk,rotateX:Yb,rotateY:Wb,rotateZ:Jk,scale:vl,set:Td,str:fT,sub:mT,subtract:Zb,targetTo:uT,translate:Ur,transpose:zb},Symbol.toStringTag,{value:"Module"}));function yt(){var t=new he(3);return he!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function br(t){var e=new he(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function wr(t){var e=t[0],n=t[1],r=t[2];return Math.hypot(e,n,r)}function St(t,e,n){var r=new he(3);return r[0]=t,r[1]=e,r[2]=n,r}function rn(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}function Gn(t,e,n,r){return t[0]=e,t[1]=n,t[2]=r,t}function ba(t,e,n){return t[0]=e[0]+n[0],t[1]=e[1]+n[1],t[2]=e[2]+n[2],t}function qv(t,e,n){return t[0]=e[0]-n[0],t[1]=e[1]-n[1],t[2]=e[2]-n[2],t}function xT(t,e,n){return t[0]=e[0]*n[0],t[1]=e[1]*n[1],t[2]=e[2]*n[2],t}function Cd(t,e,n){return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t}function wT(t,e){var n=e[0]-t[0],r=e[1]-t[1],i=e[2]-t[2];return Math.hypot(n,r,i)}function Ti(t,e){var n=e[0],r=e[1],i=e[2],a=n*n+r*r+i*i;return a>0&&(a=1/Math.sqrt(a)),t[0]=e[0]*a,t[1]=e[1]*a,t[2]=e[2]*a,t}function nr(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Qc(t,e,n){var r=e[0],i=e[1],a=e[2],o=n[0],s=n[1],c=n[2];return t[0]=i*c-a*s,t[1]=a*o-r*c,t[2]=r*s-i*o,t}function Ld(t,e,n,r){var i=e[0],a=e[1],o=e[2];return t[0]=i+r*(n[0]-i),t[1]=a+r*(n[1]-a),t[2]=o+r*(n[2]-o),t}function Oe(t,e,n){var r=e[0],i=e[1],a=e[2],o=n[3]*r+n[7]*i+n[11]*a+n[15];return o=o||1,t[0]=(n[0]*r+n[4]*i+n[8]*a+n[12])/o,t[1]=(n[1]*r+n[5]*i+n[9]*a+n[13])/o,t[2]=(n[2]*r+n[6]*i+n[10]*a+n[14])/o,t}function Jb(t,e,n){var r=e[0],i=e[1],a=e[2];return t[0]=r*n[0]+i*n[3]+a*n[6],t[1]=r*n[1]+i*n[4]+a*n[7],t[2]=r*n[2]+i*n[5]+a*n[8],t}function OT(t,e,n){var r=n[0],i=n[1],a=n[2],o=n[3],s=e[0],c=e[1],l=e[2],u=i*l-a*c,f=a*s-r*l,d=r*c-i*s,h=i*d-a*f,p=a*u-r*d,v=r*f-i*u,g=o*2;return u*=g,f*=g,d*=g,h*=2,p*=2,v*=2,t[0]=s+u+h,t[1]=c+f+p,t[2]=l+d+v,t}function vo(t,e){var n=t[0],r=t[1],i=t[2],a=e[0],o=e[1],s=e[2];return Math.abs(n-a)<=Zt*Math.max(1,Math.abs(n),Math.abs(a))&&Math.abs(r-o)<=Zt*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(i-s)<=Zt*Math.max(1,Math.abs(i),Math.abs(s))}var Kv=wT,tx=wr;(function(){var t=yt();return function(e,n,r,i,a,o){var s,c;for(n||(n=3),r||(r=0),i?c=Math.min(i*n+r,e.length):c=e.length,s=r;s0&&(o=1/Math.sqrt(o)),t[0]=n*o,t[1]=r*o,t[2]=i*o,t[3]=a*o,t}function ha(t,e,n){var r=e[0],i=e[1],a=e[2],o=e[3];return t[0]=n[0]*r+n[4]*i+n[8]*a+n[12]*o,t[1]=n[1]*r+n[5]*i+n[9]*a+n[13]*o,t[2]=n[2]*r+n[6]*i+n[10]*a+n[14]*o,t[3]=n[3]*r+n[7]*i+n[11]*a+n[15]*o,t}(function(){var t=da();return function(e,n,r,i,a,o){var s,c;for(n||(n=4),r||(r=0),i?c=Math.min(i*n+r,e.length):c=e.length,s=r;sZt?(d=Math.acos(h),p=Math.sin(d),v=Math.sin((1-r)*d)/p,g=Math.sin(r*d)/p):(v=1-r,g=r),t[0]=v*i+g*c,t[1]=v*a+g*l,t[2]=v*o+g*u,t[3]=v*s+g*f,t}function Sf(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=n*n+r*r+i*i+a*a,s=o?1/o:0;return t[0]=-n*s,t[1]=-r*s,t[2]=-i*s,t[3]=a*s,t}function ET(t,e){var n=e[0]+e[4]+e[8],r;if(n>0)r=Math.sqrt(n+1),t[3]=.5*r,r=.5/r,t[0]=(e[5]-e[7])*r,t[1]=(e[6]-e[2])*r,t[2]=(e[1]-e[3])*r;else{var i=0;e[4]>e[0]&&(i=1),e[8]>e[i*3+i]&&(i=2);var a=(i+1)%3,o=(i+2)%3;r=Math.sqrt(e[i*3+i]-e[a*3+a]-e[o*3+o]+1),t[i]=.5*r,r=.5/r,t[3]=(e[a*3+o]-e[o*3+a])*r,t[a]=(e[a*3+i]+e[i*3+a])*r,t[o]=(e[o*3+i]+e[i*3+o])*r}return t}function oc(t,e,n,r){var i=.5*Math.PI/180;e*=i,n*=i,r*=i;var a=Math.sin(e),o=Math.cos(e),s=Math.sin(n),c=Math.cos(n),l=Math.sin(r),u=Math.cos(r);return t[0]=a*c*u-o*s*l,t[1]=o*s*u+a*c*l,t[2]=o*c*l-a*s*u,t[3]=o*c*u+a*s*l,t}var _f=ST,sc=_T,Zv=qr,ml=MT;(function(){var t=yt(),e=St(1,0,0),n=St(0,1,0);return function(r,i,a){var o=nr(i,a);return o<-.999999?(Qc(t,e,i),tx(t)<1e-6&&Qc(t,n,i),Ti(t,t),Hr(r,t,Math.PI),r):o>.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(Qc(t,i,a),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=1+o,ml(r,r))}})();(function(){var t=ve(),e=ve();return function(n,r,i,a,o,s){return Of(t,r,o,s),Of(e,i,a,s),Of(n,t,e,2*s*(1-s)),n}})();(function(){var t=Ja();return function(e,n,r,i){return t[0]=r[0],t[3]=r[1],t[6]=r[2],t[1]=i[0],t[4]=i[1],t[7]=i[2],t[2]=-n[0],t[5]=-n[1],t[8]=-n[2],ml(e,ET(e,t))}})();function PT(){var t=new he(2);return he!=Float32Array&&(t[0]=0,t[1]=0),t}function AT(t,e){var n=new he(2);return n[0]=t,n[1]=e,n}function kT(t,e){return t[0]=e[0],t[1]=e[1],t}function TT(t,e){var n=e[0],r=e[1],i=n*n+r*r;return i>0&&(i=1/Math.sqrt(i)),t[0]=e[0]*i,t[1]=e[1]*i,t}function CT(t,e){return t[0]*e[0]+t[1]*e[1]}function LT(t,e){return t[0]===e[0]&&t[1]===e[1]}(function(){var t=PT();return function(e,n,r,i,a,o){var s,c;for(n||(n=2),r||(r=0),i?c=Math.min(i*n+r,e.length):c=e.length,s=r;s0&&a[a.length-1])&&(l[0]===6||l[0]===2)){n=0;continue}if(l[0]===3&&(!a||l[1]>a[0]&&l[1]=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a}function ex(){for(var t=0,e=0,n=arguments.length;e7){t[n].shift();for(var r=t[n],i=n;r.length;)e[n]="A",t.splice(i+=1,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Go={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function rx(t){return Array.isArray(t)&&t.every(function(e){var n=e[0].toLowerCase();return Go[n]===e.length-1&&"achlmqstvz".includes(n)})}function ix(t){return rx(t)&&t.every(function(e){var n=e[0];return n===n.toUpperCase()})}function ax(t){return ix(t)&&t.every(function(e){var n=e[0];return"ACLMQZ".includes(n)})}function Qv(t){for(var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;r.length>=Go[n]&&(n==="m"&&r.length>2?(t.segments.push([e].concat(r.splice(0,2))),n="l",e=e==="m"?"l":"L"):t.segments.push([e].concat(r.splice(0,Go[n]))),!!Go[n]););}function RT(t){var e=t.index,n=t.pathValue,r=n.charCodeAt(e);if(r===48){t.param=0,t.index+=1;return}if(r===49){t.param=1,t.index+=1;return}t.err='[path-util]: invalid Arc flag "'+n[e]+'", expecting 0 or 1 at index '+e}function IT(t){return t>=48&&t<=57||t===43||t===45||t===46}function ea(t){return t>=48&&t<=57}function jT(t){var e=t.max,n=t.pathValue,r=t.index,i=r,a=!1,o=!1,s=!1,c=!1,l;if(i>=e){t.err="[path-util]: Invalid path value at index "+i+', "pathValue" is missing param';return}if(l=n.charCodeAt(i),(l===43||l===45)&&(i+=1,l=n.charCodeAt(i)),!ea(l)&&l!==46){t.err="[path-util]: Invalid path value at index "+i+', "'+n[i]+'" is not a number';return}if(l!==46){if(a=l===48,i+=1,l=n.charCodeAt(i),a&&i=5760&&e.includes(t)}function Jc(t){for(var e=t.pathValue,n=t.max;t.index0;o-=1){if(BT(i)&&(o===3||o===4)?RT(t):jT(t),t.err.length)return;t.data.push(t.param),Jc(t),t.index=t.max||!IT(n.charCodeAt(t.index)))break}Qv(t)}var zT=function(){function t(e){this.pathValue=e,this.segments=[],this.max=e.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""}return t}();function GT(t){if(rx(t))return[].concat(t);var e=new zT(t);for(Jc(e);e.index1&&(E=Math.sqrt(E),d*=E,h*=E);var P=d*d,T=h*h,A=(a===o?-1:1)*Math.sqrt(Math.abs((P*T-P*M*M-T*_*_)/(P*M*M+T*_*_)));O=A*d*M/h+(u+p)/2,S=A*-h*_/d+(f+v)/2,x=Math.asin(((f-S)/h*Math.pow(10,9)>>0)/Math.pow(10,9)),w=Math.asin(((v-S)/h*Math.pow(10,9)>>0)/Math.pow(10,9)),x=uw&&(x-=Math.PI*2),!o&&w>x&&(w-=Math.PI*2)}var k=w-x;if(Math.abs(k)>g){var C=w,L=p,I=v;w=x+g*(o&&w>x?1:-1),p=O+d*Math.cos(w),v=S+h*Math.sin(w),m=hp(p,v,d,h,i,0,o,L,I,[w,C,O,S])}k=w-x;var R=Math.cos(x),j=Math.sin(x),D=Math.cos(w),$=Math.sin(w),B=Math.tan(k/4),F=4/3*d*B,Y=4/3*h*B,U=[u,f],K=[u+F*j,f-Y*R],V=[p+F*$,v-Y*D],W=[p,v];if(K[0]=2*U[0]-K[0],K[1]=2*U[1]-K[1],l)return K.concat(V,W,m);m=K.concat(V,W,m);for(var J=[],et=0,it=m.length;et=a)o={x:n,y:r};else{var s=Fr([t,e],[n,r],i/a),c=s[0],l=s[1];o={x:c,y:l}}return{length:a,point:o,min:{x:Math.min(t,n),y:Math.min(e,r)},max:{x:Math.max(t,n),y:Math.max(e,r)}}}function tg(t,e){var n=t.x,r=t.y,i=e.x,a=e.y,o=n*i+r*a,s=Math.sqrt((Math.pow(n,2)+Math.pow(r,2))*(Math.pow(i,2)+Math.pow(a,2))),c=n*a-r*i<0?-1:1,l=c*Math.acos(o/s);return l}function KT(t,e,n,r,i,a,o,s,c,l){var u=Math.abs,f=Math.sin,d=Math.cos,h=Math.sqrt,p=Math.PI,v=u(n),g=u(r),y=(i%360+360)%360,m=y*(p/180);if(t===s&&e===c)return{x:t,y:e};if(v===0||g===0)return Id(t,e,s,c,l).point;var b=(t-s)/2,x=(e-c)/2,w={x:d(m)*b+f(m)*x,y:-f(m)*b+d(m)*x},O=Math.pow(w.x,2)/Math.pow(v,2)+Math.pow(w.y,2)/Math.pow(g,2);O>1&&(v*=h(O),g*=h(O));var S=Math.pow(v,2)*Math.pow(g,2)-Math.pow(v,2)*Math.pow(w.y,2)-Math.pow(g,2)*Math.pow(w.x,2),_=Math.pow(v,2)*Math.pow(w.y,2)+Math.pow(g,2)*Math.pow(w.x,2),M=S/_;M=M<0?0:M;var E=(a!==o?1:-1)*h(M),P={x:E*(v*w.y/g),y:E*(-(g*w.x)/v)},T={x:d(m)*P.x-f(m)*P.y+(t+s)/2,y:f(m)*P.x+d(m)*P.y+(e+c)/2},A={x:(w.x-P.x)/v,y:(w.y-P.y)/g},k=tg({x:1,y:0},A),C={x:(-w.x-P.x)/v,y:(-w.y-P.y)/g},L=tg(A,C);!o&&L>0?L-=2*p:o&&L<0&&(L+=2*p),L%=2*p;var I=k+L*l,R=v*d(I),j=g*f(I),D={x:d(m)*R-f(m)*j+T.x,y:f(m)*R+d(m)*j+T.y};return D}function ZT(t,e,n,r,i,a,o,s,c,l,u){var f,d=u.bbox,h=d===void 0?!0:d,p=u.length,v=p===void 0?!0:p,g=u.sampleSize,y=g===void 0?30:g,m=typeof l=="number",b=t,x=e,w=0,O=[b,x,w],S=[b,x],_=0,M={x:0,y:0},E=[{x:b,y:x}];m&&l<=0&&(M={x:b,y:x});for(var P=0;P<=y;P+=1){if(_=P/y,f=KT(t,e,n,r,i,a,o,s,c,_),b=f.x,x=f.y,h&&E.push({x:b,y:x}),v&&(w+=nn(S,[b,x])),S=[b,x],m&&w>=l&&l>O[2]){var T=(w-l)/(w-O[2]);M={x:S[0]*(1-T)+O[0]*T,y:S[1]*(1-T)+O[1]*T}}O=[b,x,w]}return m&&l>=w&&(M={x:s,y:c}),{length:w,point:M,min:{x:Math.min.apply(null,E.map(function(A){return A.x})),y:Math.min.apply(null,E.map(function(A){return A.y}))},max:{x:Math.max.apply(null,E.map(function(A){return A.x})),y:Math.max.apply(null,E.map(function(A){return A.y}))}}}function QT(t,e,n,r,i,a,o,s,c){var l=1-c;return{x:Math.pow(l,3)*t+3*Math.pow(l,2)*c*n+3*l*Math.pow(c,2)*i+Math.pow(c,3)*o,y:Math.pow(l,3)*e+3*Math.pow(l,2)*c*r+3*l*Math.pow(c,2)*a+Math.pow(c,3)*s}}function ox(t,e,n,r,i,a,o,s,c,l){var u,f=l.bbox,d=f===void 0?!0:f,h=l.length,p=h===void 0?!0:h,v=l.sampleSize,g=v===void 0?10:v,y=typeof c=="number",m=t,b=e,x=0,w=[m,b,x],O=[m,b],S=0,_={x:0,y:0},M=[{x:m,y:b}];y&&c<=0&&(_={x:m,y:b});for(var E=0;E<=g;E+=1){if(S=E/g,u=QT(t,e,n,r,i,a,o,s,S),m=u.x,b=u.y,d&&M.push({x:m,y:b}),p&&(x+=nn(O,[m,b])),O=[m,b],y&&x>=c&&c>w[2]){var P=(x-c)/(x-w[2]);_={x:O[0]*(1-P)+w[0]*P,y:O[1]*(1-P)+w[1]*P}}w=[m,b,x]}return y&&c>=x&&(_={x:o,y:s}),{length:x,point:_,min:{x:Math.min.apply(null,M.map(function(T){return T.x})),y:Math.min.apply(null,M.map(function(T){return T.y}))},max:{x:Math.max.apply(null,M.map(function(T){return T.x})),y:Math.max.apply(null,M.map(function(T){return T.y}))}}}function JT(t,e,n,r,i,a,o){var s=1-o;return{x:Math.pow(s,2)*t+2*s*o*n+Math.pow(o,2)*i,y:Math.pow(s,2)*e+2*s*o*r+Math.pow(o,2)*a}}function t5(t,e,n,r,i,a,o,s){var c,l=s.bbox,u=l===void 0?!0:l,f=s.length,d=f===void 0?!0:f,h=s.sampleSize,p=h===void 0?10:h,v=typeof o=="number",g=t,y=e,m=0,b=[g,y,m],x=[g,y],w=0,O={x:0,y:0},S=[{x:g,y}];v&&o<=0&&(O={x:g,y});for(var _=0;_<=p;_+=1){if(w=_/p,c=JT(t,e,n,r,i,a,w),g=c.x,y=c.y,u&&S.push({x:g,y}),d&&(m+=nn(x,[g,y])),x=[g,y],v&&m>=o&&o>b[2]){var M=(m-o)/(m-b[2]);O={x:x[0]*(1-M)+b[0]*M,y:x[1]*(1-M)+b[1]*M}}b=[g,y,m]}return v&&o>=m&&(O={x:i,y:a}),{length:m,point:O,min:{x:Math.min.apply(null,S.map(function(E){return E.x})),y:Math.min.apply(null,S.map(function(E){return E.y}))},max:{x:Math.max.apply(null,S.map(function(E){return E.x})),y:Math.max.apply(null,S.map(function(E){return E.y}))}}}function sx(t,e,n){for(var r,i,a,o,s,c,l=bl(t),u=typeof e=="number",f,d=[],h,p=0,v=0,g=0,y=0,m,b=[],x=[],w=0,O={x:0,y:0},S=O,_=O,M=O,E=0,P=0,T=l.length;P=e&&(M=_),x.push(S),b.push(O),E+=w,c=h!=="Z"?m.slice(-2):[g,y],p=c[0],v=c[1];return u&&e>=E&&(M={x:p,y:v}),{length:E,point:M,min:{x:Math.min.apply(null,b.map(function(A){return A.x})),y:Math.min.apply(null,b.map(function(A){return A.y}))},max:{x:Math.max.apply(null,x.map(function(A){return A.x})),y:Math.max.apply(null,x.map(function(A){return A.y}))}}}function e5(t,e){return sx(t,void 0,z(z({},e),{bbox:!1,length:!0})).length}function n5(t){var e=t.length,n=e-1;return t.map(function(r,i){return t.map(function(a,o){var s=i+o,c;return o===0||t[s]&&t[s][0]==="M"?(c=t[s],["M"].concat(c.slice(-2))):(s>=e&&(s-=n),t[s])})})}function r5(t,e){var n=t.length-1,r=[],i=0,a=0,o=n5(t);return o.forEach(function(s,c){t.slice(1).forEach(function(l,u){a+=nn(t[(c+u)%n].slice(-2),e[u%n].slice(-2))}),r[c]=a,a=0}),i=r.indexOf(Math.min.apply(null,r)),o[i]}function i5(t,e,n,r,i,a,o,s){return 3*((s-e)*(n+i)-(o-t)*(r+a)+r*(t-i)-n*(e-a)+s*(i+t/3)-o*(a+e/3))/20}function a5(t){var e=0,n=0,r=0;return Rd(t).map(function(i){var a;switch(i[0]){case"M":return e=i[1],n=i[2],0;default:var o=i.slice(1),s=o[0],c=o[1],l=o[2],u=o[3],f=o[4],d=o[5];return r=i5(e,n,s,c,l,u,f,d),a=i.slice(-2),e=a[0],n=a[1],r}}).reduce(function(i,a){return i+a},0)}function eg(t){return a5(t)>=0}function o5(t,e,n){return sx(t,e,z(z({},n),{bbox:!1,length:!0})).point}function s5(t,e){e===void 0&&(e=.5);var n=t.slice(0,2),r=t.slice(2,4),i=t.slice(4,6),a=t.slice(6,8),o=Fr(n,r,e),s=Fr(r,i,e),c=Fr(i,a,e),l=Fr(o,s,e),u=Fr(s,c,e),f=Fr(l,u,e);return[["C"].concat(o,l,f),["C"].concat(u,c,a)]}function ng(t){return t.map(function(e,n,r){var i=n&&r[n-1].slice(-2).concat(e.slice(1)),a=n?ox(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[8],{bbox:!1}).length:0,o;return n?o=a?s5(i):[e,e]:o=[e],{s:e,ss:o,l:a}})}function cx(t,e,n){var r=ng(t),i=ng(e),a=r.length,o=i.length,s=r.filter(function(g){return g.l}).length,c=i.filter(function(g){return g.l}).length,l=r.filter(function(g){return g.l}).reduce(function(g,y){var m=y.l;return g+m},0)/s||0,u=i.filter(function(g){return g.l}).reduce(function(g,y){var m=y.l;return g+m},0)/c||0,f=n||Math.max(a,o),d=[l,u],h=[f-a,f-o],p=0,v=[r,i].map(function(g,y){return g.l===f?g.map(function(m){return m.s}):g.map(function(m,b){return p=b&&h[y]&&m.l>=d[y],h[y]-=p?1:0,p?m.ss:[m.s]}).flat()});return v[0].length===v[1].length?v:cx(v[0],v[1],f)}function rg(t){var e=document.createElement("div");e.innerHTML=t;var n=e.childNodes[0];return n&&e.contains(n)&&e.removeChild(n),n}function Wt(t,e){if(t!==null)return{type:"column",value:t,field:e}}function yu(t,e){const n=Wt(t,e);return Object.assign(Object.assign({},n),{inferred:!0})}function xl(t,e){if(t!==null)return{type:"column",value:t,field:e,visual:!0}}function c5(t,e){const n=Wt(t,e);return Object.assign(Object.assign({},n),{constant:!1})}function Kr(t,e){const n=[];for(const r of t)n[r]=e;return n}function Ot(t,e){const n=t[e];if(!n)return[null,null];const{value:r,field:i=null}=n;return[r,i]}function ts(t,...e){for(const n of e)if(typeof n=="string"){const[r,i]=Ot(t,n);if(r!==null)return[r,i]}else return[n,null];return[null,null]}function Is(t){return t instanceof Date?!1:typeof t=="object"}const js=()=>(t,e)=>{const{encode:n}=e,{y1:r}=n;return r!==void 0?[t,e]:[t,X({},e,{encode:{y1:yu(Kr(t,0))}})]};js.props={};function oe(t,e){return t==null||e==null?NaN:te?1:t>=e?0:NaN}function l5(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}function Ca(t){let e,n,r;t.length!==2?(e=oe,n=(s,c)=>oe(t(s),c),r=(s,c)=>t(s)-c):(e=t===oe||t===l5?t:u5,n=t,r=t);function i(s,c,l=0,u=s.length){if(l>>1;n(s[f],c)<0?l=f+1:u=f}while(l>>1;n(s[f],c)<=0?l=f+1:u=f}while(ll&&r(s[f-1],c)>-r(s[f],c)?f-1:f}return{left:i,center:o,right:a}}function u5(){return 0}function jd(t){return t===null?NaN:+t}function*f5(t,e){if(e===void 0)for(let n of t)n!=null&&(n=+n)>=n&&(yield n);else{let n=-1;for(let r of t)(r=e(r,++n,t))!=null&&(r=+r)>=r&&(yield r)}}const lx=Ca(oe),d5=lx.right,h5=lx.left,p5=Ca(jd).center;function ux(t,e){let n=0;if(e===void 0)for(let r of t)r!=null&&(r=+r)>=r&&++n;else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(i=+i)>=i&&++n}return n}function v5(t,e){let n=0,r,i=0,a=0;if(e===void 0)for(let o of t)o!=null&&(o=+o)>=o&&(r=o-i,i+=r/++n,a+=r*(o-i));else{let o=-1;for(let s of t)(s=e(s,++o,t))!=null&&(s=+s)>=s&&(r=s-i,i+=r/++n,a+=r*(s-i))}if(n>1)return a/(n-1)}function fx(t,e){const n=v5(t,e);return n&&Math.sqrt(n)}function Mr(t,e){let n,r;if(e===void 0)for(const i of t)i!=null&&(n===void 0?i>=i&&(n=r=i):(n>i&&(n=i),r=a&&(n=r=a):(n>a&&(n=a),r0){for(o=e[--n];n>0&&(r=o,i=e[--n],o=r+i,a=i-(o-r),!a););n>0&&(a<0&&e[n-1]<0||a>0&&e[n-1]>0)&&(i=a*2,r=o+i,i==r-o&&(o=r))}return o}}let g5=class extends Map{constructor(e,n=b5){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),e!=null)for(const[r,i]of e)this.set(r,i)}get(e){return super.get(ig(this,e))}has(e){return super.has(ig(this,e))}set(e,n){return super.set(y5(this,e),n)}delete(e){return super.delete(m5(this,e))}};function ig({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):n}function y5({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):(t.set(r,n),n)}function m5({_intern:t,_key:e},n){const r=e(n);return t.has(r)&&(n=t.get(r),t.delete(r)),n}function b5(t){return t!==null&&typeof t=="object"?t.valueOf():t}function es(t){return t}function te(t,...e){return mu(t,es,es,e)}function pp(t,...e){return mu(t,Array.from,es,e)}function vp(t,e,...n){return mu(t,es,e,n)}function dx(t,e,...n){return mu(t,Array.from,e,n)}function mu(t,e,n,r){return function i(a,o){if(o>=r.length)return n(a);const s=new g5,c=r[o++];let l=-1;for(const u of a){const f=c(u,++l,a),d=s.get(f);d?d.push(u):s.set(f,[u])}for(const[u,f]of s)s.set(u,i(f,o));return e(s)}(t,0)}function x5(t,e){return Array.from(e,n=>t[n])}function Er(t,...e){if(typeof t[Symbol.iterator]!="function")throw new TypeError("values is not iterable");t=Array.from(t);let[n]=e;if(n&&n.length!==2||e.length>1){const r=Uint32Array.from(t,(i,a)=>a);return e.length>1?(e=e.map(i=>t.map(i)),r.sort((i,a)=>{for(const o of e){const s=ns(o[i],o[a]);if(s)return s}})):(n=t.map(n),r.sort((i,a)=>ns(n[i],n[a]))),x5(t,r)}return t.sort(hx(n))}function hx(t=oe){if(t===oe)return ns;if(typeof t!="function")throw new TypeError("compare is not a function");return(e,n)=>{const r=t(e,n);return r||r===0?r:(t(n,n)===0)-(t(e,e)===0)}}function ns(t,e){return(t==null||!(t>=t))-(e==null||!(e>=e))||(te?1:0)}function w5(t,e,n){return(e.length!==2?Er(vp(t,e,n),([r,i],[a,o])=>oe(i,o)||oe(r,a)):Er(te(t,n),([r,i],[a,o])=>e(i,o)||oe(r,a))).map(([r])=>r)}var O5=Array.prototype,S5=O5.slice;function Ef(t){return()=>t}const _5=Math.sqrt(50),M5=Math.sqrt(10),E5=Math.sqrt(2);function wl(t,e,n){const r=(e-t)/Math.max(0,n),i=Math.floor(Math.log10(r)),a=r/Math.pow(10,i),o=a>=_5?10:a>=M5?5:a>=E5?2:1;let s,c,l;return i<0?(l=Math.pow(10,-i)/o,s=Math.round(t*l),c=Math.round(e*l),s/le&&--c,l=-l):(l=Math.pow(10,i)*o,s=Math.round(t/l),c=Math.round(e/l),s*le&&--c),c0))return[];if(t===e)return[t];const r=e=i))return[];const s=a-i+1,c=new Array(s);if(r)if(o<0)for(let l=0;l0?(t=Math.floor(t/i)*i,e=Math.ceil(e/i)*i):i<0&&(t=Math.ceil(t*i)/i,e=Math.floor(e*i)/i),r=i}}function k5(t){return Math.max(1,Math.ceil(Math.log(ux(t))/Math.LN2)+1)}function T5(){var t=es,e=Mr,n=k5;function r(i){Array.isArray(i)||(i=Array.from(i));var a,o=i.length,s,c,l=new Array(o);for(a=0;a=d)if(b>=d&&e===Mr){const w=Dd(f,d,x);isFinite(w)&&(w>0?d=(Math.floor(d/w)+1)*w:w<0&&(d=(Math.ceil(d*-w)+1)/-w))}else h.pop()}for(var p=h.length,v=0,g=p;h[v]<=f;)++v;for(;h[g-1]>d;)--g;(v||g0?h[a-1]:f,m.x1=a0)for(a=0;a=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n=i)&&(n=i)}return n}function to(t,e){let n,r=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(n=a)&&(n=a,r=i);else for(let a of t)(a=e(a,++i,t))!=null&&(n=a)&&(n=a,r=i);return r}function bn(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function bu(t,e){let n,r=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(n>a||n===void 0&&a>=a)&&(n=a,r=i);else for(let a of t)(a=e(a,++i,t))!=null&&(n>a||n===void 0&&a>=a)&&(n=a,r=i);return r}function gp(t,e,n=0,r=1/0,i){if(e=Math.floor(e),n=Math.floor(Math.max(0,n)),r=Math.floor(Math.min(t.length-1,r)),!(n<=e&&e<=r))return t;for(i=i===void 0?ns:hx(i);r>n;){if(r-n>600){const c=r-n+1,l=e-n+1,u=Math.log(c),f=.5*Math.exp(2*u/3),d=.5*Math.sqrt(u*f*(c-f)/c)*(l-c/2<0?-1:1),h=Math.max(n,Math.floor(e-l*f/c+d)),p=Math.min(r,Math.floor(e+(c-l)*f/c+d));gp(t,e,h,p,i)}const a=t[e];let o=n,s=r;for(go(t,n,e),i(t[r],a)>0&&go(t,n,r);o0;)--s}i(t[n],a)===0?go(t,n,s):(++s,go(t,s,r)),s<=e&&(n=s+1),e<=s&&(r=s-1)}return t}function go(t,e,n){const r=t[e];t[e]=t[n],t[n]=r}function C5(t,e=oe){let n,r=!1;if(e.length===1){let i;for(const a of t){const o=e(a);(r?oe(o,i)>0:oe(o,o)===0)&&(n=a,i=o,r=!0)}}else for(const i of t)(r?e(i,n)>0:e(i,i)===0)&&(n=i,r=!0);return n}function xu(t,e,n){if(t=Float64Array.from(f5(t,n)),!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)return bn(t);if(e>=1)return Ct(t);var r,i=(r-1)*e,a=Math.floor(i),o=Ct(gp(t,a).subarray(0,a+1)),s=bn(t.subarray(a+1));return o+(s-o)*(i-a)}}function L5(t,e,n=jd){if(!isNaN(e=+e)){if(r=Float64Array.from(t,(s,c)=>jd(n(t[c],c,t))),e<=0)return bu(r);if(e>=1)return to(r);var r,i=Uint32Array.from(t,(s,c)=>c),a=r.length-1,o=Math.floor(a*e);return gp(i,o,0,a,(s,c)=>ns(r[s],r[c])),o=C5(i.subarray(0,o+1),s=>r[s]),o>=0?o:-1}}function N5(t,e,n){const r=ux(t),i=fx(t);return r&&i?Math.ceil((n-e)*Math.cbrt(r)/(3.49*i)):1}function rs(t,e){let n=0,r=0;if(e===void 0)for(let i of t)i!=null&&(i=+i)>=i&&(++n,r+=i);else{let i=-1;for(let a of t)(a=e(a,++i,t))!=null&&(a=+a)>=a&&(++n,r+=a)}if(n)return r/n}function yp(t,e){return xu(t,.5,e)}function R5(t,e){return L5(t,.5,e)}function*I5(t){for(const e of t)yield*e}function px(t){return Array.from(I5(t))}function pa(t,e,n){t=+t,e=+e,n=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+n;for(var r=-1,i=Math.max(0,Math.ceil((e-t)/n))|0,a=new Array(i);++r(r,...i)=>n(e(r,...i),...i),ji)}function D5(t){return t.reduce((e,n)=>r=>j5(this,void 0,void 0,function*(){const i=yield e(r);return n(i)}),ji)}function bp(t){return t.replace(/( |^)[a-z]/g,e=>e.toUpperCase())}function La(t=""){throw new Error(t)}function xp(t,e){const{attributes:n}=e,r=new Set(["id","className"]);for(const[i,a]of Object.entries(n))r.has(i)||(i==="transform"&&t.attr(i,""),t.attr(i,a))}function zt(t){return t!=null&&!Number.isNaN(t)}function $5(t){const e=new Map;return n=>{if(e.has(n))return e.get(n);const r=t(n);return e.set(n,r),r}}function B5(t,e){const{transform:n}=t.style,i=(a=>a==="none"||a===void 0)(n)?"":n;t.style.transform=`${i} ${e}`.trimStart()}function Q(t,e){return vx(t,e)||{}}function vx(t,e){const n=Object.entries(t||{}).filter(([r])=>r.startsWith(e)).map(([r,i])=>[Db(r.replace(e,"").trim()),i]).filter(([r])=>!!r);return n.length===0?null:Object.fromEntries(n)}function F5(t,e){return Object.fromEntries(Object.entries(t).filter(([n])=>e.find(r=>n.startsWith(r))))}function Pf(t,...e){return Object.fromEntries(Object.entries(t).filter(([n])=>e.every(r=>!n.startsWith(r))))}function ag(t,e){if(t===void 0)return null;if(typeof t=="number")return t;const n=+t.replace("%","");return Number.isNaN(n)?null:n/100*e}function is(t){return typeof t=="object"&&!(t instanceof Date)&&t!==null&&!Array.isArray(t)}function Lr(t){return t===null||t===!1}function gx(t,e,n=5,r=0){if(!(r>=n)){for(const i of Object.keys(e)){const a=e[i];!Cr(a)||!Cr(t[i])?t[i]=a:gx(t[i],a,n,r+1)}return t}}function ai(t,e){return Object.entries(t).reduce((n,[r,i])=>(n[r]=e(i,r,t),n),{})}function Ui(t){return t.map((e,n)=>n)}function z5(t){return t[0]}function yx(t){return t[t.length-1]}function G5(t){return Array.from(new Set(t))}function mx(t,e){const n=[[],[]];return t.forEach(r=>{n[e(r)?0:1].push(r)}),n}function bx(t,e=t.length){if(e===1)return t.map(r=>[r]);const n=[];for(let r=0;r{n.push([t[r],...o])})}return n}function Y5(t){if(t.length===1)return[t];const e=[];for(let n=1;n<=t.length;n++)e.push(...bx(t,n));return e}function oi(t,e,n){const{encode:r}=n;if(t===null)return[e];const i=W5(t).map(o=>{var s;return[o,(s=Ot(r,o))===null||s===void 0?void 0:s[0]]}).filter(([,o])=>zt(o)),a=o=>i.map(([,s])=>s[o]).join("-");return Array.from(te(e,a).values())}function xx(t){return Array.isArray(t)?X5(t):typeof t=="function"?V5(t):t==="series"?H5:t==="value"?U5:t==="sum"?q5:t==="maxIndex"?K5:()=>null}function wx(t,e){for(const n of t)n.sort(e)}function Ox(t,e){return(e==null?void 0:e.domain)||Array.from(new Set(t))}function W5(t){return Array.isArray(t)?t:[t]}function H5(t,e,n){return Ds(r=>n[r])}function V5(t){return(e,n,r)=>Ds(i=>t(e[i]))}function X5(t){return(e,n,r)=>(i,a)=>t.reduce((o,s)=>o!==0?o:oe(e[i][s],e[a][s]),0)}function U5(t,e,n){return Ds(r=>e[r])}function q5(t,e,n){const r=Ui(t),i=Array.from(te(r,o=>n[+o]).entries()),a=new Map(i.map(([o,s])=>[o,s.reduce((c,l)=>c+ +e[l])]));return Ds(o=>a.get(n[o]))}function K5(t,e,n){const r=Ui(t),i=Array.from(te(r,o=>n[+o]).entries()),a=new Map(i.map(([o,s])=>[o,to(s,c=>e[c])]));return Ds(o=>a.get(n[o]))}function Ds(t){return(e,n)=>oe(t(e),t(n))}const Sx=(t={})=>{const{groupBy:e="x",orderBy:n=null,reverse:r=!1,y:i="y",y1:a="y1",series:o=!0}=t;return(s,c)=>{const{data:l,encode:u,style:f={}}=c,[d,h]=Ot(u,"y"),[p,v]=Ot(u,"y1"),[g]=o?ts(u,"series","color"):Ot(u,"color"),y=oi(e,s,c),b=xx(n)(l,d,g);b&&wx(y,b);const x=new Array(s.length),w=new Array(s.length),O=new Array(s.length),S=[],_=[];for(const A of y){r&&A.reverse();const k=p?+p[A[0]]:0,C=[],L=[];for(const F of A){const Y=O[F]=+d[F]-k;Y<0?L.push(F):Y>=0&&C.push(F)}const I=C.length>0?C:L,R=L.length>0?L:C;let j=C.length-1,D=0;for(;j>0&&d[I[j]]===0;)j--;for(;D0?B=x[F]=(w[F]=B)+Y:x[F]=w[F]=B}}const M=new Set(S),E=new Set(_),P=i==="y"?x:w,T=a==="y"?x:w;return[s,X({},c,{encode:{y0:yu(d,h),y:Wt(P,h),y1:Wt(T,v)},style:Object.assign({first:(A,k)=>M.has(k),last:(A,k)=>E.has(k)},f)})]}};Sx.props={};function yo(t){return Math.abs(t)>10?String(t):t.toString().padStart(2,"0")}function Z5(t){const e=t.getFullYear(),n=yo(t.getMonth()+1),r=yo(t.getDate()),i=`${e}-${n}-${r}`,a=t.getHours(),o=t.getMinutes(),s=t.getSeconds();return a||o||s?`${i} ${yo(a)}:${yo(o)}:${yo(s)}`:i}const wu=(t={})=>{const{channel:e="x"}=t;return(n,r)=>{const{encode:i}=r,{tooltip:a}=r;if(Lr(a))return[n,r];const{title:o}=a;if(o!==void 0)return[n,r];const s=Object.keys(i).filter(l=>l.startsWith(e)).filter(l=>!i[l].inferred).map(l=>Ot(i,l)).filter(([l])=>l).map(l=>l[0]);if(s.length===0)return[n,r];const c=[];for(const l of n)c[l]={value:s.map(u=>u[l]instanceof Date?Z5(u[l]):u[l]).join(", ")};return[n,X({},r,{tooltip:{title:c}})]}};wu.props={};const qi=()=>(t,e)=>{const{encode:n}=e,{x:r}=n;return r!==void 0?[t,e]:[t,X({},e,{encode:{x:yu(Kr(t,0))},scale:{x:{guide:null}}})]};qi.props={};const Ou=()=>(t,e)=>{const{encode:n}=e,{y:r}=n;return r!==void 0?[t,e]:[t,X({},e,{encode:{y:yu(Kr(t,0))},scale:{y:{guide:null}}})]};Ou.props={};const _x=()=>(t,e)=>{const{encode:n}=e,{size:r}=n;return r!==void 0?[t,e]:[t,X({},e,{encode:{size:xl(Kr(t,3))}})]};_x.props={};var Q5=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i(t,e)=>{const{encode:n}=e,{key:r}=n,i=Q5(n,["key"]);if(r!==void 0)return[t,e];const a=Object.values(i).map(({value:s})=>s),o=t.map(s=>a.filter(Array.isArray).map(c=>c[s]).join("-"));return[t,X({},e,{encode:{key:Wt(o)}})]};Mx.props={};const wp=()=>(t,e)=>{const{encode:n}=e,{series:r,color:i}=n;if(r!==void 0||i===void 0)return[t,e];const[a,o]=Ot(n,"color");return[t,X({},e,{encode:{series:Wt(a,o)}})]};wp.props={};const Ex=()=>(t,e)=>{const{data:n}=e;return!Array.isArray(n)||n.some(Is)?[t,e]:[t,X({},e,{encode:{y:Wt(n)}})]};Ex.props={};const Px=()=>(t,e)=>{const{data:n}=e;return!Array.isArray(n)||n.some(Is)?[t,e]:[t,X({},e,{encode:{x:Wt(n)}})]};Px.props={};const Ax=()=>(t,e)=>{const{encode:n}=e,{y1:r}=n;if(r)return[t,e];const[i]=Ot(n,"y");return[t,X({},e,{encode:{y1:Wt([...i])}})]};Ax.props={};const kx=()=>(t,e)=>{const{encode:n}=e,{x1:r}=n;if(r)return[t,e];const[i]=Ot(n,"x");return[t,X({},e,{encode:{x1:Wt([...i])}})]};kx.props={};const Tx=()=>(t,e)=>{const{data:n}=e;if(Array.isArray(n)&&(n.every(Array.isArray)||!n.some(Is))){const r=(i,a)=>Array.isArray(i[0])?i.map(o=>o[a]):[i[a]];return[t,X({},e,{encode:{x:Wt(r(n,0)),x1:Wt(r(n,1))}})]}return[t,e]};Tx.props={};const Cx=()=>(t,e)=>{const{data:n}=e;if(Array.isArray(n)&&(n.every(Array.isArray)||!n.some(Is))){const r=(i,a)=>Array.isArray(i[0])?i.map(o=>o[a]):[i[a]];return[t,X({},e,{encode:{y:Wt(r(n,0)),y1:Wt(r(n,1))}})]}return[t,e]};Cx.props={};const Su=t=>{const{channel:e}=t;return(n,r)=>{const{encode:i,tooltip:a}=r;if(Lr(a))return[n,r];const{items:o=[]}=a;if(!o||o.length>0)return[n,r];const c=(Array.isArray(e)?e:[e]).flatMap(l=>Object.keys(i).filter(u=>u.startsWith(l)).map(u=>{const{field:f,value:d,inferred:h=!1,aggregate:p}=i[u];return h?null:p&&d?{channel:u}:f?{field:f}:d?{channel:u}:null}).filter(u=>u!==null));return[n,X({},r,{tooltip:{items:c}})]}};Su.props={};const Op=()=>(t,e)=>[t,X({scale:{x:{padding:0},y:{padding:0}}},e)];Op.props={};var og=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i(t,e)=>{const{data:n,style:r={}}=e,i=og(e,["data","style"]),{x:a,y:o}=r,s=og(r,["x","y"]);if(a==null||o==null)return[t,e];const c=a||0,l=o||0;return[[0],X({},i,{data:[0],cartesian:!0,encode:{x:Wt([c]),y:Wt([l])},scale:{x:{type:"identity",independent:!0,guide:null},y:{type:"identity",independent:!0,guide:null}},style:s})]};_u.props={};const Lx=()=>(t,e)=>{const{style:n={}}=e;return[t,X({},e,{style:Object.assign(Object.assign({},n),Object.fromEntries(Object.entries(n).filter(([,r])=>typeof r=="function").map(([r,i])=>[r,()=>i])))})]};Lx.props={};const Mu=()=>(t,e)=>{const{data:n}=e;if(!Array.isArray(n)||n.some(Is))return[t,e];const r=Array.isArray(n[0])?n:[n],i=r.map(o=>o[0]),a=r.map(o=>o[1]);return[t,X({},e,{encode:{x:Wt(i),y:Wt(a)}})]};Mu.props={};const Nx=()=>(t,e)=>{const{style:n={},encode:r}=e,{series:i}=r,{gradient:a}=n;return!a||i?[t,e]:[t,X({},e,{encode:{series:xl(Kr(t,void 0))}})]};Nx.props={};var J5=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{groupBy:e="x",reverse:n=!1,orderBy:r,padding:i}=t;return J5(t,["groupBy","reverse","orderBy","padding"]),(a,o)=>{const{data:s,encode:c,scale:l}=o,{series:u}=l,[f]=Ot(c,"y"),[d]=ts(c,"series","color"),h=Ox(d,u),p=oi(e,a,o),g=xx(r)(s,f,d);g&&wx(p,g);const y=new Array(a.length);for(const m of p){n&&m.reverse();for(let b=0;b{const{groupBy:e=["x"],reducer:n=(o,s)=>s[o[0]],orderBy:r=null,reverse:i=!1,duration:a}=t;return(o,s)=>{const{encode:c}=s,u=(Array.isArray(e)?e:[e]).map(g=>[g,Ot(c,g)[0]]);if(u.length===0)return[o,s];let f=[o];for(const[,g]of u){const y=[];for(const m of f){const b=Array.from(te(m,x=>g[x]).values());y.push(...b)}f=y}if(r){const[g]=Ot(c,r);g&&f.sort((y,m)=>n(y,g)-n(m,g)),i&&f.reverse()}const d=(a||3e3)/f.length,[h]=a?[Kr(o,d)]:ts(c,"enterDuration",Kr(o,d)),[p]=ts(c,"enterDelay",Kr(o,0)),v=new Array(o.length);for(let g=0,y=0;g+h[x]);for(const x of m)v[x]=+p[x]+y;y+=b}return[o,X({},s,{encode:{enterDuration:xl(h),enterDelay:xl(v)}})]}};Ix.props={};var t3=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ibn(n,i=>r[+i]),max:(n,r)=>Ct(n,i=>r[+i]),first:(n,r)=>r[n[0]],last:(n,r)=>r[n[n.length-1]],mean:(n,r)=>rs(n,i=>r[+i]),median:(n,r)=>yp(n,i=>r[+i]),sum:(n,r)=>Cn(n,i=>r[+i]),deviation:(n,r)=>fx(n,i=>r[+i])}[t]||Ct}const jx=(t={})=>{const{groupBy:e="x",basis:n="max"}=t;return(r,i)=>{const{encode:a,tooltip:o}=i,s=t3(a,["x"]),c=Object.entries(s).filter(([p])=>p.startsWith("y")).map(([p])=>[p,Ot(a,p)[0]]),[,l]=c.find(([p])=>p==="y"),u=c.map(([p])=>[p,new Array(r.length)]),f=oi(e,r,i),d=e3(n);for(const p of f){const v=d(p,l);for(const g of p)for(let y=0;y[p,Wt(v,Ot(a,p)[1])]))},!h&&a.y0&&{tooltip:{items:[{channel:"y0"}]}}))]}};jx.props={};function Na(t,...e){return e.reduce((n,r)=>i=>n(r(i)),t)}function Ol(t,e){return e-t?n=>(n-t)/(e-t):n=>.5}function n3(t,e){const n=ee?t:e;return i=>Math.min(Math.max(n,i),r)}function Sp(t,e,n,r,i){let a=n||0,o=r||t.length;const s=i||(c=>c);for(;ae?o=c:a=c+1}return a}const $d=Math.sqrt(50),Bd=Math.sqrt(10),Fd=Math.sqrt(2);function tl(t,e,n){const r=(e-t)/Math.max(0,n),i=Math.floor(Math.log(r)/Math.LN10),a=r/10**i;return i>=0?(a>=$d?10:a>=Bd?5:a>=Fd?2:1)*10**i:-(10**-i)/(a>=$d?10:a>=Bd?5:a>=Fd?2:1)}function sg(t,e,n){const r=Math.abs(e-t)/Math.max(0,n);let i=10**Math.floor(Math.log(r)/Math.LN10);const a=r/i;return a>=$d?i*=10:a>=Bd?i*=5:a>=Fd&&(i*=2),e{const r=[t,e];let i=0,a=r.length-1,o=r[i],s=r[a],c;return s0?(o=Math.floor(o/c)*c,s=Math.ceil(s/c)*c,c=tl(o,s,n)):c<0&&(o=Math.ceil(o*c)/c,s=Math.floor(s*c)/c,c=tl(o,s,n)),c>0?(r[i]=Math.floor(o/c)*c,r[a]=Math.ceil(s/c)*c):c<0&&(r[i]=Math.ceil(o*c)/c,r[a]=Math.floor(s*c)/c),r},as=1e3,os=as*60,ss=os*60,Di=ss*24,Yo=Di*7,$x=Di*30,Bx=Di*365;function Fe(t,e,n,r){const i=(l,u)=>{const f=h=>r(h)%u===0;let d=u;for(;d&&!f(l);)n(l,-1),d-=1;return l},a=(l,u)=>{u&&i(l,u),e(l)},o=(l,u)=>{const f=new Date(+l);return a(f,u),f},s=(l,u)=>{const f=new Date(+l-1);return a(f,u),n(f,u),a(f),f};return{ceil:s,floor:o,range:(l,u,f,d)=>{const h=[],p=Math.floor(f),v=d?s(l,f):s(l);for(let g=v;gt,(t,e=1)=>{t.setTime(+t+e)},t=>t.getTime()),i3=Fe(as,t=>{t.setMilliseconds(0)},(t,e=1)=>{t.setTime(+t+as*e)},t=>t.getSeconds()),a3=Fe(os,t=>{t.setSeconds(0,0)},(t,e=1)=>{t.setTime(+t+os*e)},t=>t.getMinutes()),o3=Fe(ss,t=>{t.setMinutes(0,0,0)},(t,e=1)=>{t.setTime(+t+ss*e)},t=>t.getHours()),s3=Fe(Di,t=>{t.setHours(0,0,0,0)},(t,e=1)=>{t.setTime(+t+Di*e)},t=>t.getDate()-1),Fx=Fe($x,t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e=1)=>{const n=t.getMonth();t.setMonth(n+e)},t=>t.getMonth()),c3=Fe(Yo,t=>{t.setDate(t.getDate()-t.getDay()%7),t.setHours(0,0,0,0)},(t,e=1)=>{t.setDate(t.getDate()+7*e)},t=>{const e=Fx.floor(t),n=new Date(+t);return Math.floor((+n-+e)/Yo)}),l3=Fe(Bx,t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e=1)=>{const n=t.getFullYear();t.setFullYear(n+e)},t=>t.getFullYear()),zx={millisecond:r3,second:i3,minute:a3,hour:o3,day:s3,week:c3,month:Fx,year:l3},u3=Fe(1,t=>t,(t,e=1)=>{t.setTime(+t+e)},t=>t.getTime()),f3=Fe(as,t=>{t.setUTCMilliseconds(0)},(t,e=1)=>{t.setTime(+t+as*e)},t=>t.getUTCSeconds()),d3=Fe(os,t=>{t.setUTCSeconds(0,0)},(t,e=1)=>{t.setTime(+t+os*e)},t=>t.getUTCMinutes()),h3=Fe(ss,t=>{t.setUTCMinutes(0,0,0)},(t,e=1)=>{t.setTime(+t+ss*e)},t=>t.getUTCHours()),p3=Fe(Di,t=>{t.setUTCHours(0,0,0,0)},(t,e=1)=>{t.setTime(+t+Di*e)},t=>t.getUTCDate()-1),Gx=Fe($x,t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e=1)=>{const n=t.getUTCMonth();t.setUTCMonth(n+e)},t=>t.getUTCMonth()),v3=Fe(Yo,t=>{t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7)%7),t.setUTCHours(0,0,0,0)},(t,e=1)=>{t.setTime(+t+Yo*e)},t=>{const e=Gx.floor(t),n=new Date(+t);return Math.floor((+n-+e)/Yo)}),g3=Fe(Bx,t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e=1)=>{const n=t.getUTCFullYear();t.setUTCFullYear(n+e)},t=>t.getUTCFullYear()),Yx={millisecond:u3,second:f3,minute:d3,hour:h3,day:p3,week:v3,month:Gx,year:g3};function y3(t){const e=t?Yx:zx,{year:n,month:r,week:i,day:a,hour:o,minute:s,second:c,millisecond:l}=e;return{tickIntervals:[[c,1],[c,5],[c,15],[c,30],[s,1],[s,5],[s,15],[s,30],[o,1],[o,3],[o,6],[o,12],[a,1],[a,2],[i,1],[r,1],[r,3],[n,1]],year:n,millisecond:l}}function Wx(t,e,n,r,i){const a=+t,o=+e,{tickIntervals:s,year:c,millisecond:l}=y3(i),u=([g,y])=>g.duration*y,f=r?(o-a)/r:n||5,d=r||(o-a)/f,h=s.length,p=Sp(s,d,0,h,u);let v;if(p===h){const g=sg(a/c.duration,o/c.duration,f);v=[c,g]}else if(p){const g=d/u(s[p-1]){const a=t>e,o=a?e:t,s=a?t:e,[c,l]=Wx(o,s,n,r,i),u=[c.floor(o,l),c.ceil(s,l)];return a?u.reverse():u};var Hx=function(t){return t!==null&&typeof t!="function"&&isFinite(t.length)},b3={}.toString,$s=function(t,e){return b3.call(t)==="[object "+e+"]"};const Vx=function(t){return $s(t,"Function")};var x3=function(t){return t==null};const Xx=function(t){return Array.isArray?Array.isArray(t):$s(t,"Array")},w3=function(t){var e=typeof t;return t!==null&&e==="object"||e==="function"};function O3(t,e){if(t){var n;if(Xx(t))for(var r=0,i=t.length;re=>-t(-e),_p=(t,e)=>{const n=Math.log(t),r=t===Math.E?Math.log:t===10?Math.log10:t===2?Math.log2:i=>Math.log(i)/n;return e?Zx(r):r},Mp=(t,e)=>{const n=t===Math.E?Math.exp:r=>t**r;return e?Zx(n):n},T3=(t,e,n,r)=>{const i=t<0,a=_p(r,i),o=Mp(r,i),s=t>e,c=s?e:t,l=s?t:e,u=[o(Math.floor(a(c))),o(Math.ceil(a(l)))];return s?u.reverse():u},C3=t=>e=>{const n=t(e);return cs(n)?Math.round(n):n};function L3(t,e){return n=>{n.prototype.rescale=function(){this.initRange(),this.nice();const[r]=this.chooseTransforms();this.composeOutput(r,this.chooseClamp(r))},n.prototype.initRange=function(){const{interpolator:r}=this.options;this.options.range=t(r)},n.prototype.composeOutput=function(r,i){const{domain:a,interpolator:o,round:s}=this.getOptions(),c=e(a.map(r)),l=s?C3(o):o;this.output=Na(l,c,i,r)},n.prototype.invert=void 0}}var Qx={exports:{}},N3={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Jx={exports:{}},R3=function(e){return!e||typeof e=="string"?!1:e instanceof Array||Array.isArray(e)||e.length>=0&&(e.splice instanceof Function||Object.getOwnPropertyDescriptor(e,e.length-1)&&e.constructor.name!=="String")},I3=R3,j3=Array.prototype.concat,D3=Array.prototype.slice,ug=Jx.exports=function(e){for(var n=[],r=0,i=e.length;r=4&&t[3]!==1&&(e=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+e+")"};gn.to.keyword=function(t){return e2[t.slice(0,3)]};function Zr(t,e,n){return Math.min(Math.max(e,t),n)}function uc(t){var e=Math.round(t).toString(16).toUpperCase();return e.length<2?"0"+e:e}var B3=Qx.exports;const F3=ip(B3);function kf(t,e,n){let r=n;return r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+(e-t)*6*r:r<1/2?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function z3(t){const e=t[0]/360,n=t[1]/100,r=t[2]/100,i=t[3];if(n===0)return[r*255,r*255,r*255,i];const a=r<.5?r*(1+n):r+n-r*n,o=2*r-a,s=kf(o,a,e+1/3),c=kf(o,a,e),l=kf(o,a,e-1/3);return[s*255,c*255,l*255,i]}function fg(t){const e=F3.get(t);if(!e)return null;const{model:n,value:r}=e;return n==="rgb"?r:n==="hsl"?z3(r):null}const Ra=(t,e)=>n=>t*(1-n)+e*n,G3=(t,e)=>{const n=fg(t),r=fg(e);return n===null||r===null?n?()=>t:()=>e:i=>{const a=new Array(4);for(let u=0;u<4;u+=1){const f=n[u],d=r[u];a[u]=f*(1-i)+d*i}const[o,s,c,l]=a;return`rgba(${Math.round(o)}, ${Math.round(s)}, ${Math.round(c)}, ${l})`}},Fs=(t,e)=>typeof t=="number"&&typeof e=="number"?Ra(t,e):typeof t=="string"&&typeof e=="string"?G3(t,e):()=>t,Y3=(t,e)=>{const n=Ra(t,e);return r=>Math.round(n(r))};function W3(t,e){const{second:n,minute:r,hour:i,day:a,week:o,month:s,year:c}=e;return n.floor(t)`${e}`:typeof t=="object"?e=>JSON.stringify(e):e=>e}let n2=class r2 extends zs{getDefaultOptions(){return{domain:[],range:[],unknown:Eu}}constructor(e){super(e)}map(e){return this.domainIndexMap.size===0&&pg(this.domainIndexMap,this.getDomain(),this.domainKey),vg({value:this.domainKey(e),mapper:this.domainIndexMap,from:this.getDomain(),to:this.getRange(),notFoundReturn:this.options.unknown})}invert(e){return this.rangeIndexMap.size===0&&pg(this.rangeIndexMap,this.getRange(),this.rangeKey),vg({value:this.rangeKey(e),mapper:this.rangeIndexMap,from:this.getRange(),to:this.getDomain(),notFoundReturn:this.options.unknown})}rescale(e){const[n]=this.options.domain,[r]=this.options.range;if(this.domainKey=gg(n),this.rangeKey=gg(r),!this.rangeIndexMap){this.rangeIndexMap=new Map,this.domainIndexMap=new Map;return}(!e||e.range)&&this.rangeIndexMap.clear(),(!e||e.domain||e.compare)&&(this.domainIndexMap.clear(),this.sortedDomain=void 0)}clone(){return new r2(this.options)}getRange(){return this.options.range}getDomain(){if(this.sortedDomain)return this.sortedDomain;const{domain:e,compare:n}=this.options;return this.sortedDomain=n?[...e].sort(n):e,this.sortedDomain}};function U3(t){const e=Math.min(...t);return t.map(n=>n/e)}function q3(t,e){const n=t.length,r=e-n;return r>0?[...t,...new Array(r).fill(1)]:r<0?t.slice(0,e):t}function K3(t){return Math.round(t*1e12)/1e12}function Z3(t){const{domain:e,range:n,paddingOuter:r,paddingInner:i,flex:a,round:o,align:s}=t,c=e.length,l=q3(a,c),[u,f]=n,d=f-u,h=2/c*r+1-1/c*i,p=d/h,v=p*i/c,g=p-c*v,y=U3(l),m=y.reduce((T,A)=>T+A),b=g/m,x=new hg(e.map((T,A)=>{const k=y[A]*b;return[T,o?Math.floor(k):k]})),w=new hg(e.map((T,A)=>{const C=y[A]*b+v;return[T,o?Math.floor(C):C]})),O=Array.from(w.values()).reduce((T,A)=>T+A),_=(d-(O-O/c*i))*s,M=u+_;let E=o?Math.round(M):M;const P=new Array(c);for(let T=0;Td+b*u);return{valueStep:u,valueBandWidth:f,adjustedRange:y}}let Ia=class i2 extends n2{getDefaultOptions(){return{domain:[],range:[0,1],align:.5,round:!1,paddingInner:0,paddingOuter:0,padding:0,unknown:Eu,flex:[]}}constructor(e){super(e)}clone(){return new i2(this.options)}getStep(e){return this.valueStep===void 0?1:typeof this.valueStep=="number"?this.valueStep:e===void 0?Array.from(this.valueStep.values())[0]:this.valueStep.get(e)}getBandWidth(e){return this.valueBandWidth===void 0?1:typeof this.valueBandWidth=="number"?this.valueBandWidth:e===void 0?Array.from(this.valueBandWidth.values())[0]:this.valueBandWidth.get(e)}getRange(){return this.adjustedRange}getPaddingInner(){const{padding:e,paddingInner:n}=this.options;return e>0?e:n}getPaddingOuter(){const{padding:e,paddingOuter:n}=this.options;return e>0?e:n}rescale(){super.rescale();const{align:e,domain:n,range:r,round:i,flex:a}=this.options,{adjustedRange:o,valueBandWidth:s,valueStep:c}=Q3({align:e,range:r,round:i,flex:a,paddingInner:this.getPaddingInner(),paddingOuter:this.getPaddingOuter(),domain:n});this.valueStep=c,this.valueBandWidth=s,this.adjustedRange=o}};const Bi=(t,e,n)=>{let r,i,a=t,o=e;if(a===o&&n>0)return[a];let s=tl(a,o,n);if(s===0||!Number.isFinite(s))return[];if(s>0){a=Math.ceil(a/s),o=Math.floor(o/s),i=new Array(r=Math.ceil(o-a+1));for(let c=0;c=0&&(c=1),1-s/(o-1)-n+c}function rC(t,e,n){const r=Kx(e);return 1-qx(e,t)/(r-1)-n+1}function iC(t,e,n,r,i,a){const o=(t-1)/(a-i),s=(e-1)/(Math.max(a,r)-Math.min(n,i));return 2-Math.max(o/s,s/o)}function aC(t,e){return t>=e?2-(t-1)/(e-1):1}function oC(t,e,n,r){const i=e-t;return 1-.5*((e-r)**2+(t-n)**2)/(.1*i)**2}function sC(t,e,n){const r=e-t;return n>r?1-((n-r)/2)**2/(.1*r)**2:1}function cC(){return 1}const Pp=(t,e,n=5,r=!0,i=J3,a=[.25,.2,.5,.05])=>{const o=n<0?0:Math.round(n);if(Number.isNaN(t)||Number.isNaN(e)||typeof t!="number"||typeof e!="number"||!o)return[];if(e-t<1e-15||o===1)return[t];const s={score:-2,lmin:0,lmax:0,lstep:0};let c=1;for(;c<1/0;){for(let p=0;ps.score&&(!r||T<=t&&A>=e)&&(s.lmin=T,s.lmax=A,s.lstep=k,s.score=j)}}x+=1}y+=1}}c+=1}const l=mo(s.lmax),u=mo(s.lmin),f=mo(s.lstep),d=Math.floor(eC((l-u)/f))+1,h=new Array(d);h[0]=mo(u);for(let p=1;p{const[r,i]=t,[a,o]=e;let s,c;return r{const r=Math.min(t.length,e.length)-1,i=new Array(r),a=new Array(r),o=t[0]>t[r],s=o?[...t].reverse():t,c=o?[...e].reverse():e;for(let l=0;l{const u=Sp(t,l,1,r)-1,f=i[u],d=a[u];return Na(d,f)(l)}},mg=(t,e,n,r)=>(Math.min(t.length,e.length)>2?uC:lC)(t,e,r?Y3:n);let Pu=class extends zs{getDefaultOptions(){return{domain:[0,1],range:[0,1],nice:!1,clamp:!1,round:!1,interpolate:Ra,tickCount:5}}map(e){return Sl(e)?this.output(e):this.options.unknown}invert(e){return Sl(e)?this.input(e):this.options.unknown}nice(){if(!this.options.nice)return;const[e,n,r,...i]=this.getTickMethodOptions();this.options.domain=this.chooseNice()(e,n,r,...i)}getTicks(){const{tickMethod:e}=this.options,[n,r,i,...a]=this.getTickMethodOptions();return e(n,r,i,...a)}getTickMethodOptions(){const{domain:e,tickCount:n}=this.options,r=e[0],i=e[e.length-1];return[r,i,n]}chooseNice(){return Dx}rescale(){this.nice();const[e,n]=this.chooseTransforms();this.composeOutput(e,this.chooseClamp(e)),this.composeInput(e,n,this.chooseClamp(n))}chooseClamp(e){const{clamp:n,range:r}=this.options,i=this.options.domain.map(e),a=Math.min(i.length,r.length);return n?n3(i[0],i[a-1]):$i}composeOutput(e,n){const{domain:r,range:i,round:a,interpolate:o}=this.options,s=mg(r.map(e),i,o,a);this.output=Na(s,n,e)}composeInput(e,n,r){const{domain:i,range:a}=this.options,o=mg(a,i.map(e),Ra);this.input=Na(n,r,o)}},Yt=class c2 extends Pu{getDefaultOptions(){return{domain:[0,1],range:[0,1],unknown:void 0,nice:!1,clamp:!1,round:!1,interpolate:Fs,tickMethod:Bi,tickCount:5}}chooseTransforms(){return[$i,$i]}clone(){return new c2(this.options)}},l2=class u2 extends Ia{getDefaultOptions(){return{domain:[],range:[0,1],align:.5,round:!1,padding:0,unknown:Eu,paddingInner:1,paddingOuter:0}}constructor(e){super(e)}getPaddingInner(){return 1}clone(){return new u2(this.options)}update(e){super.update(e)}getPaddingOuter(){return this.options.padding}};const fC=t=>e=>e<0?-((-e)**t):e**t,dC=t=>e=>e<0?-((-e)**(1/t)):e**(1/t),hC=t=>t<0?-Math.sqrt(-t):Math.sqrt(t);let f2=class d2 extends Pu{getDefaultOptions(){return{domain:[0,1],range:[0,1],nice:!1,clamp:!1,round:!1,exponent:2,interpolate:Fs,tickMethod:Bi,tickCount:5}}constructor(e){super(e)}chooseTransforms(){const{exponent:e}=this.options;if(e===1)return[$i,$i];const n=e===.5?hC:fC(e),r=dC(e);return[n,r]}clone(){return new d2(this.options)}},pC=class h2 extends f2{getDefaultOptions(){return{domain:[0,1],range:[0,1],nice:!1,clamp:!1,round:!1,interpolate:Fs,tickMethod:Bi,tickCount:5,exponent:.5}}constructor(e){super(e)}update(e){super.update(e)}clone(){return new h2(this.options)}},Au=class p2 extends zs{getDefaultOptions(){return{domain:[.5],range:[0,1]}}constructor(e){super(e)}map(e){if(!Sl(e))return this.options.unknown;const n=Sp(this.thresholds,e,0,this.n);return this.options.range[n]}invert(e){const{range:n}=this.options,r=n.indexOf(e),i=this.thresholds;return[i[r-1],i[r]]}clone(){return new p2(this.options)}rescale(){const{domain:e,range:n}=this.options;this.n=Math.min(e.length,n.length-1),this.thresholds=e}};const vC=(t,e,n,r=10)=>{const i=t<0,a=Mp(r,i),o=_p(r,i),s=e=1;p-=1){const v=h*p;if(v>l)break;v>=c&&d.push(v)}}else for(;u<=f;u+=1){const h=a(u);for(let p=1;pl)break;v>=c&&d.push(v)}}d.length*2a-o);const i=[];for(let a=1;a3?0:(t-t%10!==10?1:0)*t%10]}},_C=zd({},SC),Qe=function(t,e){for(e===void 0&&(e=2),t=String(t);t.length0?"-":"+")+Qe(Math.floor(Math.abs(e)/60)*100+Math.abs(e)%60,4)},Z:function(t){var e=t.getTimezoneOffset();return(e>0?"-":"+")+Qe(Math.floor(Math.abs(e)/60),2)+":"+Qe(Math.abs(e)%60,2)}},bg={default:"ddd MMM DD YYYY HH:mm:ss",shortDate:"M/D/YY",mediumDate:"MMM D, YYYY",longDate:"MMMM D, YYYY",fullDate:"dddd, MMMM D, YYYY",isoDate:"YYYY-MM-DD",isoDateTime:"YYYY-MM-DDTHH:mm:ssZ",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},EC=function(t,e,n){if(e===void 0&&(e=bg.default),n===void 0&&(n={}),typeof t=="number"&&(t=new Date(t)),Object.prototype.toString.call(t)!=="[object Date]"||isNaN(t.getTime()))throw new Error("Invalid Date pass to format");e=bg[e]||e;var r=[];e=e.replace(xC,function(a,o){return r.push(o),"@@@"});var i=zd(zd({},_C),n);return e=e.replace(bC,function(a){return MC[a](t,i)}),e.replace(/@@@/g,function(){return r.shift()})};const PC=(t,e,n,r,i)=>{const a=t>e,o=a?e:t,s=a?t:e,[c,l]=Wx(o,s,n,r,i),u=c.range(o,new Date(+s+1),l,!0);return a?u.reverse():u};function AC(t){const e=t.getTimezoneOffset(),n=new Date(t);return n.setMinutes(n.getMinutes()+e,n.getSeconds(),n.getMilliseconds()),n}let kC=class S2 extends Pu{getDefaultOptions(){return{domain:[new Date(2e3,0,1),new Date(2e3,0,2)],range:[0,1],nice:!1,tickCount:5,tickInterval:void 0,unknown:void 0,clamp:!1,tickMethod:PC,interpolate:Ra,mask:void 0,utc:!1}}chooseTransforms(){return[r=>+r,r=>new Date(r)]}chooseNice(){return m3}getTickMethodOptions(){const{domain:e,tickCount:n,tickInterval:r,utc:i}=this.options,a=e[0],o=e[e.length-1];return[a,o,n,r,i]}getFormatter(){const{mask:e,utc:n}=this.options,r=n?Yx:zx,i=n?AC:$i;return a=>EC(i(a),e||W3(a,r))}clone(){return new S2(this.options)}};var TC=function(t,e,n,r){var i=arguments.length,a=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,n):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(t,e,n,r);else for(var s=t.length-1;s>=0;s--)(o=t[s])&&(a=(i<3?o(a):i>3?o(e,n,a):o(e,n))||a);return i>3&&a&&Object.defineProperty(e,n,a),a},Gd;function CC(t){return[t(0),t(1)]}const LC=t=>{const[e,n]=t;return Na(Ra(0,1),Ol(e,n))};let Yd=Gd=class extends Yt{getDefaultOptions(){return{domain:[0,1],unknown:void 0,nice:!1,clamp:!1,round:!1,interpolator:$i,tickMethod:Bi,tickCount:5}}constructor(e){super(e)}clone(){return new Gd(this.options)}};Yd=Gd=TC([L3(CC,LC)],Yd);function _l(t,e,n){if(t===null)return[-.5,.5];const r=Ox(t,e),a=new Ia({domain:r,range:[0,1],padding:n}).getBandWidth();return[-a/2,a/2]}function Ml(t,e,n){return e*(1-t)+n*t}const _2=(t={})=>{const{padding:e=0,paddingX:n=e,paddingY:r=e,random:i=Math.random}=t;return(a,o)=>{const{encode:s,scale:c}=o,{x:l,y:u}=c,[f]=Ot(s,"x"),[d]=Ot(s,"y"),h=_l(f,l,n),p=_l(d,u,r),v=a.map(()=>Ml(i(),...p)),g=a.map(()=>Ml(i(),...h));return[a,X({scale:{x:{padding:.5},y:{padding:.5}}},o,{encode:{dy:Wt(v),dx:Wt(g)}})]}};_2.props={};const M2=(t={})=>{const{padding:e=0,random:n=Math.random}=t;return(r,i)=>{const{encode:a,scale:o}=i,{x:s}=o,[c]=Ot(a,"x"),l=_l(c,s,e),u=r.map(()=>Ml(n(),...l));return[r,X({scale:{x:{padding:.5}}},i,{encode:{dx:Wt(u)}})]}};M2.props={};const E2=(t={})=>{const{padding:e=0,random:n=Math.random}=t;return(r,i)=>{const{encode:a,scale:o}=i,{y:s}=o,[c]=Ot(a,"y"),l=_l(c,s,e),u=r.map(()=>Ml(n(),...l));return[r,X({scale:{y:{padding:.5}}},i,{encode:{dy:Wt(u)}})]}};E2.props={};var NC=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{groupBy:e="x"}=t;return(n,r)=>{const{encode:i}=r,a=NC(i,["x"]),o=Object.entries(a).filter(([f])=>f.startsWith("y")).map(([f])=>[f,Ot(i,f)[0]]),s=o.map(([f])=>[f,new Array(n.length)]),c=oi(e,n,r),l=new Array(c.length);for(let f=0;fo.map(([,y])=>+y[g])),[p,v]=Mr(h);l[f]=(p+v)/2}const u=Math.max(...l);for(let f=0;f[f,Wt(d,Ot(i,f)[1])]))})]}};P2.props={};const A2=(t={})=>{const{groupBy:e="x",series:n=!0}=t;return(r,i)=>{const{encode:a}=i,[o]=Ot(a,"y"),[s,c]=Ot(a,"y1");n?ts(a,"series","color"):Ot(a,"color");const l=oi(e,r,i),u=new Array(r.length);for(const f of l){const d=f.map(h=>+o[h]);for(let h=0;hy!==h));u[p]=o[p]>v?v:o[p]}}return[r,X({},i,{encode:{y1:Wt(u,c)}})]}};A2.props={};function xg(t,e){return[t[0]]}function RC(t,e){const n=t.length-1;return[t[n]]}function IC(t,e){const n=to(t,r=>e[r]);return[t[n]]}function jC(t,e){const n=bu(t,r=>e[r]);return[t[n]]}function DC(t){return typeof t=="function"?t:{first:xg,last:RC,max:IC,min:jC}[t]||xg}const ku=(t={})=>{const{groupBy:e="series",channel:n,selector:r}=t;return(i,a)=>{const{encode:o}=a,s=oi(e,i,a),[c]=Ot(o,n),l=DC(r);return[s.flatMap(u=>l(u,c)),a]}};ku.props={};var $C=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{selector:e}=t,n=$C(t,["selector"]);return ku(Object.assign({channel:"x",selector:e},n))};k2.props={};var BC=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{selector:e}=t,n=BC(t,["selector"]);return ku(Object.assign({channel:"y",selector:e},n))};T2.props={};var FC=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ie===null?t:`${t} of ${e}`}function zC(t){if(typeof t=="function")return[t,null];const n={mean:GC,max:WC,count:VC,first:UC,last:qC,sum:XC,min:HC,median:YC}[t];if(!n)throw new Error(`Unknown reducer: ${t}.`);return n()}function GC(){const t=(n,r)=>rs(n,i=>+r[i]),e=si("mean");return[t,e]}function YC(){const t=(n,r)=>yp(n,i=>+r[i]),e=si("median");return[t,e]}function WC(){const t=(n,r)=>Ct(n,i=>+r[i]),e=si("max");return[t,e]}function HC(){const t=(n,r)=>bn(n,i=>+r[i]),e=si("min");return[t,e]}function VC(){const t=(n,r)=>n.length,e=si("count");return[t,e]}function XC(){const t=(n,r)=>Cn(n,i=>+r[i]),e=si("sum");return[t,e]}function UC(){const t=(n,r)=>r[n[0]],e=si("first");return[t,e]}function qC(){const t=(n,r)=>r[n[n.length-1]],e=si("last");return[t,e]}const Ap=(t={})=>{const{groupBy:e}=t,n=FC(t,["groupBy"]);return(r,i)=>{const{data:a,encode:o}=i,s=e(r,i);if(!s)return[r,i];const c=(h,p)=>{if(h)return h;const{from:v}=p;if(!v)return h;const[,g]=Ot(o,v);return g},l=Object.entries(n).map(([h,p])=>{const[v,g]=zC(p),[y,m]=Ot(o,h),b=c(m,p),x=s.map(w=>v(w,y??a));return[h,Object.assign(Object.assign({},c5(x,(g==null?void 0:g(b))||b)),{aggregate:!0})]}),u=Object.keys(o).map(h=>{const[p,v]=Ot(o,h),g=s.map(y=>p[y[0]]);return[h,Wt(g,v)]}),f=s.map(h=>a[h[0]]);return[Ui(s),X({},i,{data:f,encode:Object.fromEntries([...u,...l])})]}};Ap.props={};var KC=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{channels:e=["x","y"]}=t,n=KC(t,["channels"]),r=(i,a)=>oi(e,i,a);return Ap(Object.assign(Object.assign({},n),{groupBy:r}))};Gs.props={};const C2=(t={})=>Gs(Object.assign(Object.assign({},t),{channels:["x","color","series"]}));C2.props={};const L2=(t={})=>Gs(Object.assign(Object.assign({},t),{channels:["y","color","series"]}));L2.props={};const N2=(t={})=>Gs(Object.assign(Object.assign({},t),{channels:["color"]}));N2.props={};var R2=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ii(o,a);if(i==="max")return o=>Ct(o,s=>+a[s]);if(i==="min")return o=>bn(o,s=>+a[s]);if(i==="sum")return o=>Cn(o,s=>+a[s]);if(i==="median")return o=>yp(o,s=>+a[s]);if(i==="mean")return o=>rs(o,s=>+a[s]);if(i==="first")return o=>a[o[0]];if(i==="last")return o=>a[o[o.length-1]];throw new Error(`Unknown reducer: ${i}`)}function QC(t,e,n){const{reverse:r,channel:i}=n,{encode:a}=e,[o]=Ot(a,i),s=Er(t,c=>o[c]);return r&&s.reverse(),[s,e]}function JC(t,e,n){if(!Array.isArray(n))return t;const r=new Set(n);return t.filter(i=>r.has(e[i]))}function tL(t,e,n){var r;const{reverse:i,slice:a,channel:o}=n,s=R2(n,["reverse","slice","channel"]),{encode:c,scale:l={}}=e,u=(r=l[o])===null||r===void 0?void 0:r.domain,[f]=Ot(c,o),d=ZC(o,s,c),h=JC(t,f,u),p=w5(h,d,y=>f[y]);i&&p.reverse();const v=typeof a=="number"?[0,a]:a,g=a?p.slice(...v):p;return[t,X(e,{scale:{[o]:{domain:g}}})]}const Tu=(t={})=>{const{reverse:e=!1,slice:n,channel:r,ordinal:i=!0}=t,a=R2(t,["reverse","slice","channel","ordinal"]);return(o,s)=>i?tL(o,s,Object.assign({reverse:e,slice:n,channel:r},a)):QC(o,s,Object.assign({reverse:e,slice:n,channel:r},a))};Tu.props={};const I2=(t={})=>Tu(Object.assign(Object.assign({},t),{channel:"x"}));I2.props={};const j2=(t={})=>Tu(Object.assign(Object.assign({},t),{channel:"color"}));j2.props={};const D2=(t={})=>Tu(Object.assign(Object.assign({},t),{channel:"y"}));D2.props={};function eL(t,e){return typeof e=="string"?t.map(n=>n[e]):t.map(e)}function nL(t,e){if(typeof t=="function")return n=>t(n,e);if(t==="sum")return n=>Cn(n,r=>+e[r]);throw new Error(`Unknown reducer: ${t}`)}const $2=(t={})=>{const{field:e,channel:n="y",reducer:r="sum"}=t;return(i,a)=>{const{data:o,encode:s}=a,[c]=Ot(s,"x"),l=e?eL(o,e):Ot(s,n)[0],u=nL(r,l),f=dx(i,u,d=>c[d]).map(d=>d[1]);return[i,X({},a,{scale:{x:{flex:f}}})]}};$2.props={};function se([t,e],[n,r]){return[t-n,e-r]}function fc([t,e],[n,r]){return[t+n,e+r]}function Jt([t,e],[n,r]){return Math.sqrt(Math.pow(t-n,2)+Math.pow(e-r,2))}function Nn([t,e]){return Math.atan2(e,t)}function ja([t,e]){return Nn([t,e])+Math.PI/2}function B2(t,e){const n=Nn(t),r=Nn(e);return n{const o=r.length;if(o===0)return[];const{innerWidth:s,innerHeight:c}=a,l=c/s;let u=Math.ceil(Math.sqrt(i/l)),f=s/u,d=Math.ceil(i/u),h=d*f;for(;h>c;)u=u+1,f=s/u,d=Math.ceil(i/u),h=d*f;const p=c-d*f,v=d<=1?0:p/(d-1),[g,y]=d<=1?[(s-o*f)/(o-1),(c-f)/2]:[0,0];return r.map((m,b)=>{const[x,w,O,S]=kp(m),_=n==="col"?b%u:Math.floor(b/d),M=n==="col"?Math.floor(b/u):b%d,E=_*f,P=(d-M-1)*f+p,T=(f-e)/O,A=(f-e)/S,k=E-x+g*_+1/2*e,C=P-w-v*M-y+1/2*e;return`translate(${k}, ${C}) scale(${T}, ${A})`})}}const z2=t=>(e,n)=>[e,X({},n,{modifier:rL(t),axis:!1})];z2.props={};var iL=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{groupChannels:e=["color"],binChannels:n=["x","y"]}=t,r=iL(t,["groupChannels","binChannels"]),i={},a=(o,s)=>{const{encode:c}=s,l=n.map(p=>{const[v]=Ot(c,p);return v}),u=Q(r,wg),f=o.filter(p=>l.every(v=>zt(v[p]))),d=[...e.map(p=>{const[v]=Ot(c,p);return v}).filter(zt).map(p=>v=>p[v]),...n.map((p,v)=>{const g=l[v],y=u[p]||aL(g),m=T5().thresholds(y).value(x=>+g[x])(f),b=new Map(m.flatMap(x=>{const{x0:w,x1:O}=x,S=`${w},${O}`;return x.map(_=>[_,S])}));return i[p]=b,x=>b.get(x)})],h=p=>d.map(v=>v(p)).join("-");return Array.from(te(f,h).values())};return Ap(Object.assign(Object.assign(Object.assign({},Object.fromEntries(Object.entries(r).filter(([o])=>!o.startsWith(wg)))),Object.fromEntries(n.flatMap(o=>{const s=([l])=>+i[o].get(l).split(",")[0],c=([l])=>+i[o].get(l).split(",")[1];return c.from=o,[[o,s],[`${o}1`,c]]}))),{groupBy:a}))};Tp.props={};const G2=(t={})=>{const{thresholds:e}=t;return Tp(Object.assign(Object.assign({},t),{thresholdsX:e,groupChannels:["color"],binChannels:["x"]}))};G2.props={};function oL(t,e,n,r){const i=t.length;if(r>=i||r===0)return t;const a=h=>e[t[h]]*1,o=h=>n[t[h]]*1,s=[],c=(i-2)/(r-2);let l=0,u,f,d;s.push(l);for(let h=0;hu&&(u=f,d=b);s.push(d),l=d}return s.push(i-1),s.map(h=>t[h])}function sL(t){if(typeof t=="function")return t;if(t==="lttb")return oL;const e={first:r=>[r[0]],last:r=>[r[r.length-1]],min:(r,i,a)=>[r[bu(r,o=>a[o])]],max:(r,i,a)=>[r[to(r,o=>a[o])]],median:(r,i,a)=>[r[R5(r,o=>a[o])]]},n=e[t]||e.median;return(r,i,a,o)=>{const s=Math.max(1,Math.floor(r.length/o));return cL(r,s).flatMap(l=>n(l,i,a))}}function cL(t,e){const n=t.length,r=[];let i=0;for(;i{const{strategy:e="median",thresholds:n=2e3,groupBy:r=["series","color"]}=t,i=sL(e);return(a,o)=>{const{encode:s}=o,c=oi(r,a,o),[l]=Ot(s,"x"),[u]=Ot(s,"y");return[c.flatMap(f=>i(f,l,u,n)),o]}};Y2.props={};function lL(t){return typeof t=="object"?[t.value,t.ordinal]:[t,!0]}const W2=(t={})=>(e,n)=>{const{encode:r,data:i}=n,a=Object.entries(t).map(([u,f])=>{const[d]=Ot(r,u);if(!d)return null;const[h,p=!0]=lL(f);if(typeof h=="function")return v=>h(d[v]);if(p){const v=Array.isArray(h)?h:[h];return v.length===0?null:g=>v.includes(d[g])}else{const[v,g]=h;return y=>d[y]>=v&&d[y]<=g}}).filter(zt);if(a.length===0)return[e,n];const o=u=>a.every(f=>f(u)),s=e.filter(o),c=s.map((u,f)=>f),l=Object.entries(r).map(([u,f])=>[u,Object.assign(Object.assign({},f),{value:c.map(d=>f.value[s[d]]).filter(d=>d!==void 0)})]);return[c,X({},n,{encode:Object.fromEntries(l),data:s.map(u=>i[u])})]};W2.props={};function Ut(t){return function(){return t}}const Og=Math.abs,Re=Math.atan2,mi=Math.cos,uL=Math.max,Tf=Math.min,qn=Math.sin,va=Math.sqrt,Ie=1e-12,ls=Math.PI,El=ls/2,fL=2*ls;function dL(t){return t>1?0:t<-1?ls:Math.acos(t)}function Sg(t){return t>=1?El:t<=-1?-El:Math.asin(t)}const Wd=Math.PI,Hd=2*Wd,_i=1e-6,hL=Hd-_i;function H2(t){this._+=t[0];for(let e=1,n=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return H2;const n=10**e;return function(r){this._+=r[0];for(let i=1,a=r.length;i_i)if(!(Math.abs(f*c-l*u)>_i)||!a)this._append`L${this._x1=e},${this._y1=n}`;else{let h=r-o,p=i-s,v=c*c+l*l,g=h*h+p*p,y=Math.sqrt(v),m=Math.sqrt(d),b=a*Math.tan((Wd-Math.acos((v+d-g)/(2*y*m)))/2),x=b/m,w=b/y;Math.abs(x-1)>_i&&this._append`L${e+x*u},${n+x*f}`,this._append`A${a},${a},0,0,${+(f*h>u*p)},${this._x1=e+w*c},${this._y1=n+w*l}`}}arc(e,n,r,i,a,o){if(e=+e,n=+n,r=+r,o=!!o,r<0)throw new Error(`negative radius: ${r}`);let s=r*Math.cos(i),c=r*Math.sin(i),l=e+s,u=n+c,f=1^o,d=o?i-a:a-i;this._x1===null?this._append`M${l},${u}`:(Math.abs(this._x1-l)>_i||Math.abs(this._y1-u)>_i)&&this._append`L${l},${u}`,r&&(d<0&&(d=d%Hd+Hd),d>hL?this._append`A${r},${r},0,1,${f},${e-s},${n-c}A${r},${r},0,1,${f},${this._x1=l},${this._y1=u}`:d>_i&&this._append`A${r},${r},0,${+(d>=Wd)},${f},${this._x1=e+r*Math.cos(a)},${this._y1=n+r*Math.sin(a)}`)}rect(e,n,r,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+n}h${r=+r}v${+i}h${-r}Z`}toString(){return this._}};function jn(){return new Cp}jn.prototype=Cp.prototype;function Lp(t){let e=3;return t.digits=function(n){if(!arguments.length)return e;if(n==null)e=null;else{const r=Math.floor(n);if(!(r>=0))throw new RangeError(`invalid digits: ${n}`);e=r}return t},()=>new Cp(e)}function vL(t){return t.innerRadius}function gL(t){return t.outerRadius}function yL(t){return t.startAngle}function mL(t){return t.endAngle}function bL(t){return t&&t.padAngle}function xL(t,e,n,r,i,a,o,s){var c=n-t,l=r-e,u=o-i,f=s-a,d=f*c-u*l;if(!(d*dk*k+C*C&&(_=E,M=P),{cx:_,cy:M,x01:-u,y01:-f,x11:_*(i/w-1),y11:M*(i/w-1)}}function Cu(){var t=vL,e=gL,n=Ut(0),r=null,i=yL,a=mL,o=bL,s=null,c=Lp(l);function l(){var u,f,d=+t.apply(this,arguments),h=+e.apply(this,arguments),p=i.apply(this,arguments)-El,v=a.apply(this,arguments)-El,g=Og(v-p),y=v>p;if(s||(s=u=c()),hIe))s.moveTo(0,0);else if(g>fL-Ie)s.moveTo(h*mi(p),h*qn(p)),s.arc(0,0,h,p,v,!y),d>Ie&&(s.moveTo(d*mi(v),d*qn(v)),s.arc(0,0,d,v,p,y));else{var m=p,b=v,x=p,w=v,O=g,S=g,_=o.apply(this,arguments)/2,M=_>Ie&&(r?+r.apply(this,arguments):va(d*d+h*h)),E=Tf(Og(h-d)/2,+n.apply(this,arguments)),P=E,T=E,A,k;if(M>Ie){var C=Sg(M/d*qn(_)),L=Sg(M/h*qn(_));(O-=C*2)>Ie?(C*=y?1:-1,x+=C,w-=C):(O=0,x=w=(p+v)/2),(S-=L*2)>Ie?(L*=y?1:-1,m+=L,b-=L):(S=0,m=b=(p+v)/2)}var I=h*mi(m),R=h*qn(m),j=d*mi(w),D=d*qn(w);if(E>Ie){var $=h*mi(b),B=h*qn(b),F=d*mi(x),Y=d*qn(x),U;if(gIe?T>Ie?(A=dc(F,Y,I,R,h,T,y),k=dc($,B,j,D,h,T,y),s.moveTo(A.cx+A.x01,A.cy+A.y01),TIe)||!(O>Ie)?s.lineTo(j,D):P>Ie?(A=dc(j,D,$,B,d,-P,y),k=dc(I,R,F,Y,d,-P,y),s.lineTo(A.cx+A.x01,A.cy+A.y01),P=h;--p)s.point(b[p],x[p]);s.lineEnd(),s.areaEnd()}y&&(b[d]=+t(g,d,f),x[d]=+e(g,d,f),s.point(r?+r(g,d,f):b[d],n?+n(g,d,f):x[d]))}if(m)return s=null,m+""||null}function u(){return Jr().defined(i).curve(o).context(a)}return l.x=function(f){return arguments.length?(t=typeof f=="function"?f:Ut(+f),r=null,l):t},l.x0=function(f){return arguments.length?(t=typeof f=="function"?f:Ut(+f),l):t},l.x1=function(f){return arguments.length?(r=f==null?null:typeof f=="function"?f:Ut(+f),l):r},l.y=function(f){return arguments.length?(e=typeof f=="function"?f:Ut(+f),n=null,l):e},l.y0=function(f){return arguments.length?(e=typeof f=="function"?f:Ut(+f),l):e},l.y1=function(f){return arguments.length?(n=f==null?null:typeof f=="function"?f:Ut(+f),l):n},l.lineX0=l.lineY0=function(){return u().x(t).y(e)},l.lineY1=function(){return u().x(t).y(n)},l.lineX1=function(){return u().x(r).y(e)},l.defined=function(f){return arguments.length?(i=typeof f=="function"?f:Ut(!!f),l):i},l.curve=function(f){return arguments.length?(o=f,a!=null&&(s=o(a)),l):o},l.context=function(f){return arguments.length?(f==null?a=s=null:s=o(a=f),l):a},l}var K2=Np(Ys);function Z2(t){this._curve=t}Z2.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};function Np(t){function e(n){return new Z2(t(n))}return e._curve=t,e}function Mo(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(n){return arguments.length?e(Np(n)):e()._curve},t}function wL(){return Mo(Jr().curve(K2))}function OL(){var t=Vd().curve(K2),e=t.curve,n=t.lineX0,r=t.lineX1,i=t.lineY0,a=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Mo(n())},delete t.lineX0,t.lineEndAngle=function(){return Mo(r())},delete t.lineX1,t.lineInnerRadius=function(){return Mo(i())},delete t.lineY0,t.lineOuterRadius=function(){return Mo(a())},delete t.lineY1,t.curve=function(o){return arguments.length?e(Np(o)):e()._curve},t}function Da(){}function Xd(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function Rp(t,e){this._context=t,this._k=(1-e)/6}Rp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Xd(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Xd(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(r){return new Rp(r,e)}return n.tension=function(r){return t(+r)},n})(0);function Ip(t,e){this._context=t,this._k=(1-e)/6}Ip.prototype={areaStart:Da,areaEnd:Da,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Xd(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(r){return new Ip(r,e)}return n.tension=function(r){return t(+r)},n})(0);function Q2(t,e,n){var r=t._x1,i=t._y1,a=t._x2,o=t._y2;if(t._l01_a>Ie){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>Ie){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,u=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*l+t._x1*t._l23_2a-e*t._l12_2a)/u,o=(o*l+t._y1*t._l23_2a-n*t._l12_2a)/u}t._context.bezierCurveTo(r,i,a,o,t._x2,t._y2)}function J2(t,e){this._context=t,this._alpha=e}J2.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Q2(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};(function t(e){function n(r){return e?new J2(r,e):new Rp(r,0)}return n.alpha=function(r){return t(+r)},n})(.5);function tw(t,e){this._context=t,this._alpha=e}tw.prototype={areaStart:Da,areaEnd:Da,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Q2(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const ew=function t(e){function n(r){return e?new tw(r,e):new Ip(r,0)}return n.alpha=function(r){return t(+r)},n}(.5);function nw(t){this._context=t}nw.prototype={areaStart:Da,areaEnd:Da,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function jp(t){return new nw(t)}function _g(t){return t<0?-1:1}function Mg(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),o=(n-t._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(_g(a)+_g(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Eg(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Cf(t,e,n){var r=t._x0,i=t._y0,a=t._x1,o=t._y1,s=(a-r)/3;t._context.bezierCurveTo(r+s,i+s*e,a-s,o-s*n,a,o)}function Pl(t){this._context=t}Pl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Cf(this,this._t0,Eg(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var n=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Cf(this,Eg(this,n=Mg(this,t,e)),n);break;default:Cf(this,this._t0,n=Mg(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=n}}};function rw(t){this._context=new iw(t)}(rw.prototype=Object.create(Pl.prototype)).point=function(t,e){Pl.prototype.point.call(this,e,t)};function iw(t){this._context=t}iw.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,n,r,i,a){this._context.bezierCurveTo(e,t,r,n,a,i)}};function aw(t){return new Pl(t)}function ow(t){return new rw(t)}function Lu(t,e){this._context=t,this._t=e}Lu.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}break}}this._x=t,this._y=e}};function sw(t){return new Lu(t,.5)}function cw(t){return new Lu(t,0)}function lw(t){return new Lu(t,1)}function qt(t){const{transformations:e}=t.getOptions();return e.map(([r])=>r).filter(r=>r==="transpose").length%2!==0}function Ht(t){const{transformations:e}=t.getOptions();return e.some(([n])=>n==="polar")}function Nu(t){const{transformations:e}=t.getOptions();return e.some(([n])=>n==="reflect")&&e.some(([n])=>n.startsWith("transpose"))}function uw(t){const{transformations:e}=t.getOptions();return e.some(([n])=>n==="helix")}function Ru(t){const{transformations:e}=t.getOptions();return e.some(([n])=>n==="parallel")}function fw(t){const{transformations:e}=t.getOptions();return e.some(([n])=>n==="fisheye")}function SL(t){return Ru(t)&&Ht(t)}function eo(t){return uw(t)||Ht(t)}function _L(t){return Ht(t)&&qt(t)}function ML(t){if(eo(t)){const[e,n]=t.getSize(),r=t.getOptions().transformations.find(i=>i[0]==="polar");if(r)return Math.max(e,n)/2*r[4]}return 0}function Iu(t){const{transformations:e}=t.getOptions(),[,,,n,r]=e.find(i=>i[0]==="polar");return[+n,+r]}function Dp(t,e=!0){const{transformations:n}=t.getOptions(),[,r,i]=n.find(a=>a[0]==="polar");return e?[+r*180/Math.PI,+i*180/Math.PI]:[r,i]}function EL(t,e){const{transformations:n}=t.getOptions(),[,...r]=n.find(i=>i[0]===e);return r}var dw={exports:{}};(function(t){var e=Object.prototype.hasOwnProperty,n="~";function r(){}Object.create&&(r.prototype=Object.create(null),new r().__proto__||(n=!1));function i(c,l,u){this.fn=c,this.context=l,this.once=u||!1}function a(c,l,u,f,d){if(typeof u!="function")throw new TypeError("The listener must be a function");var h=new i(u,f||c,d),p=n?n+l:l;return c._events[p]?c._events[p].fn?c._events[p]=[c._events[p],h]:c._events[p].push(h):(c._events[p]=h,c._eventsCount++),c}function o(c,l){--c._eventsCount===0?c._events=new r:delete c._events[l]}function s(){this._events=new r,this._eventsCount=0}s.prototype.eventNames=function(){var l=[],u,f;if(this._eventsCount===0)return l;for(f in u=this._events)e.call(u,f)&&l.push(n?f.slice(1):f);return Object.getOwnPropertySymbols?l.concat(Object.getOwnPropertySymbols(u)):l},s.prototype.listeners=function(l){var u=n?n+l:l,f=this._events[u];if(!f)return[];if(f.fn)return[f.fn];for(var d=0,h=f.length,p=new Array(h);d>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):n===8?hc(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):n===4?hc(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=kL.exec(t))?new yn(e[1],e[2],e[3],1):(e=TL.exec(t))?new yn(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=CL.exec(t))?hc(e[1],e[2],e[3],e[4]):(e=LL.exec(t))?hc(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=NL.exec(t))?Ng(e[1],e[2]/100,e[3]/100,1):(e=RL.exec(t))?Ng(e[1],e[2]/100,e[3]/100,e[4]):Pg.hasOwnProperty(t)?Tg(Pg[t]):t==="transparent"?new yn(NaN,NaN,NaN,0):null}function Tg(t){return new yn(t>>16&255,t>>8&255,t&255,1)}function hc(t,e,n,r){return r<=0&&(t=e=n=NaN),new yn(t,e,n,r)}function jL(t){return t instanceof Ws||(t=ju(t)),t?(t=t.rgb(),new yn(t.r,t.g,t.b,t.opacity)):new yn}function DL(t,e,n,r){return arguments.length===1?jL(t):new yn(t,e,n,r??1)}function yn(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}Bp(yn,DL,hw(Ws,{brighter:function(t){return t=t==null?Al:Math.pow(Al,t),new yn(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=t==null?us:Math.pow(us,t),new yn(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Cg,formatHex:Cg,formatRgb:Lg,toString:Lg}));function Cg(){return"#"+Lf(this.r)+Lf(this.g)+Lf(this.b)}function Lg(){var t=this.opacity;return t=isNaN(t)?1:Math.max(0,Math.min(1,t)),(t===1?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(t===1?")":", "+t+")")}function Lf(t){return t=Math.max(0,Math.min(255,Math.round(t)||0)),(t<16?"0":"")+t.toString(16)}function Ng(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new Qn(t,e,n,r)}function pw(t){if(t instanceof Qn)return new Qn(t.h,t.s,t.l,t.opacity);if(t instanceof Ws||(t=ju(t)),!t)return new Qn;if(t instanceof Qn)return t;t=t.rgb();var e=t.r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(e===a?o=(n-r)/s+(n0&&c<1?0:o,new Qn(o,s,c,t.opacity)}function $L(t,e,n,r){return arguments.length===1?pw(t):new Qn(t,e,n,r??1)}function Qn(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}Bp(Qn,$L,hw(Ws,{brighter:function(t){return t=t==null?Al:Math.pow(Al,t),new Qn(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=t==null?us:Math.pow(us,t),new Qn(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new yn(Nf(t>=240?t-240:t+120,i,r),Nf(t,i,r),Nf(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return t=isNaN(t)?1:Math.max(0,Math.min(1,t)),(t===1?"hsl(":"hsla(")+(this.h||0)+", "+(this.s||0)*100+"%, "+(this.l||0)*100+"%"+(t===1?")":", "+t+")")}}));function Nf(t,e,n){return(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)*255}function Pr(t,e,n,r){var i=t-n,a=e-r;return Math.sqrt(i*i+a*a)}function vw(t,e){var n=Math.min.apply(Math,q([],N(t),!1)),r=Math.min.apply(Math,q([],N(e),!1)),i=Math.max.apply(Math,q([],N(t),!1)),a=Math.max.apply(Math,q([],N(e),!1));return{x:n,y:r,width:i-n,height:a-r}}function BL(t,e,n){return Math.atan(-e/t*Math.tan(n))}function FL(t,e,n){return Math.atan(e/(t*Math.tan(n)))}function zL(t,e,n,r,i,a){return n*Math.cos(i)*Math.cos(a)-r*Math.sin(i)*Math.sin(a)+t}function GL(t,e,n,r,i,a){return n*Math.sin(i)*Math.cos(a)+r*Math.cos(i)*Math.sin(a)+e}function YL(t,e,n,r,i,a,o){for(var s=BL(n,r,i),c=1/0,l=-1/0,u=[a,o],f=-Math.PI*2;f<=Math.PI*2;f+=Math.PI){var d=s+f;al&&(l=h)}for(var p=FL(n,r,i),v=1/0,g=-1/0,y=[a,o],f=-Math.PI*2;f<=Math.PI*2;f+=Math.PI){var m=p+f;ag&&(g=b)}return{x:c,y:v,width:l-c,height:g-v}}var WL=1e-4;function gw(t,e,n,r,i,a){var o=-1,s=1/0,c=[n,r],l=20;a&&a>200&&(l=a/10);for(var u=1/l,f=u/10,d=0;d<=l;d++){var h=d*u,p=[i.apply(void 0,q([],N(t.concat([h])),!1)),i.apply(void 0,q([],N(e.concat([h])),!1))],v=Pr(c[0],c[1],p[0],p[1]);v=0&&v=0&&c<=1&&s.push(c));else{var f=a*a-4*i*o;Fo(f,0)?s.push(-a/(2*i)):f>0&&(u=Math.sqrt(f),c=(-a+u)/(2*i),l=(-a-u)/(2*i),c>=0&&c<=1&&s.push(c),l>=0&&l<=1&&s.push(l))}return s}function VL(t,e,n,r,i,a,o,s){for(var c=[t,o],l=[e,s],u=Rg(t,n,i,o),f=Rg(e,r,a,s),d=0;d=0?[i]:[]}function KL(t,e,n,r,i,a){var o=jg(t,n,i)[0],s=jg(e,r,a)[0],c=[t,i],l=[e,a];return o!==void 0&&c.push(qd(t,n,i,o)),s!==void 0&&l.push(qd(e,r,a,s)),vw(c,l)}function ZL(t,e,n,r,i,a,o,s){return gw([t,n,i],[e,r,a],o,s,qd)}function QL(t,e,n,r,i,a,o,s){var c=ZL(t,e,n,r,i,a,o,s);return Pr(c.x,c.y,o,s)}var JL=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},bw={exports:{}};(function(t,e){(function(n,r){t.exports=r()})(JL,function(){function n(w,O,S,_,M){r(w,O,S||0,_||w.length-1,M||a)}function r(w,O,S,_,M){for(;_>S;){if(_-S>600){var E=_-S+1,P=O-S+1,T=Math.log(E),A=.5*Math.exp(2*T/3),k=.5*Math.sqrt(T*A*(E-A)/E)*(P-E/2<0?-1:1),C=Math.max(S,Math.floor(O-P*A/E+k)),L=Math.min(_,Math.floor(O+(E-P)*A/E+k));r(w,O,C,L,M)}var I=w[O],R=S,j=_;for(i(w,S,O),M(w[_],I)>0&&i(w,S,_);R0;)j--}M(w[S],I)===0?i(w,S,j):(j++,i(w,j,_)),j<=O&&(S=j+1),O<=j&&(_=j-1)}}function i(w,O,S){var _=w[O];w[O]=w[S],w[S]=_}function a(w,O){return wO?1:0}var o=function(O){O===void 0&&(O=9),this._maxEntries=Math.max(4,O),this._minEntries=Math.max(2,Math.ceil(this._maxEntries*.4)),this.clear()};o.prototype.all=function(){return this._all(this.data,[])},o.prototype.search=function(O){var S=this.data,_=[];if(!m(O,S))return _;for(var M=this.toBBox,E=[];S;){for(var P=0;P=0&&E[S].children.length>this._maxEntries;)this._split(E,S),S--;this._adjustParentBBoxes(M,E,S)},o.prototype._split=function(O,S){var _=O[S],M=_.children.length,E=this._minEntries;this._chooseSplitAxis(_,E,M);var P=this._chooseSplitIndex(_,E,M),T=b(_.children.splice(P,_.children.length-P));T.height=_.height,T.leaf=_.leaf,c(_,this.toBBox),c(T,this.toBBox),S?O[S-1].children.push(T):this._splitRoot(_,T)},o.prototype._splitRoot=function(O,S){this.data=b([O,S]),this.data.height=O.height+1,this.data.leaf=!1,c(this.data,this.toBBox)},o.prototype._chooseSplitIndex=function(O,S,_){for(var M,E=1/0,P=1/0,T=S;T<=_-S;T++){var A=l(O,0,T,this.toBBox),k=l(O,T,_,this.toBBox),C=g(A,k),L=h(A)+h(k);C=S;L--){var I=O.children[L];u(T,O.leaf?E(I):I),A+=p(T)}return A},o.prototype._adjustParentBBoxes=function(O,S,_){for(var M=_;M>=0;M--)u(S[M],O)},o.prototype._condense=function(O){for(var S=O.length-1,_=void 0;S>=0;S--)O[S].children.length===0?S>0?(_=O[S-1].children,_.splice(_.indexOf(O[S]),1)):this.clear():c(O[S],this.toBBox)};function s(w,O,S){if(!S)return O.indexOf(w);for(var _=0;_=w.minX&&O.maxY>=w.minY}function b(w){return{children:w,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function x(w,O,S,_,M){for(var E=[O,S];E.length;)if(S=E.pop(),O=E.pop(),!(S-O<=_)){var P=O+Math.ceil((S-O)/_/2)*_;n(w,P,O,S,M),E.push(O,P,P,S)}}return o})})(bw);var tN=bw.exports,G;(function(t){t.GROUP="g",t.CIRCLE="circle",t.ELLIPSE="ellipse",t.IMAGE="image",t.RECT="rect",t.LINE="line",t.POLYLINE="polyline",t.POLYGON="polygon",t.TEXT="text",t.PATH="path",t.HTML="html",t.MESH="mesh"})(G||(G={}));var wa;(function(t){t[t.ZERO=0]="ZERO",t[t.NEGATIVE_ONE=1]="NEGATIVE_ONE"})(wa||(wa={}));var ci=function(){function t(){this.plugins=[]}return t.prototype.addRenderingPlugin=function(e){this.plugins.push(e),this.context.renderingPlugins.push(e)},t.prototype.removeAllRenderingPlugins=function(){var e=this;this.plugins.forEach(function(n){var r=e.context.renderingPlugins.indexOf(n);r>=0&&e.context.renderingPlugins.splice(r,1)})},t}(),eN=function(){function t(e){this.clipSpaceNearZ=wa.NEGATIVE_ONE,this.plugins=[],this.config=z({enableDirtyCheck:!0,enableCulling:!1,enableAutoRendering:!0,enableDirtyRectangleRendering:!0,enableDirtyRectangleRenderingDebug:!1},e)}return t.prototype.registerPlugin=function(e){var n=this.plugins.findIndex(function(r){return r===e});n===-1&&this.plugins.push(e)},t.prototype.unregisterPlugin=function(e){var n=this.plugins.findIndex(function(r){return r===e});n>-1&&this.plugins.splice(n,1)},t.prototype.getPlugins=function(){return this.plugins},t.prototype.getPlugin=function(e){return this.plugins.find(function(n){return n.name===e})},t.prototype.getConfig=function(){return this.config},t.prototype.setConfig=function(e){Object.assign(this.config,e)},t}();function na(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}function Rf(t,e,n){return t[0]=e[0]-n[0],t[1]=e[1]-n[1],t[2]=e[2]-n[2],t}function el(t,e,n){return t[0]=e[0]+n[0],t[1]=e[1]+n[1],t[2]=e[2]+n[2],t}function Dg(t,e,n){return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t}function nN(t,e,n){return t[0]=Math.max(e[0],n[0]),t[1]=Math.max(e[1],n[1]),t[2]=Math.max(e[2],n[2]),t}function rN(t,e,n){return t[0]=Math.min(e[0],n[0]),t[1]=Math.min(e[1],n[1]),t[2]=Math.min(e[2],n[2]),t}function Oa(t){return t===void 0?0:t>360||t<-360?t%360:t}function We(t,e,n){return e===void 0&&(e=0),n===void 0&&(n=0),Array.isArray(t)&&t.length===3?br(t):de(t)?St(t,e,n):St(t[0],t[1]||e,t[2]||n)}function re(t){return t*(Math.PI/180)}function Pn(t){return t*(180/Math.PI)}function iN(t){return 360*t}function aN(t,e){var n=e[0],r=e[1],i=e[2],a=e[3],o=n*n,s=r*r,c=i*i,l=a*a,u=o+s+c+l,f=n*a-r*i;return f>.499995*u?(t[0]=Math.PI/2,t[1]=2*Math.atan2(r,n),t[2]=0):f<-.499995*u?(t[0]=-Math.PI/2,t[1]=2*Math.atan2(r,n),t[2]=0):(t[0]=Math.asin(2*(n*i-a*r)),t[1]=Math.atan2(2*(n*a+r*i),1-2*(c+l)),t[2]=Math.atan2(2*(n*r+i*a),1-2*(s+c))),t}function oN(t,e){var n,r,i=Math.PI*.5,a=N(Aa(yt(),e),3),o=a[0],s=a[1],c=a[2],l=Math.asin(-e[2]/o);return l-i?(n=Math.atan2(e[6]/s,e[10]/c),r=Math.atan2(e[1]/o,e[0]/o)):(r=0,n=-Math.atan2(e[4]/s,e[5]/s)):(r=0,n=Math.atan2(e[4]/s,e[5]/s)),t[0]=n,t[1]=l,t[2]=r,t}function If(t,e){return e.length===16?oN(t,e):aN(t,e)}function sN(t,e,n,r,i){var a=Math.cos(t),o=Math.sin(t);return Yk(r*a,i*o,0,-r*o,i*a,0,e,n,1)}function cN(t,e,n,r,i,a,o,s){s===void 0&&(s=!1);var c=2*a/(n-e),l=2*a/(r-i),u=(n+e)/(n-e),f=(r+i)/(r-i),d,h;return s?(d=-o/(o-a),h=-o*a/(o-a)):(d=-(o+a)/(o-a),h=-2*o*a/(o-a)),t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=l,t[6]=0,t[7]=0,t[8]=u,t[9]=f,t[10]=d,t[11]=-1,t[12]=0,t[13]=0,t[14]=h,t[15]=0,t}function $g(t){var e=t[0],n=t[1],r=t[3],i=t[4],a=Math.sqrt(e*e+n*n),o=Math.sqrt(r*r+i*i),s=e*i-n*r;s<0&&(eft[1][2]&&(a[0]=-a[0]),ft[0][2]>ft[2][0]&&(a[1]=-a[1]),ft[1][0]>ft[0][1]&&(a[2]=-a[2]),!0}function uN(t,e){var n=e[15];if(n===0)return!1;for(var r=1/n,i=0;i<16;i++)t[i]=e[i]*r;return!0}function fN(t,e){t[0][0]=e[0],t[0][1]=e[1],t[0][2]=e[2],t[1][0]=e[4],t[1][1]=e[5],t[1][2]=e[6],t[2][0]=e[8],t[2][1]=e[9],t[2][2]=e[10]}function jf(t,e,n,r,i){t[0]=e[0]*r+n[0]*i,t[1]=e[1]*r+n[1]*i,t[2]=e[2]*r+n[2]*i}var be=function(){function t(){this.center=[0,0,0],this.halfExtents=[0,0,0],this.min=[0,0,0],this.max=[0,0,0]}return t.isEmpty=function(e){return!e||e.halfExtents[0]===0&&e.halfExtents[1]===0&&e.halfExtents[2]===0},t.prototype.update=function(e,n){na(this.center,e),na(this.halfExtents,n),Rf(this.min,this.center,this.halfExtents),el(this.max,this.center,this.halfExtents)},t.prototype.setMinMax=function(e,n){el(this.center,n,e),Dg(this.center,this.center,.5),Rf(this.halfExtents,n,e),Dg(this.halfExtents,this.halfExtents,.5),na(this.min,e),na(this.max,n)},t.prototype.getMin=function(){return this.min},t.prototype.getMax=function(){return this.max},t.prototype.add=function(e){if(!t.isEmpty(e)){if(t.isEmpty(this)){this.setMinMax(e.getMin(),e.getMax());return}var n=this.center,r=n[0],i=n[1],a=n[2],o=this.halfExtents,s=o[0],c=o[1],l=o[2],u=r-s,f=r+s,d=i-c,h=i+c,p=a-l,v=a+l,g=e.center,y=g[0],m=g[1],b=g[2],x=e.halfExtents,w=x[0],O=x[1],S=x[2],_=y-w,M=y+w,E=m-O,P=m+O,T=b-S,A=b+S;_f&&(f=M),Eh&&(h=P),Tv&&(v=A),n[0]=(u+f)*.5,n[1]=(d+h)*.5,n[2]=(p+v)*.5,o[0]=(f-u)*.5,o[1]=(h-d)*.5,o[2]=(v-p)*.5,this.min[0]=u,this.min[1]=d,this.min[2]=p,this.max[0]=f,this.max[1]=h,this.max[2]=v}},t.prototype.setFromTransformedAABB=function(e,n){var r=this.center,i=this.halfExtents,a=e.center,o=e.halfExtents,s=n[0],c=n[4],l=n[8],u=n[1],f=n[5],d=n[9],h=n[2],p=n[6],v=n[10],g=Math.abs(s),y=Math.abs(c),m=Math.abs(l),b=Math.abs(u),x=Math.abs(f),w=Math.abs(d),O=Math.abs(h),S=Math.abs(p),_=Math.abs(v);r[0]=n[12]+s*a[0]+c*a[1]+l*a[2],r[1]=n[13]+u*a[0]+f*a[1]+d*a[2],r[2]=n[14]+h*a[0]+p*a[1]+v*a[2],i[0]=g*o[0]+y*o[1]+m*o[2],i[1]=b*o[0]+x*o[1]+w*o[2],i[2]=O*o[0]+S*o[1]+_*o[2],Rf(this.min,r,i),el(this.max,r,i)},t.prototype.intersects=function(e){var n=this.getMax(),r=this.getMin(),i=e.getMax(),a=e.getMin();return r[0]<=i[0]&&n[0]>=a[0]&&r[1]<=i[1]&&n[1]>=a[1]&&r[2]<=i[2]&&n[2]>=a[2]},t.prototype.intersection=function(e){if(!this.intersects(e))return null;var n=new t,r=nN([0,0,0],this.getMin(),e.getMin()),i=rN([0,0,0],this.getMax(),e.getMax());return n.setMinMax(r,i),n},t.prototype.getNegativeFarPoint=function(e){return e.pnVertexFlag===273?na([0,0,0],this.min):e.pnVertexFlag===272?[this.min[0],this.min[1],this.max[2]]:e.pnVertexFlag===257?[this.min[0],this.max[1],this.min[2]]:e.pnVertexFlag===256?[this.min[0],this.max[1],this.max[2]]:e.pnVertexFlag===17?[this.max[0],this.min[1],this.min[2]]:e.pnVertexFlag===16?[this.max[0],this.min[1],this.max[2]]:e.pnVertexFlag===1?[this.max[0],this.max[1],this.min[2]]:[this.max[0],this.max[1],this.max[2]]},t.prototype.getPositiveFarPoint=function(e){return e.pnVertexFlag===273?na([0,0,0],this.max):e.pnVertexFlag===272?[this.max[0],this.max[1],this.min[2]]:e.pnVertexFlag===257?[this.max[0],this.min[1],this.max[2]]:e.pnVertexFlag===256?[this.max[0],this.min[1],this.min[2]]:e.pnVertexFlag===17?[this.min[0],this.max[1],this.max[2]]:e.pnVertexFlag===16?[this.min[0],this.max[1],this.min[2]]:e.pnVertexFlag===1?[this.min[0],this.min[1],this.max[2]]:[this.min[0],this.min[1],this.min[2]]},t}(),dN=function(){function t(e,n){this.distance=e||0,this.normal=n||St(0,1,0),this.updatePNVertexFlag()}return t.prototype.updatePNVertexFlag=function(){this.pnVertexFlag=(+(this.normal[0]>=0)<<8)+(+(this.normal[1]>=0)<<4)+ +(this.normal[2]>=0)},t.prototype.distanceToPoint=function(e){return nr(e,this.normal)-this.distance},t.prototype.normalize=function(){var e=1/tx(this.normal);Cd(this.normal,this.normal,e),this.distance*=e},t.prototype.intersectsLine=function(e,n,r){var i=this.distanceToPoint(e),a=this.distanceToPoint(n),o=i/(i-a),s=o>=0&&o<=1;return s&&r&&Ld(r,e,n,o),s},t}(),zr;(function(t){t[t.OUTSIDE=4294967295]="OUTSIDE",t[t.INSIDE=0]="INSIDE",t[t.INDETERMINATE=2147483647]="INDETERMINATE"})(zr||(zr={}));var hN=function(){function t(e){if(this.planes=[],e)this.planes=e;else for(var n=0;n<6;n++)this.planes.push(new dN)}return t.prototype.extractFromVPMatrix=function(e){var n=N(e,16),r=n[0],i=n[1],a=n[2],o=n[3],s=n[4],c=n[5],l=n[6],u=n[7],f=n[8],d=n[9],h=n[10],p=n[11],v=n[12],g=n[13],y=n[14],m=n[15];Gn(this.planes[0].normal,o-r,u-s,p-f),this.planes[0].distance=m-v,Gn(this.planes[1].normal,o+r,u+s,p+f),this.planes[1].distance=m+v,Gn(this.planes[2].normal,o+i,u+c,p+d),this.planes[2].distance=m+g,Gn(this.planes[3].normal,o-i,u-c,p-d),this.planes[3].distance=m-g,Gn(this.planes[4].normal,o-a,u-l,p-h),this.planes[4].distance=m-y,Gn(this.planes[5].normal,o+a,u+l,p+h),this.planes[5].distance=m+y,this.planes.forEach(function(b){b.normalize(),b.updatePNVertexFlag()})},t}(),Ee=function(){function t(e,n){e===void 0&&(e=0),n===void 0&&(n=0),this.x=0,this.y=0,this.x=e,this.y=n}return t.prototype.clone=function(){return new t(this.x,this.y)},t.prototype.copyFrom=function(e){this.x=e.x,this.y=e.y},t}(),Fi=function(){function t(e,n,r,i){this.x=e,this.y=n,this.width=r,this.height=i,this.left=e,this.right=e+r,this.top=n,this.bottom=n+i}return t.prototype.toJSON=function(){},t}(),It="Method not implemented.",ra="Use document.documentElement instead.",pN="Cannot append a destroyed element.",Tt;(function(t){t[t.ORBITING=0]="ORBITING",t[t.EXPLORING=1]="EXPLORING",t[t.TRACKING=2]="TRACKING"})(Tt||(Tt={}));var ds;(function(t){t[t.DEFAULT=0]="DEFAULT",t[t.ROTATIONAL=1]="ROTATIONAL",t[t.TRANSLATIONAL=2]="TRANSLATIONAL",t[t.CINEMATIC=3]="CINEMATIC"})(ds||(ds={}));var tn;(function(t){t[t.ORTHOGRAPHIC=0]="ORTHOGRAPHIC",t[t.PERSPECTIVE=1]="PERSPECTIVE"})(tn||(tn={}));var xw={UPDATED:"updated"},Fg=2e-4,ww=function(){function t(){this.clipSpaceNearZ=wa.NEGATIVE_ONE,this.eventEmitter=new $p,this.matrix=Nt(),this.right=St(1,0,0),this.up=St(0,1,0),this.forward=St(0,0,1),this.position=St(0,0,1),this.focalPoint=St(0,0,0),this.distanceVector=St(0,0,-1),this.distance=1,this.azimuth=0,this.elevation=0,this.roll=0,this.relAzimuth=0,this.relElevation=0,this.relRoll=0,this.dollyingStep=0,this.maxDistance=1/0,this.minDistance=-1/0,this.zoom=1,this.rotateWorld=!1,this.fov=30,this.near=.1,this.far=1e3,this.aspect=1,this.projectionMatrix=Nt(),this.projectionMatrixInverse=Nt(),this.jitteredProjectionMatrix=void 0,this.enableUpdate=!0,this.type=Tt.EXPLORING,this.trackingMode=ds.DEFAULT,this.projectionMode=tn.PERSPECTIVE,this.frustum=new hN,this.orthoMatrix=Nt()}return t.prototype.isOrtho=function(){return this.projectionMode===tn.ORTHOGRAPHIC},t.prototype.getProjectionMode=function(){return this.projectionMode},t.prototype.getPerspective=function(){return this.jitteredProjectionMatrix||this.projectionMatrix},t.prototype.getPerspectiveInverse=function(){return this.projectionMatrixInverse},t.prototype.getFrustum=function(){return this.frustum},t.prototype.getPosition=function(){return this.position},t.prototype.getFocalPoint=function(){return this.focalPoint},t.prototype.getDollyingStep=function(){return this.dollyingStep},t.prototype.getNear=function(){return this.near},t.prototype.getFar=function(){return this.far},t.prototype.getZoom=function(){return this.zoom},t.prototype.getOrthoMatrix=function(){return this.orthoMatrix},t.prototype.getView=function(){return this.view},t.prototype.setEnableUpdate=function(e){this.enableUpdate=e},t.prototype.setType=function(e,n){return this.type=e,this.type===Tt.EXPLORING?this.setWorldRotation(!0):this.setWorldRotation(!1),this._getAngles(),this.type===Tt.TRACKING&&n!==void 0&&this.setTrackingMode(n),this},t.prototype.setProjectionMode=function(e){return this.projectionMode=e,this},t.prototype.setTrackingMode=function(e){if(this.type!==Tt.TRACKING)throw new Error("Impossible to set a tracking mode if the camera is not of tracking type");return this.trackingMode=e,this},t.prototype.setWorldRotation=function(e){return this.rotateWorld=e,this._getAngles(),this},t.prototype.getViewTransform=function(){return Wn(Nt(),this.matrix)},t.prototype.getWorldTransform=function(){return this.matrix},t.prototype.jitterProjectionMatrix=function(e,n){var r=up(Nt(),[e,n,0]);this.jitteredProjectionMatrix=$e(Nt(),r,this.projectionMatrix)},t.prototype.clearJitterProjectionMatrix=function(){this.jitteredProjectionMatrix=void 0},t.prototype.setMatrix=function(e){return this.matrix=e,this._update(),this},t.prototype.setFov=function(e){return this.setPerspective(this.near,this.far,e,this.aspect),this},t.prototype.setAspect=function(e){return this.setPerspective(this.near,this.far,this.fov,e),this},t.prototype.setNear=function(e){return this.projectionMode===tn.PERSPECTIVE?this.setPerspective(e,this.far,this.fov,this.aspect):this.setOrthographic(this.left,this.rright,this.top,this.bottom,e,this.far),this},t.prototype.setFar=function(e){return this.projectionMode===tn.PERSPECTIVE?this.setPerspective(this.near,e,this.fov,this.aspect):this.setOrthographic(this.left,this.rright,this.top,this.bottom,this.near,e),this},t.prototype.setViewOffset=function(e,n,r,i,a,o){return this.aspect=e/n,this.view===void 0&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=n,this.view.offsetX=r,this.view.offsetY=i,this.view.width=a,this.view.height=o,this.projectionMode===tn.PERSPECTIVE?this.setPerspective(this.near,this.far,this.fov,this.aspect):this.setOrthographic(this.left,this.rright,this.top,this.bottom,this.near,this.far),this},t.prototype.clearViewOffset=function(){return this.view!==void 0&&(this.view.enabled=!1),this.projectionMode===tn.PERSPECTIVE?this.setPerspective(this.near,this.far,this.fov,this.aspect):this.setOrthographic(this.left,this.rright,this.top,this.bottom,this.near,this.far),this},t.prototype.setZoom=function(e){return this.zoom=e,this.projectionMode===tn.ORTHOGRAPHIC?this.setOrthographic(this.left,this.rright,this.top,this.bottom,this.near,this.far):this.projectionMode===tn.PERSPECTIVE&&this.setPerspective(this.near,this.far,this.fov,this.aspect),this},t.prototype.setZoomByViewportPoint=function(e,n){var r=this.canvas.viewport2Canvas({x:n[0],y:n[1]}),i=r.x,a=r.y,o=this.roll;this.rotate(0,0,-o),this.setPosition(i,a),this.setFocalPoint(i,a),this.setZoom(e),this.rotate(0,0,o);var s=this.canvas.viewport2Canvas({x:n[0],y:n[1]}),c=s.x,l=s.y,u=St(c-i,l-a,0),f=nr(u,this.right)/wr(this.right),d=nr(u,this.up)/wr(this.up);return this.pan(-f,-d),this},t.prototype.setPerspective=function(e,n,r,i){var a;this.projectionMode=tn.PERSPECTIVE,this.fov=r,this.near=e,this.far=n,this.aspect=i;var o=this.near*Math.tan(re(.5*this.fov))/this.zoom,s=2*o,c=this.aspect*s,l=-.5*c;if(!((a=this.view)===null||a===void 0)&&a.enabled){var u=this.view.fullWidth,f=this.view.fullHeight;l+=this.view.offsetX*c/u,o-=this.view.offsetY*s/f,c*=this.view.width/u,s*=this.view.height/f}return cN(this.projectionMatrix,l,l+c,o,o-s,e,this.far,this.clipSpaceNearZ===wa.ZERO),vl(this.projectionMatrix,this.projectionMatrix,St(1,-1,1)),Wn(this.projectionMatrixInverse,this.projectionMatrix),this.triggerUpdate(),this},t.prototype.setOrthographic=function(e,n,r,i,a,o){var s;this.projectionMode=tn.ORTHOGRAPHIC,this.rright=n,this.left=e,this.top=r,this.bottom=i,this.near=a,this.far=o;var c=(this.rright-this.left)/(2*this.zoom),l=(this.top-this.bottom)/(2*this.zoom),u=(this.rright+this.left)/2,f=(this.top+this.bottom)/2,d=u-c,h=u+c,p=f+l,v=f-l;if(!((s=this.view)===null||s===void 0)&&s.enabled){var g=(this.rright-this.left)/this.view.fullWidth/this.zoom,y=(this.top-this.bottom)/this.view.fullHeight/this.zoom;d+=g*this.view.offsetX,h=d+g*this.view.width,p-=y*this.view.offsetY,v=p-y*this.view.height}return this.clipSpaceNearZ===wa.NEGATIVE_ONE?Ub(this.projectionMatrix,d,h,v,p,a,o):qb(this.projectionMatrix,d,h,v,p,a,o),vl(this.projectionMatrix,this.projectionMatrix,St(1,-1,1)),Wn(this.projectionMatrixInverse,this.projectionMatrix),this._getOrthoMatrix(),this.triggerUpdate(),this},t.prototype.setPosition=function(e,n,r){n===void 0&&(n=this.position[1]),r===void 0&&(r=this.position[2]);var i=We(e,n,r);return this._setPosition(i),this.setFocalPoint(this.focalPoint),this.triggerUpdate(),this},t.prototype.setFocalPoint=function(e,n,r){n===void 0&&(n=this.focalPoint[1]),r===void 0&&(r=this.focalPoint[2]);var i=St(0,1,0);if(this.focalPoint=We(e,n,r),this.trackingMode===ds.CINEMATIC){var a=qv(yt(),this.focalPoint,this.position);e=a[0],n=a[1],r=a[2];var o=wr(a),s=Pn(Math.asin(n/o)),c=90+Pn(Math.atan2(r,e)),l=Nt();Wb(l,l,re(c)),Yb(l,l,re(s)),i=Oe(yt(),[0,1,0],l)}return Wn(this.matrix,Kb(Nt(),this.position,this.focalPoint,i)),this._getAxes(),this._getDistance(),this._getAngles(),this.triggerUpdate(),this},t.prototype.getDistance=function(){return this.distance},t.prototype.getDistanceVector=function(){return this.distanceVector},t.prototype.setDistance=function(e){if(this.distance===e||e<0)return this;this.distance=e,this.distance=Z.kEms&&e=ti.kUnitType&&this.getType()<=ti.kClampType},t}(),xN=function(t){rt(e,t);function e(n){var r=t.call(this)||this;return r.colorSpace=n,r}return e.prototype.getType=function(){return ti.kColorType},e.prototype.to=function(n){return this},e}(Du),rr;(function(t){t[t.Constant=0]="Constant",t[t.LinearGradient=1]="LinearGradient",t[t.RadialGradient=2]="RadialGradient"})(rr||(rr={}));var pc=function(t){rt(e,t);function e(n,r){var i=t.call(this)||this;return i.type=n,i.value=r,i}return e.prototype.clone=function(){return new e(this.type,this.value)},e.prototype.buildCSSText=function(n,r,i){return i},e.prototype.getType=function(){return ti.kColorType},e}(Du),sn=function(t){rt(e,t);function e(n){var r=t.call(this)||this;return r.value=n,r}return e.prototype.clone=function(){return new e(this.value)},e.prototype.getType=function(){return ti.kKeywordType},e.prototype.buildCSSText=function(n,r,i){return i+this.value},e}(Du),wN=Ne(function(t){return t===void 0&&(t=""),t.replace(/-([a-z])/g,function(e){return e[1].toUpperCase()})}),Yg=function(t){return t.split("").map(function(e,n){return e.toUpperCase()===e?"".concat(n!==0?"-":"").concat(e.toLowerCase()):e}).join("")};function ON(t){if(!t)throw new Error}function ga(t){return typeof t=="function"}function SN(t){return typeof t=="symbol"}var _N={d:{alias:"path"},strokeDasharray:{alias:"lineDash"},strokeWidth:{alias:"lineWidth"},textAnchor:{alias:"textAlign"},src:{alias:"img"}},Jd=Ne(function(t){var e=wN(t),n=_N[e];return e=(n==null?void 0:n.alias)||e,e}),MN=function(t,e){e===void 0&&(e="");var n="";return Number.isFinite(t)?(ON(Number.isNaN(t)),n="NaN"):t>0?n="infinity":n="-infinity",n+=e},th=function(t){return bN(mN(t))},jt=function(t){rt(e,t);function e(n,r){r===void 0&&(r=Z.kNumber);var i=t.call(this)||this,a;return typeof r=="string"?a=yN(r):a=r,i.unit=a,i.value=n,i}return e.prototype.clone=function(){return new e(this.value,this.unit)},e.prototype.equals=function(n){var r=n;return this.value===r.value&&this.unit===r.unit},e.prototype.getType=function(){return ti.kUnitType},e.prototype.convertTo=function(n){if(this.unit===n)return new e(this.value,this.unit);var r=th(this.unit);if(r!==th(n)||r===Z.kUnknown)return null;var i=Gg(this.unit)/Gg(n);return new e(this.value*i,n)},e.prototype.buildCSSText=function(n,r,i){var a;switch(this.unit){case Z.kUnknown:break;case Z.kInteger:a=Number(this.value).toFixed(0);break;case Z.kNumber:case Z.kPercentage:case Z.kEms:case Z.kRems:case Z.kPixels:case Z.kDegrees:case Z.kRadians:case Z.kGradians:case Z.kMilliseconds:case Z.kSeconds:case Z.kTurns:{var o=-999999,s=999999,c=this.value,l=Qd(this.unit);if(cs){var u=Qd(this.unit);!Number.isFinite(c)||Number.isNaN(c)?a=MN(c,u):a=c+(u||"")}else a="".concat(c).concat(l)}}return i+=a,i},e}(Du),we=new jt(0,"px");new jt(1,"px");var Hn=new jt(0,"deg"),Fp=function(t){rt(e,t);function e(n,r,i,a,o){a===void 0&&(a=1),o===void 0&&(o=!1);var s=t.call(this,"rgb")||this;return s.r=n,s.g=r,s.b=i,s.alpha=a,s.isNone=o,s}return e.prototype.clone=function(){return new e(this.r,this.g,this.b,this.alpha)},e.prototype.buildCSSText=function(n,r,i){return i+"rgba(".concat(this.r,",").concat(this.g,",").concat(this.b,",").concat(this.alpha,")")},e}(xN),Gt=new sn("unset"),EN=new sn("initial"),PN=new sn("inherit"),Df={"":Gt,unset:Gt,initial:EN,inherit:PN},eh=function(t){return Df[t]||(Df[t]=new sn(t)),Df[t]},nh=new Fp(0,0,0,0,!0),Ow=new Fp(0,0,0,0),AN=Ne(function(t,e,n,r){return new Fp(t,e,n,r)},function(t,e,n,r){return"rgba(".concat(t,",").concat(e,",").concat(n,",").concat(r,")")}),Ft=function(t,e){return e===void 0&&(e=Z.kNumber),new jt(t,e)},kl=new jt(50,"%"),rh;(function(t){t[t.Standard=0]="Standard"})(rh||(rh={}));var $a;(function(t){t[t.ADDED=0]="ADDED",t[t.REMOVED=1]="REMOVED",t[t.Z_INDEX_CHANGED=2]="Z_INDEX_CHANGED"})($a||($a={}));var Sw={absolutePath:[],hasArc:!1,segments:[],polygons:[],polylines:[],curve:null,totalLength:0,rect:new Fi(0,0,0,0)},tt;(function(t){t.COORDINATE="",t.COLOR="",t.PAINT="",t.NUMBER="",t.ANGLE="",t.OPACITY_VALUE="",t.SHADOW_BLUR="",t.LENGTH="",t.PERCENTAGE="",t.LENGTH_PERCENTAGE=" | ",t.LENGTH_PERCENTAGE_12="[ | ]{1,2}",t.LENGTH_PERCENTAGE_14="[ | ]{1,4}",t.LIST_OF_POINTS="",t.PATH="",t.FILTER="",t.Z_INDEX="",t.OFFSET_DISTANCE="",t.DEFINED_PATH="",t.MARKER="",t.TRANSFORM="",t.TRANSFORM_ORIGIN="",t.TEXT="",t.TEXT_TRANSFORM=""})(tt||(tt={}));function kN(t){var e=t.type,n=t.value;return e==="hex"?"#".concat(n):e==="literal"?n:e==="rgb"?"rgb(".concat(n.join(","),")"):"rgba(".concat(n.join(","),")")}var TN=function(){var t={linearGradient:/^(linear\-gradient)/i,repeatingLinearGradient:/^(repeating\-linear\-gradient)/i,radialGradient:/^(radial\-gradient)/i,repeatingRadialGradient:/^(repeating\-radial\-gradient)/i,conicGradient:/^(conic\-gradient)/i,sideOrCorner:/^to (left (top|bottom)|right (top|bottom)|top (left|right)|bottom (left|right)|left|right|top|bottom)/i,extentKeywords:/^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,positionKeywords:/^(left|center|right|top|bottom)/i,pixelValue:/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,percentageValue:/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,emValue:/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,angleValue:/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,startCall:/^\(/,endCall:/^\)/,comma:/^,/,hexColor:/^\#([0-9a-fA-F]+)/,literalColor:/^([a-zA-Z]+)/,rgbColor:/^rgb/i,rgbaColor:/^rgba/i,number:/^(([0-9]*\.[0-9]+)|([0-9]+\.?))/},e="";function n(I){throw new Error(e+": "+I)}function r(){var I=i();return e.length>0&&n("Invalid input not EOF"),I}function i(){return b(a)}function a(){return o("linear-gradient",t.linearGradient,c)||o("repeating-linear-gradient",t.repeatingLinearGradient,c)||o("radial-gradient",t.radialGradient,f)||o("repeating-radial-gradient",t.repeatingRadialGradient,f)||o("conic-gradient",t.conicGradient,f)}function o(I,R,j){return s(R,function(D){var $=j();return $&&(C(t.comma)||n("Missing comma before color stops")),{type:I,orientation:$,colorStops:b(x)}})}function s(I,R){var j=C(I);if(j){C(t.startCall)||n("Missing (");var D=R(j);return C(t.endCall)||n("Missing )"),D}}function c(){return l()||u()}function l(){return k("directional",t.sideOrCorner,1)}function u(){return k("angular",t.angleValue,1)}function f(){var I,R=d(),j;return R&&(I=[],I.push(R),j=e,C(t.comma)&&(R=d(),R?I.push(R):e=j)),I}function d(){var I=h()||p();if(I)I.at=g();else{var R=v();if(R){I=R;var j=g();j&&(I.at=j)}else{var D=y();D&&(I={type:"default-radial",at:D})}}return I}function h(){var I=k("shape",/^(circle)/i,0);return I&&(I.style=A()||v()),I}function p(){var I=k("shape",/^(ellipse)/i,0);return I&&(I.style=P()||v()),I}function v(){return k("extent-keyword",t.extentKeywords,1)}function g(){if(k("position",/^at/,0)){var I=y();return I||n("Missing positioning value"),I}}function y(){var I=m();if(I.x||I.y)return{type:"position",value:I}}function m(){return{x:P(),y:P()}}function b(I){var R=I(),j=[];if(R)for(j.push(R);C(t.comma);)R=I(),R?j.push(R):n("One extra comma");return j}function x(){var I=w();return I||n("Expected color definition"),I.length=P(),I}function w(){return S()||M()||_()||O()}function O(){return k("literal",t.literalColor,0)}function S(){return k("hex",t.hexColor,1)}function _(){return s(t.rgbColor,function(){return{type:"rgb",value:b(E)}})}function M(){return s(t.rgbaColor,function(){return{type:"rgba",value:b(E)}})}function E(){return C(t.number)[1]}function P(){return k("%",t.percentageValue,1)||T()||A()}function T(){return k("position-keyword",t.positionKeywords,1)}function A(){return k("px",t.pixelValue,1)||k("em",t.emValue,1)}function k(I,R,j){var D=C(R);if(D)return{type:I,value:D[j]}}function C(I){var R=/^[\n\r\t\s]+/.exec(e);R&&L(R[0].length);var j=I.exec(e);return j&&L(j[0].length),j}function L(I){e=e.substring(I)}return function(I){return e=I,r()}}();function CN(t,e,n){var r=re(n.value),i=0,a=0,o=i+t/2,s=a+e/2,c=Math.abs(t*Math.cos(r))+Math.abs(e*Math.sin(r)),l=o-Math.cos(r)*c/2,u=s-Math.sin(r)*c/2,f=o+Math.cos(r)*c/2,d=s+Math.sin(r)*c/2;return{x1:l,y1:u,x2:f,y2:d}}function LN(t,e,n,r,i){var a=n.value,o=r.value;n.unit===Z.kPercentage&&(a=n.value/100*t),r.unit===Z.kPercentage&&(o=r.value/100*e);var s=Math.max(nn([0,0],[a,o]),nn([0,e],[a,o]),nn([t,e],[a,o]),nn([t,0],[a,o]));return i&&(i instanceof jt?s=i.value:i instanceof sn&&(i.value==="closest-side"?s=Math.min(a,t-a,o,e-o):i.value==="farthest-side"?s=Math.max(a,t-a,o,e-o):i.value==="closest-corner"&&(s=Math.min(nn([0,0],[a,o]),nn([0,e],[a,o]),nn([t,e],[a,o]),nn([t,0],[a,o]))))),{x:a,y:o,r:s}}var NN=/^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i,RN=/^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i,IN=/^p\s*\(\s*([axyn])\s*\)\s*(.*)/i,_w=/[\d.]+:(#[^\s]+|[^\)]+\))/gi;function jN(t){var e,n,r,i=t.length;t[i-1].length=(e=t[i-1].length)!==null&&e!==void 0?e:{type:"%",value:"100"},i>1&&(t[0].length=(n=t[0].length)!==null&&n!==void 0?n:{type:"%",value:"0"});for(var a=0,o=Number(t[0].length.value),s=1;s-1||t.indexOf("radial")>-1){var n=TN(t);return n.map(function(s){var c=s.type,l=s.orientation,u=s.colorStops;jN(u);var f=u.map(function(b){return{offset:Ft(Number(b.length.value),"%"),color:kN(b)}});if(c==="linear-gradient")return new pc(rr.LinearGradient,{angle:l?$N(l):Hn,steps:f});if(c==="radial-gradient"&&(l||(l=[{type:"shape",value:"circle"}]),l[0].type==="shape"&&l[0].value==="circle")){var d=BN(l[0].at),h=d.cx,p=d.cy,v=void 0;if(l[0].style){var g=l[0].style,y=g.type,m=g.value;y==="extent-keyword"?v=eh(m):v=Ft(m,y)}return new pc(rr.RadialGradient,{cx:h,cy:p,size:v,steps:f})}})}var r=t[0];if(t[1]==="("||t[2]==="("){if(r==="l"){var i=NN.exec(t);if(i){var a=((e=i[2].match(_w))===null||e===void 0?void 0:e.map(function(s){return s.split(":")}))||[];return[new pc(rr.LinearGradient,{angle:Ft(parseFloat(i[1]),"deg"),steps:a.map(function(s){var c=N(s,2),l=c[0],u=c[1];return{offset:Ft(Number(l)*100,"%"),color:u}})})]}}else if(r==="r"){var o=zN(t);if(o)if(le(o))t=o;else return[new pc(rr.RadialGradient,o)]}else if(r==="p")return GN(t)}});function zN(t){var e,n=RN.exec(t);if(n){var r=((e=n[4].match(_w))===null||e===void 0?void 0:e.map(function(i){return i.split(":")}))||[];return{cx:Ft(50,"%"),cy:Ft(50,"%"),steps:r.map(function(i){var a=N(i,2),o=a[0],s=a[1];return{offset:Ft(Number(o)*100,"%"),color:s}})}}return null}function GN(t){var e=IN.exec(t);if(e){var n=e[1],r=e[2];switch(n){case"a":n="repeat";break;case"x":n="repeat-x";break;case"y":n="repeat-y";break;case"n":n="no-repeat";break;default:n="no-repeat"}return{image:r,repetition:n}}return null}function hs(t){return t&&!!t.image}function Tl(t){return t&&!nt(t.r)&&!nt(t.g)&&!nt(t.b)}var Ar=Ne(function(t){if(hs(t))return z({repetition:"repeat"},t);if(nt(t)&&(t=""),t==="transparent")return Ow;t==="currentColor"&&(t="black");var e=FN(t);if(e)return e;var n=ju(t),r=[0,0,0,0];return n!==null&&(r[0]=n.r||0,r[1]=n.g||0,r[2]=n.b||0,r[3]=n.opacity),AN.apply(void 0,q([],N(r),!1))});function YN(t,e){if(!(!Tl(t)||!Tl(e)))return[[Number(t.r),Number(t.g),Number(t.b),Number(t.alpha)],[Number(e.r),Number(e.g),Number(e.b),Number(e.alpha)],function(n){var r=n.slice();if(r[3])for(var i=0;i<3;i++)r[i]=Math.round(ce(r[i],0,255));return r[3]=ce(r[3],0,1),"rgba(".concat(r.join(","),")")}]}function Hs(t,e){if(nt(e))return Ft(0,"px");if(e="".concat(e).trim().toLowerCase(),isFinite(Number(e))){if("px".search(t)>=0)return Ft(Number(e),"px");if("deg".search(t)>=0)return Ft(Number(e),"deg")}var n=[];e=e.replace(t,function(i){return n.push(i),"U"+i});var r="U("+t.source+")";return n.map(function(i){return Ft(Number(e.replace(new RegExp("U"+i,"g"),"").replace(new RegExp(r,"g"),"*0")),i)})[0]}var Mw=function(t){return Hs(new RegExp("px","g"),t)},WN=Ne(Mw),HN=function(t){return Hs(new RegExp("%","g"),t)};Ne(HN);var ps=function(t){return de(t)||isFinite(Number(t))?Ft(Number(t)||0,"px"):Hs(new RegExp("px|%|em|rem","g"),t)},Ba=Ne(ps),zp=function(t){return Hs(new RegExp("deg|rad|grad|turn","g"),t)},Ew=Ne(zp);function VN(t,e,n,r,i){i===void 0&&(i=0);var a="",o=t.value||0,s=e.value||0,c=th(t.unit),l=t.convertTo(c),u=e.convertTo(c);return l&&u?(o=l.value,s=u.value,a=Qd(t.unit)):(jt.isLength(t.unit)||jt.isLength(e.unit))&&(o=dn(t,i,n),s=dn(e,i,n),a="px"),[o,s,function(f){return r&&(f=Math.max(f,0)),f+a}]}function hn(t){var e=0;return t.unit===Z.kDegrees?e=t.value:t.unit===Z.kRadians?e=Pn(Number(t.value)):t.unit===Z.kTurns&&(e=iN(Number(t.value))),e}function $f(t,e){var n;return Array.isArray(t)?n=t.map(function(r){return Number(r)}):le(t)?n=t.split(" ").map(function(r){return Number(r)}):de(t)&&(n=[t]),e===2?n.length===1?[n[0],n[0]]:[n[0],n[1]]:n.length===1?[n[0],n[0],n[0],n[0]]:n.length===2?[n[0],n[1],n[0],n[1]]:n.length===3?[n[0],n[1],n[2],n[1]]:[n[0],n[1],n[2],n[3]]}function Pw(t){return le(t)?t.split(" ").map(function(e){return Ba(e)}):t.map(function(e){return Ba(e.toString())})}function dn(t,e,n){if(t.value===0)return 0;if(t.unit===Z.kPixels)return Number(t.value);if(t.unit===Z.kPercentage&&n){var r=n.nodeName===G.GROUP?n.getLocalBounds():n.geometry.contentBounds;return t.value/100*r.halfExtents[e]*2}return 0}var XN=function(t){return Hs(/deg|rad|grad|turn|px|%/g,t)},UN=["blur","brightness","drop-shadow","contrast","grayscale","sepia","saturate","hue-rotate","invert"];function Aw(t){if(t===void 0&&(t=""),t=t.toLowerCase().trim(),t==="none")return[];for(var e=/\s*([\w-]+)\(([^)]*)\)/g,n=[],r,i=0;r=e.exec(t);){if(r.index!==i)return[];if(i=r.index+r[0].length,UN.indexOf(r[1])>-1&&n.push({name:r[1],params:r[2].split(" ").map(function(a){return XN(a)||Ar(a)})}),e.lastIndex===t.length)return n}return[]}function kw(t){return t.toString()}var no=function(t){return typeof t=="number"?Ft(t):/^\s*[-+]?(\d*\.)?\d+\s*$/.test(t)?Ft(Number(t)):Ft(0)},zi=Ne(no);Ne(function(t){return le(t)?t.split(" ").map(zi):t.map(zi)});function Gp(t,e){return[t,e,kw]}function Yp(t,e){return function(n,r){return[n,r,function(i){return kw(ce(i,t,e))}]}}function Tw(t,e){if(t.length===e.length)return[t,e,function(n){return n}]}function ih(t){return t.parsedStyle.path.totalLength===0&&(t.parsedStyle.path.totalLength=e5(t.parsedStyle.path.absolutePath)),t.parsedStyle.path.totalLength}function qN(t){for(var e=0;e0&&n.push(r),{polygons:e,polylines:n}}function Cl(t,e){return t[0]===e[0]&&t[1]===e[1]}function QN(t,e){for(var n=[],r=[],i=[],a=0;aMath.PI/2?Math.PI-l:l,u=u>Math.PI/2?Math.PI-u:u;var f={xExtra:Math.cos(c/2-l)*(e/2*(1/Math.sin(c/2)))-e/2||0,yExtra:Math.cos(u-c/2)*(e/2*(1/Math.sin(c/2)))-e/2||0};return f}function Wg(t,e){return[e[0]+(e[0]-t[0]),e[1]+(e[1]-t[1])]}var Hg=function(t,e){var n=t.x*e.x+t.y*e.y,r=Math.sqrt((Math.pow(t.x,2)+Math.pow(t.y,2))*(Math.pow(e.x,2)+Math.pow(e.y,2))),i=t.x*e.y-t.y*e.x<0?-1:1,a=i*Math.acos(n/r);return a},Vg=function(t,e,n,r,i,a,o,s){e=Math.abs(e),n=Math.abs(n),r=Ib(r,360);var c=re(r);if(t.x===o.x&&t.y===o.y)return{x:t.x,y:t.y,ellipticalArcAngle:0};if(e===0||n===0)return{x:0,y:0,ellipticalArcAngle:0};var l=(t.x-o.x)/2,u=(t.y-o.y)/2,f={x:Math.cos(c)*l+Math.sin(c)*u,y:-Math.sin(c)*l+Math.cos(c)*u},d=Math.pow(f.x,2)/Math.pow(e,2)+Math.pow(f.y,2)/Math.pow(n,2);d>1&&(e=Math.sqrt(d)*e,n=Math.sqrt(d)*n);var h=Math.pow(e,2)*Math.pow(n,2)-Math.pow(e,2)*Math.pow(f.y,2)-Math.pow(n,2)*Math.pow(f.x,2),p=Math.pow(e,2)*Math.pow(f.y,2)+Math.pow(n,2)*Math.pow(f.x,2),v=h/p;v=v<0?0:v;var g=(i!==a?1:-1)*Math.sqrt(v),y={x:g*(e*f.y/n),y:g*(-(n*f.x)/e)},m={x:Math.cos(c)*y.x-Math.sin(c)*y.y+(t.x+o.x)/2,y:Math.sin(c)*y.x+Math.cos(c)*y.y+(t.y+o.y)/2},b={x:(f.x-y.x)/e,y:(f.y-y.y)/n},x=Hg({x:1,y:0},b),w={x:(-f.x-y.x)/e,y:(-f.y-y.y)/n},O=Hg(b,w);!a&&O>0?O-=2*Math.PI:a&&O<0&&(O+=2*Math.PI),O%=2*Math.PI;var S=x+O*s,_=e*Math.cos(S),M=n*Math.sin(S),E={x:Math.cos(c)*_-Math.sin(c)*M+m.x,y:Math.sin(c)*_+Math.cos(c)*M+m.y,ellipticalArcStartAngle:x,ellipticalArcEndAngle:x+O,ellipticalArcAngle:S,ellipticalArcCenter:m,resultantRx:e,resultantRy:n};return E};function JN(t){for(var e=[],n=null,r=null,i=null,a=0,o=t.length,s=0;s1&&(n*=Math.sqrt(h),r*=Math.sqrt(h));var p=n*n*(d*d)+r*r*(f*f),v=p?Math.sqrt((n*n*(r*r)-p)/p):1;a===o&&(v*=-1),isNaN(v)&&(v=0);var g=r?v*n*d/r:0,y=n?v*-r*f/n:0,m=(s+l)/2+Math.cos(i)*g-Math.sin(i)*y,b=(c+u)/2+Math.sin(i)*g+Math.cos(i)*y,x=[(f-g)/n,(d-y)/r],w=[(-1*f-g)/n,(-1*d-y)/r],O=Ug([1,0],x),S=Ug(x,w);return ah(x,w)<=-1&&(S=Math.PI),ah(x,w)>=1&&(S=0),o===0&&S>0&&(S=S-2*Math.PI),o===1&&S<0&&(S=S+2*Math.PI),{cx:m,cy:b,rx:Cl(t,[l,u])?0:n,ry:Cl(t,[l,u])?0:r,startAngle:O,endAngle:O+S,xRotation:i,arcFlag:a,sweepFlag:o}}function e4(t,e,n){var r=e.parsedStyle,i=r.defX,a=i===void 0?0:i,o=r.defY,s=o===void 0?0:o;return t.reduce(function(c,l){var u="";if(l[0]==="M"||l[0]==="L"){var f=St(l[1]-a,l[2]-s,0);n&&Oe(f,f,n),u="".concat(l[0]).concat(f[0],",").concat(f[1])}else if(l[0]==="Z")u=l[0];else if(l[0]==="C"){var d=St(l[1]-a,l[2]-s,0),h=St(l[3]-a,l[4]-s,0),p=St(l[5]-a,l[6]-s,0);n&&(Oe(d,d,n),Oe(h,h,n),Oe(p,p,n)),u="".concat(l[0]).concat(d[0],",").concat(d[1],",").concat(h[0],",").concat(h[1],",").concat(p[0],",").concat(p[1])}else if(l[0]==="A"){var v=St(l[6]-a,l[7]-s,0);n&&Oe(v,v,n),u="".concat(l[0]).concat(l[1],",").concat(l[2],",").concat(l[3],",").concat(l[4],",").concat(l[5],",").concat(v[0],",").concat(v[1])}else if(l[0]==="Q"){var d=St(l[1]-a,l[2]-s,0),h=St(l[3]-a,l[4]-s,0);n&&(Oe(d,d,n),Oe(h,h,n)),u="".concat(l[0]).concat(l[1],",").concat(l[2],",").concat(l[3],",").concat(l[4],"}")}return c+=u},"")}function n4(t,e,n,r){return[["M",t,e],["L",n,r]]}function qg(t,e,n,r){var i=(-1+Math.sqrt(2))/3*4,a=t*i,o=e*i,s=n-t,c=n+t,l=r-e,u=r+e;return[["M",s,r],["C",s,r-o,n-a,l,n,l],["C",n+a,l,c,r-o,c,r],["C",c,r+o,n+a,u,n,u],["C",n-a,u,s,r+o,s,r],["Z"]]}function r4(t,e){var n=t.map(function(r,i){return[i===0?"M":"L",r[0],r[1]]});return e&&n.push(["Z"]),n}function i4(t,e,n,r,i){if(i){var a=N(i,4),o=a[0],s=a[1],c=a[2],l=a[3],u=t>0?1:-1,f=e>0?1:-1,d=u+f!==0?1:0;return[["M",u*o+n,r],["L",t-u*s+n,r],s?["A",s,s,0,0,d,t+n,f*s+r]:null,["L",t+n,e-f*c+r],c?["A",c,c,0,0,d,t+n-u*c,e+r]:null,["L",n+u*l,e+r],l?["A",l,l,0,0,d,n,e+r-f*l]:null,["L",n,f*o+r],o?["A",o,o,0,0,d,u*o+n,r]:null,["Z"]].filter(function(h){return h})}return[["M",n,r],["L",n+t,r],["L",n+t,r+e],["L",n,r+e],["Z"]]}function Wp(t,e){e===void 0&&(e=t.getLocalTransform());var n=[];switch(t.nodeName){case G.LINE:var r=t.parsedStyle,i=r.x1,a=i===void 0?0:i,o=r.y1,s=o===void 0?0:o,c=r.x2,l=c===void 0?0:c,u=r.y2,f=u===void 0?0:u;n=n4(a,s,l,f);break;case G.CIRCLE:{var d=t.parsedStyle,h=d.r,p=h===void 0?0:h,v=d.cx,g=v===void 0?0:v,y=d.cy,m=y===void 0?0:y;n=qg(p,p,g,m);break}case G.ELLIPSE:{var b=t.parsedStyle,x=b.rx,w=x===void 0?0:x,O=b.ry,S=O===void 0?0:O,_=b.cx,g=_===void 0?0:_,M=b.cy,m=M===void 0?0:M;n=qg(w,S,g,m);break}case G.POLYLINE:case G.POLYGON:var E=t.parsedStyle.points;n=r4(E.points,t.nodeName===G.POLYGON);break;case G.RECT:var P=t.parsedStyle,T=P.width,A=T===void 0?0:T,k=P.height,C=k===void 0?0:k,L=P.x,I=L===void 0?0:L,R=P.y,j=R===void 0?0:R,D=P.radius,$=D&&D.some(function(F){return F!==0});n=i4(A,C,I,j,$&&D.map(function(F){return ce(F,0,Math.min(Math.abs(A)/2,Math.abs(C)/2))}));break;case G.PATH:var B=t.parsedStyle.path.absolutePath;n=q([],N(B),!1);break}if(n.length)return e4(n,t,e)}var Cw=function(t){if(t===""||Array.isArray(t)&&t.length===0)return{absolutePath:[],hasArc:!1,segments:[],polygons:[],polylines:[],curve:null,totalLength:0,rect:{x:0,y:0,width:0,height:0}};var e;try{e=bl(t)}catch{e=bl(""),console.error("[g]: Invalid SVG Path definition: ".concat(t))}qN(e);var n=KN(e),r=ZN(e),i=r.polygons,a=r.polylines,o=JN(e),s=QN(o,0),c=s.x,l=s.y,u=s.width,f=s.height;return{absolutePath:e,hasArc:n,segments:o,polygons:i,polylines:a,totalLength:0,rect:{x:Number.isFinite(c)?c:0,y:Number.isFinite(l)?l:0,width:Number.isFinite(u)?u:0,height:Number.isFinite(f)?f:0}}},a4=Ne(Cw);function oh(t){return le(t)?a4(t):Cw(t)}function o4(t,e,n){var r=t.curve,i=e.curve;(!r||r.length===0)&&(r=Rd(t.absolutePath,!1),t.curve=r),(!i||i.length===0)&&(i=Rd(e.absolutePath,!1),e.curve=i);var a=[r,i];r.length!==i.length&&(a=cx(r,i));var o=eg(a[0])!==eg(a[1])?qT(a[0]):UT(a[0]);return[o,r5(a[1],o),function(s){return s}]}function Lw(t,e){var n;le(t)?n=t.split(" ").map(function(u){var f=N(u.split(","),2),d=f[0],h=f[1];return[Number(d),Number(h)]}):n=t;var r=[],i=0,a,o,s=qL(n);n.forEach(function(u,f){n[f+1]&&(a=[0,0],a[0]=i/s,o=yw(u[0],u[1],n[f+1][0],n[f+1][1]),i+=o,a[1]=i/s,r.push(a))});var c=Math.min.apply(Math,q([],N(n.map(function(u){return u[0]})),!1)),l=Math.min.apply(Math,q([],N(n.map(function(u){return u[1]})),!1));return e&&(e.parsedStyle.defX=c,e.parsedStyle.defY=l),{points:n,totalLength:s,segments:r}}function s4(t,e){return[t.points,e.points,function(n){return n}]}var ie=null;function Je(t){return function(e){var n=0;return t.map(function(r){return r===ie?e[n++]:r})}}function bi(t){return t}var Ll={matrix:["NNNNNN",[ie,ie,0,0,ie,ie,0,0,0,0,1,0,ie,ie,0,1],bi],matrix3d:["NNNNNNNNNNNNNNNN",bi],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",Je([ie,ie,new jt(1)]),bi],scalex:["N",Je([ie,new jt(1),new jt(1)]),Je([ie,new jt(1)])],scaley:["N",Je([new jt(1),ie,new jt(1)]),Je([new jt(1),ie])],scalez:["N",Je([new jt(1),new jt(1),ie])],scale3d:["NNN",bi],skew:["Aa",null,bi],skewx:["A",null,Je([ie,Hn])],skewy:["A",null,Je([Hn,ie])],translate:["Tt",Je([ie,ie,we]),bi],translatex:["T",Je([ie,we,we]),Je([ie,we])],translatey:["T",Je([we,ie,we]),Je([we,ie])],translatez:["L",Je([we,we,ie])],translate3d:["TTL",bi]};function Hp(t){if(t=(t||"none").toLowerCase().trim(),t==="none")return[];for(var e=/\s*(\w+)\(([^)]*)\)/g,n=[],r,i=0;r=e.exec(t);){if(r.index!==i)return[];i=r.index+r[0].length;var a=r[1],o=Ll[a];if(!o)return[];var s=r[2].split(","),c=o[0];if(c.length"].calculator(null,null,{value:n.textTransform},e,null),n.clipPath&&this.runtime.CSSPropertySyntaxFactory[""].calculator("clipPath",o,n.clipPath,e,this.runtime),n.offsetPath&&this.runtime.CSSPropertySyntaxFactory[""].calculator("offsetPath",s,n.offsetPath,e,this.runtime),n.anchor&&(e.parsedStyle.anchor=$f(n.anchor,2)),n.transform&&(e.parsedStyle.transform=Hp(n.transform)),n.transformOrigin&&(e.parsedStyle.transformOrigin=Nw(n.transformOrigin)),n.markerStart&&(e.parsedStyle.markerStart=this.runtime.CSSPropertySyntaxFactory[""].calculator(null,n.markerStart,n.markerStart,null,null)),n.markerEnd&&(e.parsedStyle.markerEnd=this.runtime.CSSPropertySyntaxFactory[""].calculator(null,n.markerEnd,n.markerEnd,null,null)),n.markerMid&&(e.parsedStyle.markerMid=this.runtime.CSSPropertySyntaxFactory[""].calculator("",n.markerMid,n.markerMid,null,null)),((e.nodeName===G.CIRCLE||e.nodeName===G.ELLIPSE)&&(!nt(n.cx)||!nt(n.cy))||(e.nodeName===G.RECT||e.nodeName===G.IMAGE||e.nodeName===G.GROUP||e.nodeName===G.HTML||e.nodeName===G.TEXT||e.nodeName===G.MESH)&&(!nt(n.x)||!nt(n.y)||!nt(n.z))||e.nodeName===G.LINE&&(!nt(n.x1)||!nt(n.y1)||!nt(n.z1)||!nt(n.x2)||!nt(n.y2)||!nt(n.z2)))&&this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),nt(n.zIndex)||this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),n.path&&this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),n.points&&this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),nt(n.offsetDistance)||this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),n.transform&&this.runtime.CSSPropertySyntaxFactory[""].postProcessor(e,a),c&&this.updateGeometry(e);return}var u=r.skipUpdateAttribute,f=r.skipParse,d=r.forceUpdateGeometry,h=r.usedAttributes,p=r.memoize,v=d,g=Object.keys(n);g.forEach(function(y){var m;u||(e.attributes[y]=n[y]),!v&&(!((m=Br[y])===null||m===void 0)&&m.l)&&(v=!0)}),f||g.forEach(function(y){e.computedStyle[y]=i.parseProperty(y,e.attributes[y],e,p)}),h!=null&&h.length&&(g=Array.from(new Set(g.concat(h)))),g.forEach(function(y){y in e.computedStyle&&(e.parsedStyle[y]=i.computeProperty(y,e.computedStyle[y],e,p))}),v&&this.updateGeometry(e),g.forEach(function(y){y in e.parsedStyle&&i.postProcessProperty(y,e,g)}),this.runtime.enableCSSParsing&&e.children.length&&g.forEach(function(y){y in e.parsedStyle&&i.isPropertyInheritable(y)&&e.children.forEach(function(m){m.internalSetAttribute(y,null,{skipUpdateAttribute:!0,skipParse:!0})})})},t.prototype.parseProperty=function(e,n,r,i){var a=Br[e],o=n;if((n===""||nt(n))&&(n="unset"),n==="unset"||n==="initial"||n==="inherit")o=eh(n);else if(a){var s=a.k,c=a.syntax,l=c&&this.getPropertySyntax(c);s&&s.indexOf(n)>-1?o=eh(n):l&&(!i&&l.parserUnmemoize?o=l.parserUnmemoize(n,r):l.parser&&(o=l.parser(n,r)))}return o},t.prototype.computeProperty=function(e,n,r,i){var a=Br[e],o=r.id==="g-root",s=n;if(a){var c=a.syntax,l=a.inh,u=a.d;if(n instanceof sn){var f=n.value;if(f==="unset"&&(l&&!o?f="inherit":f="initial"),f==="initial")nt(u)||(n=this.parseProperty(e,ga(u)?u(r.nodeName):u,r,i));else if(f==="inherit"){var d=this.tryToResolveProperty(r,e,{inherited:!0});if(nt(d)){this.addUnresolveProperty(r,e);return}else return d}}var h=c&&this.getPropertySyntax(c);if(h&&h.calculator){var p=r.parsedStyle[e];s=h.calculator(e,p,n,r,this.runtime)}else n instanceof sn?s=n.value:s=n}return s},t.prototype.postProcessProperty=function(e,n,r){var i=Br[e];if(i&&i.syntax){var a=i.syntax&&this.getPropertySyntax(i.syntax),o=a;o&&o.postProcessor&&o.postProcessor(n,r)}},t.prototype.addUnresolveProperty=function(e,n){var r=la.get(e);r||(la.set(e,[]),r=la.get(e)),r.indexOf(n)===-1&&r.push(n)},t.prototype.tryToResolveProperty=function(e,n,r){r===void 0&&(r={});var i=r.inherited;if(i&&e.parentElement&&m4(e.parentElement,n)){var a=e.parentElement.parsedStyle[n];return a==="unset"||a==="initial"||a==="inherit"?void 0:a}},t.prototype.recalc=function(e){var n=la.get(e);if(n&&n.length){var r={};n.forEach(function(i){r[i]=e.attributes[i]}),this.processProperties(e,r),la.delete(e)}},t.prototype.updateGeometry=function(e){var n=e.nodeName,r=this.runtime.geometryUpdaterFactory[n];if(r){var i=e.geometry;i.contentBounds||(i.contentBounds=new be),i.renderBounds||(i.renderBounds=new be);var a=e.parsedStyle,o=r.update(a,e),s=o.width,c=o.height,l=o.depth,u=l===void 0?0:l,f=o.offsetX,d=f===void 0?0:f,h=o.offsetY,p=h===void 0?0:h,v=o.offsetZ,g=v===void 0?0:v,y=[Math.abs(s)/2,Math.abs(c)/2,u/2],m=a,b=m.stroke,x=m.lineWidth,w=m.increasedLineWidthForHitTesting,O=m.shadowType,S=m.shadowColor,_=m.filter,M=_===void 0?[]:_,E=m.transformOrigin,P=a.anchor;n===G.TEXT?delete a.anchor:n===G.MESH&&(a.anchor[2]=.5);var T=[(1-(P&&P[0]||0)*2)*s/2+d,(1-(P&&P[1]||0)*2)*c/2+p,(1-(P&&P[2]||0)*2)*y[2]+g];i.contentBounds.update(T,y);var A=n===G.POLYLINE||n===G.POLYGON||n===G.PATH?Math.SQRT2:.5,k=b&&!b.isNone;if(k){var C=((x||0)+(w||0))*A;y[0]+=C,y[1]+=C}if(i.renderBounds.update(T,y),S&&O&&O!=="inner"){var L=i.renderBounds,I=L.min,R=L.max,j=a,D=j.shadowBlur,$=j.shadowOffsetX,B=j.shadowOffsetY,F=D||0,Y=$||0,U=B||0,K=I[0]-F+Y,V=R[0]+F+Y,W=I[1]-F+U,J=R[1]+F+U;I[0]=Math.min(I[0],K),R[0]=Math.max(R[0],V),I[1]=Math.min(I[1],W),R[1]=Math.max(R[1],J),i.renderBounds.setMinMax(I,R)}M.forEach(function(lt){var xt=lt.name,Et=lt.params;if(xt==="blur"){var Xt=Et[0].value;i.renderBounds.update(i.renderBounds.center,el(i.renderBounds.halfExtents,i.renderBounds.halfExtents,[Xt,Xt,0]))}else if(xt==="drop-shadow"){var ue=Et[0].value,Ke=Et[1].value,vr=Et[2].value,gi=i.renderBounds,Ge=gi.min,wn=gi.max,_t=Ge[0]-vr+ue,Pt=wn[0]+vr+ue,ee=Ge[1]-vr+Ke,kt=wn[1]+vr+Ke;Ge[0]=Math.min(Ge[0],_t),wn[0]=Math.max(wn[0],Pt),Ge[1]=Math.min(Ge[1],ee),wn[1]=Math.max(wn[1],kt),i.renderBounds.setMinMax(Ge,wn)}}),P=a.anchor;var et=s<0,it=c<0,ct=(et?-1:1)*(E?dn(E[0],0,e):0),ot=(it?-1:1)*(E?dn(E[1],1,e):0);ct=ct-(et?-1:1)*(P&&P[0]||0)*i.contentBounds.halfExtents[0]*2,ot=ot-(it?-1:1)*(P&&P[1]||0)*i.contentBounds.halfExtents[1]*2,e.setOrigin(ct,ot),this.runtime.sceneGraphService.dirtifyToRoot(e)}},t.prototype.isPropertyInheritable=function(e){var n=Br[e];return n?n.inh:!1},t}(),x4=function(){function t(){this.parser=Ew,this.parserUnmemoize=zp,this.parserWithCSSDisabled=null,this.mixer=Gp}return t.prototype.calculator=function(e,n,r,i){return hn(r)},t}(),w4=function(){function t(){}return t.prototype.calculator=function(e,n,r,i,a){return r instanceof sn&&(r=null),a.sceneGraphService.updateDisplayObjectDependency(e,n,r,i),e==="clipPath"&&i.forEach(function(o){o.childNodes.length===0&&a.sceneGraphService.dirtifyToRoot(o)}),r},t}(),O4=function(){function t(){this.parser=Ar,this.parserWithCSSDisabled=Ar,this.mixer=YN}return t.prototype.calculator=function(e,n,r,i){return r instanceof sn?r.value==="none"?nh:Ow:r},t}(),S4=function(){function t(){this.parser=Aw}return t.prototype.calculator=function(e,n,r){return r instanceof sn?[]:r},t}();function Jg(t){var e=t.parsedStyle.fontSize;return nt(e)?null:e}var Xp=function(){function t(){this.parser=Ba,this.parserUnmemoize=ps,this.parserWithCSSDisabled=null,this.mixer=Gp}return t.prototype.calculator=function(e,n,r,i,a){var o;if(de(r))return r;if(jt.isRelativeUnit(r.unit)){var s=a.styleValueRegistry;if(r.unit===Z.kPercentage)return 0;if(r.unit===Z.kEms){if(i.parentNode){var c=Jg(i.parentNode);if(c)return c*=r.value,c;s.addUnresolveProperty(i,e)}else s.addUnresolveProperty(i,e);return 0}else if(r.unit===Z.kRems){if(!((o=i==null?void 0:i.ownerDocument)===null||o===void 0)&&o.documentElement){var c=Jg(i.ownerDocument.documentElement);if(c)return c*=r.value,c;s.addUnresolveProperty(i,e)}else s.addUnresolveProperty(i,e);return 0}}else return r.value},t}(),_4=function(){function t(){this.mixer=Tw}return t.prototype.parser=function(e){var n=Pw(de(e)?[e]:e),r;return n.length===1?r=[n[0],n[0]]:r=[n[0],n[1]],r},t.prototype.calculator=function(e,n,r){return r.map(function(i){return i.value})},t}(),M4=function(){function t(){this.mixer=Tw}return t.prototype.parser=function(e){var n=Pw(de(e)?[e]:e),r;return n.length===1?r=[n[0],n[0],n[0],n[0]]:n.length===2?r=[n[0],n[1],n[0],n[1]]:n.length===3?r=[n[0],n[1],n[2],n[1]]:r=[n[0],n[1],n[2],n[3]],r},t.prototype.calculator=function(e,n,r){return r.map(function(i){return i.value})},t}(),xo=Nt();function Up(t,e){var n=e.parsedStyle.defX||0,r=e.parsedStyle.defY||0;return e.resetLocalTransform(),e.setLocalPosition(n,r),t.forEach(function(i){var a=i.t,o=i.d;if(a==="scale"){var s=(o==null?void 0:o.map(function(m){return m.value}))||[1,1];e.scaleLocal(s[0],s[1],1)}else if(a==="scalex"){var s=(o==null?void 0:o.map(function(b){return b.value}))||[1];e.scaleLocal(s[0],1,1)}else if(a==="scaley"){var s=(o==null?void 0:o.map(function(b){return b.value}))||[1];e.scaleLocal(1,s[0],1)}else if(a==="scalez"){var s=(o==null?void 0:o.map(function(b){return b.value}))||[1];e.scaleLocal(1,1,s[0])}else if(a==="scale3d"){var s=(o==null?void 0:o.map(function(b){return b.value}))||[1,1,1];e.scaleLocal(s[0],s[1],s[2])}else if(a==="translate"){var c=o||[we,we];e.translateLocal(c[0].value,c[1].value,0)}else if(a==="translatex"){var c=o||[we];e.translateLocal(c[0].value,0,0)}else if(a==="translatey"){var c=o||[we];e.translateLocal(0,c[0].value,0)}else if(a==="translatez"){var c=o||[we];e.translateLocal(0,0,c[0].value)}else if(a==="translate3d"){var c=o||[we,we,we];e.translateLocal(c[0].value,c[1].value,c[2].value)}else if(a==="rotate"){var l=o||[Hn];e.rotateLocal(0,0,hn(l[0]))}else if(a==="rotatex"){var l=o||[Hn];e.rotateLocal(hn(l[0]),0,0)}else if(a==="rotatey"){var l=o||[Hn];e.rotateLocal(0,hn(l[0]),0)}else if(a==="rotatez"){var l=o||[Hn];e.rotateLocal(0,0,hn(l[0]))}else if(a!=="rotate3d")if(a==="skew"){var u=(o==null?void 0:o.map(function(m){return m.value}))||[0,0];e.setLocalSkew(re(u[0]),re(u[1]))}else if(a==="skewx"){var u=(o==null?void 0:o.map(function(b){return b.value}))||[0];e.setLocalSkew(re(u[0]),e.getLocalSkew()[1])}else if(a==="skewy"){var u=(o==null?void 0:o.map(function(b){return b.value}))||[0];e.setLocalSkew(e.getLocalSkew()[0],re(u[0]))}else if(a==="matrix"){var f=N(o.map(function(m){return m.value}),6),d=f[0],h=f[1],p=f[2],v=f[3],g=f[4],y=f[5];e.setLocalTransform(Td(xo,d,h,0,0,p,v,0,0,0,0,1,0,g+n,y+r,0,1))}else a==="matrix3d"&&(Td.apply(bT,q([xo],N(o.map(function(m){return m.value})),!1)),xo[12]+=n,xo[13]+=r,e.setLocalTransform(xo))}),e.getLocalTransform()}var E4=function(t){rt(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.postProcessor=function(n,r){var i,a,o;switch(n.nodeName){case G.CIRCLE:case G.ELLIPSE:var s=n.parsedStyle,c=s.cx,l=s.cy,u=s.cz;nt(c)||(i=c),nt(l)||(a=l),nt(u)||(o=u);break;case G.LINE:var f=n.parsedStyle,d=f.x1,h=f.x2,p=f.y1,v=f.y2,g=Math.min(d,h),y=Math.min(p,v);i=g,a=y,o=0;break;case G.RECT:case G.IMAGE:case G.GROUP:case G.HTML:case G.TEXT:case G.MESH:nt(n.parsedStyle.x)||(i=n.parsedStyle.x),nt(n.parsedStyle.y)||(a=n.parsedStyle.y),nt(n.parsedStyle.z)||(o=n.parsedStyle.z);break}n.nodeName!==G.PATH&&n.nodeName!==G.POLYLINE&&n.nodeName!==G.POLYGON&&(n.parsedStyle.defX=i||0,n.parsedStyle.defY=a||0);var m=!nt(i)||!nt(a)||!nt(o);if(m&&r.indexOf("transform")===-1){var b=n.parsedStyle.transform;if(b&&b.length)Up(b,n);else{var x=N(n.getLocalPosition(),3),w=x[0],O=x[1],S=x[2];n.setLocalPosition(nt(i)?w:i,nt(a)?O:a,nt(o)?S:o)}}},e}(Xp),P4=function(){function t(){}return t.prototype.calculator=function(e,n,r,i){r instanceof sn&&(r=null);var a=r==null?void 0:r.cloneNode(!0);return a&&(a.style.isMarker=!0),a},t}(),A4=function(){function t(){this.mixer=Gp,this.parser=zi,this.parserUnmemoize=no,this.parserWithCSSDisabled=null}return t.prototype.calculator=function(e,n,r){return r.value},t}(),k4=function(){function t(){this.parser=zi,this.parserUnmemoize=no,this.parserWithCSSDisabled=null,this.mixer=Yp(0,1)}return t.prototype.calculator=function(e,n,r){return r.value},t.prototype.postProcessor=function(e){var n=e.parsedStyle,r=n.offsetPath,i=n.offsetDistance;if(r){var a=r.nodeName;if(a===G.LINE||a===G.PATH||a===G.POLYLINE){var o=r.getPoint(i);o&&(e.parsedStyle.defX=o.x,e.parsedStyle.defY=o.y,e.setLocalPosition(o.x,o.y))}}},t}(),T4=function(){function t(){this.parser=zi,this.parserUnmemoize=no,this.parserWithCSSDisabled=null,this.mixer=Yp(0,1)}return t.prototype.calculator=function(e,n,r){return r.value},t}(),C4=function(){function t(){this.parser=oh,this.parserWithCSSDisabled=oh,this.mixer=o4}return t.prototype.calculator=function(e,n,r){return r instanceof sn&&r.value==="unset"?{absolutePath:[],hasArc:!1,segments:[],polygons:[],polylines:[],curve:null,totalLength:0,rect:new Fi(0,0,0,0)}:r},t.prototype.postProcessor=function(e,n){if(e.parsedStyle.defX=e.parsedStyle.path.rect.x,e.parsedStyle.defY=e.parsedStyle.path.rect.y,e.nodeName===G.PATH&&n.indexOf("transform")===-1){var r=e.parsedStyle,i=r.defX,a=i===void 0?0:i,o=r.defY,s=o===void 0?0:o;e.setLocalPosition(a,s)}},t}(),L4=function(){function t(){this.parser=Lw,this.mixer=s4}return t.prototype.postProcessor=function(e,n){if((e.nodeName===G.POLYGON||e.nodeName===G.POLYLINE)&&n.indexOf("transform")===-1){var r=e.parsedStyle,i=r.defX,a=r.defY;e.setLocalPosition(i,a)}},t}(),N4=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.mixer=Yp(0,1/0),n}return e}(Xp),R4=function(){function t(){}return t.prototype.calculator=function(e,n,r,i){return r instanceof sn?r.value==="unset"?"":r.value:"".concat(r)},t.prototype.postProcessor=function(e){e.nodeValue="".concat(e.parsedStyle.text)||""},t}(),I4=function(){function t(){}return t.prototype.calculator=function(e,n,r,i){var a=i.getAttribute("text");if(a){var o=a;r.value==="capitalize"?o=a.charAt(0).toUpperCase()+a.slice(1):r.value==="lowercase"?o=a.toLowerCase():r.value==="uppercase"&&(o=a.toUpperCase()),i.parsedStyle.text=o}return r.value},t}(),Gf={},j4=0;function D4(t,e){if(t){var n=typeof t=="string"?t:t.id||j4++;Gf[n]&&Gf[n].destroy(),Gf[n]=e}}var Vs=typeof window<"u"&&typeof window.document<"u";function $4(t){return!!t.getAttribute}function B4(t,e){for(var n=0,r=t.length;n>>1;Rw(t[i],e)<0?n=i+1:r=i}return n}function Rw(t,e){var n=Number(t.parsedStyle.zIndex),r=Number(e.parsedStyle.zIndex);if(n===r){var i=t.parentNode;if(i){var a=i.childNodes||[];return a.indexOf(t)-a.indexOf(e)}}return n-r}function Iw(t){var e,n=t;do{var r=(e=n.parsedStyle)===null||e===void 0?void 0:e.clipPath;if(r)return n;n=n.parentElement}while(n!==null);return null}var ty="px";function F4(t,e,n){Vs&&t.style&&(t.style.width=e+ty,t.style.height=n+ty)}function jw(t,e){if(Vs)return document.defaultView.getComputedStyle(t,null).getPropertyValue(e)}function z4(t){var e=jw(t,"width");return e==="auto"?t.offsetWidth:parseFloat(e)}function G4(t){var e=jw(t,"height");return e==="auto"?t.offsetHeight:parseFloat(e)}var Y4=1,W4={touchstart:"pointerdown",touchend:"pointerup",touchendoutside:"pointerupoutside",touchmove:"pointermove",touchcancel:"pointercancel"},sh=typeof performance=="object"&&performance.now?performance:Date;function Ki(t,e,n){var r=!1,i=!1,a=!!e&&!e.isNone,o=!!n&&!n.isNone;return t==="visiblepainted"||t==="painted"||t==="auto"?(r=a,i=o):t==="visiblefill"||t==="fill"?r=!0:t==="visiblestroke"||t==="stroke"?i=!0:(t==="visible"||t==="all")&&(r=!0,i=!0),[r,i]}var H4=1,V4=function(){return H4++},sr=typeof self=="object"&&self.self==self?self:typeof global=="object"&&global.global==global?global:{},X4=Date.now(),U4=function(){return sr.performance&&typeof sr.performance.now=="function"?sr.performance.now():Date.now()-X4},Eo={},ey=Date.now(),q4=function(t){if(typeof t!="function")throw new TypeError(t+" is not a function");var e=Date.now(),n=e-ey,r=n>16?0:16-n,i=V4();return Eo[i]=t,Object.keys(Eo).length>1||setTimeout(function(){ey=e;var a=Eo;Eo={},Object.keys(a).forEach(function(o){return a[o](U4())})},r),i},K4=function(t){delete Eo[t]},Z4=["","webkit","moz","ms","o"],Dw=function(t){return typeof t!="string"?q4:t===""?sr.requestAnimationFrame:sr[t+"RequestAnimationFrame"]},Q4=function(t){return typeof t!="string"?K4:t===""?sr.cancelAnimationFrame:sr[t+"CancelAnimationFrame"]||sr[t+"CancelRequestAnimationFrame"]},J4=function(t,e){for(var n=0;t[n]!==void 0;){if(e(t[n]))return t[n];n=n+1}},$w=J4(Z4,function(t){return!!Dw(t)}),Bw=Dw($w),Fw=Q4($w);sr.requestAnimationFrame=Bw;sr.cancelAnimationFrame=Fw;var tR=function(){function t(){this.callbacks=[]}return t.prototype.getCallbacksNum=function(){return this.callbacks.length},t.prototype.tapPromise=function(e,n){this.callbacks.push(n)},t.prototype.promise=function(){for(var e=[],n=0;n=0;c--){var l=s[c].trim();!rR.test(l)&&nR.indexOf(l)<0&&(l='"'.concat(l,'"')),s[c]=l}return"".concat(r," ").concat(i," ").concat(a," ").concat(o," ").concat(s.join(","))}var aR=function(){function t(){this.parser=Hp,this.parserUnmemoize=Kg,this.parserWithCSSDisabled=Kg,this.mixer=g4}return t.prototype.calculator=function(e,n,r,i){return r instanceof sn?[]:r},t.prototype.postProcessor=function(e){var n=e.parsedStyle.transform;Up(n,e)},t}(),oR=function(){function t(){this.parser=Nw,this.parserUnmemoize=y4}return t}(),sR=function(){function t(){this.parser=zi,this.parserUnmemoize=no}return t.prototype.calculator=function(e,n,r,i){return r.value},t.prototype.postProcessor=function(e){if(e.parentNode){var n=e.parentNode,r=n.renderable,i=n.sortable;r&&(r.dirty=!0),i&&(i.dirty=!0,i.dirtyReason=$a.Z_INDEX_CHANGED)}},t}(),cR=function(){function t(){}return t.prototype.update=function(e,n){var r=e.r,i=r*2,a=r*2;return{width:i,height:a}},t}(),lR=function(){function t(){}return t.prototype.update=function(e,n){var r=e.rx,i=e.ry,a=r*2,o=i*2;return{width:a,height:o}},t}(),uR=function(){function t(){}return t.prototype.update=function(e){var n=e.x1,r=e.y1,i=e.x2,a=e.y2,o=Math.min(n,i),s=Math.max(n,i),c=Math.min(r,a),l=Math.max(r,a),u=s-o,f=l-c;return{width:u,height:f}},t}(),fR=function(){function t(){}return t.prototype.update=function(e){var n=e.path,r=n.rect,i=r.width,a=r.height;return{width:i,height:a}},t}(),dR=function(){function t(){}return t.prototype.update=function(e){if(e.points&&Le(e.points.points)){var n=e.points.points,r=Math.min.apply(Math,q([],N(n.map(function(l){return l[0]})),!1)),i=Math.max.apply(Math,q([],N(n.map(function(l){return l[0]})),!1)),a=Math.min.apply(Math,q([],N(n.map(function(l){return l[1]})),!1)),o=Math.max.apply(Math,q([],N(n.map(function(l){return l[1]})),!1)),s=i-r,c=o-a;return{width:s,height:c}}return{width:0,height:0}},t}(),hR=function(){function t(){}return t.prototype.update=function(e,n){var r=e.img,i=e.width,a=i===void 0?0:i,o=e.height,s=o===void 0?0:o,c=a,l=s;return r&&!le(r)&&(c||(c=r.width,e.width=c),l||(l=r.height,e.height=l)),{width:c,height:l}},t}(),pR=function(){function t(e){this.globalRuntime=e}return t.prototype.isReadyToMeasure=function(e,n){var r=e.text,i=e.textAlign,a=e.textBaseline,o=e.fontSize,s=e.fontStyle,c=e.fontWeight,l=e.fontVariant,u=e.lineWidth;return r&&o&&s&&c&&l&&i&&a&&!nt(u)},t.prototype.update=function(e,n){var r,i,a=e.text,o=e.textAlign,s=e.lineWidth,c=e.textBaseline,l=e.dx,u=e.dy;if(!this.isReadyToMeasure(e,n))return e.metrics={font:"",width:0,height:0,lines:[],lineWidths:[],lineHeight:0,maxLineWidth:0,fontProperties:{ascent:0,descent:0,fontSize:0},lineMetrics:[]},{width:0,height:0,x:0,y:0,offsetX:0,offsetY:0};var f=(((i=(r=n==null?void 0:n.ownerDocument)===null||r===void 0?void 0:r.defaultView)===null||i===void 0?void 0:i.getConfig())||{}).offscreenCanvas,d=this.globalRuntime.textService.measureText(a,e,f);e.metrics=d;var h=d.width,p=d.height,v=d.lineHeight,g=d.fontProperties,y=[h/2,p/2,0],m=[0,1],b=0;o==="center"||o==="middle"?(b=s/2,m=[.5,1]):(o==="right"||o==="end")&&(b=s,m=[1,1]);var x=0;return c==="middle"?x=y[1]:c==="top"||c==="hanging"?x=y[1]*2:c==="alphabetic"?x=this.globalRuntime.enableCSSParsing?v-g.ascent:0:(c==="bottom"||c==="ideographic")&&(x=0),l&&(b+=l),u&&(x+=u),e.anchor=[m[0],m[1],0],{width:y[0]*2,height:y[1]*2,offsetX:b,offsetY:x}},t}();function vR(t){return!!t.type}var $u=function(){function t(e){this.eventPhase=t.prototype.NONE,this.bubbles=!0,this.cancelBubble=!0,this.cancelable=!1,this.defaultPrevented=!1,this.propagationStopped=!1,this.propagationImmediatelyStopped=!1,this.layer=new Ee,this.page=new Ee,this.canvas=new Ee,this.viewport=new Ee,this.composed=!1,this.NONE=0,this.CAPTURING_PHASE=1,this.AT_TARGET=2,this.BUBBLING_PHASE=3,this.manager=e}return Object.defineProperty(t.prototype,"name",{get:function(){return this.type},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layerX",{get:function(){return this.layer.x},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layerY",{get:function(){return this.layer.y},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"pageX",{get:function(){return this.page.x},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"pageY",{get:function(){return this.page.y},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"x",{get:function(){return this.canvas.x},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"y",{get:function(){return this.canvas.y},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"canvasX",{get:function(){return this.canvas.x},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"canvasY",{get:function(){return this.canvas.y},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"viewportX",{get:function(){return this.viewport.x},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"viewportY",{get:function(){return this.viewport.y},enumerable:!1,configurable:!0}),t.prototype.composedPath=function(){return this.manager&&(!this.path||this.path[0]!==this.target)&&(this.path=this.target?this.manager.propagationPath(this.target):[]),this.path},Object.defineProperty(t.prototype,"propagationPath",{get:function(){return this.composedPath()},enumerable:!1,configurable:!0}),t.prototype.preventDefault=function(){this.nativeEvent instanceof Event&&this.nativeEvent.cancelable&&this.nativeEvent.preventDefault(),this.defaultPrevented=!0},t.prototype.stopImmediatePropagation=function(){this.propagationImmediatelyStopped=!0},t.prototype.stopPropagation=function(){this.propagationStopped=!0},t.prototype.initEvent=function(){},t.prototype.initUIEvent=function(){},t.prototype.clone=function(){throw new Error(It)},t}(),zw=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.client=new Ee,n.movement=new Ee,n.offset=new Ee,n.global=new Ee,n.screen=new Ee,n}return Object.defineProperty(e.prototype,"clientX",{get:function(){return this.client.x},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"clientY",{get:function(){return this.client.y},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"movementX",{get:function(){return this.movement.x},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"movementY",{get:function(){return this.movement.y},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"offsetX",{get:function(){return this.offset.x},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"offsetY",{get:function(){return this.offset.y},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"globalX",{get:function(){return this.global.x},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"globalY",{get:function(){return this.global.y},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"screenX",{get:function(){return this.screen.x},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"screenY",{get:function(){return this.screen.y},enumerable:!1,configurable:!0}),e.prototype.getModifierState=function(n){return"getModifierState"in this.nativeEvent&&this.nativeEvent.getModifierState(n)},e.prototype.initMouseEvent=function(){throw new Error(It)},e}($u),ch=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.width=0,n.height=0,n.isPrimary=!1,n}return e.prototype.getCoalescedEvents=function(){return this.type==="pointermove"||this.type==="mousemove"||this.type==="touchmove"?[this]:[]},e.prototype.getPredictedEvents=function(){throw new Error("getPredictedEvents is not supported!")},e.prototype.clone=function(){return this.manager.clonePointerEvent(this)},e}(zw),lh=function(t){rt(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.clone=function(){return this.manager.cloneWheelEvent(this)},e}(zw),Dt=function(t){rt(e,t);function e(n,r){var i=t.call(this,null)||this;return i.type=n,i.detail=r,Object.assign(i,r),i}return e}($u),ny=":",Gw=function(){function t(){this.emitter=new $p}return t.prototype.on=function(e,n,r){return this.addEventListener(e,n,r),this},t.prototype.addEventListener=function(e,n,r){var i=Xv(r)&&r||ki(r)&&r.capture,a=ki(r)&&r.once,o=ga(n)?void 0:n,s=!1,c="";if(e.indexOf(ny)>-1){var l=N(e.split(ny),2),u=l[0],f=l[1];e=f,c=u,s=!0}if(e=i?"".concat(e,"capture"):e,n=ga(n)?n:n.handleEvent,s){var d=n;n=function(){for(var h,p=[],v=0;v0},e.prototype.isDefaultNamespace=function(n){throw new Error(It)},e.prototype.lookupNamespaceURI=function(n){throw new Error(It)},e.prototype.lookupPrefix=function(n){throw new Error(It)},e.prototype.normalize=function(){throw new Error(It)},e.prototype.isEqualNode=function(n){return this===n},e.prototype.isSameNode=function(n){return this.isEqualNode(n)},Object.defineProperty(e.prototype,"parent",{get:function(){return this.parentNode},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"parentElement",{get:function(){return null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"nextSibling",{get:function(){return null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"previousSibling",{get:function(){return null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"firstChild",{get:function(){return this.childNodes.length>0?this.childNodes[0]:null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"lastChild",{get:function(){return this.childNodes.length>0?this.childNodes[this.childNodes.length-1]:null},enumerable:!1,configurable:!0}),e.prototype.compareDocumentPosition=function(n){var r;if(n===this)return 0;for(var i=n,a=this,o=[i],s=[a];(r=i.parentNode)!==null&&r!==void 0?r:a.parentNode;)i=i.parentNode?(o.push(i.parentNode),i.parentNode):i,a=a.parentNode?(s.push(a.parentNode),a.parentNode):a;if(i!==a)return e.DOCUMENT_POSITION_DISCONNECTED|e.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|e.DOCUMENT_POSITION_PRECEDING;var c=o.length>s.length?o:s,l=c===o?s:o;if(c[c.length-l.length]===l[0])return c===o?e.DOCUMENT_POSITION_CONTAINED_BY|e.DOCUMENT_POSITION_FOLLOWING:e.DOCUMENT_POSITION_CONTAINS|e.DOCUMENT_POSITION_PRECEDING;for(var u=c.length-l.length,f=l.length-1;f>=0;f--){var d=l[f],h=c[u+f];if(h!==d){var p=d.parentNode.childNodes;return p.indexOf(d)0&&r;)r=r.parentNode,n--;return r},e.prototype.forEach=function(n,r){r===void 0&&(r=!1),n(this)||(r?this.childNodes.slice():this.childNodes).forEach(function(i){i.forEach(n)})},e.DOCUMENT_POSITION_DISCONNECTED=1,e.DOCUMENT_POSITION_PRECEDING=2,e.DOCUMENT_POSITION_FOLLOWING=4,e.DOCUMENT_POSITION_CONTAINS=8,e.DOCUMENT_POSITION_CONTAINED_BY=16,e.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC=32,e}(Gw),gR=2048,yR=function(){function t(e,n){var r=this;this.globalRuntime=e,this.context=n,this.emitter=new $p,this.nativeHTMLMap=new WeakMap,this.cursor="default",this.mappingTable={},this.mappingState={trackingData:{}},this.eventPool=new Map,this.tmpMatrix=Nt(),this.tmpVec3=yt(),this.onPointerDown=function(i){var a=r.createPointerEvent(i);if(r.dispatchEvent(a,"pointerdown"),a.pointerType==="touch")r.dispatchEvent(a,"touchstart");else if(a.pointerType==="mouse"||a.pointerType==="pen"){var o=a.button===2;r.dispatchEvent(a,o?"rightdown":"mousedown")}var s=r.trackingData(i.pointerId);s.pressTargetsByButton[i.button]=a.composedPath(),r.freeEvent(a)},this.onPointerUp=function(i){var a,o=sh.now(),s=r.createPointerEvent(i,void 0,void 0,r.context.config.alwaysTriggerPointerEventOnCanvas?r.rootTarget:void 0);if(r.dispatchEvent(s,"pointerup"),s.pointerType==="touch")r.dispatchEvent(s,"touchend");else if(s.pointerType==="mouse"||s.pointerType==="pen"){var c=s.button===2;r.dispatchEvent(s,c?"rightup":"mouseup")}var l=r.trackingData(i.pointerId),u=r.findMountedTarget(l.pressTargetsByButton[i.button]),f=u;if(u&&!s.composedPath().includes(u)){for(var d=u;d&&!s.composedPath().includes(d);){if(s.currentTarget=d,r.notifyTarget(s,"pointerupoutside"),s.pointerType==="touch")r.notifyTarget(s,"touchendoutside");else if(s.pointerType==="mouse"||s.pointerType==="pen"){var c=s.button===2;r.notifyTarget(s,c?"rightupoutside":"mouseupoutside")}_e.isNode(d)&&(d=d.parentNode)}delete l.pressTargetsByButton[i.button],f=d}if(f){var h=r.clonePointerEvent(s,"click");h.target=f,h.path=[],l.clicksByButton[i.button]||(l.clicksByButton[i.button]={clickCount:0,target:h.target,timeStamp:o});var p=l.clicksByButton[i.button];p.target===h.target&&o-p.timeStamp<200?++p.clickCount:p.clickCount=1,p.target=h.target,p.timeStamp=o,h.detail=p.clickCount,!((a=s.detail)===null||a===void 0)&&a.preventClick||(!r.context.config.useNativeClickEvent&&(h.pointerType==="mouse"||h.pointerType==="touch")&&r.dispatchEvent(h,"click"),r.dispatchEvent(h,"pointertap")),r.freeEvent(h)}r.freeEvent(s)},this.onPointerMove=function(i){var a=r.createPointerEvent(i,void 0,void 0,r.context.config.alwaysTriggerPointerEventOnCanvas?r.rootTarget:void 0),o=a.pointerType==="mouse"||a.pointerType==="pen",s=r.trackingData(i.pointerId),c=r.findMountedTarget(s.overTargets);if(s.overTargets&&c!==a.target){var l=i.type==="mousemove"?"mouseout":"pointerout",u=r.createPointerEvent(i,l,c||void 0);if(r.dispatchEvent(u,"pointerout"),o&&r.dispatchEvent(u,"mouseout"),!a.composedPath().includes(c)){var f=r.createPointerEvent(i,"pointerleave",c||void 0);for(f.eventPhase=f.AT_TARGET;f.target&&!a.composedPath().includes(f.target);)f.currentTarget=f.target,r.notifyTarget(f),o&&r.notifyTarget(f,"mouseleave"),_e.isNode(f.target)&&(f.target=f.target.parentNode);r.freeEvent(f)}r.freeEvent(u)}if(c!==a.target){var d=i.type==="mousemove"?"mouseover":"pointerover",h=r.clonePointerEvent(a,d);r.dispatchEvent(h,"pointerover"),o&&r.dispatchEvent(h,"mouseover");for(var p=c&&_e.isNode(c)&&c.parentNode;p&&p!==(_e.isNode(r.rootTarget)&&r.rootTarget.parentNode)&&p!==a.target;)p=p.parentNode;var v=!p||p===(_e.isNode(r.rootTarget)&&r.rootTarget.parentNode);if(v){var g=r.clonePointerEvent(a,"pointerenter");for(g.eventPhase=g.AT_TARGET;g.target&&g.target!==c&&g.target!==(_e.isNode(r.rootTarget)&&r.rootTarget.parentNode);)g.currentTarget=g.target,r.notifyTarget(g),o&&r.notifyTarget(g,"mouseenter"),_e.isNode(g.target)&&(g.target=g.target.parentNode);r.freeEvent(g)}r.freeEvent(h)}r.dispatchEvent(a,"pointermove"),a.pointerType==="touch"&&r.dispatchEvent(a,"touchmove"),o&&(r.dispatchEvent(a,"mousemove"),r.cursor=r.getCursor(a.target)),s.overTargets=a.composedPath(),r.freeEvent(a)},this.onPointerOut=function(i){var a=r.trackingData(i.pointerId);if(a.overTargets){var o=i.pointerType==="mouse"||i.pointerType==="pen",s=r.findMountedTarget(a.overTargets),c=r.createPointerEvent(i,"pointerout",s||void 0);r.dispatchEvent(c),o&&r.dispatchEvent(c,"mouseout");var l=r.createPointerEvent(i,"pointerleave",s||void 0);for(l.eventPhase=l.AT_TARGET;l.target&&l.target!==(_e.isNode(r.rootTarget)&&r.rootTarget.parentNode);)l.currentTarget=l.target,r.notifyTarget(l),o&&r.notifyTarget(l,"mouseleave"),_e.isNode(l.target)&&(l.target=l.target.parentNode);a.overTargets=null,r.freeEvent(c),r.freeEvent(l)}r.cursor=null},this.onPointerOver=function(i){var a=r.trackingData(i.pointerId),o=r.createPointerEvent(i),s=o.pointerType==="mouse"||o.pointerType==="pen";r.dispatchEvent(o,"pointerover"),s&&r.dispatchEvent(o,"mouseover"),o.pointerType==="mouse"&&(r.cursor=r.getCursor(o.target));var c=r.clonePointerEvent(o,"pointerenter");for(c.eventPhase=c.AT_TARGET;c.target&&c.target!==(_e.isNode(r.rootTarget)&&r.rootTarget.parentNode);)c.currentTarget=c.target,r.notifyTarget(c),s&&r.notifyTarget(c,"mouseenter"),_e.isNode(c.target)&&(c.target=c.target.parentNode);a.overTargets=o.composedPath(),r.freeEvent(o),r.freeEvent(c)},this.onPointerUpOutside=function(i){var a=r.trackingData(i.pointerId),o=r.findMountedTarget(a.pressTargetsByButton[i.button]),s=r.createPointerEvent(i);if(o){for(var c=o;c;)s.currentTarget=c,r.notifyTarget(s,"pointerupoutside"),s.pointerType==="touch"||(s.pointerType==="mouse"||s.pointerType==="pen")&&r.notifyTarget(s,s.button===2?"rightupoutside":"mouseupoutside"),_e.isNode(c)&&(c=c.parentNode);delete a.pressTargetsByButton[i.button]}r.freeEvent(s)},this.onWheel=function(i){var a=r.createWheelEvent(i);r.dispatchEvent(a),r.freeEvent(a)},this.onClick=function(i){if(r.context.config.useNativeClickEvent){var a=r.createPointerEvent(i);r.dispatchEvent(a),r.freeEvent(a)}},this.onPointerCancel=function(i){var a=r.createPointerEvent(i,void 0,void 0,r.context.config.alwaysTriggerPointerEventOnCanvas?r.rootTarget:void 0);r.dispatchEvent(a),r.freeEvent(a)}}return t.prototype.init=function(){this.rootTarget=this.context.renderingContext.root.parentNode,this.addEventMapping("pointerdown",this.onPointerDown),this.addEventMapping("pointerup",this.onPointerUp),this.addEventMapping("pointermove",this.onPointerMove),this.addEventMapping("pointerout",this.onPointerOut),this.addEventMapping("pointerleave",this.onPointerOut),this.addEventMapping("pointercancel",this.onPointerCancel),this.addEventMapping("pointerover",this.onPointerOver),this.addEventMapping("pointerupoutside",this.onPointerUpOutside),this.addEventMapping("wheel",this.onWheel),this.addEventMapping("click",this.onClick)},t.prototype.destroy=function(){this.emitter.removeAllListeners(),this.mappingTable={},this.mappingState={},this.eventPool.clear()},t.prototype.client2Viewport=function(e){var n=this.context.contextService.getBoundingClientRect();return new Ee(e.x-((n==null?void 0:n.left)||0),e.y-((n==null?void 0:n.top)||0))},t.prototype.viewport2Client=function(e){var n=this.context.contextService.getBoundingClientRect();return new Ee(e.x+((n==null?void 0:n.left)||0),e.y+((n==null?void 0:n.top)||0))},t.prototype.viewport2Canvas=function(e){var n=e.x,r=e.y,i=this.rootTarget.defaultView,a=i.getCamera(),o=this.context.config,s=o.width,c=o.height,l=a.getPerspectiveInverse(),u=a.getWorldTransform(),f=$e(this.tmpMatrix,u,l),d=Gn(this.tmpVec3,n/s*2-1,(1-r/c)*2-1,0);return Oe(d,d,f),new Ee(d[0],d[1])},t.prototype.canvas2Viewport=function(e){var n=this.rootTarget.defaultView,r=n.getCamera(),i=r.getPerspective(),a=r.getViewTransform(),o=$e(this.tmpMatrix,i,a),s=Gn(this.tmpVec3,e.x,e.y,0);Oe(this.tmpVec3,this.tmpVec3,o);var c=this.context.config,l=c.width,u=c.height;return new Ee((s[0]+1)/2*l,(1-(s[1]+1)/2)*u)},t.prototype.setPickHandler=function(e){this.pickHandler=e},t.prototype.addEventMapping=function(e,n){this.mappingTable[e]||(this.mappingTable[e]=[]),this.mappingTable[e].push({fn:n,priority:0}),this.mappingTable[e].sort(function(r,i){return r.priority-i.priority})},t.prototype.mapEvent=function(e){if(this.rootTarget){var n=this.mappingTable[e.type];if(n)for(var r=0,i=n.length;r=1;i--)if(e.currentTarget=r[i],this.notifyTarget(e,n),e.propagationStopped||e.propagationImmediatelyStopped)return;if(e.eventPhase=e.AT_TARGET,e.currentTarget=e.target,this.notifyTarget(e,n),!(e.propagationStopped||e.propagationImmediatelyStopped)){var a=r.indexOf(e.currentTarget);e.eventPhase=e.BUBBLING_PHASE;for(var i=a+1;ia||r>o?null:!s&&this.pickHandler(e)||this.rootTarget||null},t.prototype.isNativeEventFromCanvas=function(e){var n,r=this.context.contextService.getDomElement(),i=(n=e.nativeEvent)===null||n===void 0?void 0:n.target;if(i){if(i===r)return!0;if(r&&r.contains)return r.contains(i)}return e.nativeEvent.composedPath?e.nativeEvent.composedPath().indexOf(r)>-1:!1},t.prototype.getExistedHTML=function(e){var n,r;if(e.nativeEvent.composedPath)try{for(var i=vn(e.nativeEvent.composedPath()),a=i.next();!a.done;a=i.next()){var o=a.value,s=this.nativeHTMLMap.get(o);if(s)return s}}catch(c){n={error:c}}finally{try{a&&!a.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return null},t.prototype.pickTarget=function(e){return this.hitTest({clientX:e.clientX,clientY:e.clientY,viewportX:e.viewportX,viewportY:e.viewportY,x:e.canvasX,y:e.canvasY})},t.prototype.createPointerEvent=function(e,n,r,i){var a=this.allocateEvent(ch);this.copyPointerData(e,a),this.copyMouseData(e,a),this.copyData(e,a),a.nativeEvent=e.nativeEvent,a.originalEvent=e;var o=this.getExistedHTML(a);return a.target=r??(o||this.isNativeEventFromCanvas(a)&&this.pickTarget(a)||i),typeof n=="string"&&(a.type=n),a},t.prototype.createWheelEvent=function(e){var n=this.allocateEvent(lh);this.copyWheelData(e,n),this.copyMouseData(e,n),this.copyData(e,n),n.nativeEvent=e.nativeEvent,n.originalEvent=e;var r=this.getExistedHTML(n);return n.target=r||this.isNativeEventFromCanvas(n)&&this.pickTarget(n),n},t.prototype.trackingData=function(e){return this.mappingState.trackingData[e]||(this.mappingState.trackingData[e]={pressTargetsByButton:{},clicksByButton:{},overTarget:null}),this.mappingState.trackingData[e]},t.prototype.cloneWheelEvent=function(e){var n=this.allocateEvent(lh);return n.nativeEvent=e.nativeEvent,n.originalEvent=e.originalEvent,this.copyWheelData(e,n),this.copyMouseData(e,n),this.copyData(e,n),n.target=e.target,n.path=e.composedPath().slice(),n.type=e.type,n},t.prototype.clonePointerEvent=function(e,n){var r=this.allocateEvent(ch);return r.nativeEvent=e.nativeEvent,r.originalEvent=e.originalEvent,this.copyPointerData(e,r),this.copyMouseData(e,r),this.copyData(e,r),r.target=e.target,r.path=e.composedPath().slice(),r.type=n??r.type,r},t.prototype.copyPointerData=function(e,n){n.pointerId=e.pointerId,n.width=e.width,n.height=e.height,n.isPrimary=e.isPrimary,n.pointerType=e.pointerType,n.pressure=e.pressure,n.tangentialPressure=e.tangentialPressure,n.tiltX=e.tiltX,n.tiltY=e.tiltY,n.twist=e.twist},t.prototype.copyMouseData=function(e,n){n.altKey=e.altKey,n.button=e.button,n.buttons=e.buttons,n.ctrlKey=e.ctrlKey,n.metaKey=e.metaKey,n.shiftKey=e.shiftKey,n.client.copyFrom(e.client),n.movement.copyFrom(e.movement),n.canvas.copyFrom(e.canvas),n.screen.copyFrom(e.screen),n.global.copyFrom(e.global),n.offset.copyFrom(e.offset)},t.prototype.copyWheelData=function(e,n){n.deltaMode=e.deltaMode,n.deltaX=e.deltaX,n.deltaY=e.deltaY,n.deltaZ=e.deltaZ},t.prototype.copyData=function(e,n){n.isTrusted=e.isTrusted,n.timeStamp=sh.now(),n.type=e.type,n.detail=e.detail,n.view=e.view,n.page.copyFrom(e.page),n.viewport.copyFrom(e.viewport)},t.prototype.allocateEvent=function(e){this.eventPool.has(e)||this.eventPool.set(e,[]);var n=this.eventPool.get(e).pop()||new e(this);return n.eventPhase=n.NONE,n.currentTarget=null,n.path=[],n.target=null,n},t.prototype.freeEvent=function(e){if(e.manager!==this)throw new Error("It is illegal to free an event not managed by this EventBoundary!");var n=e.constructor;this.eventPool.has(n)||this.eventPool.set(n,[]),this.eventPool.get(n).push(e)},t.prototype.notifyTarget=function(e,n){n=n??e.type;var r=e.eventPhase===e.CAPTURING_PHASE||e.eventPhase===e.AT_TARGET?"".concat(n,"capture"):n;this.notifyListeners(e,r),e.eventPhase===e.AT_TARGET&&this.notifyListeners(e,n)},t.prototype.notifyListeners=function(e,n){var r=e.currentTarget.emitter,i=r._events[n];if(i)if("fn"in i)i.once&&r.removeListener(n,i.fn,void 0,!0),i.fn.call(e.currentTarget||i.context,e);else for(var a=0;a=0;r--){var i=e[r];if(i===this.rootTarget||_e.isNode(i)&&i.parentNode===n)n=e[r];else break}return n},t.prototype.getCursor=function(e){for(var n=e;n;){var r=$4(n)&&n.getAttribute("cursor");if(r)return r;n=_e.isNode(n)&&n.parentNode}},t}(),mR=function(){function t(){}return t.prototype.getOrCreateCanvas=function(e,n){if(this.canvas)return this.canvas;if(e||H.offscreenCanvas)this.canvas=e||H.offscreenCanvas,this.context=this.canvas.getContext("2d",z({willReadFrequently:!0},n));else try{this.canvas=new window.OffscreenCanvas(0,0),this.context=this.canvas.getContext("2d",z({willReadFrequently:!0},n)),(!this.context||!this.context.measureText)&&(this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"))}catch{this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d",z({willReadFrequently:!0},n))}return this.canvas.width=10,this.canvas.height=10,this.canvas},t.prototype.getOrCreateContext=function(e,n){return this.context?this.context:(this.getOrCreateCanvas(e,n),this.context)},t}(),Qr;(function(t){t[t.CAMERA_CHANGED=0]="CAMERA_CHANGED",t[t.DISPLAY_OBJECT_CHANGED=1]="DISPLAY_OBJECT_CHANGED",t[t.NONE=2]="NONE"})(Qr||(Qr={}));var bR=function(){function t(e,n){this.globalRuntime=e,this.context=n,this.inited=!1,this.stats={total:0,rendered:0},this.zIndexCounter=0,this.hooks={init:new Ye,initAsync:new tR,dirtycheck:new Yf,cull:new Yf,beginFrame:new Ye,beforeRender:new Ye,render:new Ye,afterRender:new Ye,endFrame:new Ye,destroy:new Ye,pick:new eR,pickSync:new Yf,pointerDown:new Ye,pointerUp:new Ye,pointerMove:new Ye,pointerOut:new Ye,pointerOver:new Ye,pointerWheel:new Ye,pointerCancel:new Ye,click:new Ye}}return t.prototype.init=function(e){var n=this,r=z(z({},this.globalRuntime),this.context);this.context.renderingPlugins.forEach(function(i){i.apply(r,n.globalRuntime)}),this.hooks.init.call(),this.hooks.initAsync.getCallbacksNum()===0?(this.inited=!0,e()):this.hooks.initAsync.promise().then(function(){n.inited=!0,e()})},t.prototype.getStats=function(){return this.stats},t.prototype.disableDirtyRectangleRendering=function(){var e=this.context.config.renderer,n=e.getConfig().enableDirtyRectangleRendering;return!n||this.context.renderingContext.renderReasons.has(Qr.CAMERA_CHANGED)},t.prototype.render=function(e,n){var r=this;this.stats.total=0,this.stats.rendered=0,this.zIndexCounter=0;var i=this.context.renderingContext;if(this.globalRuntime.sceneGraphService.syncHierarchy(i.root),this.globalRuntime.sceneGraphService.triggerPendingEvents(),i.renderReasons.size&&this.inited){i.dirtyRectangleRenderingDisabled=this.disableDirtyRectangleRendering();var a=i.renderReasons.size===1&&i.renderReasons.has(Qr.CAMERA_CHANGED),o=!e.disableRenderHooks||!(e.disableRenderHooks&&a);o&&this.renderDisplayObject(i.root,e,i),this.hooks.beginFrame.call(),o&&i.renderListCurrentFrame.forEach(function(s){r.hooks.beforeRender.call(s),r.hooks.render.call(s),r.hooks.afterRender.call(s)}),this.hooks.endFrame.call(),i.renderListCurrentFrame=[],i.renderReasons.clear(),n()}},t.prototype.renderDisplayObject=function(e,n,r){var i=this,a=n.renderer.getConfig(),o=a.enableDirtyCheck,s=a.enableCulling;this.globalRuntime.enableCSSParsing&&this.globalRuntime.styleValueRegistry.recalc(e);var c=e.renderable,l=o?c.dirty||r.dirtyRectangleRenderingDisabled?e:null:e;if(l){var u=s?this.hooks.cull.call(l,this.context.camera):l;u&&(this.stats.rendered++,r.renderListCurrentFrame.push(u))}e.renderable.dirty=!1,e.sortable.renderOrder=this.zIndexCounter++,this.stats.total++;var f=e.sortable;f.dirty&&(this.sort(e,f),f.dirty=!1,f.dirtyChildren=[],f.dirtyReason=void 0),(f.sorted||e.childNodes).forEach(function(d){i.renderDisplayObject(d,n,r)})},t.prototype.sort=function(e,n){n.sorted&&n.dirtyReason!==$a.Z_INDEX_CHANGED?n.dirtyChildren.forEach(function(r){var i=e.childNodes.indexOf(r);if(i===-1){var a=n.sorted.indexOf(r);a>=0&&n.sorted.splice(a,1)}else if(n.sorted.length===0)n.sorted.push(r);else{var o=B4(n.sorted,r);n.sorted.splice(o,0,r)}}):n.sorted=e.childNodes.slice().sort(Rw)},t.prototype.destroy=function(){this.inited=!1,this.hooks.destroy.call(),this.globalRuntime.sceneGraphService.clearPendingEvents()},t.prototype.dirtify=function(){this.context.renderingContext.renderReasons.add(Qr.DISPLAY_OBJECT_CHANGED)},t}(),xR=/\[\s*(.*)=(.*)\s*\]/,wR=function(){function t(){}return t.prototype.selectOne=function(e,n){var r=this;if(e.startsWith("."))return n.find(function(s){return((s==null?void 0:s.classList)||[]).indexOf(r.getIdOrClassname(e))>-1});if(e.startsWith("#"))return n.find(function(s){return s.id===r.getIdOrClassname(e)});if(e.startsWith("[")){var i=this.getAttribute(e),a=i.name,o=i.value;return a?n.find(function(s){return n!==s&&(a==="name"?s.name===o:r.attributeToString(s,a)===o)}):null}else return n.find(function(s){return n!==s&&s.nodeName===e})},t.prototype.selectAll=function(e,n){var r=this;if(e.startsWith("."))return n.findAll(function(s){return n!==s&&((s==null?void 0:s.classList)||[]).indexOf(r.getIdOrClassname(e))>-1});if(e.startsWith("#"))return n.findAll(function(s){return n!==s&&s.id===r.getIdOrClassname(e)});if(e.startsWith("[")){var i=this.getAttribute(e),a=i.name,o=i.value;return a?n.findAll(function(s){return n!==s&&(a==="name"?s.name===o:r.attributeToString(s,a)===o)}):[]}else return n.findAll(function(s){return n!==s&&s.nodeName===e})},t.prototype.is=function(e,n){if(e.startsWith("."))return n.className===this.getIdOrClassname(e);if(e.startsWith("#"))return n.id===this.getIdOrClassname(e);if(e.startsWith("[")){var r=this.getAttribute(e),i=r.name,a=r.value;return i==="name"?n.name===a:this.attributeToString(n,i)===a}else return n.nodeName===e},t.prototype.getIdOrClassname=function(e){return e.substring(1)},t.prototype.getAttribute=function(e){var n=e.match(xR),r="",i="";return n&&n.length>2&&(r=n[1].replace(/"/g,""),i=n[2].replace(/"/g,"")),{name:r,value:i}},t.prototype.attributeToString=function(e,n){if(!e.getAttribute)return"";var r=e.getAttribute(n);return nt(r)?"":r.toString?r.toString():""},t}(),Gi=function(t){rt(e,t);function e(n,r,i,a,o,s,c,l){var u=t.call(this,null)||this;return u.relatedNode=r,u.prevValue=i,u.newValue=a,u.attrName=o,u.attrChange=s,u.prevParsedValue=c,u.newParsedValue=l,u.type=n,u}return e.ADDITION=2,e.MODIFICATION=1,e.REMOVAL=3,e}($u),ht;(function(t){t.REPARENT="reparent",t.DESTROY="destroy",t.ATTR_MODIFIED="DOMAttrModified",t.INSERTED="DOMNodeInserted",t.REMOVED="removed",t.MOUNTED="DOMNodeInsertedIntoDocument",t.UNMOUNTED="DOMNodeRemovedFromDocument",t.BOUNDS_CHANGED="bounds-changed",t.CULLED="culled"})(ht||(ht={}));function ry(t){var e=t.renderable;e&&(e.renderBoundsDirty=!0,e.boundsDirty=!0)}var OR=new Gi(ht.REPARENT,null,"","","",0,"",""),SR=function(){function t(e){var n=this;this.runtime=e,this.pendingEvents=[],this.boundsChangedEvent=new Dt(ht.BOUNDS_CHANGED),this.rotate=function(){var r=ve();return function(i,a,o,s){o===void 0&&(o=0),s===void 0&&(s=0),typeof a=="number"&&(a=St(a,o,s));var c=i.transformable;if(i.parentNode===null||!i.parentNode.transformable)n.rotateLocal(i,a);else{var l=ve();oc(l,a[0],a[1],a[2]);var u=n.getRotation(i),f=n.getRotation(i.parentNode);sc(r,f),Sf(r,r),qr(l,r,l),qr(c.localRotation,l,u),ml(c.localRotation,c.localRotation),n.dirtifyLocal(i,c)}}}(),this.rotateLocal=function(){var r=ve();return function(i,a,o,s){o===void 0&&(o=0),s===void 0&&(s=0),typeof a=="number"&&(a=St(a,o,s));var c=i.transformable;oc(r,a[0],a[1],a[2]),Zv(c.localRotation,c.localRotation,r),n.dirtifyLocal(i,c)}}(),this.setEulerAngles=function(){var r=ve();return function(i,a,o,s){o===void 0&&(o=0),s===void 0&&(s=0),typeof a=="number"&&(a=St(a,o,s));var c=i.transformable;if(i.parentNode===null||!i.parentNode.transformable)n.setLocalEulerAngles(i,a);else{oc(c.localRotation,a[0],a[1],a[2]);var l=n.getRotation(i.parentNode);sc(r,Sf(ve(),l)),Zv(c.localRotation,c.localRotation,r),n.dirtifyLocal(i,c)}}}(),this.translateLocal=function(){return function(r,i,a,o){a===void 0&&(a=0),o===void 0&&(o=0),typeof i=="number"&&(i=St(i,a,o));var s=r.transformable;vo(i,yt())||(OT(i,i,s.localRotation),ba(s.localPosition,s.localPosition,i),n.dirtifyLocal(r,s))}}(),this.setPosition=function(){var r=Nt(),i=yt();return function(a,o){var s=a.transformable;if(i[0]=o[0],i[1]=o[1],i[2]=o[2]||0,!vo(n.getPosition(a),i)){if(rn(s.position,i),a.parentNode===null||!a.parentNode.transformable)rn(s.localPosition,i);else{var c=a.parentNode.transformable;Ri(r,c.worldTransform),Wn(r,r),Oe(s.localPosition,i,r)}n.dirtifyLocal(a,s)}}}(),this.setLocalPosition=function(){var r=yt();return function(i,a){var o=i.transformable;r[0]=a[0],r[1]=a[1],r[2]=a[2]||0,!vo(o.localPosition,r)&&(rn(o.localPosition,r),n.dirtifyLocal(i,o))}}(),this.translate=function(){var r=yt(),i=yt(),a=yt();return function(o,s,c,l){c===void 0&&(c=0),l===void 0&&(l=0),typeof s=="number"&&(s=Gn(i,s,c,l)),!vo(s,r)&&(ba(a,n.getPosition(o),s),n.setPosition(o,a))}}(),this.setRotation=function(){var r=ve();return function(i,a,o,s,c){var l=i.transformable;if(typeof a=="number"&&(a=_f(a,o,s,c)),i.parentNode===null||!i.parentNode.transformable)n.setLocalRotation(i,a);else{var u=n.getRotation(i.parentNode);sc(r,u),Sf(r,r),qr(l.localRotation,r,a),ml(l.localRotation,l.localRotation),n.dirtifyLocal(i,l)}}},this.displayObjectDependencyMap=new WeakMap,this.calcLocalTransform=function(){var r=Nt(),i=yt(),a=_f(0,0,0,1);return function(o){var s=o.localSkew[0]!==0||o.localSkew[1]!==0;if(s){if(zo(o.localTransform,o.localRotation,o.localPosition,St(1,1,1),o.origin),o.localSkew[0]!==0||o.localSkew[1]!==0){var c=Rs(r);c[4]=Math.tan(o.localSkew[0]),c[1]=Math.tan(o.localSkew[1]),$e(o.localTransform,o.localTransform,c)}var l=zo(r,a,i,o.localScale,o.origin);$e(o.localTransform,o.localTransform,l)}else zo(o.localTransform,o.localRotation,o.localPosition,o.localScale,o.origin)}}()}return t.prototype.matches=function(e,n){return this.runtime.sceneGraphSelector.is(e,n)},t.prototype.querySelector=function(e,n){return this.runtime.sceneGraphSelector.selectOne(e,n)},t.prototype.querySelectorAll=function(e,n){return this.runtime.sceneGraphSelector.selectAll(e,n)},t.prototype.attach=function(e,n,r){var i,a,o=!1;e.parentNode&&(o=e.parentNode!==n,this.detach(e)),e.parentNode=n,nt(r)?e.parentNode.childNodes.push(e):e.parentNode.childNodes.splice(r,0,e);var s=n.sortable;(!((i=s==null?void 0:s.sorted)===null||i===void 0)&&i.length||!((a=e.style)===null||a===void 0)&&a.zIndex)&&(s.dirtyChildren.indexOf(e)===-1&&s.dirtyChildren.push(e),s.dirty=!0,s.dirtyReason=$a.ADDED);var c=e.transformable;c&&this.dirtifyWorld(e,c),c.frozen&&this.unfreezeParentToRoot(e),o&&e.dispatchEvent(OR)},t.prototype.detach=function(e){var n,r;if(e.parentNode){var i=e.transformable,a=e.parentNode.sortable;(!((n=a==null?void 0:a.sorted)===null||n===void 0)&&n.length||!((r=e.style)===null||r===void 0)&&r.zIndex)&&(a.dirtyChildren.indexOf(e)===-1&&a.dirtyChildren.push(e),a.dirty=!0,a.dirtyReason=$a.REMOVED);var o=e.parentNode.childNodes.indexOf(e);o>-1&&e.parentNode.childNodes.splice(o,1),i&&this.dirtifyWorld(e,i),e.parentNode=null}},t.prototype.getOrigin=function(e){return e.transformable.origin},t.prototype.setOrigin=function(e,n,r,i){r===void 0&&(r=0),i===void 0&&(i=0),typeof n=="number"&&(n=[n,r,i]);var a=e.transformable;if(!(n[0]===a.origin[0]&&n[1]===a.origin[1]&&n[2]===a.origin[2])){var o=a.origin;o[0]=n[0],o[1]=n[1],o[2]=n[2]||0,this.dirtifyLocal(e,a)}},t.prototype.setLocalEulerAngles=function(e,n,r,i){r===void 0&&(r=0),i===void 0&&(i=0),typeof n=="number"&&(n=St(n,r,i));var a=e.transformable;oc(a.localRotation,n[0],n[1],n[2]),this.dirtifyLocal(e,a)},t.prototype.scaleLocal=function(e,n){var r=e.transformable;xT(r.localScale,r.localScale,St(n[0],n[1],n[2]||1)),this.dirtifyLocal(e,r)},t.prototype.setLocalScale=function(e,n){var r=e.transformable,i=St(n[0],n[1],n[2]||r.localScale[2]);vo(i,r.localScale)||(rn(r.localScale,i),this.dirtifyLocal(e,r))},t.prototype.setLocalRotation=function(e,n,r,i,a){typeof n=="number"&&(n=_f(n,r,i,a));var o=e.transformable;sc(o.localRotation,n),this.dirtifyLocal(e,o)},t.prototype.setLocalSkew=function(e,n,r){typeof n=="number"&&(n=AT(n,r));var i=e.transformable;kT(i.localSkew,n),this.dirtifyLocal(e,i)},t.prototype.dirtifyLocal=function(e,n){n.localDirtyFlag||(n.localDirtyFlag=!0,n.dirtyFlag||this.dirtifyWorld(e,n))},t.prototype.dirtifyWorld=function(e,n){n.dirtyFlag||this.unfreezeParentToRoot(e),this.dirtifyWorldInternal(e,n),this.dirtifyToRoot(e,!0)},t.prototype.triggerPendingEvents=function(){var e=this,n=new Set,r=function(i,a){i.isConnected&&!n.has(i.entity)&&(e.boundsChangedEvent.detail=a,e.boundsChangedEvent.target=i,i.isMutationObserved?i.dispatchEvent(e.boundsChangedEvent):i.ownerDocument.defaultView.dispatchEvent(e.boundsChangedEvent,!0),n.add(i.entity))};this.pendingEvents.forEach(function(i){var a=N(i,2),o=a[0],s=a[1];s.affectChildren?o.forEach(function(c){r(c,s)}):r(o,s)}),this.clearPendingEvents(),n.clear()},t.prototype.clearPendingEvents=function(){this.pendingEvents=[]},t.prototype.dirtifyToRoot=function(e,n){n===void 0&&(n=!1);var r=e;for(r.renderable&&(r.renderable.dirty=!0);r;)ry(r),r=r.parentNode;n&&e.forEach(function(i){ry(i)}),this.informDependentDisplayObjects(e),this.pendingEvents.push([e,{affectChildren:n}])},t.prototype.updateDisplayObjectDependency=function(e,n,r,i){if(n&&n!==r){var a=this.displayObjectDependencyMap.get(n);if(a&&a[e]){var o=a[e].indexOf(i);a[e].splice(o,1)}}if(r){var s=this.displayObjectDependencyMap.get(r);s||(this.displayObjectDependencyMap.set(r,{}),s=this.displayObjectDependencyMap.get(r)),s[e]||(s[e]=[]),s[e].push(i)}},t.prototype.informDependentDisplayObjects=function(e){var n=this,r=this.displayObjectDependencyMap.get(e);r&&Object.keys(r).forEach(function(i){r[i].forEach(function(a){n.dirtifyToRoot(a,!0),a.dispatchEvent(new Gi(ht.ATTR_MODIFIED,a,n,n,i,Gi.MODIFICATION,n,n)),a.isCustomElement&&a.isConnected&&a.attributeChangedCallback&&a.attributeChangedCallback(i,n,n)})})},t.prototype.getPosition=function(e){var n=e.transformable;return gl(n.position,this.getWorldTransform(e,n))},t.prototype.getRotation=function(e){var n=e.transformable;return yl(n.rotation,this.getWorldTransform(e,n))},t.prototype.getScale=function(e){var n=e.transformable;return Aa(n.scaling,this.getWorldTransform(e,n))},t.prototype.getWorldTransform=function(e,n){return n===void 0&&(n=e.transformable),!n.localDirtyFlag&&!n.dirtyFlag||(e.parentNode&&e.parentNode.transformable&&this.getWorldTransform(e.parentNode),this.sync(e,n)),n.worldTransform},t.prototype.getLocalPosition=function(e){return e.transformable.localPosition},t.prototype.getLocalRotation=function(e){return e.transformable.localRotation},t.prototype.getLocalScale=function(e){return e.transformable.localScale},t.prototype.getLocalSkew=function(e){return e.transformable.localSkew},t.prototype.getLocalTransform=function(e){var n=e.transformable;return n.localDirtyFlag&&(this.calcLocalTransform(n),n.localDirtyFlag=!1),n.localTransform},t.prototype.setLocalTransform=function(e,n){var r=gl(yt(),n),i=yl(ve(),n),a=Aa(yt(),n);this.setLocalScale(e,a),this.setLocalPosition(e,r),this.setLocalRotation(e,i)},t.prototype.resetLocalTransform=function(e){this.setLocalScale(e,[1,1,1]),this.setLocalPosition(e,[0,0,0]),this.setLocalEulerAngles(e,[0,0,0]),this.setLocalSkew(e,[0,0])},t.prototype.getTransformedGeometryBounds=function(e,n,r){n===void 0&&(n=!1);var i=this.getGeometryBounds(e,n);if(be.isEmpty(i))return null;var a=r||new be;return a.setFromTransformedAABB(i,this.getWorldTransform(e)),a},t.prototype.getGeometryBounds=function(e,n){n===void 0&&(n=!1);var r=e.geometry,i=n?r.renderBounds:r.contentBounds||null;return i||new be},t.prototype.getBounds=function(e,n){var r=this;n===void 0&&(n=!1);var i=e.renderable;if(!i.boundsDirty&&!n&&i.bounds)return i.bounds;if(!i.renderBoundsDirty&&n&&i.renderBounds)return i.renderBounds;var a=n?i.renderBounds:i.bounds,o=this.getTransformedGeometryBounds(e,n,a),s=e.childNodes;if(s.forEach(function(u){var f=r.getBounds(u,n);f&&(o?o.add(f):(o=a||new be,o.update(f.center,f.halfExtents)))}),n){var c=Iw(e);if(c){var l=c.parsedStyle.clipPath.getBounds(n);o?l&&(o=l.intersection(o)):o=l}}return o||(o=new be),o&&(n?i.renderBounds=o:i.bounds=o),n?i.renderBoundsDirty=!1:i.boundsDirty=!1,o},t.prototype.getLocalBounds=function(e){if(e.parentNode){var n=Nt();e.parentNode.transformable&&(n=Wn(Nt(),this.getWorldTransform(e.parentNode)));var r=this.getBounds(e);if(!be.isEmpty(r)){var i=new be;return i.setFromTransformedAABB(r,n),i}}return this.getBounds(e)},t.prototype.getBoundingClientRect=function(e){var n,r,i,a=this.getGeometryBounds(e);be.isEmpty(a)||(i=new be,i.setFromTransformedAABB(a,this.getWorldTransform(e)));var o=(r=(n=e.ownerDocument)===null||n===void 0?void 0:n.defaultView)===null||r===void 0?void 0:r.getContextService().getBoundingClientRect();if(i){var s=N(i.getMin(),2),c=s[0],l=s[1],u=N(i.getMax(),2),f=u[0],d=u[1];return new Fi(c+((o==null?void 0:o.left)||0),l+((o==null?void 0:o.top)||0),f-c,d-l)}return new Fi((o==null?void 0:o.left)||0,(o==null?void 0:o.top)||0,0,0)},t.prototype.dirtifyWorldInternal=function(e,n){var r=this;if(!n.dirtyFlag){n.dirtyFlag=!0,n.frozen=!1,e.childNodes.forEach(function(a){var o=a.transformable;o.dirtyFlag||r.dirtifyWorldInternal(a,o)});var i=e.renderable;i&&(i.renderBoundsDirty=!0,i.boundsDirty=!0,i.dirty=!0)}},t.prototype.syncHierarchy=function(e){var n=e.transformable;if(!n.frozen){n.frozen=!0,(n.localDirtyFlag||n.dirtyFlag)&&this.sync(e,n);for(var r=e.childNodes,i=0;ic;--h){for(var g=0;g=l){n.isOverflowing=!0;break}g=0,p[v]="";continue}if(g>0&&g+M>d){if(v+1>=l){if(n.isOverflowing=!0,b>0&&b<=d){for(var E=p[v].length,P=0,T=E,A=0;Ad){T=A;break}P+=k}p[v]=(p[v]||"").slice(0,T)+h}break}if(v++,g=0,p[v]="",this.isBreakingSpace(O))continue;this.canBreakInLastChar(O)||(p=this.trimToBreakable(p),g=this.sumTextWidthByCache(p[v]||"",y)),this.shouldBreakByKinsokuShorui(O,_)&&(p=this.trimByKinsokuShorui(p),g+=m(S||""))}g+=M,p[v]=(p[v]||"")+O}return p.join(` -`)},t.prototype.isBreakingSpace=function(e){return typeof e!="string"?!1:xi.BreakingSpaces.indexOf(e.charCodeAt(0))>=0},t.prototype.isNewline=function(e){return typeof e!="string"?!1:xi.Newlines.indexOf(e.charCodeAt(0))>=0},t.prototype.trimToBreakable=function(e){var n=q([],N(e),!1),r=n[n.length-2],i=this.findBreakableIndex(r);if(i===-1||!r)return n;var a=r.slice(i,i+1),o=this.isBreakingSpace(a),s=i+1,c=i+(o?0:1);return n[n.length-1]+=r.slice(s,r.length),n[n.length-2]=r.slice(0,c),n},t.prototype.canBreakInLastChar=function(e){return!(e&&iy.test(e))},t.prototype.sumTextWidthByCache=function(e,n){return e.split("").reduce(function(r,i){if(!n[i])throw Error("cannot count the word without cache");return r+n[i]},0)},t.prototype.findBreakableIndex=function(e){for(var n=e.length-1;n>=0;n--)if(!iy.test(e[n]))return n;return-1},t.prototype.getFromCache=function(e,n,r,i){var a=r[e];if(typeof a!="number"){var o=e.length*n;a=i.measureText(e).width+o,r[e]=a}return a},t}(),H={},IR=function(){var t,e=new hR,n=new dR;return t={},t[G.CIRCLE]=new cR,t[G.ELLIPSE]=new lR,t[G.RECT]=e,t[G.IMAGE]=e,t[G.GROUP]=e,t[G.LINE]=new uR,t[G.TEXT]=new pR(H),t[G.POLYLINE]=n,t[G.POLYGON]=n,t[G.PATH]=new fR,t[G.HTML]=null,t[G.MESH]=null,t}(),jR=function(){var t,e=new O4,n=new Xp;return t={},t[tt.PERCENTAGE]=null,t[tt.NUMBER]=new A4,t[tt.ANGLE]=new x4,t[tt.DEFINED_PATH]=new w4,t[tt.PAINT]=e,t[tt.COLOR]=e,t[tt.FILTER]=new S4,t[tt.LENGTH]=n,t[tt.LENGTH_PERCENTAGE]=n,t[tt.LENGTH_PERCENTAGE_12]=new _4,t[tt.LENGTH_PERCENTAGE_14]=new M4,t[tt.COORDINATE]=new E4,t[tt.OFFSET_DISTANCE]=new k4,t[tt.OPACITY_VALUE]=new T4,t[tt.PATH]=new C4,t[tt.LIST_OF_POINTS]=new L4,t[tt.SHADOW_BLUR]=new N4,t[tt.TEXT]=new R4,t[tt.TEXT_TRANSFORM]=new I4,t[tt.TRANSFORM]=new aR,t[tt.TRANSFORM_ORIGIN]=new oR,t[tt.Z_INDEX]=new sR,t[tt.MARKER]=new P4,t}(),DR=function(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}};H.CameraContribution=ww;H.AnimationTimeline=null;H.EasingFunction=null;H.offscreenCanvasCreator=new mR;H.sceneGraphSelector=new wR;H.sceneGraphService=new SR(H);H.textService=new RR(H);H.geometryUpdaterFactory=IR;H.CSSPropertySyntaxFactory=jR;H.styleValueRegistry=new b4(H);H.layoutRegistry=null;H.globalThis=DR();H.enableCSSParsing=!0;H.enableDataset=!1;H.enableStyleSyntax=!0;var $R=0,ay=new Gi(ht.INSERTED,null,"","","",0,"",""),oy=new Gi(ht.REMOVED,null,"","","",0,"",""),BR=new Dt(ht.DESTROY),FR=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.entity=$R++,n.renderable={bounds:void 0,boundsDirty:!0,renderBounds:void 0,renderBoundsDirty:!0,dirtyRenderBounds:void 0,dirty:!1},n.cullable={strategy:rh.Standard,visibilityPlaneMask:-1,visible:!0,enable:!0},n.transformable={dirtyFlag:!1,localDirtyFlag:!1,frozen:!1,localPosition:[0,0,0],localRotation:[0,0,0,1],localScale:[1,1,1],localTransform:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],localSkew:[0,0],position:[0,0,0],rotation:[0,0,0,1],scaling:[1,1,1],worldTransform:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],origin:[0,0,0]},n.sortable={dirty:!1,sorted:void 0,renderOrder:0,dirtyChildren:[],dirtyReason:void 0},n.geometry={contentBounds:void 0,renderBounds:void 0},n.rBushNode={aabb:void 0},n.namespaceURI="g",n.scrollLeft=0,n.scrollTop=0,n.clientTop=0,n.clientLeft=0,n.destroyed=!1,n.style={},n.computedStyle=H.enableCSSParsing?{anchor:Gt,opacity:Gt,fillOpacity:Gt,strokeOpacity:Gt,fill:Gt,stroke:Gt,transform:Gt,transformOrigin:Gt,visibility:Gt,pointerEvents:Gt,lineWidth:Gt,lineCap:Gt,lineJoin:Gt,increasedLineWidthForHitTesting:Gt,fontSize:Gt,fontFamily:Gt,fontStyle:Gt,fontWeight:Gt,fontVariant:Gt,textAlign:Gt,textBaseline:Gt,textTransform:Gt,zIndex:Gt,filter:Gt,shadowType:Gt}:null,n.parsedStyle={},n.attributes={},n}return Object.defineProperty(e.prototype,"className",{get:function(){return this.getAttribute("class")||""},set:function(n){this.setAttribute("class",n)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"classList",{get:function(){return this.className.split(" ").filter(function(n){return n!==""})},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"tagName",{get:function(){return this.nodeName},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"children",{get:function(){return this.childNodes},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"childElementCount",{get:function(){return this.childNodes.length},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"firstElementChild",{get:function(){return this.firstChild},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"lastElementChild",{get:function(){return this.lastChild},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"parentElement",{get:function(){return this.parentNode},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"nextSibling",{get:function(){if(this.parentNode){var n=this.parentNode.childNodes.indexOf(this);return this.parentNode.childNodes[n+1]||null}return null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"previousSibling",{get:function(){if(this.parentNode){var n=this.parentNode.childNodes.indexOf(this);return this.parentNode.childNodes[n-1]||null}return null},enumerable:!1,configurable:!0}),e.prototype.cloneNode=function(n){throw new Error(It)},e.prototype.appendChild=function(n,r){var i;if(n.destroyed)throw new Error(pN);return H.sceneGraphService.attach(n,this,r),!((i=this.ownerDocument)===null||i===void 0)&&i.defaultView&&this.ownerDocument.defaultView.mountChildren(n),ay.relatedNode=this,n.dispatchEvent(ay),n},e.prototype.insertBefore=function(n,r){if(!r)this.appendChild(n);else{n.parentElement&&n.parentElement.removeChild(n);var i=this.childNodes.indexOf(r);i===-1?this.appendChild(n):this.appendChild(n,i)}return n},e.prototype.replaceChild=function(n,r){var i=this.childNodes.indexOf(r);return this.removeChild(r),this.appendChild(n,i),r},e.prototype.removeChild=function(n){var r;return oy.relatedNode=this,n.dispatchEvent(oy),!((r=n.ownerDocument)===null||r===void 0)&&r.defaultView&&n.ownerDocument.defaultView.unmountChildren(n),H.sceneGraphService.detach(n),n},e.prototype.removeChildren=function(){for(var n=this.childNodes.length-1;n>=0;n--){var r=this.childNodes[n];this.removeChild(r)}},e.prototype.destroyChildren=function(){for(var n=this.childNodes.length-1;n>=0;n--){var r=this.childNodes[n];r.childNodes.length&&r.destroyChildren(),r.destroy()}},e.prototype.matches=function(n){return H.sceneGraphService.matches(n,this)},e.prototype.getElementById=function(n){return H.sceneGraphService.querySelector("#".concat(n),this)},e.prototype.getElementsByName=function(n){return H.sceneGraphService.querySelectorAll('[name="'.concat(n,'"]'),this)},e.prototype.getElementsByClassName=function(n){return H.sceneGraphService.querySelectorAll(".".concat(n),this)},e.prototype.getElementsByTagName=function(n){return H.sceneGraphService.querySelectorAll(n,this)},e.prototype.querySelector=function(n){return H.sceneGraphService.querySelector(n,this)},e.prototype.querySelectorAll=function(n){return H.sceneGraphService.querySelectorAll(n,this)},e.prototype.closest=function(n){var r=this;do{if(H.sceneGraphService.matches(n,r))return r;r=r.parentElement}while(r!==null);return null},e.prototype.find=function(n){var r=this,i=null;return this.forEach(function(a){return a!==r&&n(a)?(i=a,!0):!1}),i},e.prototype.findAll=function(n){var r=this,i=[];return this.forEach(function(a){a!==r&&n(a)&&i.push(a)}),i},e.prototype.after=function(){for(var n=this,r=[],i=0;i1){var i=n[0].currentPoint,a=n[1].currentPoint,o=n[1].startTangent;r=[],o?(r.push([i[0]-o[0],i[1]-o[1]]),r.push([i[0],i[1]])):(r.push([a[0],a[1]]),r.push([i[0],i[1]]))}return r},e.prototype.getEndTangent=function(){var n=this.parsedStyle.path.segments,r=n.length,i=[];if(r>1){var a=n[r-2].currentPoint,o=n[r-1].currentPoint,s=n[r-1].endTangent;i=[],s?(i.push([o[0]-s[0],o[1]-s[1]]),i.push([o[0],o[1]])):(i.push([a[0],a[1]]),i.push([o[0],o[1]]))}return i},e}(ze),Fu=function(t){rt(e,t);function e(n){n===void 0&&(n={});var r=this,i=n.style,a=$t(n,["style"]);r=t.call(this,z({type:G.POLYGON,style:H.enableCSSParsing?z({points:"",miterLimit:"",isClosed:!0},i):z({},i),initialParsedStyle:H.enableCSSParsing?null:{points:{points:[],totalLength:0,segments:[]},miterLimit:4,isClosed:!0}},a))||this,r.markerStartAngle=0,r.markerEndAngle=0,r.markerMidList=[];var o=r.parsedStyle,s=o.markerStart,c=o.markerEnd,l=o.markerMid;return s&&Mt(s)&&(r.markerStartAngle=s.getLocalEulerAngles(),r.appendChild(s)),l&&Mt(l)&&r.placeMarkerMid(l),c&&Mt(c)&&(r.markerEndAngle=c.getLocalEulerAngles(),r.appendChild(c)),r.transformMarker(!0),r.transformMarker(!1),r}return e.prototype.attributeChangedCallback=function(n,r,i,a,o){n==="points"?(this.transformMarker(!0),this.transformMarker(!1),this.placeMarkerMid(this.parsedStyle.markerMid)):n==="markerStartOffset"||n==="markerEndOffset"?(this.transformMarker(!0),this.transformMarker(!1)):n==="markerStart"?(a&&Mt(a)&&(this.markerStartAngle=0,a.remove()),o&&Mt(o)&&(this.markerStartAngle=o.getLocalEulerAngles(),this.appendChild(o),this.transformMarker(!0))):n==="markerEnd"?(a&&Mt(a)&&(this.markerEndAngle=0,a.remove()),o&&Mt(o)&&(this.markerEndAngle=o.getLocalEulerAngles(),this.appendChild(o),this.transformMarker(!1))):n==="markerMid"&&this.placeMarkerMid(o)},e.prototype.transformMarker=function(n){var r=this.parsedStyle,i=r.markerStart,a=r.markerEnd,o=r.markerStartOffset,s=r.markerEndOffset,c=r.points,l=r.defX,u=r.defY,f=(c||{}).points,d=n?i:a;if(!(!d||!Mt(d)||!f)){var h=0,p,v,g,y,m,b;if(g=f[0][0]-l,y=f[0][1]-u,n)p=f[1][0]-f[0][0],v=f[1][1]-f[0][1],m=o||0,b=this.markerStartAngle;else{var x=f.length;this.parsedStyle.isClosed?(p=f[x-1][0]-f[0][0],v=f[x-1][1]-f[0][1]):(g=f[x-1][0]-l,y=f[x-1][1]-u,p=f[x-2][0]-f[x-1][0],v=f[x-2][1]-f[x-1][1]),m=s||0,b=this.markerEndAngle}h=Math.atan2(v,p),d.setLocalEulerAngles(h*180/Math.PI+b),d.setLocalPosition(g+Math.cos(h)*m,y+Math.sin(h)*m)}},e.prototype.placeMarkerMid=function(n){var r=this.parsedStyle,i=r.points,a=r.defX,o=r.defY,s=(i||{}).points;if(this.markerMidList.forEach(function(d){d.remove()}),this.markerMidList=[],n&&Mt(n)&&s)for(var c=1;c<(this.parsedStyle.isClosed?s.length:s.length-1);c++){var l=s[c][0]-a,u=s[c][1]-o,f=c===1?n:n.cloneNode(!0);this.markerMidList.push(f),this.appendChild(f),f.setLocalPosition(l,u)}},e}(ze),Qp=function(t){rt(e,t);function e(n){n===void 0&&(n={});var r=n.style,i=$t(n,["style"]);return t.call(this,z({type:G.POLYLINE,style:H.enableCSSParsing?z({points:"",miterLimit:"",isClosed:!1},r):z({},r),initialParsedStyle:H.enableCSSParsing?null:{points:{points:[],totalLength:0,segments:[]},miterLimit:4,isClosed:!1}},i))||this}return e.prototype.getTotalLength=function(){return this.parsedStyle.points.totalLength},e.prototype.getPointAtLength=function(n,r){return r===void 0&&(r=!1),this.getPoint(n/this.getTotalLength(),r)},e.prototype.getPoint=function(n,r){r===void 0&&(r=!1);var i=this.parsedStyle,a=i.defX,o=i.defY,s=i.points,c=s.points,l=s.segments,u=0,f=0;l.forEach(function(g,y){n>=g[0]&&n<=g[1]&&(u=(n-g[0])/(g[1]-g[0]),f=y)});var d=mw(c[f][0],c[f][1],c[f+1][0],c[f+1][1],u),h=d.x,p=d.y,v=Oe(yt(),St(h-a,p-o,0),r?this.getWorldTransform():this.getLocalTransform());return new Ee(v[0],v[1])},e.prototype.getStartTangent=function(){var n=this.parsedStyle.points.points,r=[];return r.push([n[1][0],n[1][1]]),r.push([n[0][0],n[0][1]]),r},e.prototype.getEndTangent=function(){var n=this.parsedStyle.points.points,r=n.length-1,i=[];return i.push([n[r-1][0],n[r-1][1]]),i.push([n[r][0],n[r][1]]),i},e}(Fu),Zi=function(t){rt(e,t);function e(n){n===void 0&&(n={});var r=n.style,i=$t(n,["style"]);return t.call(this,z({type:G.RECT,style:H.enableCSSParsing?z({x:"",y:"",width:"",height:"",radius:""},r):z({},r)},i))||this}return e}(ze),ei=function(t){rt(e,t);function e(n){n===void 0&&(n={});var r=n.style,i=$t(n,["style"]);return t.call(this,z({type:G.TEXT,style:H.enableCSSParsing?z({x:"",y:"",text:"",fontSize:"",fontFamily:"",fontStyle:"",fontWeight:"",fontVariant:"",textAlign:"",textBaseline:"",textTransform:"",fill:"black",letterSpacing:"",lineHeight:"",miterLimit:"",wordWrap:!1,wordWrapWidth:0,leading:0,dx:"",dy:""},r):z({fill:"black"},r),initialParsedStyle:H.enableCSSParsing?{}:{x:0,y:0,fontSize:16,fontFamily:"sans-serif",fontStyle:"normal",fontWeight:"normal",fontVariant:"normal",lineHeight:0,letterSpacing:0,textBaseline:"alphabetic",textAlign:"start",wordWrap:!1,wordWrapWidth:0,leading:0,dx:0,dy:0}},i))||this}return e.prototype.getComputedTextLength=function(){var n;return((n=this.parsedStyle.metrics)===null||n===void 0?void 0:n.maxLineWidth)||0},e.prototype.getLineBoundingRects=function(){var n;return((n=this.parsedStyle.metrics)===null||n===void 0?void 0:n.lineMetrics)||[]},e.prototype.isOverflowing=function(){return!!this.parsedStyle.isOverflowing},e}(ze),HR=function(){function t(){this.registry={},this.define(G.CIRCLE,Xs),this.define(G.ELLIPSE,Kp),this.define(G.RECT,Zi),this.define(G.IMAGE,Zp),this.define(G.LINE,Us),this.define(G.GROUP,Ce),this.define(G.PATH,Xe),this.define(G.POLYGON,Fu),this.define(G.POLYLINE,Qp),this.define(G.TEXT,ei),this.define(G.HTML,Bu)}return t.prototype.define=function(e,n){this.registry[e]=n},t.prototype.get=function(e){return this.registry[e]},t}(),VR=function(t){rt(e,t);function e(){var n=t.call(this)||this;n.defaultView=null,n.ownerDocument=null,n.nodeName="document";try{n.timeline=new H.AnimationTimeline(n)}catch{}var r={};return Vp.forEach(function(i){var a=i.n,o=i.inh,s=i.d;o&&s&&(r[a]=ga(s)?s(G.GROUP):s)}),n.documentElement=new Ce({id:"g-root",style:r}),n.documentElement.ownerDocument=n,n.documentElement.parentNode=n,n.childNodes=[n.documentElement],n}return Object.defineProperty(e.prototype,"children",{get:function(){return this.childNodes},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"childElementCount",{get:function(){return this.childNodes.length},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"firstElementChild",{get:function(){return this.firstChild},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"lastElementChild",{get:function(){return this.lastChild},enumerable:!1,configurable:!0}),e.prototype.createElement=function(n,r){if(n==="svg")return this.documentElement;var i=this.defaultView.customElements.get(n);i||(console.warn("Unsupported tagName: ",n),i=n==="tspan"?ei:Ce);var a=new i(r);return a.ownerDocument=this,a},e.prototype.createElementNS=function(n,r,i){return this.createElement(r,i)},e.prototype.cloneNode=function(n){throw new Error(It)},e.prototype.destroy=function(){try{this.documentElement.destroyChildren(),this.timeline.destroy()}catch{}},e.prototype.elementsFromBBox=function(n,r,i,a){var o=this.defaultView.context.rBushRoot,s=o.search({minX:n,minY:r,maxX:i,maxY:a}),c=[];return s.forEach(function(l){var u=l.displayObject,f=u.parsedStyle.pointerEvents,d=["auto","visiblepainted","visiblefill","visiblestroke","visible"].includes(f);(!d||d&&u.isVisible())&&!u.isCulled()&&u.isInteractive()&&c.push(u)}),c.sort(function(l,u){return u.sortable.renderOrder-l.sortable.renderOrder}),c},e.prototype.elementFromPointSync=function(n,r){var i=this.defaultView.canvas2Viewport({x:n,y:r}),a=i.x,o=i.y,s=this.defaultView.getConfig(),c=s.width,l=s.height;if(a<0||o<0||a>c||o>l)return null;var u=this.defaultView.viewport2Client({x:a,y:o}),f=u.x,d=u.y,h=this.defaultView.getRenderingService().hooks.pickSync.call({topmost:!0,position:{x:n,y:r,viewportX:a,viewportY:o,clientX:f,clientY:d},picked:[]}).picked;return h&&h[0]||this.documentElement},e.prototype.elementFromPoint=function(n,r){return ka(this,void 0,void 0,function(){var i,a,o,s,c,l,u,f,d,h;return Ta(this,function(p){switch(p.label){case 0:return i=this.defaultView.canvas2Viewport({x:n,y:r}),a=i.x,o=i.y,s=this.defaultView.getConfig(),c=s.width,l=s.height,a<0||o<0||a>c||o>l?[2,null]:(u=this.defaultView.viewport2Client({x:a,y:o}),f=u.x,d=u.y,[4,this.defaultView.getRenderingService().hooks.pick.promise({topmost:!0,position:{x:n,y:r,viewportX:a,viewportY:o,clientX:f,clientY:d},picked:[]})]);case 1:return h=p.sent().picked,[2,h&&h[0]||this.documentElement]}})})},e.prototype.elementsFromPointSync=function(n,r){var i=this.defaultView.canvas2Viewport({x:n,y:r}),a=i.x,o=i.y,s=this.defaultView.getConfig(),c=s.width,l=s.height;if(a<0||o<0||a>c||o>l)return[];var u=this.defaultView.viewport2Client({x:a,y:o}),f=u.x,d=u.y,h=this.defaultView.getRenderingService().hooks.pickSync.call({topmost:!1,position:{x:n,y:r,viewportX:a,viewportY:o,clientX:f,clientY:d},picked:[]}).picked;return h[h.length-1]!==this.documentElement&&h.push(this.documentElement),h},e.prototype.elementsFromPoint=function(n,r){return ka(this,void 0,void 0,function(){var i,a,o,s,c,l,u,f,d,h;return Ta(this,function(p){switch(p.label){case 0:return i=this.defaultView.canvas2Viewport({x:n,y:r}),a=i.x,o=i.y,s=this.defaultView.getConfig(),c=s.width,l=s.height,a<0||o<0||a>c||o>l?[2,[]]:(u=this.defaultView.viewport2Client({x:a,y:o}),f=u.x,d=u.y,[4,this.defaultView.getRenderingService().hooks.pick.promise({topmost:!1,position:{x:n,y:r,viewportX:a,viewportY:o,clientX:f,clientY:d},picked:[]})]);case 1:return h=p.sent().picked,h[h.length-1]!==this.documentElement&&h.push(this.documentElement),[2,h]}})})},e.prototype.appendChild=function(n,r){throw new Error(ra)},e.prototype.insertBefore=function(n,r){throw new Error(ra)},e.prototype.removeChild=function(n,r){throw new Error(ra)},e.prototype.replaceChild=function(n,r,i){throw new Error(ra)},e.prototype.append=function(){throw new Error(ra)},e.prototype.prepend=function(){throw new Error(ra)},e.prototype.getElementById=function(n){return this.documentElement.getElementById(n)},e.prototype.getElementsByName=function(n){return this.documentElement.getElementsByName(n)},e.prototype.getElementsByTagName=function(n){return this.documentElement.getElementsByTagName(n)},e.prototype.getElementsByClassName=function(n){return this.documentElement.getElementsByClassName(n)},e.prototype.querySelector=function(n){return this.documentElement.querySelector(n)},e.prototype.querySelectorAll=function(n){return this.documentElement.querySelectorAll(n)},e.prototype.find=function(n){return this.documentElement.find(n)},e.prototype.findAll=function(n){return this.documentElement.findAll(n)},e}(_e),XR=function(){function t(e){this.strategies=e}return t.prototype.apply=function(e){var n=e.camera,r=e.renderingService,i=e.renderingContext,a=this.strategies;r.hooks.cull.tap(t.tag,function(o){if(o){var s=o.cullable;return a.length===0?s.visible=i.unculledEntities.indexOf(o.entity)>-1:s.visible=a.every(function(c){return c.isVisible(n,o)}),!o.isCulled()&&o.isVisible()?o:(o.dispatchEvent(new Dt(ht.CULLED)),null)}return o}),r.hooks.afterRender.tap(t.tag,function(o){o.cullable.visibilityPlaneMask=-1})},t.tag="Culling",t}(),UR=function(){function t(){var e=this;this.autoPreventDefault=!1,this.rootPointerEvent=new ch(null),this.rootWheelEvent=new lh(null),this.onPointerMove=function(n){var r,i,a,o,s=(o=(a=e.context.renderingContext.root)===null||a===void 0?void 0:a.ownerDocument)===null||o===void 0?void 0:o.defaultView;if(!(s.supportsTouchEvents&&n.pointerType==="touch")){var c=e.normalizeToPointerEvent(n,s);try{for(var l=vn(c),u=l.next();!u.done;u=l.next()){var f=u.value,d=e.bootstrapEvent(e.rootPointerEvent,f,s,n);e.context.eventService.mapEvent(d)}}catch(h){r={error:h}}finally{try{u&&!u.done&&(i=l.return)&&i.call(l)}finally{if(r)throw r.error}}e.setCursor(e.context.eventService.cursor)}},this.onClick=function(n){var r,i,a,o,s=(o=(a=e.context.renderingContext.root)===null||a===void 0?void 0:a.ownerDocument)===null||o===void 0?void 0:o.defaultView,c=e.normalizeToPointerEvent(n,s);try{for(var l=vn(c),u=l.next();!u.done;u=l.next()){var f=u.value,d=e.bootstrapEvent(e.rootPointerEvent,f,s,n);e.context.eventService.mapEvent(d)}}catch(h){r={error:h}}finally{try{u&&!u.done&&(i=l.return)&&i.call(l)}finally{if(r)throw r.error}}e.setCursor(e.context.eventService.cursor)}}return t.prototype.apply=function(e){var n=this;this.context=e;var r=e.renderingService,i=this.context.renderingContext.root.ownerDocument.defaultView;this.context.eventService.setPickHandler(function(a){var o=n.context.renderingService.hooks.pickSync.call({position:a,picked:[],topmost:!0}).picked;return o[0]||null}),r.hooks.pointerWheel.tap(t.tag,function(a){var o=n.normalizeWheelEvent(a);n.context.eventService.mapEvent(o)}),r.hooks.pointerDown.tap(t.tag,function(a){var o,s;if(!(i.supportsTouchEvents&&a.pointerType==="touch")){var c=n.normalizeToPointerEvent(a,i);if(n.autoPreventDefault&&c[0].isNormalized){var l=a.cancelable||!("cancelable"in a);l&&a.preventDefault()}try{for(var u=vn(c),f=u.next();!f.done;f=u.next()){var d=f.value,h=n.bootstrapEvent(n.rootPointerEvent,d,i,a);n.context.eventService.mapEvent(h)}}catch(p){o={error:p}}finally{try{f&&!f.done&&(s=u.return)&&s.call(u)}finally{if(o)throw o.error}}n.setCursor(n.context.eventService.cursor)}}),r.hooks.pointerUp.tap(t.tag,function(a){var o,s;if(!(i.supportsTouchEvents&&a.pointerType==="touch")){var c=n.context.contextService.getDomElement(),l="outside";try{l=c&&a.target&&a.target!==c&&c.contains&&!c.contains(a.target)?"outside":""}catch{}var u=n.normalizeToPointerEvent(a,i);try{for(var f=vn(u),d=f.next();!d.done;d=f.next()){var h=d.value,p=n.bootstrapEvent(n.rootPointerEvent,h,i,a);p.type+=l,n.context.eventService.mapEvent(p)}}catch(v){o={error:v}}finally{try{d&&!d.done&&(s=f.return)&&s.call(f)}finally{if(o)throw o.error}}n.setCursor(n.context.eventService.cursor)}}),r.hooks.pointerMove.tap(t.tag,this.onPointerMove),r.hooks.pointerOver.tap(t.tag,this.onPointerMove),r.hooks.pointerOut.tap(t.tag,this.onPointerMove),r.hooks.click.tap(t.tag,this.onClick),r.hooks.pointerCancel.tap(t.tag,function(a){var o,s,c=n.normalizeToPointerEvent(a,i);try{for(var l=vn(c),u=l.next();!u.done;u=l.next()){var f=u.value,d=n.bootstrapEvent(n.rootPointerEvent,f,i,a);n.context.eventService.mapEvent(d)}}catch(h){o={error:h}}finally{try{u&&!u.done&&(s=l.return)&&s.call(l)}finally{if(o)throw o.error}}n.setCursor(n.context.eventService.cursor)})},t.prototype.getViewportXY=function(e){var n,r,i=e.offsetX,a=e.offsetY,o=e.clientX,s=e.clientY;if(this.context.config.supportsCSSTransform&&!nt(i)&&!nt(a))n=i,r=a;else{var c=this.context.eventService.client2Viewport(new Ee(o,s));n=c.x,r=c.y}return{x:n,y:r}},t.prototype.bootstrapEvent=function(e,n,r,i){e.view=r,e.originalEvent=null,e.nativeEvent=i,e.pointerId=n.pointerId,e.width=n.width,e.height=n.height,e.isPrimary=n.isPrimary,e.pointerType=n.pointerType,e.pressure=n.pressure,e.tangentialPressure=n.tangentialPressure,e.tiltX=n.tiltX,e.tiltY=n.tiltY,e.twist=n.twist,this.transferMouseData(e,n);var a=this.getViewportXY(n),o=a.x,s=a.y;e.viewport.x=o,e.viewport.y=s;var c=this.context.eventService.viewport2Canvas(e.viewport),l=c.x,u=c.y;return e.canvas.x=l,e.canvas.y=u,e.global.copyFrom(e.canvas),e.offset.copyFrom(e.canvas),e.isTrusted=i.isTrusted,e.type==="pointerleave"&&(e.type="pointerout"),e.type.startsWith("mouse")&&(e.type=e.type.replace("mouse","pointer")),e.type.startsWith("touch")&&(e.type=W4[e.type]||e.type),e},t.prototype.normalizeWheelEvent=function(e){var n=this.rootWheelEvent;this.transferMouseData(n,e),n.deltaMode=e.deltaMode,n.deltaX=e.deltaX,n.deltaY=e.deltaY,n.deltaZ=e.deltaZ;var r=this.getViewportXY(e),i=r.x,a=r.y;n.viewport.x=i,n.viewport.y=a;var o=this.context.eventService.viewport2Canvas(n.viewport),s=o.x,c=o.y;return n.canvas.x=s,n.canvas.y=c,n.global.copyFrom(n.canvas),n.offset.copyFrom(n.canvas),n.nativeEvent=e,n.type=e.type,n},t.prototype.transferMouseData=function(e,n){e.isTrusted=n.isTrusted,e.srcElement=n.srcElement,e.timeStamp=sh.now(),e.type=n.type,e.altKey=n.altKey,e.metaKey=n.metaKey,e.shiftKey=n.shiftKey,e.ctrlKey=n.ctrlKey,e.button=n.button,e.buttons=n.buttons,e.client.x=n.clientX,e.client.y=n.clientY,e.movement.x=n.movementX,e.movement.y=n.movementY,e.page.x=n.pageX,e.page.y=n.pageY,e.screen.x=n.screenX,e.screen.y=n.screenY,e.relatedTarget=null},t.prototype.setCursor=function(e){this.context.contextService.applyCursorStyle(e||this.context.config.cursor||"default")},t.prototype.normalizeToPointerEvent=function(e,n){var r=[];if(n.isTouchEvent(e))for(var i=0;i-1,s=0,c=i.length;s=1?Math.ceil(P):1,M=s||z4(a)||a.width/P,E=c||G4(a)||a.height/P),o&&(H.offscreenCanvas=o),r.devicePixelRatio=P,r.requestAnimationFrame=p??Bw.bind(H.globalThis),r.cancelAnimationFrame=v??Fw.bind(H.globalThis),r.supportsTouchEvents=m??"ontouchstart"in H.globalThis,r.supportsPointerEvents=y??!!H.globalThis.PointerEvent,r.isTouchEvent=S??function(T){return r.supportsTouchEvents&&T instanceof H.globalThis.TouchEvent},r.isMouseEvent=_??function(T){return!H.globalThis.MouseEvent||T instanceof H.globalThis.MouseEvent&&(!r.supportsPointerEvents||!(T instanceof H.globalThis.PointerEvent))},r.initRenderingContext({container:i,canvas:a,width:M,height:E,renderer:u,offscreenCanvas:o,devicePixelRatio:P,cursor:d||"default",background:f||"transparent",createImage:g,document:h,supportsCSSTransform:b,useNativeClickEvent:w,alwaysTriggerPointerEventOnCanvas:O}),r.initDefaultCamera(M,E,u.clipSpaceNearZ),r.initRenderer(u,!0),r}return e.prototype.initRenderingContext=function(n){this.context.config=n,this.context.renderingContext={root:this.document.documentElement,renderListCurrentFrame:[],unculledEntities:[],renderReasons:new Set,force:!1,dirty:!1}},e.prototype.initDefaultCamera=function(n,r,i){var a=this,o=new H.CameraContribution;o.clipSpaceNearZ=i,o.setType(Tt.EXPLORING,ds.DEFAULT).setPosition(n/2,r/2,cy).setFocalPoint(n/2,r/2,0).setOrthographic(n/-2,n/2,r/2,r/-2,QR,JR),o.canvas=this,o.eventEmitter.on(xw.UPDATED,function(){a.context.renderingContext.renderReasons.add(Qr.CAMERA_CHANGED)}),this.context.camera=o},e.prototype.getConfig=function(){return this.context.config},e.prototype.getRoot=function(){return this.document.documentElement},e.prototype.getCamera=function(){return this.context.camera},e.prototype.getContextService=function(){return this.context.contextService},e.prototype.getEventService=function(){return this.context.eventService},e.prototype.getRenderingService=function(){return this.context.renderingService},e.prototype.getRenderingContext=function(){return this.context.renderingContext},e.prototype.getStats=function(){return this.getRenderingService().getStats()},Object.defineProperty(e.prototype,"ready",{get:function(){var n=this;return this.readyPromise||(this.readyPromise=new Promise(function(r){n.resolveReadyPromise=function(){r(n)}}),this.inited&&this.resolveReadyPromise()),this.readyPromise},enumerable:!1,configurable:!0}),e.prototype.destroy=function(n,r){if(n===void 0&&(n=!0),r===void 0&&(r=!1),r||this.dispatchEvent(new Dt(an.BEFORE_DESTROY)),this.frameId){var i=this.getConfig().cancelAnimationFrame||cancelAnimationFrame;i(this.frameId)}var a=this.getRoot();this.unmountChildren(a),n&&(this.document.destroy(),this.getEventService().destroy()),this.getRenderingService().destroy(),this.getContextService().destroy(),n&&this.context.rBushRoot&&(this.context.rBushRoot.clear(),this.context.rBushRoot=null,this.context.renderingContext.root=null),r||this.dispatchEvent(new Dt(an.AFTER_DESTROY))},e.prototype.changeSize=function(n,r){this.resize(n,r)},e.prototype.resize=function(n,r){var i=this.context.config;i.width=n,i.height=r,this.getContextService().resize(n,r);var a=this.context.camera,o=a.getProjectionMode();a.setPosition(n/2,r/2,cy).setFocalPoint(n/2,r/2,0),o===tn.ORTHOGRAPHIC?a.setOrthographic(n/-2,n/2,r/2,r/-2,a.getNear(),a.getFar()):a.setAspect(n/r),this.dispatchEvent(new Dt(an.RESIZE,{width:n,height:r}))},e.prototype.appendChild=function(n,r){return this.document.documentElement.appendChild(n,r)},e.prototype.insertBefore=function(n,r){return this.document.documentElement.insertBefore(n,r)},e.prototype.removeChild=function(n){return this.document.documentElement.removeChild(n)},e.prototype.removeChildren=function(){this.document.documentElement.removeChildren()},e.prototype.destroyChildren=function(){this.document.documentElement.destroyChildren()},e.prototype.render=function(){var n=this;this.dispatchEvent(t6);var r=this.getRenderingService();r.render(this.getConfig(),function(){n.dispatchEvent(e6)}),this.dispatchEvent(n6)},e.prototype.run=function(){var n=this,r=function(){n.render(),n.frameId=n.requestAnimationFrame(r)};r()},e.prototype.initRenderer=function(n,r){var i=this;if(r===void 0&&(r=!1),!n)throw new Error("Renderer is required.");this.inited=!1,this.readyPromise=void 0,this.context.rBushRoot=new tN,this.context.renderingPlugins=[],this.context.renderingPlugins.push(new UR,new ZR,new XR([new KR])),this.loadRendererContainerModule(n),this.context.contextService=new this.context.ContextService(z(z({},H),this.context)),this.context.renderingService=new bR(H,this.context),this.context.eventService=new yR(H,this.context),this.context.eventService.init(),this.context.contextService.init?(this.context.contextService.init(),this.initRenderingService(n,r,!0)):this.context.contextService.initAsync().then(function(){i.initRenderingService(n,r)})},e.prototype.initRenderingService=function(n,r,i){var a=this;r===void 0&&(r=!1),i===void 0&&(i=!1),this.context.renderingService.init(function(){a.inited=!0,r?(i?a.requestAnimationFrame(function(){a.dispatchEvent(new Dt(an.READY))}):a.dispatchEvent(new Dt(an.READY)),a.readyPromise&&a.resolveReadyPromise()):a.dispatchEvent(new Dt(an.RENDERER_CHANGED)),r||a.getRoot().forEach(function(o){var s=o.renderable;s&&(s.renderBoundsDirty=!0,s.boundsDirty=!0,s.dirty=!0)}),a.mountChildren(a.getRoot()),n.getConfig().enableAutoRendering&&a.run()})},e.prototype.loadRendererContainerModule=function(n){var r=this,i=n.getPlugins();i.forEach(function(a){a.context=r.context,a.init(H)})},e.prototype.setRenderer=function(n){var r=this.getConfig();if(r.renderer!==n){var i=r.renderer;r.renderer=n,this.destroy(!1,!0),q([],N(i==null?void 0:i.getPlugins()),!1).reverse().forEach(function(a){a.destroy(H)}),this.initRenderer(n)}},e.prototype.setCursor=function(n){var r=this.getConfig();r.cursor=n,this.getContextService().applyCursorStyle(n)},e.prototype.unmountChildren=function(n){var r=this;n.childNodes.forEach(function(i){r.unmountChildren(i)}),this.inited&&(n.isMutationObserved?n.dispatchEvent(Hf):(Hf.target=n,this.dispatchEvent(Hf,!0)),n!==this.document.documentElement&&(n.ownerDocument=null),n.isConnected=!1),n.isCustomElement&&n.disconnectedCallback&&n.disconnectedCallback()},e.prototype.mountChildren=function(n){var r=this;this.inited?n.isConnected||(n.ownerDocument=this.document,n.isConnected=!0,n.isMutationObserved?n.dispatchEvent(Wf):(Wf.target=n,this.dispatchEvent(Wf,!0))):console.warn("[g]: You are trying to call `canvas.appendChild` before canvas' initialization finished. You can either await `canvas.ready` or listen to `CanvasEvent.READY` manually.","appended child: ",n.nodeName),n.childNodes.forEach(function(i){r.mountChildren(i)}),n.isCustomElement&&n.connectedCallback&&n.connectedCallback()},e.prototype.client2Viewport=function(n){return this.getEventService().client2Viewport(n)},e.prototype.viewport2Client=function(n){return this.getEventService().viewport2Client(n)},e.prototype.viewport2Canvas=function(n){return this.getEventService().viewport2Canvas(n)},e.prototype.canvas2Viewport=function(n){return this.getEventService().canvas2Viewport(n)},e.prototype.getPointByClient=function(n,r){return this.client2Viewport({x:n,y:r})},e.prototype.getClientByPoint=function(n,r){return this.viewport2Client({x:n,y:r})},e}(Gw),r6=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.landmarks=[],n}return e.prototype.rotate=function(n,r,i){if(this.relElevation=Oa(r),this.relAzimuth=Oa(n),this.relRoll=Oa(i),this.elevation+=this.relElevation,this.azimuth+=this.relAzimuth,this.roll+=this.relRoll,this.type===Tt.EXPLORING){var a=Hr(ve(),[1,0,0],re((this.rotateWorld?1:-1)*this.relElevation)),o=Hr(ve(),[0,1,0],re((this.rotateWorld?1:-1)*this.relAzimuth)),s=Hr(ve(),[0,0,1],re(this.relRoll)),c=qr(ve(),o,a);c=qr(ve(),c,s);var l=dp(Nt(),c);Ur(this.matrix,this.matrix,[0,0,-this.distance]),$e(this.matrix,this.matrix,l),Ur(this.matrix,this.matrix,[0,0,this.distance])}else{if(Math.abs(this.elevation)>90)return this;this.computeMatrix()}return this._getAxes(),this.type===Tt.ORBITING||this.type===Tt.EXPLORING?this._getPosition():this.type===Tt.TRACKING&&this._getFocalPoint(),this._update(),this},e.prototype.pan=function(n,r){var i=We(n,r,0),a=br(this.position);return ba(a,a,Cd(yt(),this.right,i[0])),ba(a,a,Cd(yt(),this.up,i[1])),this._setPosition(a),this.triggerUpdate(),this},e.prototype.dolly=function(n){var r=this.forward,i=br(this.position),a=n*this.dollyingStep,o=this.distance+n*this.dollyingStep;return a=Math.max(Math.min(o,this.maxDistance),this.minDistance)-this.distance,i[0]+=a*r[0],i[1]+=a*r[1],i[2]+=a*r[2],this._setPosition(i),this.type===Tt.ORBITING||this.type===Tt.EXPLORING?this._getDistance():this.type===Tt.TRACKING&&ba(this.focalPoint,i,this.distanceVector),this.triggerUpdate(),this},e.prototype.cancelLandmarkAnimation=function(){this.landmarkAnimationID!==void 0&&this.canvas.cancelAnimationFrame(this.landmarkAnimationID)},e.prototype.createLandmark=function(n,r){var i,a,o,s;r===void 0&&(r={});var c=r.position,l=c===void 0?this.position:c,u=r.focalPoint,f=u===void 0?this.focalPoint:u,d=r.roll,h=r.zoom,p=new H.CameraContribution;p.setType(this.type,void 0),p.setPosition(l[0],(i=l[1])!==null&&i!==void 0?i:this.position[1],(a=l[2])!==null&&a!==void 0?a:this.position[2]),p.setFocalPoint(f[0],(o=f[1])!==null&&o!==void 0?o:this.focalPoint[1],(s=f[2])!==null&&s!==void 0?s:this.focalPoint[2]),p.setRoll(d??this.roll),p.setZoom(h??this.zoom);var v={name:n,matrix:lp(p.getWorldTransform()),right:br(p.right),up:br(p.up),forward:br(p.forward),position:br(p.getPosition()),focalPoint:br(p.getFocalPoint()),distanceVector:br(p.getDistanceVector()),distance:p.getDistance(),dollyingStep:p.getDollyingStep(),azimuth:p.getAzimuth(),elevation:p.getElevation(),roll:p.getRoll(),relAzimuth:p.relAzimuth,relElevation:p.relElevation,relRoll:p.relRoll,zoom:p.getZoom()};return this.landmarks.push(v),v},e.prototype.gotoLandmark=function(n,r){var i=this;r===void 0&&(r={});var a=le(n)?this.landmarks.find(function(E){return E.name===n}):n;if(a){var o=de(r)?{duration:r}:r,s=o.easing,c=s===void 0?"linear":s,l=o.duration,u=l===void 0?100:l,f=o.easingFunction,d=f===void 0?void 0:f,h=o.onfinish,p=h===void 0?void 0:h,v=o.onframe,g=v===void 0?void 0:v,y=.01;if(u===0){this.syncFromLandmark(a),p&&p();return}this.cancelLandmarkAnimation();var m=a.position,b=a.focalPoint,x=a.zoom,w=a.roll,O=d||H.EasingFunction(c),S,_=function(){i.setFocalPoint(b),i.setPosition(m),i.setRoll(w),i.setZoom(x),i.computeMatrix(),i.triggerUpdate(),p&&p()},M=function(E){S===void 0&&(S=E);var P=E-S;if(P>u){_();return}var T=O(P/u),A=yt(),k=yt(),C=1,L=0;Ld(A,i.focalPoint,b,T),Ld(k,i.position,m,T),L=i.roll*(1-T)+w*T,C=i.zoom*(1-T)+x*T,i.setFocalPoint(A),i.setPosition(k),i.setRoll(L),i.setZoom(C);var I=Kv(A,b)+Kv(k,m);if(I<=y&&x==null&&w==null){_();return}i.computeMatrix(),i.triggerUpdate(),P0&&Number(this._currentTime)>=this._totalDuration||this._playbackRate<0&&Number(this._currentTime)<=0)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"totalDuration",{get:function(){return this._totalDuration},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"_needsTick",{get:function(){return this.pending||this.playState==="running"||!this._finishedFlag},enumerable:!1,configurable:!0}),t.prototype.updatePromises=function(){var e=this.oldPlayState,n=this.pending?"pending":this.playState;return this.readyPromise&&n!==e&&(n==="idle"?(this.rejectReadyPromise(),this.readyPromise=void 0):e==="pending"?this.resolveReadyPromise():n==="pending"&&(this.readyPromise=void 0)),this.finishedPromise&&n!==e&&(n==="idle"?(this.rejectFinishedPromise(),this.finishedPromise=void 0):n==="finished"?this.resolveFinishedPromise():e==="finished"&&(this.finishedPromise=void 0)),this.oldPlayState=n,this.readyPromise||this.finishedPromise},t.prototype.play=function(){this.updatePromises(),this._paused=!1,(this._isFinished||this._idle)&&(this.rewind(),this._startTime=null),this._finishedFlag=!1,this._idle=!1,this.ensureAlive(),this.timeline.applyDirtiedAnimation(this),this.timeline.animations.indexOf(this)===-1&&this.timeline.animations.push(this),this.updatePromises()},t.prototype.pause=function(){this.updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),!this._isFinished&&!this._paused&&!this._idle?this.currentTimePending=!0:this._idle&&(this.rewind(),this._idle=!1),this._startTime=null,this._paused=!0,this.updatePromises()},t.prototype.finish=function(){this.updatePromises(),!this._idle&&(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this.currentTimePending=!1,this.timeline.applyDirtiedAnimation(this),this.updatePromises())},t.prototype.cancel=function(){var e=this;if(this.updatePromises(),!!this._inEffect&&(this._inEffect=!1,this._idle=!0,this._paused=!1,this._finishedFlag=!0,this._currentTime=0,this._startTime=null,this.effect.update(null),this.timeline.applyDirtiedAnimation(this),this.updatePromises(),this.oncancel)){var n=new Vf(null,this,this.currentTime,null);setTimeout(function(){e.oncancel(n)})}},t.prototype.reverse=function(){this.updatePromises();var e=this.currentTime;this.playbackRate*=-1,this.play(),e!==null&&(this.currentTime=e),this.updatePromises()},t.prototype.updatePlaybackRate=function(e){this.playbackRate=e},t.prototype.targetAnimations=function(){var e,n=(e=this.effect)===null||e===void 0?void 0:e.target;return n.getAnimations()},t.prototype.markTarget=function(){var e=this.targetAnimations();e.indexOf(this)===-1&&e.push(this)},t.prototype.unmarkTarget=function(){var e=this.targetAnimations(),n=e.indexOf(this);n!==-1&&e.splice(n,1)},t.prototype.tick=function(e,n){!this._idle&&!this._paused&&(this._startTime===null?n&&(this.startTime=e-this._currentTime/this.playbackRate):this._isFinished||this.tickCurrentTime((e-this._startTime)*this.playbackRate)),n&&(this.currentTimePending=!1,this.fireEvents(e))},t.prototype.rewind=function(){if(this.playbackRate>=0)this.currentTime=0;else if(this._totalDuration<1/0)this.currentTime=this._totalDuration;else throw new Error("Unable to rewind negative playback rate animation with infinite duration")},t.prototype.persist=function(){throw new Error(It)},t.prototype.addEventListener=function(e,n,r){throw new Error(It)},t.prototype.removeEventListener=function(e,n,r){throw new Error(It)},t.prototype.dispatchEvent=function(e){throw new Error(It)},t.prototype.commitStyles=function(){throw new Error(It)},t.prototype.ensureAlive=function(){var e,n;this.playbackRate<0&&this.currentTime===0?this._inEffect=!!(!((e=this.effect)===null||e===void 0)&&e.update(-1)):this._inEffect=!!(!((n=this.effect)===null||n===void 0)&&n.update(this.currentTime)),!this._inTimeline&&(this._inEffect||!this._finishedFlag)&&(this._inTimeline=!0,this.timeline.animations.push(this))},t.prototype.tickCurrentTime=function(e,n){e!==this._currentTime&&(this._currentTime=e,this._isFinished&&!n&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this.ensureAlive())},t.prototype.fireEvents=function(e){var n=this;if(this._isFinished){if(!this._finishedFlag){if(this.onfinish){var r=new Vf(null,this,this.currentTime,e);setTimeout(function(){n.onfinish&&n.onfinish(r)})}this._finishedFlag=!0}}else{if(this.onframe&&this.playState==="running"){var i=new Vf(null,this,this.currentTime,e);this.onframe(i)}this._finishedFlag=!1}},t}(),o6=4,s6=.001,c6=1e-7,l6=10,Po=11,yc=1/(Po-1),u6=typeof Float32Array=="function",Vw=function(t,e){return 1-3*e+3*t},Xw=function(t,e){return 3*e-6*t},Uw=function(t){return 3*t},Rl=function(t,e,n){return((Vw(e,n)*t+Xw(e,n))*t+Uw(e))*t},qw=function(t,e,n){return 3*Vw(e,n)*t*t+2*Xw(e,n)*t+Uw(e)},f6=function(t,e,n,r,i){var a,o,s=0;do o=e+(n-e)/2,a=Rl(o,r,i)-t,a>0?n=o:e=o;while(Math.abs(a)>c6&&++s=s6?d6(s,d,t,n):h===0?d:f6(s,c,c+yc,t,n)};return function(s){return s===0||s===1?s:Rl(o(s),e,r)}},h6=function(t){return t=t.replace(/([A-Z])/g,function(e){return"-".concat(e.toLowerCase())}),t.charAt(0)==="-"?t.substring(1):t},mc=function(t){return Math.pow(t,2)},bc=function(t){return Math.pow(t,3)},xc=function(t){return Math.pow(t,4)},wc=function(t){return Math.pow(t,5)},Oc=function(t){return Math.pow(t,6)},Sc=function(t){return 1-Math.cos(t*Math.PI/2)},_c=function(t){return 1-Math.sqrt(1-t*t)},Mc=function(t){return t*t*(3*t-2)},Ec=function(t){for(var e,n=4;t<((e=Math.pow(2,--n))-1)/11;);return 1/Math.pow(4,3-n)-7.5625*Math.pow((e*3-2)/22-t,2)},Pc=function(t,e){e===void 0&&(e=[]);var n=N(e,2),r=n[0],i=r===void 0?1:r,a=n[1],o=a===void 0?.5:a,s=ce(Number(i),1,10),c=ce(Number(o),.1,2);return t===0||t===1?t:-s*Math.pow(2,10*(t-1))*Math.sin((t-1-c/(Math.PI*2)*Math.asin(1/s))*(Math.PI*2)/c)},wo=function(t,e,n){e===void 0&&(e=[]);var r=N(e,4),i=r[0],a=i===void 0?1:i,o=r[1],s=o===void 0?100:o,c=r[2],l=c===void 0?10:c,u=r[3],f=u===void 0?0:u;a=ce(a,.1,1e3),s=ce(s,.1,1e3),l=ce(l,.1,1e3),f=ce(f,.1,1e3);var d=Math.sqrt(s/a),h=l/(2*Math.sqrt(s*a)),p=h<1?d*Math.sqrt(1-h*h):0,v=1,g=h<1?(h*d+-f)/p:-f+d,y=n?n*t/1e3:t;return h<1?y=Math.exp(-y*h*d)*(v*Math.cos(p*y)+g*Math.sin(p*y)):y=(v+g*y)*Math.exp(-y*d),t===0||t===1?t:1-y},Xf=function(t,e){e===void 0&&(e=[]);var n=N(e,2),r=n[0],i=r===void 0?10:r,a=n[1],o=a=="start"?Math.ceil:Math.floor;return o(ce(t,0,1)*i)/i},ly=function(t,e){e===void 0&&(e=[]);var n=N(e,4),r=n[0],i=n[1],a=n[2],o=n[3];return Jp(r,i,a,o)(t)},Ac=Jp(.42,0,1,1),Sn=function(t){return function(e,n,r){return n===void 0&&(n=[]),1-t(1-e,n,r)}},_n=function(t){return function(e,n,r){return n===void 0&&(n=[]),e<.5?t(e*2,n,r)/2:1-t(e*-2+2,n,r)/2}},Mn=function(t){return function(e,n,r){return n===void 0&&(n=[]),e<.5?(1-t(1-e*2,n,r))/2:(t(e*2-1,n,r)+1)/2}},uy={steps:Xf,"step-start":function(t){return Xf(t,[1,"start"])},"step-end":function(t){return Xf(t,[1,"end"])},linear:function(t){return t},"cubic-bezier":ly,ease:function(t){return ly(t,[.25,.1,.25,1])},in:Ac,out:Sn(Ac),"in-out":_n(Ac),"out-in":Mn(Ac),"in-quad":mc,"out-quad":Sn(mc),"in-out-quad":_n(mc),"out-in-quad":Mn(mc),"in-cubic":bc,"out-cubic":Sn(bc),"in-out-cubic":_n(bc),"out-in-cubic":Mn(bc),"in-quart":xc,"out-quart":Sn(xc),"in-out-quart":_n(xc),"out-in-quart":Mn(xc),"in-quint":wc,"out-quint":Sn(wc),"in-out-quint":_n(wc),"out-in-quint":Mn(wc),"in-expo":Oc,"out-expo":Sn(Oc),"in-out-expo":_n(Oc),"out-in-expo":Mn(Oc),"in-sine":Sc,"out-sine":Sn(Sc),"in-out-sine":_n(Sc),"out-in-sine":Mn(Sc),"in-circ":_c,"out-circ":Sn(_c),"in-out-circ":_n(_c),"out-in-circ":Mn(_c),"in-back":Mc,"out-back":Sn(Mc),"in-out-back":_n(Mc),"out-in-back":Mn(Mc),"in-bounce":Ec,"out-bounce":Sn(Ec),"in-out-bounce":_n(Ec),"out-in-bounce":Mn(Ec),"in-elastic":Pc,"out-elastic":Sn(Pc),"in-out-elastic":_n(Pc),"out-in-elastic":Mn(Pc),spring:wo,"spring-in":wo,"spring-out":Sn(wo),"spring-in-out":_n(wo),"spring-out-in":Mn(wo)},p6=function(t){return h6(t).replace(/^ease-/,"").replace(/(\(|\s).+/,"").toLowerCase().trim()},v6=function(t){return uy[p6(t)]||uy.linear},g6=function(t){return t},y6=1,m6=.5,fy=0;function dy(t,e){return function(n){if(n>=1)return 1;var r=1/t;return n+=e*r,n-n%r}}var kc="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",b6=new RegExp("cubic-bezier\\("+kc+","+kc+","+kc+","+kc+"\\)"),x6=/steps\(\s*(\d+)\s*\)/,w6=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;function t0(t){var e=b6.exec(t);if(e)return Jp.apply(void 0,q([],N(e.slice(1).map(Number)),!1));var n=x6.exec(t);if(n)return dy(Number(n[1]),fy);var r=w6.exec(t);return r?dy(Number(r[1]),{start:y6,middle:m6,end:fy}[r[2]]):v6(t)}function O6(t){return Math.abs(S6(t)/(t.playbackRate||1))}function S6(t){var e;return t.duration===0||t.iterations===0?0:(t.duration==="auto"?0:Number(t.duration))*((e=t.iterations)!==null&&e!==void 0?e:1)}var Kw=0,e0=1,zu=2,Zw=3;function _6(t,e,n){if(e===null)return Kw;var r=n.endTime;return e=Math.min(n.delay+t+n.endDelay,r)?zu:Zw}function M6(t,e,n,r,i){switch(r){case e0:return e==="backwards"||e==="both"?0:null;case Zw:return n-i;case zu:return e==="forwards"||e==="both"?t:null;case Kw:return null}}function E6(t,e,n,r,i){var a=i;return t===0?e!==e0&&(a+=n):a+=r/t,a}function P6(t,e,n,r,i,a){var o=t===1/0?e%1:t%1;return o===0&&n===zu&&r!==0&&(i!==0||a===0)&&(o=1),o}function A6(t,e,n,r){return t===zu&&e===1/0?1/0:n===1?Math.floor(r)-1:Math.floor(r)}function k6(t,e,n){var r=t;if(t!=="normal"&&t!=="reverse"){var i=e;t==="alternate-reverse"&&(i+=1),r="normal",i!==1/0&&i%2!==0&&(r="reverse")}return r==="normal"?n:1-n}function T6(t,e,n){var r=_6(t,e,n),i=M6(t,n.fill,e,r,n.delay);if(i===null)return null;var a=n.duration==="auto"?0:n.duration,o=E6(a,r,n.iterations,i,n.iterationStart),s=P6(o,n.iterationStart,r,n.iterations,i,a),c=A6(r,n.iterations,s,o),l=k6(n.direction,c,s);return n.currentIteration=c,n.progress=l,n.easingFunction(l)}function C6(t,e,n){var r=L6(t,e),i=N6(r,n);return function(a,o){if(o!==null)i.filter(function(c){return o>=c.applyFrom&&o1)throw new Error("Keyframe offsets must be between 0 and 1.");l.computedOffset=f}}else if(u==="composite"&&["replace","add","accumulate","auto"].indexOf(f)===-1)throw new Error("".concat(f," compositing is not supported"));l[u]=f}return l.offset===void 0&&(l.offset=null),l.easing===void 0&&(l.easing=(e==null?void 0:e.easing)||"linear"),l.composite===void 0&&(l.composite="auto"),l}),r=!0,i=-1/0,a=0;a=0&&Number(c.offset)<=1});function s(){var c,l,u=n.length;n[u-1].computedOffset=Number((c=n[u-1].offset)!==null&&c!==void 0?c:1),u>1&&(n[0].computedOffset=Number((l=n[0].offset)!==null&&l!==void 0?l:0));for(var f=0,d=Number(n[0].computedOffset),h=1;hthis.createElement(e),r=[];if(this._data!==null){for(let i=0;ii,r=()=>null){const i=[],a=[],o=new Set(this._elements),s=[],c=new Set,l=new Map(this._elements.map((h,p)=>[n(h.__data__,p),h])),u=new Map(this._facetElements.map((h,p)=>[n(h.__data__,p),h])),f=te(this._elements,h=>r(h.__data__));for(let h=0;ho,n=o=>o,r=o=>o.remove(),i=o=>o,a=o=>o.remove()){const o=e(this._enter),s=n(this._update),c=r(this._exit),l=i(this._merge),u=a(this._split);return s.merge(o).merge(c).merge(l).merge(u)}remove(){for(let e=0;ei.finished)).then(()=>{this._elements[e].remove()})}else this._elements[e].remove()}return new Ae([],null,this._parent,this._document,void 0,this._transitions)}each(e){for(let n=0;nn:n;return this.each(function(i,a,o){n!==void 0&&(o[e]=r(i,a,o))})}style(e,n){const r=typeof n!="function"?()=>n:n;return this.each(function(i,a,o){n!==void 0&&(o.style[e]=r(i,a,o))})}transition(e){const n=typeof e!="function"?()=>e:e,{_transitions:r}=this;return this.each(function(i,a,o){r[a]=n(i,a,o)})}on(e,n){return this.each(function(r,i,a){a.addEventListener(e,n)}),this}call(e,...n){return e(this,...n),this}node(){return this._elements[0]}nodes(){return this._elements}transitions(){return this._transitions}parent(){return this._parent}};Il.registry={g:Ce,rect:Zi,circle:Xs,path:Xe,text:ei,ellipse:Kp,image:Zp,line:Us,polygon:Fu,polyline:Qp,html:Bu};function Tc(t,e,n){return Math.max(e,Math.min(t,n))}function jl(t,e=10){return typeof t!="number"||Math.abs(t)<1e-15?t:parseFloat(t.toFixed(e))}function at(t,e){for(const[n,r]of Object.entries(e))t.style(n,r)}function W6(t,e){return e.forEach((n,r)=>r===0?t.moveTo(n[0],n[1]):t.lineTo(n[0],n[1])),t.closePath(),t}function H6(t,e,n){const{arrowSize:r}=n,i=typeof r=="string"?+parseFloat(r)/100*Jt(t,e):r,a=Math.PI/6,o=Math.atan2(e[1]-t[1],e[0]-t[0]),s=Math.PI/2-o-a,c=[e[0]-i*Math.sin(s),e[1]-i*Math.cos(s)],l=o-a,u=[e[0]-i*Math.cos(l),e[1]-i*Math.sin(l)];return[c,u]}function vs(t,e,n,r,i){const a=Nn(se(r,e))+Math.PI,o=Nn(se(r,n))+Math.PI;return t.arc(r[0],r[1],i,a,o,o-a<0),t}function tO(t,e,n,r="y",i="between",a=!1){const o=(g,y)=>g==="y"||g===!0?y?180:90:y?90:0,s=r==="y"||r===!0?n:e,c=o(r,a),l=Ui(s),[u,f]=Mr(l,g=>s[g]),d=new Yt({domain:[u,f],range:[0,100]}),h=g=>de(s[g])&&!Number.isNaN(s[g])?d.map(s[g]):0,p={between:g=>`${t[g]} ${h(g)}%`,start:g=>g===0?`${t[g]} ${h(g)}%`:`${t[g-1]} ${h(g)}%, ${t[g]} ${h(g)}%`,end:g=>g===t.length-1?`${t[g]} ${h(g)}%`:`${t[g]} ${h(g)}%, ${t[g+1]} ${h(g)}%`},v=l.sort((g,y)=>h(g)-h(y)).map(p[i]||p.between).join(",");return`linear-gradient(${c}deg, ${v})`}function Gu(t){const[e,n,r,i]=t;return[i,e,n,r]}function Qi(t,e,n){const[r,i,,a]=qt(t)?Gu(e):e,[o,s]=n,c=t.getCenter(),l=ja(se(r,c)),u=ja(se(i,c)),f=u===l&&o!==s?u+Math.PI*2:u;return{startAngle:l,endAngle:f-l>=0?f:Math.PI*2+f,innerRadius:Jt(a,c),outerRadius:Jt(r,c)}}function eO(t){const{colorAttribute:e,opacityAttribute:n=e}=t;return`${n}Opacity`}function nO(t,e){if(!Ht(t))return"";const n=t.getCenter(),{transform:r}=e;return`translate(${n[0]}, ${n[1]}) ${r||""}`}function rO(t){if(t.length===1)return t[0];const[[e,n,r=0],[i,a,o=0]]=t;return[(e+i)/2,(n+a)/2,(r+o)/2]}var nl=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i0?P:P+A,L=k>0?T:T+k,I=Math.abs(A),R=Math.abs(k),j=C+s,D=L+c,$=I-(s+l),B=R-(c+u),F=_?Tc($,y,1/0):Tc($,v,g),Y=_?Tc(B,v,g):Tc(B,y,1/0),U=_?j:j-(F-$)/2,K=_?D-(Y-B)/2:D-(Y-B);return st(t.createElement("rect",{})).style("x",U).style("y",K).style("width",F).style("height",Y).style("radius",[h,p,d,f]).call(at,m).node()}const{y:b,y1:x}=n,w=r.getCenter(),O=Qi(r,e,[b,x]),S=Cu().cornerRadius(o).padAngle(a*Math.PI/180);return st(t.createElement("path",{})).style("path",S(O)).style("transform",`translate(${w[0]}, ${w[1]})`).style("radius",o).style("inset",a).call(at,m).node()}const qs=(t,e)=>{const{colorAttribute:n,opacityAttribute:r="fill",first:i=!0,last:a=!0}=t,o=nl(t,["colorAttribute","opacityAttribute","first","last"]),{coordinate:s,document:c}=e;return(l,u,f)=>{const{color:d,radius:h=0}=f,p=nl(f,["color","radius"]),v=p.lineWidth||1,{stroke:g,radius:y=h,radiusTopLeft:m=y,radiusTopRight:b=y,radiusBottomRight:x=y,radiusBottomLeft:w=y,innerRadius:O=0,innerRadiusTopLeft:S=O,innerRadiusTopRight:_=O,innerRadiusBottomRight:M=O,innerRadiusBottomLeft:E=O,lineWidth:P=n==="stroke"||g?v:0,inset:T=0,insetLeft:A=T,insetRight:k=T,insetBottom:C=T,insetTop:L=T,minWidth:I,maxWidth:R,minHeight:j}=o,D=nl(o,["stroke","radius","radiusTopLeft","radiusTopRight","radiusBottomRight","radiusBottomLeft","innerRadius","innerRadiusTopLeft","innerRadiusTopRight","innerRadiusBottomRight","innerRadiusBottomLeft","lineWidth","inset","insetLeft","insetRight","insetBottom","insetTop","minWidth","maxWidth","minHeight"]),{color:$=d,opacity:B}=u,F=[i?m:S,i?b:_,a?x:M,a?w:E],Y=["radiusTopLeft","radiusTopRight","radiusBottomRight","radiusBottomLeft"];qt(s)&&Y.push(Y.shift());const U=Object.assign(Object.assign({radius:y},Object.fromEntries(Y.map((K,V)=>[K,F[V]]))),{inset:T,insetLeft:A,insetRight:k,insetBottom:C,insetTop:L,minWidth:I,maxWidth:R,minHeight:j});return st(iO(c,l,u,s,U)).call(at,p).style("fill","transparent").style(n,$).style(eO(t),B).style("lineWidth",P).style("stroke",g===void 0?$:g).call(at,D).node()}};qs.props={defaultEnterAnimation:"scaleInY",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const Ji=(t,e)=>qs(Object.assign({colorAttribute:"fill"},t),e);Ji.props=Object.assign(Object.assign({},qs.props),{defaultMarker:"square"});const Yu=(t,e)=>qs(Object.assign({colorAttribute:"stroke"},t),e);Yu.props=Object.assign(Object.assign({},qs.props),{defaultMarker:"hollowSquare"});var gy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{adjustPoints:n=V6}=t,r=gy(t,["adjustPoints"]),{coordinate:i,document:a}=e;return(o,s,c,l)=>{const{index:u}=s,{color:f}=c,d=gy(c,["color"]),h=l[u+1],p=n(o,h,i),v=!!qt(i),[g,y,m,b]=v?Gu(p):p,{color:x=f,opacity:w}=s,O=Jr().curve(jp)([g,y,m,b]);return st(a.createElement("path",{})).call(at,d).style("path",O).style("fill",x).style("fillOpacity",w).call(at,r).node()}};n0.props={defaultMarker:"square"};function X6(t,e,n){const[r,i,a,o]=t;if(qt(n)){const l=[e?e[0][0]:(i[0]+a[0])/2,i[1]],u=[e?e[3][0]:(i[0]+a[0])/2,a[1]];return[r,l,u,o]}const s=[i[0],e?e[0][1]:(i[1]+a[1])/2],c=[a[0],e?e[3][1]:(i[1]+a[1])/2];return[r,s,c,o]}const aO=(t,e)=>n0(Object.assign({adjustPoints:X6},t),e);aO.props={defaultMarker:"square"};function Fa(t){const e=typeof t=="function"?t:t.render;return class extends qp{connectedCallback(){this.draw()}attributeChangedCallback(){this.draw()}draw(){e(this)}}}var yy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{d1:e,d2:n,style1:r,style2:i}=t.attributes,a=t.ownerDocument;st(t).maybeAppend("line",()=>a.createElement("path",{})).style("d",e).call(at,r),st(t).maybeAppend("line1",()=>a.createElement("path",{})).style("d",n).call(at,i)});function q6(t,e){const n=[],r=[];let i=!1,a=null;for(const o of t)!e(o[0])||!e(o[1])?i=!0:(n.push(o),i&&(i=!1,r.push([a,o])),a=o);return[n,r]}const Dn=(t,e)=>{const{curve:n,gradient:r=!1,gradientColor:i="between",defined:a=u=>!Number.isNaN(u)&&u!==void 0&&u!==null,connect:o=!1}=t,s=yy(t,["curve","gradient","gradientColor","defined","connect"]),{coordinate:c,document:l}=e;return(u,f,d)=>{const{color:h,lineWidth:p}=d,v=yy(d,["color","lineWidth"]),{color:g=h,size:y=p,seriesColor:m,seriesX:b,seriesY:x}=f,w=nO(c,f),O=qt(c),S=r&&m?tO(m,b,x,r,i,O):g,_=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},v),S&&{stroke:S}),y&&{lineWidth:y}),w&&{transform:w}),s);let M;if(Ht(c)){const C=c.getCenter();M=L=>wL().angle((I,R)=>ja(se(L[R],C))).radius((I,R)=>Jt(L[R],C)).defined(([I,R])=>a(I)&&a(R)).curve(n)(L)}else M=Jr().x(C=>C[0]).y(C=>C[1]).defined(([C,L])=>a(C)&&a(L)).curve(n);const[E,P]=q6(u,a),T=Q(_,"connect"),A=!!P.length;if(!A||o&&!Object.keys(T).length)return st(l.createElement("path",{})).style("d",M(E)||[]).call(at,_).node();if(A&&!o)return st(l.createElement("path",{})).style("d",M(u)).call(at,_).node();const k=C=>C.map(M).join(",");return st(new U6).style("style1",Object.assign(Object.assign({},_),T)).style("style2",_).style("d1",k(P)).style("d2",M(u)).node()}};Dn.props={defaultMarker:"smooth",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const oO=(t,e)=>{const{coordinate:n}=e;return(...r)=>{const i=Ht(n)?jp:Ys;return Dn(Object.assign({curve:i},t),e)(...r)}};oO.props=Object.assign(Object.assign({},Dn.props),{defaultMarker:"line"});var K6=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const n=K6(t,[]),{coordinate:r}=e;return(...i)=>{const a=Ht(r)?ew:qt(r)?ow:aw;return Dn(Object.assign({curve:a},n),e)(...i)}};sO.props=Object.assign(Object.assign({},Dn.props),{defaultMarker:"smooth"});const cO=(t,e)=>Dn(Object.assign({curve:lw},t),e);cO.props=Object.assign(Object.assign({},Dn.props),{defaultMarker:"hv"});const lO=(t,e)=>Dn(Object.assign({curve:cw},t),e);lO.props=Object.assign(Object.assign({},Dn.props),{defaultMarker:"vh"});const uO=(t,e)=>Dn(Object.assign({curve:sw},t),e);uO.props=Object.assign(Object.assign({},Dn.props),{defaultMarker:"hvh"});var Z6=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{document:n}=e;return(r,i,a)=>{const{seriesSize:o,color:s}=i,{color:c}=a,l=Z6(a,["color"]),u=jn();for(let f=0;f[["M",t-n,e],["A",n,n,0,1,0,t+n,e],["A",n,n,0,1,0,t-n,e],["Z"]];r0.style=["fill"];const dO=r0.bind(void 0);dO.style=["stroke","lineWidth"];const Wu=(t,e,n)=>[["M",t-n,e-n],["L",t+n,e-n],["L",t+n,e+n],["L",t-n,e+n],["Z"]];Wu.style=["fill"];const hO=Wu.bind(void 0);hO.style=["fill"];const pO=Wu.bind(void 0);pO.style=["stroke","lineWidth"];const i0=(t,e,n)=>{const r=n*.618;return[["M",t-r,e],["L",t,e-n],["L",t+r,e],["L",t,e+n],["Z"]]};i0.style=["fill"];const vO=i0.bind(void 0);vO.style=["stroke","lineWidth"];const a0=(t,e,n)=>{const r=n*Math.sin(.3333333333333333*Math.PI);return[["M",t-n,e+r],["L",t,e-r],["L",t+n,e+r],["Z"]]};a0.style=["fill"];const gO=a0.bind(void 0);gO.style=["stroke","lineWidth"];const o0=(t,e,n)=>{const r=n*Math.sin(.3333333333333333*Math.PI);return[["M",t-n,e-r],["L",t+n,e-r],["L",t,e+r],["Z"]]};o0.style=["fill"];const yO=o0.bind(void 0);yO.style=["stroke","lineWidth"];const s0=(t,e,n)=>{const r=n/2*Math.sqrt(3);return[["M",t,e-n],["L",t+r,e-n/2],["L",t+r,e+n/2],["L",t,e+n],["L",t-r,e+n/2],["L",t-r,e-n/2],["Z"]]};s0.style=["fill"];const mO=s0.bind(void 0);mO.style=["stroke","lineWidth"];const c0=(t,e,n)=>{const r=n-1.5;return[["M",t-n,e-r],["L",t+n,e+r],["L",t+n,e-r],["L",t-n,e+r],["Z"]]};c0.style=["fill"];const bO=c0.bind(void 0);bO.style=["stroke","lineWidth"];const xO=(t,e,n)=>[["M",t,e+n],["L",t,e-n]];xO.style=["stroke","lineWidth"];const wO=(t,e,n)=>[["M",t-n,e-n],["L",t+n,e+n],["M",t+n,e-n],["L",t-n,e+n]];wO.style=["stroke","lineWidth"];const OO=(t,e,n)=>[["M",t-n/2,e-n],["L",t+n/2,e-n],["M",t,e-n],["L",t,e+n],["M",t-n/2,e+n],["L",t+n/2,e+n]];OO.style=["stroke","lineWidth"];const SO=(t,e,n)=>[["M",t-n,e],["L",t+n,e],["M",t,e-n],["L",t,e+n]];SO.style=["stroke","lineWidth"];const _O=(t,e,n)=>[["M",t-n,e],["L",t+n,e]];_O.style=["stroke","lineWidth"];const l0=(t,e,n)=>[["M",t-n,e],["L",t+n,e]];l0.style=["stroke","lineWidth"];const MO=l0.bind(void 0);MO.style=["stroke","lineWidth"];const EO=(t,e,n)=>[["M",t-n,e],["A",n/2,n/2,0,1,1,t,e],["A",n/2,n/2,0,1,0,t+n,e]];EO.style=["stroke","lineWidth"];const PO=(t,e,n)=>[["M",t-n-1,e-2.5],["L",t,e-2.5],["L",t,e+2.5],["L",t+n+1,e+2.5]];PO.style=["stroke","lineWidth"];const AO=(t,e,n)=>[["M",t-n-1,e+2.5],["L",t,e+2.5],["L",t,e-2.5],["L",t+n+1,e-2.5]];AO.style=["stroke","lineWidth"];const kO=(t,e,n)=>[["M",t-(n+1),e+2.5],["L",t-n/2,e+2.5],["L",t-n/2,e-2.5],["L",t+n/2,e-2.5],["L",t+n/2,e+2.5],["L",t+n+1,e+2.5]];kO.style=["stroke","lineWidth"];const TO=(t,e,n)=>[["M",t-5,e+2.5],["L",t-5,e],["L",t,e],["L",t,e-3],["L",t,e+3],["L",t+6.5,e+3]];TO.style=["stroke","lineWidth"];const Dl=new Map([["bowtie",c0],["cross",wO],["dash",MO],["diamond",i0],["dot",l0],["hexagon",s0],["hollowBowtie",bO],["hollowDiamond",vO],["hollowHexagon",mO],["hollowPoint",dO],["hollowSquare",pO],["hollowTriangle",gO],["hollowTriangleDown",yO],["hv",PO],["hvh",kO],["hyphen",_O],["line",xO],["plus",SO],["point",r0],["rect",hO],["smooth",EO],["square",Wu],["tick",OO],["triangleDown",o0],["triangle",a0],["vh",AO],["vhv",TO]]);function tI(t,e){var{d:n,fill:r,strokeWidth:i,path:a,stroke:o,lineWidth:s,color:c}=e,l=J6(e,["d","fill","strokeWidth","path","stroke","lineWidth","color"]);const u=Dl.get(t)||Dl.get("point");return(...f)=>new Xe({style:Object.assign(Object.assign({},l),{path:u(...f),stroke:u.style.includes("stroke")?c||o:"",fill:u.style.includes("fill")?c||r:"",lineWidth:u.style.includes("lineWidth")?s||s||2:0})})}var eI=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{colorAttribute:n,symbol:r,mode:i="auto"}=t,a=eI(t,["colorAttribute","symbol","mode"]),o=Dl.get(r)||Dl.get("point"),{coordinate:s,document:c}=e;return(l,u,f)=>{const{lineWidth:d,color:h}=f,p=a.stroke?d||1:d,{color:v=h,transform:g,opacity:y}=u,[m,b]=rO(l),w=nI(i,l,u,s)||a.r||f.r;return st(c.createElement("path",{})).call(at,f).style("fill","transparent").style("d",o(m,b,w)).style("lineWidth",p).style("transform",g).style("stroke",v).style(eO(t),y).style(n,v).call(at,a).node()}};bt.props={defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const CO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"bowtie"},t),e);CO.props=Object.assign({defaultMarker:"hollowBowtie"},bt.props);const LO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"diamond"},t),e);LO.props=Object.assign({defaultMarker:"hollowDiamond"},bt.props);const NO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"hexagon"},t),e);NO.props=Object.assign({defaultMarker:"hollowHexagon"},bt.props);const RO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"point"},t),e);RO.props=Object.assign({defaultMarker:"hollowPoint"},bt.props);const IO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"square"},t),e);IO.props=Object.assign({defaultMarker:"hollowSquare"},bt.props);const jO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"triangle"},t),e);jO.props=Object.assign({defaultMarker:"hollowTriangle"},bt.props);const DO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"triangle-down"},t),e);DO.props=Object.assign({defaultMarker:"hollowTriangleDown"},bt.props);const $O=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"bowtie"},t),e);$O.props=Object.assign({defaultMarker:"bowtie"},bt.props);const BO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"cross"},t),e);BO.props=Object.assign({defaultMarker:"cross"},bt.props);const FO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"diamond"},t),e);FO.props=Object.assign({defaultMarker:"diamond"},bt.props);const zO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"hexagon"},t),e);zO.props=Object.assign({defaultMarker:"hexagon"},bt.props);const GO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"hyphen"},t),e);GO.props=Object.assign({defaultMarker:"hyphen"},bt.props);const YO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"line"},t),e);YO.props=Object.assign({defaultMarker:"line"},bt.props);const WO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"plus"},t),e);WO.props=Object.assign({defaultMarker:"plus"},bt.props);const HO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"point"},t),e);HO.props=Object.assign({defaultMarker:"point"},bt.props);const VO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"square"},t),e);VO.props=Object.assign({defaultMarker:"square"},bt.props);const XO=(t,e)=>bt(Object.assign({colorAttribute:"stroke",symbol:"tick"},t),e);XO.props=Object.assign({defaultMarker:"tick"},bt.props);const UO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"triangle"},t),e);UO.props=Object.assign({defaultMarker:"triangle"},bt.props);const qO=(t,e)=>bt(Object.assign({colorAttribute:"fill",symbol:"triangle-down"},t),e);qO.props=Object.assign({defaultMarker:"triangleDown"},bt.props);var my=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{arrow:n=!0,arrowSize:r="40%"}=t,i=my(t,["arrow","arrowSize"]),{document:a}=e;return(o,s,c)=>{const{defaultColor:l}=c,u=my(c,["defaultColor"]),{color:f=l,transform:d}=s,[h,p]=o,v=jn();if(v.moveTo(...h),v.lineTo(...p),n){const[g,y]=H6(h,p,{arrowSize:r});v.moveTo(...p),v.lineTo(...g),v.moveTo(...p),v.lineTo(...y)}return st(a.createElement("path",{})).call(at,u).style("d",v.toString()).style("stroke",f).style("transform",d).call(at,i).node()}};u0.props={defaultMarker:"line",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};function KO(t,e){e(t),t.children&&t.children.forEach(function(n){n&&KO(n,e)})}function Ks(t){Hu(t,!0)}function li(t){Hu(t,!1)}function Hu(t,e){var n=e?"visible":"hidden";KO(t,function(r){r.attr("visibility",n)})}var rI=function(t){rt(e,t);function e(){for(var n=[],r=0;r=this.left&&e<=this.right&&n>=this.top&&n<=this.bottom},t}();function Rn(t,e){return Ve(t)?t.apply(void 0,q([],N(e),!1)):t}var $n=function(t,e){var n=function(i){return"".concat(e,"-").concat(i)},r=Object.fromEntries(Object.entries(t).map(function(i){var a=N(i,2),o=a[0],s=a[1],c=n(s);return[o,{name:c,class:".".concat(c),id:"#".concat(c),toString:function(){return c}}]}));return Object.assign(r,{prefix:n}),r},aI=5,JO=function(t,e,n,r){n===void 0&&(n=0),r===void 0&&(r=aI),Object.entries(e).forEach(function(i){var a=N(i,2),o=a[0],s=a[1],c=t;Object.prototype.hasOwnProperty.call(e,o)&&(s?Cr(s)?(Cr(t[o])||(c[o]={}),ne&&tr&&(r=d),h>i&&(i=h)}return new Qt(e,n,r-e,i-n)}var hI=function(t,e,n){var r=t.width,i=t.height,a=n.flexDirection,o=a===void 0?"row":a;n.flexWrap;var s=n.justifyContent,c=s===void 0?"flex-start":s;n.alignContent;var l=n.alignItems,u=l===void 0?"flex-start":l,f=o==="row",d=o==="row"||o==="column",h=f?d?[1,0]:[-1,0]:d?[0,1]:[0,-1],p=N([0,0],2),v=p[0],g=p[1],y=e.map(function(_){var M,E=_.width,P=_.height,T=N([v,g],2),A=T[0],k=T[1];return M=N([v+E*h[0],g+P*h[1]],2),v=M[0],g=M[1],new Qt(A,k,E,P)}),m=by(y),b={"flex-start":0,"flex-end":f?r-m.width:i-m.height,center:f?(r-m.width)/2:(i-m.height)/2},x=y.map(function(_){var M=_.x,E=_.y,P=Qt.fromRect(_);return P.x=f?M+b[c]:M,P.y=f?E:E+b[c],P});by(x);var w=function(_){var M=N(f?["height",i]:["width",r],2),E=M[0],P=M[1];switch(u){case"flex-start":return 0;case"flex-end":return P-_[E];case"center":return P/2-_[E]/2;default:return 0}},O=x.map(function(_){var M=_.x,E=_.y,P=Qt.fromRect(_);return P.x=f?M:M+w(P),P.y=f?E+w(P):E,P}),S=O.map(function(_){var M,E,P=Qt.fromRect(_);return P.x+=(M=t.x)!==null&&M!==void 0?M:0,P.y+=(E=t.y)!==null&&E!==void 0?E:0,P});return S},pI=function(t,e,n){return[]};const vI=function(t,e,n){if(e.length===0)return[];var r={flex:hI,grid:pI},i=n.display in r?r[n.display]:null;return(i==null?void 0:i.call(null,t,e,n))||[]};function Or(t,e){return[t[0]*e,t[1]*e]}function Ao(t,e){return[t[0]+e[0],t[1]+e[1]]}function Uf(t,e){return[t[0]-e[0],t[1]-e[1]]}function wi(t,e){return[Math.min(t[0],e[0]),Math.min(t[1],e[1])]}function Oi(t,e){return[Math.max(t[0],e[0]),Math.max(t[1],e[1])]}function gs(t,e){return Math.sqrt(Math.pow(t[0]-e[0],2)+Math.pow(t[1]-e[1],2))}function iS(t){if(t[0]===0&&t[1]===0)return[0,0];var e=Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2));return[t[0]/e,t[1]/e]}function gI(t,e){return e?[t[1],-t[0]]:[-t[1],t[0]]}function fh(t,e){return+t.toPrecision(e)}function xy(t,e){var n={},r=Array.isArray(e)?e:[e];for(var i in t)r.includes(i)||(n[i]=t[i]);return n}function yI(t,e,n,r){var i,a=[],o=!!r,s,c,l=[1/0,1/0],u=[-1/0,-1/0],f,d,h;if(o){i=N(r,2),l=i[0],u=i[1];for(var p=0,v=t.length;p="A"&&n<="Z"};function vt(t,e,n){n===void 0&&(n=!1);var r={};return Object.entries(t).forEach(function(i){var a=N(i,2),o=a[0],s=a[1];if(!(o==="className"||o==="class")){if(Lc(o,"show")&&Lc(Sy(o,"show"),e)!==n)o===kI(e,"show")?r[o]=s:r[o.replace(new RegExp(p0(e)),"")]=s;else if(!Lc(o,"show")&&Lc(o,e)!==n){var c=Sy(o,e);c==="filter"&&typeof s=="function"||(r[c]=s)}}}),r}function Jn(t,e){return Object.entries(t).reduce(function(n,r){var i=N(r,2),a=i[0],o=i[1];return a.startsWith("show")?n["show".concat(e).concat(a.slice(4))]=o:n["".concat(e).concat(p0(a))]=o,n},{})}function Rr(t,e){e===void 0&&(e=["x","y","class","className"]);var n=["transform","transformOrigin","anchor","visibility","pointerEvents","zIndex","cursor","clipPath","clipPathTargets","offsetPath","offsetPathTargets","offsetDistance","draggable","droppable"],r={},i={};return Object.entries(t).forEach(function(a){var o=N(a,2),s=o[0],c=o[1];e.includes(s)||(n.indexOf(s)!==-1?i[s]=c:r[s]=c)}),[r,i]}function CI(t,e,n){var r=t.getBBox(),i=r.width,a=r.height,o=N([e,n].map(function(l,u){var f;return l.includes("%")?parseFloat(((f=l.match(/[+-]?([0-9]*[.])?[0-9]+/))===null||f===void 0?void 0:f[0])||"0")/100*(u===0?i:a):l}),2),s=o[0],c=o[1];return[s,c]}function Bl(t,e){if(e)try{var n=/translate\(([+-]*[\d]+[%]*),[ ]*([+-]*[\d]+[%]*)\)/g,r=e.replace(n,function(i,a,o){return"translate(".concat(CI(t,a,o),")")});t.attr("transform",r)}catch{}}function LI(t){var e;return((e=t[0])===null||e===void 0?void 0:e.map(function(n,r){return t.map(function(i){return i[r]})}))||[]}function NI(){Hu(this,this.attributes.visibility!=="hidden")}var Pe=function(t){rt(e,t);function e(n,r){r===void 0&&(r={});var i=t.call(this,Nr({},{style:r},n))||this;return i.initialized=!1,i._defaultOptions=r,i}return Object.defineProperty(e.prototype,"offscreenGroup",{get:function(){return this._offscreen||(this._offscreen=ZO(this)),this._offscreen},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"defaultOptions",{get:function(){return this._defaultOptions},enumerable:!1,configurable:!0}),e.prototype.connectedCallback=function(){this.render(this.attributes,this),this.bindEvents(this.attributes,this),this.initialized=!0},e.prototype.disconnectedCallback=function(){var n;(n=this._offscreen)===null||n===void 0||n.destroy()},e.prototype.attributeChangedCallback=function(n){n==="visibility"&&NI.call(this)},e.prototype.update=function(n,r){var i;return this.attr(Nr({},this.attributes,n||{})),(i=this.render)===null||i===void 0?void 0:i.call(this,this.attributes,this,r)},e.prototype.clear=function(){this.removeChildren()},e.prototype.bindEvents=function(n,r){},e}(qp),aS=function(t,e,n){return[["M",t-n,e],["A",n,n,0,1,0,t+n,e],["A",n,n,0,1,0,t-n,e],["Z"]]},RI=aS,II=function(t,e,n){return[["M",t-n,e-n],["L",t+n,e-n],["L",t+n,e+n],["L",t-n,e+n],["Z"]]},jI=function(t,e,n){return[["M",t-n,e],["L",t,e-n],["L",t+n,e],["L",t,e+n],["Z"]]},DI=function(t,e,n){var r=n*Math.sin(.3333333333333333*Math.PI);return[["M",t-n,e+r],["L",t,e-r],["L",t+n,e+r],["Z"]]},$I=function(t,e,n){var r=n*Math.sin(.3333333333333333*Math.PI);return[["M",t-n,e-r],["L",t+n,e-r],["L",t,e+r],["Z"]]},BI=function(t,e,n){var r=n/2*Math.sqrt(3);return[["M",t,e-n],["L",t+r,e-n/2],["L",t+r,e+n/2],["L",t,e+n],["L",t-r,e+n/2],["L",t-r,e-n/2],["Z"]]},FI=function(t,e,n){var r=n-1.5;return[["M",t-n,e-r],["L",t+n,e+r],["L",t+n,e-r],["L",t-n,e+r],["Z"]]},oS=function(t,e,n){return[["M",t,e+n],["L",t,e-n]]},zI=function(t,e,n){return[["M",t-n,e-n],["L",t+n,e+n],["M",t+n,e-n],["L",t-n,e+n]]},GI=function(t,e,n){return[["M",t-n/2,e-n],["L",t+n/2,e-n],["M",t,e-n],["L",t,e+n],["M",t-n/2,e+n],["L",t+n/2,e+n]]},YI=function(t,e,n){return[["M",t-n,e],["L",t+n,e],["M",t,e-n],["L",t,e+n]]},WI=function(t,e,n){return[["M",t-n,e],["L",t+n,e]]},sS=function(t,e,n){return[["M",t-n,e],["L",t+n,e]]},HI=sS,VI=function(t,e,n){return[["M",t-n,e],["A",n/2,n/2,0,1,1,t,e],["A",n/2,n/2,0,1,0,t+n,e]]},XI=function(t,e,n){return[["M",t-n-1,e-2.5],["L",t,e-2.5],["L",t,e+2.5],["L",t+n+1,e+2.5]]},UI=function(t,e,n){return[["M",t-n-1,e+2.5],["L",t,e+2.5],["L",t,e-2.5],["L",t+n+1,e-2.5]]},qI=function(t,e,n){return[["M",t-(n+1),e+2.5],["L",t-n/2,e+2.5],["L",t-n/2,e-2.5],["L",t+n/2,e-2.5],["L",t+n/2,e+2.5],["L",t+n+1,e+2.5]]};function KI(t,e){return[["M",t-5,e+2.5],["L",t-5,e],["L",t,e],["L",t,e-3],["L",t,e+3],["L",t+6.5,e+3]]}var ZI=function(t,e,n){return[["M",t-n,e-n],["L",t+n,e],["L",t-n,e+n],["Z"]]};function QI(t){var e="default";if(ki(t)&&t instanceof Image)e="image";else if(Ve(t))e="symbol";else if(le(t)){var n=new RegExp("data:(image|text)");t.match(n)?e="base64":/^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(t)?e="url":e="symbol"}return e}function JI(t){var e=QI(t);return["base64","url","image"].includes(e)?"image":t&&e==="symbol"?"path":null}var Bt=function(t){rt(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.render=function(n,r){var i=n.symbol,a=n.size,o=a===void 0?16:a,s=$t(n,["symbol","size"]),c=JI(i);on(!!c,dt(r),function(l){l.maybeAppendByClassName("marker",c).attr("className","marker ".concat(c,"-marker")).call(function(u){if(c==="image"){var f=o*2;u.styles({img:i,width:f,height:f,x:-o,y:-o})}else{var f=o/2,d=Ve(i)?i:e.getSymbol(i);u.styles(z({path:d==null?void 0:d(0,0,f)},s))}})})},e.MARKER_SYMBOL_MAP=new Map,e.registerSymbol=function(n,r){e.MARKER_SYMBOL_MAP.set(n,r)},e.getSymbol=function(n){return e.MARKER_SYMBOL_MAP.get(n)},e.getSymbols=function(){return Array.from(e.MARKER_SYMBOL_MAP.keys())},e}(Pe);Bt.registerSymbol("cross",zI);Bt.registerSymbol("hyphen",WI);Bt.registerSymbol("line",oS);Bt.registerSymbol("plus",YI);Bt.registerSymbol("tick",GI);Bt.registerSymbol("circle",aS);Bt.registerSymbol("point",RI);Bt.registerSymbol("bowtie",FI);Bt.registerSymbol("hexagon",BI);Bt.registerSymbol("square",II);Bt.registerSymbol("diamond",jI);Bt.registerSymbol("triangle",DI);Bt.registerSymbol("triangle-down",$I);Bt.registerSymbol("line",oS);Bt.registerSymbol("dot",sS);Bt.registerSymbol("dash",HI);Bt.registerSymbol("smooth",VI);Bt.registerSymbol("hv",XI);Bt.registerSymbol("vh",UI);Bt.registerSymbol("hvh",qI);Bt.registerSymbol("vhv",KI);var t8=function(t){rt(e,t);function e(n){var r=this,i=n.style,a=$t(n,["style"]);return r=t.call(this,X({},{type:"column"},z({style:i},a)))||this,r.columnsGroup=new Ce({name:"columns"}),r.appendChild(r.columnsGroup),r.render(),r}return e.prototype.render=function(){var n=this.attributes.columns;dt(this.columnsGroup).selectAll(".column").data(n.flat()).join(function(r){return r.append("rect").attr("className","column").each(function(i){this.attr(i)})},function(r){return r.each(function(i){this.attr(i)})},function(r){return r.remove()})},e.prototype.update=function(n){this.attr(Nr({},this.attributes,n)),this.render()},e.prototype.clear=function(){this.removeChildren()},e}(ze),e8=function(t){rt(e,t);function e(n){var r=this,i=n.style,a=$t(n,["style"]);return r=t.call(this,X({},{type:"lines"},z({style:i},a)))||this,r.linesGroup=r.appendChild(new Ce),r.areasGroup=r.appendChild(new Ce),r.render(),r}return e.prototype.render=function(){var n=this.attributes,r=n.lines,i=n.areas;r&&this.renderLines(r),i&&this.renderAreas(i)},e.prototype.clear=function(){this.linesGroup.removeChildren(),this.areasGroup.removeChildren()},e.prototype.update=function(n){this.attr(Nr({},this.attributes,n)),this.render()},e.prototype.renderLines=function(n){dt(this.linesGroup).selectAll(".line").data(n).join(function(r){return r.append("path").attr("className","line").each(function(i){this.attr(i)})},function(r){return r.each(function(i){this.attr(i)})},function(r){return r.remove()})},e.prototype.renderAreas=function(n){dt(this.linesGroup).selectAll(".area").data(n).join(function(r){return r.append("path").attr("className","area").each(function(i){this.attr(i)})},function(r){return r.each(function(i){this.style(i)})},function(r){return r.remove()})},e}(ze);function n8(t,e){var n,r=e.x,i=e.y,a=N(i.getOptions().range||[0,0],2),o=a[0],s=a[1];return s>o&&(n=N([o,s],2),s=n[0],o=n[1]),t.map(function(c){var l=c.map(function(u,f){return[r.map(f),ce(i.map(u),s,o)]});return l})}function ys(t,e){e===void 0&&(e=!1);var n=e?t.length-1:0,r=t.map(function(i,a){return q([a===n?"M":"L"],N(i),!1)});return e?r.reverse():r}function Fl(t,e){if(e===void 0&&(e=!1),t.length<=2)return ys(t);for(var n=[],r=t.length,i=0;i=0;i-=1){var a=t[i],o=ys(a),s=void 0;if(i===0)s=v0(o,e,n);else{var c=t[i-1],l=ys(c,!0);l[0][0]="L",s=q(q(q([],N(o),!1),N(l),!1),[["Z"]],!1)}r.push(s)}return r}function a8(t,e,n){for(var r=[],i=t.length-1;i>=0;i-=1){var a=t[i],o=Fl(a),s=void 0;if(i===0)s=v0(o,e,n);else{var c=t[i-1],l=Fl(c,!0),u=a[0];l[0][0]="L",s=q(q(q([],N(o),!1),N(l),!1),[q(["M"],N(u),!1),["Z"]],!1)}r.push(s)}return r}function _y(t){return t.length===0?[0,0]:[hl(Lk(t,function(e){return hl(e)||0})),dl(Ck(t,function(e){return dl(e)||0}))]}function My(t){for(var e=Jo(t),n=e[0].length,r=N([Array(n).fill(0),Array(n).fill(0)],2),i=r[0],a=r[1],o=0;o=0?(s[c]+=i[c],i[c]=s[c]):(s[c]+=a[c],a[c]=s[c]);return e}var o8=function(t){rt(e,t);function e(n){return t.call(this,n,{type:"line",width:200,height:20,isStack:!1,color:["#83daad","#edbf45","#d2cef9","#e290b3","#6f63f4"],smooth:!0,lineLineWidth:1,areaOpacity:0,isGroup:!1,columnLineWidth:1,columnStroke:"#fff",scale:1,spacing:0})||this}return Object.defineProperty(e.prototype,"rawData",{get:function(){var n=this.attributes.data;if(!n||(n==null?void 0:n.length)===0)return[[]];var r=Jo(n);return de(r[0])?[r]:r},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"data",{get:function(){return this.attributes.isStack?My(this.rawData):this.rawData},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"scales",{get:function(){return this.createScales(this.data)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"baseline",{get:function(){var n=this.scales.y,r=N(n.getOptions().domain||[0,0],2),i=r[0],a=r[1];return a<0?n.map(a):n.map(i<0?0:i)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"containerShape",{get:function(){var n=this.attributes,r=n.width,i=n.height;return{width:r,height:i}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"linesStyle",{get:function(){var n=this,r=this.attributes,i=r.type,a=r.isStack,o=r.smooth;if(i!=="line")throw new Error("linesStyle can only be used in line type");var s=vt(this.attributes,"area"),c=vt(this.attributes,"line"),l=this.containerShape.width,u=this.data;if(u[0].length===0)return{lines:[],areas:[]};var f=this.scales,d=f.x,h=f.y,p=n8(u,{type:"line",x:d,y:h}),v=[];if(s){var g=this.baseline;a?v=o?a8(p,l,g):i8(p,l,g):v=r8(p,o,l,g)}return{lines:p.map(function(y,m){return z({stroke:n.getColor(m),path:o?Fl(y):ys(y)},c)}),areas:v.map(function(y,m){return z({path:y,fill:n.getColor(m)},s)})}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"columnsStyle",{get:function(){var n=this,r=vt(this.attributes,"column"),i=this.attributes,a=i.isStack,o=i.type,s=i.scale;if(o!=="column")throw new Error("columnsStyle can only be used in column type");var c=this.containerShape.height,l=this.rawData;if(!l)return{columns:[]};a&&(l=My(l));var u=this.createScales(l),f=u.x,d=u.y,h=N(_y(l),2),p=h[0],v=h[1],g=new Yt({domain:[0,v-(p>0?0:p)],range:[0,c*s]}),y=f.getBandWidth(),m=this.rawData;return{columns:l.map(function(b,x){return b.map(function(w,O){var S=y/l.length,_=function(){return{x:f.map(O)+S*x,y:w>=0?d.map(w):d.map(0),width:S,height:g.map(Math.abs(w))}},M=function(){return{x:f.map(O),y:d.map(w),width:y,height:g.map(m[x][O])}};return z(z({fill:n.getColor(x)},r),a?M():_())})})}},enumerable:!1,configurable:!0}),e.prototype.render=function(n,r){MI(r,".container","rect").attr("className","container").node();var i=n.type,a="spark".concat(i),o=i==="line"?this.linesStyle:this.columnsStyle;dt(r).selectAll(".spark").data([i]).join(function(s){return s.append(function(c){return c==="line"?new e8({className:a,style:o}):new t8({className:a,style:o})}).attr("className","spark ".concat(a))},function(s){return s.update(o)},function(s){return s.remove()})},e.prototype.getColor=function(n){var r=this.attributes.color;return Le(r)?r[n%r.length]:Ve(r)?r.call(null,n):r},e.prototype.createScales=function(n){var r,i,a=this.attributes,o=a.type,s=a.scale,c=a.range,l=c===void 0?[]:c,u=a.spacing,f=this.containerShape,d=f.width,h=f.height,p=N(_y(n),2),v=p[0],g=p[1],y=new Yt({domain:[(r=l[0])!==null&&r!==void 0?r:v,(i=l[1])!==null&&i!==void 0?i:g],range:[h,h*(1-s)]});return o==="line"?{type:o,x:new Yt({domain:[0,n[0].length-1],range:[0,d]}),y}:{type:o,x:new Ia({domain:n[0].map(function(m,b){return b}),range:[0,d],paddingInner:u,paddingOuter:u/2,align:.5}),y}},e.tag="sparkline",e}(Pe);function s8(t){return typeof t=="boolean"?!1:"enter"in t&&"update"in t&&"exit"in t}function Ey(t){if(!t)return{enter:!1,update:!1,exit:!1};var e=["enter","update","exit"],n=Object.fromEntries(Object.entries(t).filter(function(r){var i=N(r,1),a=i[0];return!e.includes(a)}));return Object.fromEntries(e.map(function(r){return s8(t)?t[r]===!1?[r,!1]:[r,z(z({},t[r]),n)]:[r,n]}))}function ro(t,e){t?t.finished.then(e):e()}function c8(t,e){t.length===0?e():Promise.all(t.map(function(n){return n==null?void 0:n.finished})).then(e)}function cS(t,e){"update"in t?t.update(e):t.attr(e)}function lS(t,e,n){if(e.length===0)return null;if(!n){var r=e.slice(-1)[0];return cS(t,{style:r}),null}return t.animate(e,n)}function l8(t,e){return!(t.nodeName!=="text"||e.nodeName!=="text"||t.attributes.text!==e.attributes.text)}function u8(t,e,n,r){if(r===void 0&&(r="destroy"),l8(t,e))return t.remove(),[null];var i=function(){r==="destroy"?t.destroy():r==="hide"&&li(t),e.isVisible()&&Ks(e)};if(!n)return i(),[null];var a=n.duration,o=a===void 0?0:a,s=n.delay,c=s===void 0?0:s,l=Math.ceil(+o/2),u=+o/4,f=function(P){if(P.nodeName==="circle"){var T=N(P.getLocalPosition(),2),A=T[0],k=T[1],C=P.attr("r");return[A-C,k-C]}return P.getLocalPosition()},d=N(f(t),2),h=d[0],p=d[1],v=N(f(e),2),g=v[0],y=v[1],m=N([(h+g)/2-h,(p+y)/2-p],2),b=m[0],x=m[1],w=t.style.opacity,O=w===void 0?1:w,S=e.style.opacity,_=S===void 0?1:S,M=t.animate([{opacity:O,transform:"translate(0, 0)"},{opacity:0,transform:"translate(".concat(b,", ").concat(x,")")}],z(z({fill:"both"},n),{duration:c+l+u})),E=e.animate([{opacity:0,transform:"translate(".concat(-b,", ").concat(-x,")"),offset:.01},{opacity:_,transform:"translate(0, 0)"}],z(z({fill:"both"},n),{duration:l+u,delay:c+l-u}));return ro(E,i),[M,E]}function Vn(t,e,n){var r={},i={};return Object.entries(e).forEach(function(a){var o=N(a,2),s=o[0],c=o[1];if(!nt(c)){var l=t.style[s]||t.parsedStyle[s]||0;l!==c&&(r[s]=l,i[s]=c)}}),n?lS(t,[r,i],z({fill:"both"},n)):(cS(t,i),null)}function Vu(t,e){return t.style.opacity||(t.style.opacity=1),Vn(t,{opacity:0},e)}var uS={fill:"#fff",lineWidth:1,radius:2,size:10,stroke:"#bfbfbf",strokeOpacity:1,zIndex:0},fS={fill:"#000",fillOpacity:.45,fontSize:12,textAlign:"center",textBaseline:"middle",zIndex:1},dS={orientation:"horizontal",showLabel:!0,type:"start"},Zn=$n({foreground:"foreground",handle:"handle",selection:"selection",sparkline:"sparkline",sparklineGroup:"sparkline-group",track:"track",brushArea:"brush-area"},"slider"),Yr=$n({labelGroup:"label-group",label:"label",iconGroup:"icon-group",icon:"icon",iconRect:"icon-rect",iconLine:"icon-line"},"handle"),f8=function(t){rt(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.render=function(n,r){var i=n.size,a=i===void 0?10:i,o=n.radius,s=o===void 0?a/4:o,c=n.orientation,l=$t(n,["size","radius","orientation"]),u=a,f=u*2.4,d=dt(r).maybeAppendByClassName(Yr.iconRect,"rect").styles(z(z({},l),{width:u,height:f,radius:s,x:-u/2,y:-f/2})),h=1/3*u,p=2/3*u,v=1/4*f,g=3/4*f;d.maybeAppendByClassName("".concat(Yr.iconLine,"-1"),"line").styles(z({x1:h,x2:h,y1:v,y2:g},l)),d.maybeAppendByClassName("".concat(Yr.iconLine,"-2"),"line").styles(z({x1:p,x2:p,y1:v,y2:g},l)),d.node().setOrigin(u/2,f/2),c==="vertical"?r.setLocalEulerAngles(90):r.setLocalEulerAngles(0)},e}(Pe),hS=function(t){rt(e,t);function e(n){return t.call(this,n,dS)||this}return e.prototype.renderLabel=function(n){var r=this,i=this.attributes.showLabel,a=vt(this.attributes,"label"),o=a.transform,s=$t(a,["transform"]),c=N(Rr(s,[]),2),l=c[0],u=c[1],f=dt(n).maybeAppendByClassName(Yr.labelGroup,"g").styles(u),d=z(z({},fS),l),h=d.text,p=$t(d,["text"]);on(!!i,f,function(v){r.label=v.maybeAppendByClassName(Yr.label,"text").styles(z(z({},p),{transform:o,text:"".concat(h)})),r.label.on("mousedown",function(g){g.stopPropagation()}),r.label.on("touchstart",function(g){g.stopPropagation()})})},e.prototype.renderIcon=function(n){var r=this.attributes,i=r.orientation,a=r.type,o=z(z({orientation:i},uS),vt(this.attributes,"icon")),s=this.attributes.iconShape,c=s===void 0?function(){return new f8({style:o})}:s,l=dt(n).maybeAppendByClassName(Yr.iconGroup,"g");l.selectAll(Yr.icon.class).data([c]).join(function(u){return u.append(typeof c=="string"?c:function(){return c(a)}).attr("className",Yr.icon.name)},function(u){return u.update(o)},function(u){return u.remove()})},e.prototype.render=function(n,r){this.renderIcon(r),this.renderLabel(r)},e}(Pe),pS=function(t){rt(e,t);function e(n){var r=t.call(this,n,z(z(z({animate:{duration:100,fill:"both"},brushable:!0,formatter:function(i){return i.toString()},handleSpacing:2,orientation:"horizontal",padding:0,autoFitLabel:!0,scrollable:!0,selectionFill:"#5B8FF9",selectionFillOpacity:.45,selectionZIndex:2,showHandle:!0,showLabel:!0,slidable:!0,trackFill:"#416180",trackLength:200,trackOpacity:.05,trackSize:20,trackZIndex:-1,values:[0,1],type:"range",selectionType:"select",handleIconOffset:0},Jn(dS,"handle")),Jn(uS,"handleIcon")),Jn(fS,"handleLabel")))||this;return r.range=[0,1],r.onDragStart=function(i){return function(a){a.stopPropagation(),r.target=i,r.prevPos=r.getOrientVal($l(a));var o=r.availableSpace,s=o.x,c=o.y,l=r.getBBox(),u=l.x,f=l.y;r.selectionStartPos=r.getRatio(r.prevPos-r.getOrientVal([s,c])-r.getOrientVal([+u,+f])),r.selectionWidth=0,document.addEventListener("pointermove",r.onDragging),document.addEventListener("pointerup",r.onDragEnd)}},r.onDragging=function(i){var a=r.attributes,o=a.slidable,s=a.brushable,c=a.type;i.stopPropagation();var l=r.getOrientVal($l(i)),u=l-r.prevPos;if(u){var f=r.getRatio(u);switch(r.target){case"start":o&&r.setValuesOffset(f);break;case"end":o&&r.setValuesOffset(0,f);break;case"selection":o&&r.setValuesOffset(f,f);break;case"track":if(!s)return;r.selectionWidth+=f,c==="range"?r.innerSetValues([r.selectionStartPos,r.selectionStartPos+r.selectionWidth].sort(),!0):r.innerSetValues([0,r.selectionStartPos+r.selectionWidth],!0);break}r.prevPos=l}},r.onDragEnd=function(){document.removeEventListener("pointermove",r.onDragging),document.removeEventListener("pointermove",r.onDragging),document.removeEventListener("pointerup",r.onDragEnd),r.target="",r.updateHandlesPosition(!1)},r.onValueChange=function(i){var a=r.attributes,o=a.onChange,s=a.type,c=s==="range"?i:i[1],l=s==="range"?r.getValues():r.getValues()[1],u=new Dt("valuechange",{detail:{oldValue:c,value:l}});r.dispatchEvent(u),o==null||o(l)},r.selectionStartPos=0,r.selectionWidth=0,r.prevPos=0,r.target="",r}return Object.defineProperty(e.prototype,"values",{get:function(){return this.attributes.values},set:function(n){this.attributes.values=this.clampValues(n)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"sparklineStyle",{get:function(){var n=this.attributes.orientation;if(n!=="horizontal")return null;var r=vt(this.attributes,"sparkline");return z(z({zIndex:0},this.availableSpace),r)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"shape",{get:function(){var n=this.attributes,r=n.trackLength,i=n.trackSize,a=N(this.getOrientVal([[r,i],[i,r]]),2),o=a[0],s=a[1];return{width:o,height:s}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"availableSpace",{get:function(){var n=this.attributes.padding,r=N(Te(n),4),i=r[0],a=r[1],o=r[2],s=r[3],c=this.shape,l=c.width,u=c.height;return{x:s,y:i,width:l-(s+a),height:u-(i+o)}},enumerable:!1,configurable:!0}),e.prototype.getValues=function(){return this.values},e.prototype.setValues=function(n,r){n===void 0&&(n=[0,0]),r===void 0&&(r=!1),this.attributes.values=n;var i=r===!1?!1:this.attributes.animate;this.updateSelectionArea(i),this.updateHandlesPosition(i)},e.prototype.updateSelectionArea=function(n){var r=this.calcSelectionArea();this.foregroundGroup.selectAll(Zn.selection.class).each(function(i,a){Vn(this,r[a],n)})},e.prototype.updateHandlesPosition=function(n){this.attributes.showHandle&&(this.startHandle&&Vn(this.startHandle,this.getHandleStyle("start"),n),this.endHandle&&Vn(this.endHandle,this.getHandleStyle("end"),n))},e.prototype.innerSetValues=function(n,r){n===void 0&&(n=[0,0]),r===void 0&&(r=!1);var i=this.values,a=this.clampValues(n);this.attributes.values=a,this.setValues(a),r&&this.onValueChange(i)},e.prototype.renderTrack=function(n){var r=vt(this.attributes,"track");this.trackShape=dt(n).maybeAppendByClassName(Zn.track,"rect").styles(z(z({},this.shape),r))},e.prototype.renderBrushArea=function(n){var r=this.attributes.brushable;this.brushArea=dt(n).maybeAppendByClassName(Zn.brushArea,"rect").styles(z({fill:"transparent",cursor:r?"crosshair":"default"},this.shape))},e.prototype.renderSparkline=function(n){var r=this,i=this.attributes.orientation,a=dt(n).maybeAppendByClassName(Zn.sparklineGroup,"g");on(i==="horizontal",a,function(o){var s=r.sparklineStyle;o.maybeAppendByClassName(Zn.sparkline,function(){return new o8({style:s})}).update(s)})},e.prototype.renderHandles=function(){var n=this,r,i=this.attributes,a=i.showHandle,o=i.type,s=o==="range"?["start","end"]:["end"],c=a?s:[],l=this;(r=this.foregroundGroup)===null||r===void 0||r.selectAll(Zn.handle.class).data(c.map(function(u){return{type:u}}),function(u){return u.type}).join(function(u){return u.append(function(f){var d=f.type;return new hS({style:n.getHandleStyle(d)})}).each(function(f){var d=f.type;this.attr("class","".concat(Zn.handle.name," ").concat(d,"-handle"));var h="".concat(d,"Handle");l[h]=this,this.addEventListener("pointerdown",l.onDragStart(d))})},function(u){return u.each(function(f){var d=f.type;this.update(l.getHandleStyle(d))})},function(u){return u.each(function(f){var d=f.type,h="".concat(d,"Handle");l[h]=void 0}).remove()})},e.prototype.renderSelection=function(n){var r=this.attributes,i=r.type,a=r.selectionType;this.foregroundGroup=dt(n).maybeAppendByClassName(Zn.foreground,"g");var o=vt(this.attributes,"selection"),s=function(l){return l.style("visibility",function(u){return u.show?"visible":"hidden"}).style("cursor",function(u){return a==="select"?"grab":a==="invert"?"crosshair":"default"}).styles(o)},c=this;this.foregroundGroup.selectAll(Zn.selection.class).data(i==="value"?[]:this.calcSelectionArea().map(function(l,u){return{style:z({},l),index:u,show:a==="select"?u===1:u!==1}}),function(l){return l.index}).join(function(l){return l.append("rect").attr("className",Zn.selection.name).call(s).each(function(u,f){var d=this;f===1?(c.selectionShape=dt(this),this.on("pointerdown",function(h){d.attr("cursor","grabbing"),c.onDragStart("selection")(h)}),c.dispatchCustomEvent(this,"pointerenter","selectionMouseenter"),c.dispatchCustomEvent(this,"pointerleave","selectionMouseleave"),c.dispatchCustomEvent(this,"click","selectionClick"),this.addEventListener("pointerdown",function(){d.attr("cursor","grabbing")}),this.addEventListener("pointerup",function(){d.attr("cursor","pointer")}),this.addEventListener("pointerover",function(){d.attr("cursor","pointer")})):this.on("pointerdown",c.onDragStart("track"))})},function(l){return l.call(s)},function(l){return l.remove()}),this.updateSelectionArea(!1),this.renderHandles()},e.prototype.render=function(n,r){this.renderTrack(r),this.renderSparkline(r),this.renderBrushArea(r),this.renderSelection(r)},e.prototype.clampValues=function(n,r){var i;r===void 0&&(r=4);var a=N(this.range,2),o=a[0],s=a[1],c=N(this.getValues().map(function(g){return fh(g,r)}),2),l=c[0],u=c[1],f=Array.isArray(n)?n:[l,n??u],d=N((f||[l,u]).map(function(g){return fh(g,r)}),2),h=d[0],p=d[1];if(this.attributes.type==="value")return[0,ce(p,o,s)];h>p&&(i=N([p,h],2),h=i[0],p=i[1]);var v=p-h;return v>s-o?[o,s]:hs?u===s&&l===h?[h,s]:[s-v,s]:[h,p]},e.prototype.calcSelectionArea=function(n){var r=N(this.clampValues(n),2),i=r[0],a=r[1],o=this.availableSpace,s=o.x,c=o.y,l=o.width,u=o.height;return this.getOrientVal([[{y:c,height:u,x:s,width:i*l},{y:c,height:u,x:i*l+s,width:(a-i)*l},{y:c,height:u,x:a*l,width:(1-a)*l}],[{x:s,width:l,y:c,height:i*u},{x:s,width:l,y:i*u+c,height:(a-i)*u},{x:s,width:l,y:a*u,height:(1-a)*u}]])},e.prototype.calcHandlePosition=function(n){var r=this.attributes.handleIconOffset,i=this.availableSpace,a=i.x,o=i.y,s=i.width,c=i.height,l=N(this.clampValues(),2),u=l[0],f=l[1],d=n==="start"?-r:r,h=(n==="start"?u:f)*this.getOrientVal([s,c])+d;return{x:a+this.getOrientVal([h,s/2]),y:o+this.getOrientVal([c/2,h])}},e.prototype.inferTextStyle=function(n){var r=this.attributes.orientation;return r==="horizontal"?{}:n==="start"?{transform:"rotate(90)",textAlign:"start"}:n==="end"?{transform:"rotate(90)",textAlign:"end"}:{}},e.prototype.calcHandleText=function(n){var r,i=this.attributes,a=i.type,o=i.orientation,s=i.formatter,c=i.autoFitLabel,l=vt(this.attributes,"handle"),u=vt(l,"label"),f=l.spacing,d=this.getHandleSize(),h=this.clampValues(),p=n==="start"?h[0]:h[1],v=s(p),g=new f0({style:z(z(z({},u),this.inferTextStyle(n)),{text:v})}),y=g.getBBox(),m=y.width,b=y.height;if(g.destroy(),!c){if(a==="value")return{text:v,x:0,y:-b-f};var x=f+d+(o==="horizontal"?m/2:0);return r={text:v},r[o==="horizontal"?"x":"y"]=n==="start"?-x:x,r}var w=0,O=0,S=this.availableSpace,_=S.width,M=S.height,E=this.calcSelectionArea()[1],P=E.x,T=E.y,A=E.width,k=E.height,C=f+d;if(o==="horizontal"){var L=C+m/2;if(n==="start"){var I=P-C-m;w=I>0?-L:L}else{var R=_-P-A-C>m;w=R?L:-L}}else{var j=C,D=b+C;n==="start"?O=T-d>b?-D:j:O=M-(T+k)-d>b?D:-j}return{x:w,y:O,text:v}},e.prototype.getHandleLabelStyle=function(n){var r=vt(this.attributes,"handleLabel");return z(z(z({},r),this.calcHandleText(n)),this.inferTextStyle(n))},e.prototype.getHandleIconStyle=function(){var n=this.attributes.handleIconShape,r=vt(this.attributes,"handleIcon"),i=this.getOrientVal(["ew-resize","ns-resize"]),a=this.getHandleSize();return z({cursor:i,shape:n,size:a},r)},e.prototype.getHandleStyle=function(n){var r=this.attributes,i=r.showLabel,a=r.showLabelOnInteraction,o=r.orientation,s=this.calcHandlePosition(n),c=this.calcHandleText(n),l=i;return!i&&a&&(this.target?l=!0:l=!1),z(z(z(z({},Jn(this.getHandleIconStyle(),"icon")),Jn(z(z({},this.getHandleLabelStyle(n)),c),"label")),s),{orientation:o,showLabel:l,type:n,zIndex:3})},e.prototype.getHandleSize=function(){var n=this.attributes,r=n.handleIconSize,i=n.width,a=n.height;return r||Math.floor((this.getOrientVal([+a,+i])+4)/2.4)},e.prototype.getOrientVal=function(n){var r=N(n,2),i=r[0],a=r[1],o=this.attributes.orientation;return o==="horizontal"?i:a},e.prototype.setValuesOffset=function(n,r,i){r===void 0&&(r=0),i===void 0&&(i=!1);var a=this.attributes.type,o=N(this.getValues(),2),s=o[0],c=o[1],l=a==="range"?n:0,u=[s+l,c+r].sort();i?this.setValues(u):this.innerSetValues(u,!0)},e.prototype.getRatio=function(n){var r=this.availableSpace,i=r.width,a=r.height;return n/this.getOrientVal([i,a])},e.prototype.dispatchCustomEvent=function(n,r,i){var a=this;n.on(r,function(o){o.stopPropagation(),a.dispatchEvent(new Dt(i,{detail:o}))})},e.prototype.bindEvents=function(){this.addEventListener("wheel",this.onScroll);var n=this.brushArea;this.dispatchCustomEvent(n,"click","trackClick"),this.dispatchCustomEvent(n,"pointerenter","trackMouseenter"),this.dispatchCustomEvent(n,"pointerleave","trackMouseleave"),n.on("pointerdown",this.onDragStart("track"))},e.prototype.onScroll=function(n){var r=this.attributes.scrollable;if(r){var i=n.deltaX,a=n.deltaY,o=a||i,s=this.getRatio(o);this.setValuesOffset(s,s,!0)}},e.tag="slider",e}(Pe),d8=function(t){rt(e,t);function e(n){var r=t.call(this,n,{isRound:!0,orientation:"vertical",padding:[2,2,2,2],scrollable:!0,slidable:!0,thumbCursor:"default",trackSize:10,value:0})||this;return r.range=[0,1],r.onValueChange=function(i){var a=r.attributes.value;if(i!==a){var o={detail:{oldValue:i,value:a}};r.dispatchEvent(new Dt("scroll",o)),r.dispatchEvent(new Dt("valuechange",o))}},r.onTrackClick=function(i){var a=r.attributes.slidable;if(a){var o=N(r.getLocalPosition(),2),s=o[0],c=o[1],l=N(r.padding,4),u=l[0],f=l[3],d=r.getOrientVal([s+f,c+u]),h=r.getOrientVal($l(i)),p=(h-d)/r.trackLength;r.setValue(p,!0)}},r.onThumbMouseenter=function(i){r.dispatchEvent(new Dt("thumbMouseenter",{detail:i.detail}))},r.onTrackMouseenter=function(i){r.dispatchEvent(new Dt("trackMouseenter",{detail:i.detail}))},r.onThumbMouseleave=function(i){r.dispatchEvent(new Dt("thumbMouseleave",{detail:i.detail}))},r.onTrackMouseleave=function(i){r.dispatchEvent(new Dt("trackMouseleave",{detail:i.detail}))},r}return Object.defineProperty(e.prototype,"padding",{get:function(){var n=this.attributes.padding;return Te(n)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"value",{get:function(){var n=this.attributes.value,r=N(this.range,2),i=r[0],a=r[1];return ce(n,i,a)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"trackLength",{get:function(){var n=this.attributes,r=n.viewportLength,i=n.trackLength,a=i===void 0?r:i;return a},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"availableSpace",{get:function(){var n=this.attributes.trackSize,r=this.trackLength,i=N(this.padding,4),a=i[0],o=i[1],s=i[2],c=i[3],l=N(this.getOrientVal([[r,n],[n,r]]),2),u=l[0],f=l[1];return{x:c,y:a,width:+u-(c+o),height:+f-(a+s)}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"trackRadius",{get:function(){var n=this.attributes,r=n.isRound,i=n.trackSize;return r?i/2:0},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"thumbRadius",{get:function(){var n=this.attributes,r=n.isRound,i=n.thumbRadius;if(!r)return 0;var a=this.availableSpace,o=a.width,s=a.height;return i||this.getOrientVal([s,o])/2},enumerable:!1,configurable:!0}),e.prototype.getValues=function(n){n===void 0&&(n=this.value);var r=this.attributes,i=r.viewportLength,a=r.contentLength,o=i/a,s=N(this.range,2),c=s[0],l=s[1],u=n*(l-c-o);return[u,u+o]},e.prototype.getValue=function(){return this.value},e.prototype.renderSlider=function(n){var r=this.attributes,i=r.orientation,a=r.trackSize,o=r.padding,s=r.slidable,c=vt(this.attributes,"track"),l=vt(this.attributes,"thumb"),u=z(z({brushable:!1,orientation:i,padding:o,selectionRadius:this.thumbRadius,showHandle:!1,slidable:s,trackLength:this.trackLength,trackRadius:this.trackRadius,trackSize:a,values:this.getValues()},Jn(c,"track")),Jn(l,"selection"));this.slider=dt(n).maybeAppendByClassName("scrollbar",function(){return new pS({style:u})}).update(u).node()},e.prototype.render=function(n,r){this.renderSlider(r)},e.prototype.setValue=function(n,r){r===void 0&&(r=!1);var i=this.attributes.value,a=N(this.range,2),o=a[0],s=a[1];this.slider.setValues(this.getValues(ce(n,o,s)),r),this.onValueChange(i)},e.prototype.bindEvents=function(){var n=this;this.slider.addEventListener("trackClick",function(r){r.stopPropagation(),n.onTrackClick(r.detail)}),this.onHover()},e.prototype.getOrientVal=function(n){var r=this.attributes.orientation;return r==="horizontal"?n[0]:n[1]},e.prototype.onHover=function(){this.slider.addEventListener("selectionMouseenter",this.onThumbMouseenter),this.slider.addEventListener("trackMouseenter",this.onTrackMouseenter),this.slider.addEventListener("selectionMouseleave",this.onThumbMouseleave),this.slider.addEventListener("trackMouseleave",this.onTrackMouseleave)},e.tag="scrollbar",e}(Pe),g0={data:[],animate:{enter:!1,update:{duration:100,easing:"ease-in-out-sine",fill:"both"},exit:{duration:100,fill:"both"}},showArrow:!0,showGrid:!0,showLabel:!0,showLine:!0,showTick:!0,showTitle:!0,showTrunc:!1,dataThreshold:100,lineLineWidth:1,lineStroke:"black",crossPadding:10,titleFill:"black",titleFontSize:12,titlePosition:"lb",titleSpacing:0,titleTextAlign:"center",titleTextBaseline:"middle",lineArrow:function(){return new Xe({style:{path:[["M",10,10],["L",-10,0],["L",10,-10],["L",0,0],["L",10,10],["Z"]],anchor:"0.5 0.5",fill:"black",transformOrigin:"center"}})},labelAlign:"parallel",labelDirection:"positive",labelFontSize:12,labelSpacing:0,gridConnect:"line",gridControlAngles:[],gridDirection:"positive",gridLength:0,gridType:"segment",lineArrowOffset:15,lineArrowSize:10,tickDirection:"positive",tickLength:5,tickLineWidth:1,tickStroke:"black",labelOverlap:[]};X({},g0,{style:{type:"arc"}});X({},g0,{style:{}});var Rt=$n({mainGroup:"main-group",gridGroup:"grid-group",grid:"grid",lineGroup:"line-group",line:"line",tickGroup:"tick-group",tick:"tick",tickItem:"tick-item",labelGroup:"label-group",label:"label",labelItem:"label-item",titleGroup:"title-group",title:"title",lineFirst:"line-first",lineSecond:"line-second"},"axis"),Ga=$n({lineGroup:"line-group",line:"line",regionGroup:"region-group",region:"region"},"grid");function vS(t){return t.reduce(function(e,n,r){return e.push(q([r===0?"M":"L"],N(n),!1)),e},[])}function h8(t,e,n){var r=e.connect,i=r===void 0?"line":r,a=e.center;if(i==="line")return vS(t);if(!a)return[];var o=gs(t[0],a),s=n?0:1;return t.reduce(function(c,l,u){return u===0?c.push(q(["M"],N(l),!1)):c.push(q(["A",o,o,0,0,s],N(l),!1)),c},[])}function dh(t,e,n){return e.type==="surround"?h8(t,e,n):vS(t)}function p8(t,e,n){var r=n.type,i=n.connect,a=n.center,o=n.closed,s=o?[["Z"]]:[],c=N([dh(t,n),dh(e.slice().reverse(),n,!0)],2),l=c[0],u=c[1],f=N([t[0],e.slice(-1)[0]],2),d=f[0],h=f[1],p=function(m,b){return[l,m,u,b,s].flat()};if(i==="line"||r==="surround")return p([q(["L"],N(h),!1)],[q(["L"],N(d),!1)]);if(!a)throw new Error("Arc grid need to specified center");var v=N([gs(h,a),gs(d,a)],2),g=v[0],y=v[1];return p([q(["A",g,g,0,0,1],N(h),!1),q(["L"],N(h),!1)],[q(["A",y,y,0,0,0],N(d),!1),q(["L"],N(d),!1)])}function v8(t,e,n,r){var i=n.animate,a=n.isBillboard,o=e.map(function(s,c){return{id:s.id||"grid-line-".concat(c),path:dh(s.points,n)}});return t.selectAll(Ga.line.class).data(o,function(s){return s.id}).join(function(s){return s.append("path").each(function(c,l){var u=Rn(wy(z({path:c.path},r)),[c,l,o]);this.attr(z({class:Ga.line.name,stroke:"#D9D9D9",lineWidth:1,lineDash:[4,4],isBillboard:a},u))})},function(s){return s.transition(function(c,l){var u=Rn(wy(z({path:c.path},r)),[c,l,o]);return Vn(this,u,i.update)})},function(s){return s.transition(function(){var c=this,l=Vu(this,i.exit);return ro(l,function(){return c.remove()}),l})}).transitions()}function g8(t,e,n){var r=n.animate,i=n.connect,a=n.areaFill;if(e.length<2||!a||!i)return[];for(var o=Array.isArray(a)?a:[a,"transparent"],s=function(p){return o[p%o.length]},c=[],l=0;l180?1:0,_=t>e?0:1;return"M".concat(p,",").concat(v,",A").concat(s,",").concat(c,",0,").concat(S,",").concat(_,",").concat(y,",").concat(m)}function w8(t){var e=t.attributes,n=e.startAngle,r=e.endAngle,i=e.center,a=e.radius;return q(q([n,r],N(i),!1),[a],!1)}function O8(t,e,n,r){var i=e.startAngle,a=e.endAngle,o=e.center,s=e.radius;return t.selectAll(Rt.line.class).data([{path:Py.apply(void 0,q(q([i,a],N(o),!1),[s],!1))}],function(c,l){return l}).join(function(c){return c.append("path").attr("className",Rt.line.name).styles(e).styles({path:function(l){return l.path}})},function(c){return c.transition(function(){var l=this,u=dI(this,w8(this),q(q([i,a],N(o),!1),[s],!1),r.update);if(u){var f=function(){var d=je(l.attributes,"__keyframe_data__");l.style.path=Py.apply(void 0,q([],N(d),!1))};u.onframe=f,u.onfinish=f}return u}).styles(e)},function(c){return c.remove()}).styles(n).transitions()}function S8(t,e){e.truncRange,e.truncShape,e.lineExtension}function _8(t,e,n){n===void 0&&(n=[0,0]);var r=N([t,e,n],3),i=N(r[0],2),a=i[0],o=i[1],s=N(r[1],2),c=s[0],l=s[1],u=N(r[2],2),f=u[0],d=u[1],h=N([c-a,l-o],2),p=h[0],v=h[1],g=Math.sqrt(Math.pow(p,2)+Math.pow(v,2)),y=N([-f/g,d/g],2),m=y[0],b=y[1];return[m*p,m*v,b*p,b*v]}function Ay(t){var e=N(t,2),n=N(e[0],2),r=n[0],i=n[1],a=N(e[1],2),o=a[0],s=a[1];return{x1:r,y1:i,x2:o,y2:s}}function M8(t,e,n,r){var i=e.showTrunc,a=e.startPos,o=e.endPos,s=e.truncRange,c=e.lineExtension,l=N([a,o],2),u=N(l[0],2),f=u[0],d=u[1],h=N(l[1],2),p=h[0],v=h[1],g=N(c?_8(a,o,c):new Array(4).fill(0),4),y=g[0],m=g[1],b=g[2],x=g[3],w=function(R){return t.selectAll(Rt.line.class).data(R,function(j,D){return D}).join(function(j){return j.append("line").attr("className",function(D){return"".concat(Rt.line.name," ").concat(D.className)}).styles(n).transition(function(D){return Vn(this,Ay(D.line),!1)})},function(j){return j.styles(n).transition(function(D){var $=D.line;return Vn(this,Ay($),r.update)})},function(j){return j.remove()}).transitions()};if(!i||!s)return w([{line:[[f+y,d+m],[p+b,v+x]],className:Rt.line.name}]);var O=N(s,2),S=O[0],_=O[1],M=p-f,E=v-d,P=N([f+M*S,d+E*S],2),T=P[0],A=P[1],k=N([f+M*_,d+E*_],2),C=k[0],L=k[1],I=w([{line:[[f+y,d+m],[T,A]],className:Rt.lineFirst.name},{line:[[C,L],[p+b,v+x]],className:Rt.lineSecond.name}]);return S8(t,e),I}function E8(t,e,n,r){var i=n.showArrow,a=n.showTrunc,o=n.lineArrow,s=n.lineArrowOffset,c=n.lineArrowSize,l;if(e==="arc"?l=t.select(Rt.line.class):a?l=t.select(Rt.lineSecond.class):l=t.select(Rt.line.class),!i||!o||n.type==="arc"&&xS(n.startAngle,n.endAngle)){var u=l.node();u&&(u.style.markerEnd=void 0);return}var f=Yi(o);f.attr(r),h0(f,c,!0),l.style("markerEnd",f).style("markerEndOffset",-s)}function P8(t,e,n){var r=e.type,i,a=vt(e,"line");return r==="linear"?i=M8(t,e,xy(a,"arrow"),n):i=O8(t,e,xy(a,"arrow"),n),E8(t,r,e,a),i}function A8(t,e){return m0(t,e.gridDirection,e)}function wS(t){var e=t.type,n=t.gridCenter;return e==="linear"?n:n||t.center}function k8(t,e){var n=e.gridLength;return t.map(function(r,i){var a=r.value,o=N(Uu(a,e),2),s=o[0],c=o[1],l=N(Or(A8(a,e),n),2),u=l[0],f=l[1];return{id:i,points:[[s,c],[s+u,c+f]]}})}function T8(t,e){var n=e.gridControlAngles,r=wS(e);if(!r)throw new Error("grid center is not provide");if(t.length<2)throw new Error("Invalid grid data");if(!n||n.length===0)throw new Error("Invalid gridControlAngles");var i=N(r,2),a=i[0],o=i[1];return t.map(function(s,c){var l=s.value,u=N(Uu(l,e),2),f=u[0],d=u[1],h=N([f-a,d-o],2),p=h[0],v=h[1],g=[];return n.forEach(function(y){var m=za(y),b=N([Math.cos(m),Math.sin(m)],2),x=b[0],w=b[1],O=p*x-v*w+a,S=p*w+v*x+o;g.push([O,S])}),{points:g,id:c}})}function C8(t,e,n,r){var i=vt(n,"grid"),a=i.type,o=i.areaFill,s=wS(n),c=y0(e,n.gridFilter),l=a==="segment"?k8(c,n):T8(c,n),u=z(z({},i),{center:s,areaFill:Ve(o)?c.map(function(f,d){return Rn(o,[f,d,c])}):o,animate:r,data:l});return t.selectAll(Rt.grid.class).data([1]).join(function(f){return f.append(function(){return new m8({style:u})}).attr("className",Rt.grid.name)},function(f){return f.transition(function(){return this.update(u)})},function(f){return f.remove()}).transitions()}var hh=function(){function t(e,n,r,i){this.set(e,n,r,i)}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x1},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y1},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x2},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y2},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"width",{get:function(){return this.defined("x2")&&this.defined("x1")?this.x2-this.x1:void 0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"height",{get:function(){return this.defined("y2")&&this.defined("y1")?this.y2-this.y1:void 0},enumerable:!1,configurable:!0}),t.prototype.rotatedPoints=function(e,n,r){var i=this,a=i.x1,o=i.y1,s=i.x2,c=i.y2,l=Math.cos(e),u=Math.sin(e),f=n-n*l+r*u,d=r-n*u-r*l,h=[[l*a-u*c+f,u*a+l*c+d],[l*s-u*c+f,u*s+l*c+d],[l*a-u*o+f,u*a+l*o+d],[l*s-u*o+f,u*s+l*o+d]];return h},t.prototype.set=function(e,n,r,i){return r0,m=r-c,b=i-l,x=d*b-h*m;if(x<0===y)return!1;var w=p*b-v*m;return!(w<0===y||x>g===y||w>g===y)}function D8(t,e){var n=[[t[0],t[1],t[2],t[3]],[t[2],t[3],t[4],t[5]],[t[4],t[5],t[6],t[7]],[t[6],t[7],t[0],t[1]]];return n.some(function(r){return j8(e,r)})}function $8(t,e,n){var r,i,a=ph(t,n).flat(1),o=ph(e,n).flat(1),s=[[a[0],a[1],a[2],a[3]],[a[0],a[1],a[4],a[5]],[a[4],a[5],a[6],a[7]],[a[2],a[3],a[6],a[7]]];try{for(var c=vn(s),l=c.next();!l.done;l=c.next()){var u=l.value;if(D8(o,u))return!0}}catch(f){r={error:f}}finally{try{l&&!l.done&&(i=c.return)&&i.call(c)}finally{if(r)throw r.error}}return!1}function B8(t,e){var n=t.type,r=t.labelDirection,i=t.crossSize;if(!i)return!1;if(n==="arc"){var a=t.center,o=t.radius,s=N(a,2),c=s[0],l=s[1],u=r==="negative"?0:i,f=-o-u,d=o+u,h=N(Te(e),4),p=h[0],v=h[1],g=h[2],y=h[3];return new hh(c+f-y,l+f-p,c+d+v,l+d+g)}var m=N(t.startPos,2),b=m[0],x=m[1],w=N(t.endPos,2),O=w[0],S=w[1],_=N(bS(t)?[-e,0,e,0]:[0,e,0,-e],4),M=_[0],E=_[1],P=_[2],T=_[3],A=Zs(0,t),k=Or(A,i),C=new hh(b,x,O,S);return C.x1+=T,C.y1+=M,C.x2+=E+k[0],C.y2+=P+k[1],C}function qu(t,e,n){var r,i,a=e.crossPadding,o=new Set,s=null,c=B8(e,a),l=function(p){return c?I8(c,p):!0},u=function(p,v){return p?!$8(p,v,Te(n)):!0};try{for(var f=vn(t),d=f.next();!d.done;d=f.next()){var h=d.value;l(h)?!s||u(s,h)?s=h:(o.add(s),o.add(h)):o.add(h)}}catch(p){r={error:p}}finally{try{d&&!d.done&&(i=f.return)&&i.call(f)}finally{if(r)throw r.error}}return Array.from(o)}function qf(t,e){return e===void 0&&(e={}),nt(t)?0:typeof t=="number"?t:Math.floor(oI(t,e))}function F8(t,e,n,r){if(!(t.length<=1)){var i=e.suffix,a=i===void 0?"...":i,o=e.minLength,s=e.maxLength,c=s===void 0?1/0:s,l=e.step,u=l===void 0?" ":l,f=e.margin,d=f===void 0?[0,0,0,0]:f,h=eS(r.getTextShape(t[0])),p=qf(u,h),v=o?qf(o,h):p,g=qf(c,h);(nt(g)||g===1/0)&&(g=Math.max.apply(null,t.map(function(O){return b0(O).width})));var y=t.slice(),m=N(d,4);m[0],m[1],m[2],m[3];for(var b=function(O){if(y.forEach(function(S){r.ellipsis(r.getTextShape(S),O,a)}),y=qu(t,n,d),y.length<1)return{value:void 0}},x=g;x>v+p;x-=p){var w=b(x);if(typeof w=="object")return w.value}}}var z8={parity:function(t,e){var n=e.seq,r=n===void 0?2:n;return t.filter(function(i,a){return a%r?(li(i),!1):!0})}},G8=function(t){return t.filter(tS)};function Y8(t,e,n,r){var i=t.length,a=e.keepHeader,o=e.keepTail;if(!(i<=1||i===2&&a&&o)){var s=z8.parity,c=function(b){return b.forEach(r.show),b},l=2,u=t.slice(),f=t.slice(),d=Math.min.apply(Math,q([1],N(t.map(function(b){return b0(b).width})),!1));if(n.type==="linear"&&(mS(n)||bS(n))){var h=Oy(t[0]).left,p=Oy(t[i-1]).right,v=Math.abs(p-h)||1;l=Math.max(Math.floor(i*d/v),l)}var g,y;for(a&&(g=u.splice(0,1)[0]),o&&(y=u.splice(-1,1)[0],u.reverse()),c(u);ls)){for(var y=h;y<=s;y++)if(g(y),p())return;l&&g(d)}}var X8=new Map([["hide",Y8],["rotate",W8],["ellipsis",F8],["wrap",V8]]);function U8(t,e,n){return e.labelOverlap.length<1?!1:n==="hide"?!iI(t[0]):n==="rotate"?!t.some(function(r){var i;return!!(!((i=r.attr("transform"))===null||i===void 0)&&i.includes("rotate"))}):n==="ellipsis"||n==="wrap"?t.filter(function(r){return r.querySelector("text")}).length>1:!0}function q8(t,e,n){var r=e.labelOverlap,i=r===void 0?[]:r;i.length&&i.forEach(function(a){var o=a.type,s=X8.get(o);U8(t,e,o)&&(s==null||s(t,a,e,n))})}function K8(){for(var t=[],e=0;e2?[t[0]]:t.split("")}function sj(t,e){var n=t.attributes,r=n.position,i=n.spacing,a=n.inset,o=n.text,s=t.getBBox(),c=e.getBBox(),l=Ku(r),u=N(Te(o?i:0),4),f=u[0],d=u[1],h=u[2],p=u[3],v=N(Te(a),4),g=v[0],y=v[1],m=v[2],b=v[3],x=N([p+d,f+h],2),w=x[0],O=x[1],S=N([b+y,g+m],2),_=S[0],M=S[1];if(l[0]==="l")return new Qt(s.x,s.y,c.width+s.width+w+_,Math.max(c.height+M,s.height));if(l[0]==="t")return new Qt(s.x,s.y,Math.max(c.width+_,s.width),c.height+s.height+O+M);var E=N([e.attributes.width||c.width,e.attributes.height||c.height],2),P=E[0],T=E[1];return new Qt(c.x,c.y,P+s.width+w+_,T+s.height+O+M)}function cj(t,e){var n=Object.entries(e).reduce(function(r,i){var a=N(i,2),o=a[0],s=a[1],c=t.node().attr(o);return c||(r[o]=s),r},{});t.styles(n)}function lj(t){var e,n,r,i,a=t,o=a.width,s=a.height,c=a.position,l=N([+o/2,+s/2],2),u=l[0],f=l[1],d=N([+u,+f,"center","middle"],4),h=d[0],p=d[1],v=d[2],g=d[3],y=Ku(c);return y.includes("l")&&(e=N([0,"start"],2),h=e[0],v=e[1]),y.includes("r")&&(n=N([+o,"end"],2),h=n[0],v=n[1]),y.includes("t")&&(r=N([0,"top"],2),p=r[0],g=r[1]),y.includes("b")&&(i=N([+s,"bottom"],2),p=i[0],g=i[1]),{x:h,y:p,textAlign:v,textBaseline:g}}var MS=function(t){rt(e,t);function e(n){return t.call(this,n,{text:"",width:0,height:0,fill:"#4a505a",fontWeight:"bold",fontSize:12,fontFamily:"sans-serif",inset:0,spacing:0,position:"top-left"})||this}return e.prototype.getAvailableSpace=function(){var n=this,r=this.attributes,i=r.width,a=r.height,o=r.position,s=r.spacing,c=r.inset,l=n.querySelector(Ry.text.class);if(!l)return new Qt(0,0,+i,+a);var u=l.getBBox(),f=u.width,d=u.height,h=N(Te(s),4),p=h[0],v=h[1],g=h[2],y=h[3],m=N([0,0,+i,+a],4),b=m[0],x=m[1],w=m[2],O=m[3],S=Ku(o);if(S.includes("i"))return new Qt(b,x,w,O);S.forEach(function(L,I){var R,j,D,$;L==="t"&&(R=N(I===0?[d+g,+a-d-g]:[0,+a],2),x=R[0],O=R[1]),L==="r"&&(j=N([+i-f-y],1),w=j[0]),L==="b"&&(D=N([+a-d-p],1),O=D[0]),L==="l"&&($=N(I===0?[f+v,+i-f-v]:[0,+i],2),b=$[0],w=$[1])});var _=N(Te(c),4),M=_[0],E=_[1],P=_[2],T=_[3],A=N([T+E,M+P],2),k=A[0],C=A[1];return new Qt(b+T,x+M,w-k,O-C)},e.prototype.getBBox=function(){return this.title?this.title.getBBox():new Qt(0,0,0,0)},e.prototype.render=function(n,r){var i=this;n.width,n.height,n.position,n.spacing;var a=$t(n,["width","height","position","spacing"]),o=N(Rr(a),1),s=o[0],c=lj(n),l=c.x,u=c.y,f=c.textAlign,d=c.textBaseline;on(!!a.text,dt(r),function(h){i.title=h.maybeAppendByClassName(Ry.text,"text").styles(s).call(cj,{x:l,y:u,textAlign:f,textBaseline:d}).node()})},e}(Pe);function uj(t,e,n){var r=n.titlePosition,i=r===void 0?"lb":r,a=n.titleSpacing,o=Ku(i),s=t.node().getLocalBounds(),c=N(s.min,2),l=c[0],u=c[1],f=N(s.halfExtents,2),d=f[0],h=f[1],p=N(e.node().getLocalBounds().halfExtents,2),v=p[0],g=p[1],y=N([l+d,u+h],2),m=y[0],b=y[1],x=N(Te(a),4),w=x[0],O=x[1],S=x[2],_=x[3];if(["start","end"].includes(i)&&n.type==="linear"){var M=n.startPos,E=n.endPos,P=N(i==="start"?[M,E]:[E,M],2),T=P[0],A=P[1],k=iS([-A[0]+T[0],-A[1]+T[1]]),C=N(Or(k,w),2),L=C[0],I=C[1];return{x:T[0]+L,y:T[1]+I}}return o.includes("t")&&(b-=h+g+w),o.includes("r")&&(m+=d+v+O),o.includes("l")&&(m-=d+v*2+_),o.includes("b")&&(b+=h+g*2+S),{x:m,y:b}}function fj(t,e,n){var r=t.cloneNode(!0);r.style.transform="scale(1, 1)",r.style.transform="none";var i=r.getBBox().height;if(e==="vertical"){if(n==="left")return"rotate(-90) translate(0, ".concat(i/2,")");if(n==="right")return"rotate(-90) translate(0, -".concat(i/2,")")}return""}function Iy(t,e,n,r,i){var a=vt(r,"title"),o=N(Rr(a),2),s=o[0],c=o[1],l=c.transform,u=$t(c,["transform"]);t.styles(s),e.styles(u);var f=l||fj(t.node(),s.direction,s.position);Bl(t.node(),f);var d=uj(dt(n._offscreen||n.querySelector(Rt.mainGroup.class)),e,r),h=d.x,p=d.y,v=Vn(e.node(),{x:h,y:p},i);return Bl(t.node(),f),v}function dj(t,e,n,r){var i=n.titleText;return t.selectAll(Rt.title.class).data([{title:i}].filter(function(a){return!!a.title}),function(a,o){return a.title}).join(function(a){return a.append(function(){return Yi(i)}).attr("className",Rt.title.name).transition(function(){return Iy(dt(this),t,e,n,r.enter)})},function(a){return a.transition(function(){return Iy(dt(this),t,e,n,r.update)})},function(a){return a.remove()}).transitions()}function jy(t,e,n,r){var i=t.showLine,a=t.showTick,o=t.showLabel,s=e.maybeAppendByClassName(Rt.lineGroup,"g"),c=on(i,s,function(h){return P8(h,t,r)})||[],l=e.maybeAppendByClassName(Rt.tickGroup,"g"),u=on(a,l,function(h){return oj(h,n,t,r)})||[],f=e.maybeAppendByClassName(Rt.labelGroup,"g"),d=on(o,f,function(h){return ej(h,n,t,r)})||[];return q(q(q([],N(c),!1),N(u),!1),N(d),!1).filter(function(h){return!!h})}var x0=function(t){rt(e,t);function e(n){return t.call(this,n,g0)||this}return e.prototype.render=function(n,r,i){var a=this,o=n.titleText,s=n.data,c=n.animate,l=n.showTitle,u=n.showGrid,f=n.dataThreshold,d=n.truncRange,h=wI(s,f).filter(function(w){var O=w.value;return!(d&&O>d[0]&&O1?{width:55,height:0}:{width:0,height:0}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"pageShape",{get:function(){var n=this.pageViews,r=N(LI(n.map(function(f){var d=f.getBBox(),h=d.width,p=d.height;return[h,p]})).map(function(f){return Math.max.apply(Math,q([],N(f),!1))}),2),i=r[0],a=r[1],o=this.attributes,s=o.pageWidth,c=s===void 0?i:s,l=o.pageHeight,u=l===void 0?a:l;return{pageWidth:c,pageHeight:u}},enumerable:!1,configurable:!0}),e.prototype.getContainer=function(){return this.playWindow},Object.defineProperty(e.prototype,"totalPages",{get:function(){return this.pageViews.length},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"currPage",{get:function(){return this.innerCurrPage},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var n=t.prototype.getBBox.call(this),r=n.x,i=n.y,a=this.controllerShape,o=this.pageShape,s=o.pageWidth,c=o.pageHeight;return new Qt(r,i,s+a.width,c)},e.prototype.goTo=function(n){var r=this,i=this.attributes.animate,a=this,o=a.currPage,s=a.playState,c=a.playWindow,l=a.pageViews;if(s!=="idle"||n<0||l.length<=0||n>=l.length)return null;l[o].setLocalPosition(0,0),this.prepareFollowingPage(n);var u=N(this.getFollowingPageDiff(n),2),f=u[0],d=u[1];this.playState="running";var h=lS(c,[{transform:"translate(0, 0)"},{transform:"translate(".concat(-f,", ").concat(-d,")")}],i);return ro(h,function(){r.innerCurrPage=n,r.playState="idle",r.setVisiblePages([n]),r.updatePageInfo()}),h},e.prototype.prev=function(){var n=this.attributes.loop,r=this.pageViews.length,i=this.currPage;if(!n&&i<=0)return null;var a=n?(i-1+r)%r:ce(i-1,0,r);return this.goTo(a)},e.prototype.next=function(){var n=this.attributes.loop,r=this.pageViews.length,i=this.currPage;if(!n&&i>=r-1)return null;var a=n?(i+1)%r:ce(i+1,0,r);return this.goTo(a)},e.prototype.renderClipPath=function(n){var r=this.pageShape,i=r.pageWidth,a=r.pageHeight;if(!i||!a){this.contentGroup.style.clipPath=void 0;return}this.clipPath=n.maybeAppendByClassName(En.clipPath,"rect").styles({width:i,height:a}),this.contentGroup.attr("clipPath",this.clipPath.node())},e.prototype.setVisiblePages=function(n){this.playWindow.children.forEach(function(r,i){n.includes(i)?Ks(r):li(r)})},e.prototype.adjustControllerLayout=function(){var n=this,r=n.prevBtnGroup,i=n.nextBtnGroup,a=n.pageInfoGroup,o=this.attributes,s=o.orientation,c=o.controllerPadding,l=a.getBBox(),u=l.width;l.height;var f=N(s==="horizontal"?[-180,0]:[-90,90],2),d=f[0],h=f[1];r.setLocalEulerAngles(d),i.setLocalEulerAngles(h);var p=r.getBBox(),v=p.width,g=p.height,y=i.getBBox(),m=y.width,b=y.height,x=Math.max(v,u,m),w=s==="horizontal"?{offset:[[0,0],[v/2+c,0],[v+u+c*2,0]],textAlign:"start"}:{offset:[[x/2,-g-c],[x/2,0],[x/2,b+c]],textAlign:"center"},O=N(w.offset,3),S=N(O[0],2),_=S[0],M=S[1],E=N(O[1],2),P=E[0],T=E[1],A=N(O[2],2),k=A[0],C=A[1],L=w.textAlign,I=a.querySelector("text");I&&(I.style.textAlign=L),r.setLocalPosition(_,M),a.setLocalPosition(P,T),i.setLocalPosition(k,C)},e.prototype.updatePageInfo=function(){var n,r=this,i=r.currPage,a=r.pageViews,o=r.attributes.formatter;a.length<2||((n=this.pageInfoGroup.querySelector(En.pageInfo.class))===null||n===void 0||n.attr("text",o(i+1,a.length)),this.adjustControllerLayout())},e.prototype.getFollowingPageDiff=function(n){var r=this.currPage;if(r===n)return[0,0];var i=this.attributes.orientation,a=this.pageShape,o=a.pageWidth,s=a.pageHeight,c=n=2,l=n.maybeAppendByClassName(En.controller,"g");if(Hu(l.node(),c),!!c){var u=vt(this.attributes,"button"),f=vt(this.attributes,"pageNum"),d=N(Rr(u),2),h=d[0],p=d[1],v=h.size,g=$t(h,["size"]),y=!l.select(En.prevBtnGroup.class).node(),m=l.maybeAppendByClassName(En.prevBtnGroup,"g").styles(p);this.prevBtnGroup=m.node();var b=m.maybeAppendByClassName(En.prevBtn,"path"),x=l.maybeAppendByClassName(En.nextBtnGroup,"g").styles(p);this.nextBtnGroup=x.node();var w=x.maybeAppendByClassName(En.nextBtn,"path");[b,w].forEach(function(S){S.styles(z(z({},g),{transformOrigin:"center"})),h0(S.node(),v,!0)});var O=l.maybeAppendByClassName(En.pageInfoGroup,"g");this.pageInfoGroup=O.node(),O.maybeAppendByClassName(En.pageInfo,"text").styles(f),this.updatePageInfo(),l.node().setLocalPosition(o+i,s/2),y&&(this.prevBtnGroup.addEventListener("click",function(){r.prev()}),this.nextBtnGroup.addEventListener("click",function(){r.next()}))}},e.prototype.render=function(n,r){var i=dt(r);this.renderClipPath(i),this.renderController(i),this.setVisiblePages([this.defaultPage]),this.goTo(this.defaultPage)},e.prototype.bindEvents=function(){var n=this,r=$b(function(){return n.render(n.attributes,n)},50);this.playWindow.addEventListener(ht.INSERTED,r),this.playWindow.addEventListener(ht.REMOVED,r)},e}(Pe);function pj(t,e,n){var r=Math.round((t-n)/e);return n+r*e}function vj(t,e,n){var r=1.4,i=r*n;return[["M",t-n,e-i],["L",t+n,e-i],["L",t+n,e+i],["L",t-n,e+i],["Z"]]}var ES=1.4,PS=.4;function gj(t,e,n){var r=n,i=r*ES,a=r/2,o=r/6,s=t+i*PS;return[["M",t,e],["L",s,e+a],["L",t+i,e+a],["L",t+i,e-a],["L",s,e-a],["Z"],["M",s,e+o],["L",t+i-2,e+o],["M",s,e-o],["L",t+i-2,e-o]]}function yj(t,e,n){var r=n,i=r*ES,a=r/2,o=r/6,s=e+i*PS;return[["M",t,e],["L",t-a,s],["L",t-a,e+i],["L",t+a,e+i],["L",t+a,s],["Z"],["M",t-o,s],["L",t-o,e+i-2],["M",t+o,s],["L",t+o,e+i-2]]}Bt.registerSymbol("hiddenHandle",vj);Bt.registerSymbol("verticalHandle",gj);Bt.registerSymbol("horizontalHandle",yj);function mj(t,e,n,r){var i,a=N(t,2),o=a[0],s=a[1],c=N(e,2),l=c[0],u=c[1],f=N(n,2),d=f[0],h=f[1],p=N([l,u],2),v=p[0],g=p[1],y=g-v;return v>g&&(i=N([g,v],2),v=i[0],g=i[1]),y>s-o?[o,s]:vs?h===s&&d===v?[v,s]:[s-y,s]:[v,g]}function ir(t,e,n){return t===void 0&&(t="horizontal"),t==="horizontal"?e:n}var un=$n({layout:"flex",markerGroup:"marker-group",marker:"marker",labelGroup:"label-group",label:"label",valueGroup:"value-group",value:"value",backgroundGroup:"background-group",background:"background"},"legend-category-item");function bj(t){var e=t.querySelector(un.marker.class);return e?e.style:{}}var xj=function(t){rt(e,t);function e(n){return t.call(this,n,{span:[1,1],marker:function(){return new Xs({style:{r:6}})},markerSize:10,labelFill:"#646464",valueFill:"#646464",labelFontSize:12,valueFontSize:12,labelTextBaseline:"middle",valueTextBaseline:"middle"})||this}return Object.defineProperty(e.prototype,"showValue",{get:function(){var n=this.attributes.valueText;return n?typeof n=="string"||typeof n=="number"?n!=="":typeof n=="function"?!0:n.attr("text")!=="":!1},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"actualSpace",{get:function(){var n=this.labelGroup,r=this.valueGroup,i=this.attributes.markerSize,a=n.node().getBBox(),o=a.width,s=a.height,c=r.node().getBBox(),l=c.width,u=c.height;return{markerWidth:i,labelWidth:o,valueWidth:l,height:Math.max(i,s,u)}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"span",{get:function(){var n=this.attributes.span;if(!n)return[1,1];var r=N(Te(n),2),i=r[0],a=r[1],o=this.showValue?a:0,s=i+o;return[i/s,o/s]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"shape",{get:function(){var n,r=this.attributes,i=r.markerSize,a=r.width,o=this.actualSpace,s=o.markerWidth,c=o.height,l=this.actualSpace,u=l.labelWidth,f=l.valueWidth,d=N(this.spacing,2),h=d[0],p=d[1];if(a){var v=a-i-h-p,g=N(this.span,2),y=g[0],m=g[1];n=N([y*v,m*v],2),u=n[0],f=n[1]}var b=s+u+f+h+p;return{width:b,height:c,markerWidth:s,labelWidth:u,valueWidth:f}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"spacing",{get:function(){var n=this.attributes.spacing;if(!n)return[0,0];var r=N(Te(n),2),i=r[0],a=r[1];return this.showValue?[i,a]:[i,0]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"layout",{get:function(){var n=this.shape,r=n.markerWidth,i=n.labelWidth,a=n.valueWidth,o=n.width,s=n.height,c=N(this.spacing,2),l=c[0],u=c[1];return{height:s,width:o,markerWidth:r,labelWidth:i,valueWidth:a,position:[r/2,r+l,r+i+l+u]}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"scaleSize",{get:function(){var n=bj(this.markerGroup.node()),r=this.attributes,i=r.markerSize,a=r.markerStrokeWidth,o=a===void 0?n.strokeWidth:a,s=r.markerLineWidth,c=s===void 0?n.lineWidth:s,l=r.markerStroke,u=l===void 0?n.stroke:l,f=+(o||c||(u?1:0))*Math.sqrt(2),d=this.markerGroup.node().getBBox(),h=d.width,p=d.height;return(1-f/Math.max(h,p))*i},enumerable:!1,configurable:!0}),e.prototype.renderMarker=function(n){var r=this,i=this.attributes.marker,a=vt(this.attributes,"marker");this.markerGroup=n.maybeAppendByClassName(un.markerGroup,"g").style("zIndex",0),on(!!i,this.markerGroup,function(){var o=r.markerGroup.node(),s=o.getElementsByClassName(un.marker.name)[0],c=i();s?c.nodeName===s.nodeName?(PI(s,c),dt(s).styles(a)):(s.remove(),dt(c).attr("className",un.marker.name).styles(a),o.appendChild(c)):(dt(c).attr("className",un.marker.name).styles(a),o.appendChild(c)),r.markerGroup.node().scale(1/r.markerGroup.node().getScale()[0]),h0(r.markerGroup.node(),r.scaleSize,!0)})},e.prototype.renderLabel=function(n){var r=vt(this.attributes,"label"),i=r.text,a=$t(r,["text"]);this.labelGroup=n.maybeAppendByClassName(un.labelGroup,"g").style("zIndex",0),this.labelGroup.maybeAppendByClassName(un.label,function(){return Yi(i)}).styles(a)},e.prototype.renderValue=function(n){var r=this,i=vt(this.attributes,"value"),a=i.text,o=$t(i,["text"]);this.valueGroup=n.maybeAppendByClassName(un.valueGroup,"g").style("zIndex",0),on(this.showValue,this.valueGroup,function(){r.valueGroup.maybeAppendByClassName(un.value,function(){return Yi(a)}).styles(o)})},e.prototype.renderBackground=function(n){var r=this.shape,i=r.width,a=r.height,o=vt(this.attributes,"background");this.background=n.maybeAppendByClassName(un.backgroundGroup,"g").style("zIndex",-1),this.background.maybeAppendByClassName(un.background,"rect").styles(z({width:i,height:a},o))},e.prototype.adjustLayout=function(){var n=this.layout,r=n.labelWidth,i=n.valueWidth,a=n.height,o=N(n.position,3),s=o[0],c=o[1],l=o[2],u=a/2;this.markerGroup.styles({x:s,y:u}),this.labelGroup.styles({x:c,y:u}),uh(this.labelGroup.select(un.label.class).node(),Math.ceil(r)),this.showValue&&(this.valueGroup.styles({x:l,y:u}),uh(this.valueGroup.select(un.value.class).node(),Math.ceil(i)))},e.prototype.render=function(n,r){var i=dt(r);this.renderMarker(i),this.renderLabel(i),this.renderValue(i),this.renderBackground(i),this.adjustLayout()},e}(Pe),Si=$n({page:"item-page",navigator:"navigator",item:"item"},"items"),Dy=function(t,e,n){return n===void 0&&(n=!0),t?e(t):n},wj=function(t){rt(e,t);function e(n){var r=t.call(this,n,{data:[],gridRow:1/0,gridCol:void 0,padding:0,width:1e3,height:100,rowPadding:0,colPadding:0,layout:"flex",orientation:"horizontal",click:wf,mouseenter:wf,mouseleave:wf})||this;return r.navigatorShape=[0,0],r}return Object.defineProperty(e.prototype,"pageViews",{get:function(){return this.navigator.getContainer()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"grid",{get:function(){var n=this.attributes,r=n.gridRow,i=n.gridCol,a=n.data;if(!r&&!i)throw new Error("gridRow and gridCol can not be set null at the same time");return r&&i?[r,i]:r?[r,a.length]:[a.length,i]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"renderData",{get:function(){var n=this.attributes,r=n.data,i=n.layout,a=vt(this.attributes,"item"),o=r.map(function(s,c){var l=s.id,u=l===void 0?c:l,f=s.label,d=s.value;return{id:"".concat(u),index:c,style:z({layout:i,labelText:f,valueText:d},Object.fromEntries(Object.entries(a).map(function(h){var p=N(h,2),v=p[0],g=p[1];return[v,Rn(g,[s,c,r])]})))}});return o},enumerable:!1,configurable:!0}),e.prototype.getGridLayout=function(){var n=this,r=this.attributes,i=r.orientation,a=r.width,o=r.rowPadding,s=r.colPadding,c=N(this.navigatorShape,1),l=c[0],u=N(this.grid,2),f=u[0],d=u[1],h=d*f,p=0;return this.pageViews.children.map(function(v,g){var y,m,b=Math.floor(g/h),x=g%h,w=n.ifHorizontal(d,f),O=[Math.floor(x/w),x%w];i==="vertical"&&O.reverse();var S=N(O,2),_=S[0],M=S[1],E=(a-l-(d-1)*s)/d,P=v.getBBox().height,T=N([0,0],2),A=T[0],k=T[1];return i==="horizontal"?(y=N([p,_*(P+o)],2),A=y[0],k=y[1],p=M===d-1?0:p+E+s):(m=N([M*(E+s),p],2),A=m[0],k=m[1],p=_===f-1?0:p+P+o),{page:b,index:g,row:_,col:M,pageIndex:x,width:E,height:P,x:A,y:k}})},e.prototype.getFlexLayout=function(){var n=this.attributes,r=n.width,i=n.height,a=n.rowPadding,o=n.colPadding,s=N(this.navigatorShape,1),c=s[0],l=N(this.grid,2),u=l[0],f=l[1],d=N([r-c,i],2),h=d[0],p=d[1],v=N([0,0,0,0,0,0,0,0],8),g=v[0],y=v[1],m=v[2],b=v[3],x=v[4],w=v[5],O=v[6],S=v[7];return this.pageViews.children.map(function(_,M){var E,P,T,A,k=_.getBBox(),C=k.width,L=k.height,I=O===0?0:o,R=O+I+C;if(R<=h&&Dy(x,function(D){return D0?(this.navigatorShape=[55,0],n.call(this)):r},enumerable:!1,configurable:!0}),e.prototype.ifHorizontal=function(n,r){var i=this.attributes.orientation;return ir(i,n,r)},e.prototype.flattenPage=function(n){n.querySelectorAll(Si.item.class).forEach(function(r){n.appendChild(r)}),n.querySelectorAll(Si.page.class).forEach(function(r){var i=n.removeChild(r);i.destroy()})},e.prototype.renderItems=function(n){var r=this.attributes,i=r.click,a=r.mouseenter,o=r.mouseleave;this.flattenPage(n);var s=this.dispatchCustomEvent.bind(this);dt(n).selectAll(Si.item.class).data(this.renderData,function(c){return c.id}).join(function(c){return c.append(function(l){var u=l.style;return new xj({style:u})}).attr("className",Si.item.name).on("click",function(){i==null||i(this),s("itemClick",{item:this})}).on("pointerenter",function(){a==null||a(this),s("itemMouseenter",{item:this})}).on("pointerleave",function(){o==null||o(this),s("itemMouseleave",{item:this})})},function(c){return c.each(function(l){var u=l.style;this.update(u)})},function(c){return c.remove()})},e.prototype.relayoutNavigator=function(){var n,r=this.attributes,i=r.layout,a=r.width,o=((n=this.pageViews.children[0])===null||n===void 0?void 0:n.getBBox().height)||0,s=N(this.navigatorShape,2),c=s[0],l=s[1];this.navigator.update(i==="grid"?{pageWidth:a-c,pageHeight:o-l}:{})},e.prototype.adjustLayout=function(){var n=this,r=Object.entries(cI(this.itemsLayout,"page")).map(function(a){var o=N(a,2),s=o[0],c=o[1];return{page:s,layouts:c}}),i=q([],N(this.navigator.getContainer().children),!1);r.forEach(function(a){var o=a.layouts,s=n.pageViews.appendChild(new Ce({className:Si.page.name}));o.forEach(function(c){var l=c.x,u=c.y,f=c.index,d=c.width,h=c.height,p=i[f];s.appendChild(p),$k(p,"__layout__",c),p.update({x:l,y:u,width:d,height:h})})}),this.relayoutNavigator()},e.prototype.renderNavigator=function(n){var r=this.attributes.orientation,i=vt(this.attributes,"nav"),a=Nr({orientation:r},i),o=this;return n.selectAll(Si.navigator.class).data(["nav"]).join(function(s){return s.append(function(){return new hj({style:a})}).attr("className",Si.navigator.name).each(function(){o.navigator=this})},function(s){return s.each(function(){this.update(a)})},function(s){return s.remove()}),this.navigator},e.prototype.getBBox=function(){return this.navigator.getBBox()},e.prototype.render=function(n,r){var i=this.attributes.data;if(!(!i||i.length===0)){var a=this.renderNavigator(dt(r));this.renderItems(a.getContainer()),this.adjustLayout()}},e.prototype.dispatchCustomEvent=function(n,r){var i=new Dt(n,{detail:r});this.dispatchEvent(i)},e}(Pe),Oo=$n({markerGroup:"marker-group",marker:"marker",labelGroup:"label-group",label:"label"},"handle"),AS={showLabel:!0,formatter:function(t){return t.toString()},markerSize:25,markerStroke:"#c5c5c5",markerFill:"#fff",markerLineWidth:1,labelFontSize:12,labelFill:"#c5c5c5",labelText:"",orientation:"vertical",spacing:0},Oj=function(t){rt(e,t);function e(n){return t.call(this,n,AS)||this}return e.prototype.render=function(n,r){var i=dt(r).maybeAppendByClassName(Oo.markerGroup,"g");this.renderMarker(i);var a=dt(r).maybeAppendByClassName(Oo.labelGroup,"g");this.renderLabel(a)},e.prototype.renderMarker=function(n){var r=this,i=this.attributes,a=i.orientation,o=i.markerSymbol,s=o===void 0?ir(a,"horizontalHandle","verticalHandle"):o;on(!!s,n,function(c){var l=vt(r.attributes,"marker"),u=z({symbol:s},l);r.marker=c.maybeAppendByClassName(Oo.marker,function(){return new Bt({style:u})}).update(u)})},e.prototype.renderLabel=function(n){var r=this,i=this.attributes,a=i.showLabel,o=i.orientation,s=i.spacing,c=s===void 0?0:s,l=i.formatter;on(a,n,function(u){var f,d=vt(r.attributes,"label"),h=d.text,p=$t(d,["text"]),v=((f=u.select(Oo.marker.class))===null||f===void 0?void 0:f.node().getBBox())||{},g=v.width,y=g===void 0?0:g,m=v.height,b=m===void 0?0:m,x=N(ir(o,[0,b+c,"center","top"],[y+c,0,"start","middle"]),4),w=x[0],O=x[1],S=x[2],_=x[3];u.maybeAppendByClassName(Oo.label,"text").styles(z(z({},p),{x:w,y:O,text:l(h).toString(),textAlign:S,textBaseline:_}))})},e}(Pe),kS={showTitle:!0,padding:0,orientation:"horizontal",backgroundFill:"transparent",titleText:"",titleSpacing:4,titlePosition:"top-left",titleFill:"#2C3542",titleFontWeight:"bold",titleFontFamily:"sans-serif",titleFontSize:12},Sj=Nr({},kS,{}),_j=Nr({},kS,Jn(AS,"handle"),{color:["#d0e3fa","#acc7f6","#8daaf2","#6d8eea","#4d73cd","#325bb1","#5a3e75","#8c3c79","#e23455","#e7655b"],indicatorBackgroundFill:"#262626",indicatorLabelFill:"white",indicatorLabelFontSize:12,indicatorVisibility:"hidden",labelAlign:"value",labelDirection:"positive",labelSpacing:5,showHandle:!0,showIndicator:!0,showLabel:!0,slidable:!0,titleText:"",type:"continuous"}),Mj=.01,Me=$n({title:"title",titleGroup:"title-group",items:"items",itemsGroup:"items-group",contentGroup:"content-group",ribbonGroup:"ribbon-group",ribbon:"ribbon",handlesGroup:"handles-group",handle:"handle",startHandle:"start-handle",endHandle:"end-handle",labelGroup:"label-group",label:"label",indicator:"indicator"},"legend"),Ej=function(t){rt(e,t);function e(n){return t.call(this,n,Sj)||this}return e.prototype.renderTitle=function(n,r,i){var a=this.attributes,o=a.showTitle,s=a.titleText,c=vt(this.attributes,"title"),l=N(Rr(c),2),u=l[0],f=l[1];this.titleGroup=n.maybeAppendByClassName(Me.titleGroup,"g").styles(f);var d=z(z({width:r,height:i},u),{text:o?s:""});this.title=this.titleGroup.maybeAppendByClassName(Me.title,function(){return new MS({style:d})}).update(d)},e.prototype.renderItems=function(n,r){var i=r.x,a=r.y,o=r.width,s=r.height,c=vt(this.attributes,"title",!0),l=N(Rr(c),2),u=l[0],f=l[1],d=z(z({},u),{width:o,height:s,x:0,y:0});this.itemsGroup=n.maybeAppendByClassName(Me.itemsGroup,"g").styles(z({x:i,y:a},f));var h=this;this.itemsGroup.selectAll(Me.items.class).data(["items"]).join(function(p){return p.append(function(){return new wj({style:d})}).attr("className",Me.items.name).each(function(){h.items=dt(this)})},function(p){return p.update(d)},function(p){return p.remove()})},e.prototype.adjustLayout=function(){var n=this.attributes.showTitle;if(n){var r=this.title.node().getAvailableSpace(),i=r.x,a=r.y;this.itemsGroup.node().setLocalPosition(i,a)}},Object.defineProperty(e.prototype,"availableSpace",{get:function(){var n=this.attributes,r=n.showTitle,i=n.width,a=n.height;return r?this.title.node().getAvailableSpace():new Qt(0,0,i,a)},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var n,r,i=(n=this.title)===null||n===void 0?void 0:n.node(),a=(r=this.items)===null||r===void 0?void 0:r.node();return!i||!a?t.prototype.getBBox.call(this):sj(i,a)},e.prototype.render=function(n,r){var i=n.width,a=n.height,o=dt(r);this.renderTitle(o,i,a),this.renderItems(o,this.availableSpace),this.adjustLayout()},e}(Pe),Pj={backgroundFill:"#262626",backgroundLineCap:"round",backgroundLineWidth:1,backgroundStroke:"#333",backgroundZIndex:-1,formatter:function(t){return t.toString()},labelFill:"#fff",labelFontSize:12,labelTextBaseline:"middle",padding:[2,4],position:"right",radius:0,zIndex:999},Kf=$n({background:"background",labelGroup:"label-group",label:"label"},"indicator"),Aj=function(t){rt(e,t);function e(n){var r=t.call(this,n,Pj)||this;return r.point=[0,0],r.group=r.appendChild(new Ce({})),r.isMutationObserved=!0,r}return e.prototype.renderBackground=function(){if(this.label){var n=this.attributes,r=n.position,i=n.padding,a=N(Te(i),4),o=a[0],s=a[1],c=a[2],l=a[3],u=this.label.node().getLocalBounds(),f=u.min,d=u.max,h=new Qt(f[0]-l,f[1]-o,d[0]+s-f[0]+l,d[1]+c-f[1]+o),p=this.getPath(r,h),v=vt(this.attributes,"background");this.background=dt(this.group).maybeAppendByClassName(Kf.background,"path").styles(z(z({},v),{path:p})),this.group.appendChild(this.label.node())}},e.prototype.renderLabel=function(){var n=this.attributes,r=n.formatter,i=n.labelText,a=vt(this.attributes,"label"),o=N(Rr(a),2),s=o[0],c=o[1];s.text;var l=$t(s,["text"]);if(this.label=dt(this.group).maybeAppendByClassName(Kf.labelGroup,"g").styles(c),!!i){var u=this.label.maybeAppendByClassName(Kf.label,function(){return Yi(r(i))}).style("text",r(i).toString());u.selectAll("text").styles(l)}},e.prototype.adjustLayout=function(){var n=N(this.point,2),r=n[0],i=n[1];this.group.attr("x",-r).attr("y",-i)},e.prototype.getPath=function(n,r){var i=this.attributes.radius,a=r.x,o=r.y,s=r.width,c=r.height,l=[["M",a+i,o],["L",a+s-i,o],["A",i,i,0,0,1,a+s,o+i],["L",a+s,o+c-i],["A",i,i,0,0,1,a+s-i,o+c],["L",a+i,o+c],["A",i,i,0,0,1,a,o+c-i],["L",a,o+i],["A",i,i,0,0,1,a+i,o],["Z"]],u={top:4,right:6,bottom:0,left:2},f=u[n],d=this.createCorner([l[f].slice(-2),l[f+1].slice(-2)]);return l.splice.apply(l,q([f+1,1],N(d),!1)),l[0][0]="M",l},e.prototype.createCorner=function(n,r){r===void 0&&(r=10);var i=.8,a=EI.apply(void 0,q([],N(n),!1)),o=N(n,2),s=N(o[0],2),c=s[0],l=s[1],u=N(o[1],2),f=u[0],d=u[1],h=N(a?[f-c,[c,f]]:[d-l,[l,d]],2),p=h[0],v=N(h[1],2),g=v[0],y=v[1],m=p/2,b=p/Math.abs(p),x=r*b,w=x/2,O=x*Math.sqrt(3)/2*i,S=N([g,g+m-w,g+m,g+m+w,y],5),_=S[0],M=S[1],E=S[2],P=S[3],T=S[4];return a?(this.point=[E,l-O],[["L",_,l],["L",M,l],["L",E,l-O],["L",P,l],["L",T,l]]):(this.point=[c+O,E],[["L",c,_],["L",c,M],["L",c+O,E],["L",c,P],["L",c,T]])},e.prototype.applyVisibility=function(){var n=this.attributes.visibility;n==="hidden"?li(this):Ks(this)},e.prototype.bindEvents=function(){this.label.on(ht.BOUNDS_CHANGED,this.renderBackground)},e.prototype.render=function(){this.renderLabel(),this.renderBackground(),this.adjustLayout(),this.applyVisibility()},e}(Pe);function kj(t,e){for(var n=1;n=r&&e<=i)return[r,i]}return[e,e]}function Tj(t,e,n){var r=Array.from(e),i=t.length;return new Array(i).fill(0).reduce(function(a,o,s){var c=r[s%r.length];return a+=" ".concat(t[s],":").concat(c).concat(s(r+i)/2?i:r,range:[r,i]}}var ms=$n({trackGroup:"background-group",track:"background",selectionGroup:"ribbon-group",selection:"ribbon",clipPath:"clip-path"},"ribbon");function TS(t){var e=t.orientation,n=t.size,r=t.length;return ir(e,[r,n],[n,r])}function CS(t){var e=t.type,n=N(TS(t),2),r=n[0],i=n[1];return e==="size"?[["M",0,i],["L",0+r,0],["L",0+r,i],["Z"]]:[["M",0,i],["L",0,0],["L",0+r,0],["L",0+r,i],["Z"]]}function Cj(t){return CS(t)}function Lj(t){var e=t.orientation,n=t.color,r=t.block,i=t.partition,a;if(Ve(n)){var o=20;a=new Array(o).fill(0).map(function(l,u,f){return n(u/(f.length-1))})}else a=n;var s=a.length,c=a.map(function(l){return Ar(l).toString()});return s?s===1?c[0]:r?Tj(i,c,e):c.reduce(function(l,u,f){return l+=" ".concat(f/(s-1),":").concat(u)},"l(".concat(ir(e,"0","270"),")")):""}function Nj(t){var e=t.orientation,n=t.range;if(!n)return[];var r=N(TS(t),2),i=r[0],a=r[1],o=N(n,2),s=o[0],c=o[1],l=ir(e,s*i,0),u=ir(e,0,s*a),f=ir(e,c*i,i),d=ir(e,a,c*a);return[["M",l,u],["L",l,d],["L",f,d],["L",f,u],["Z"]]}function Rj(t,e){var n=vt(e,"track");t.maybeAppendByClassName(ms.track,"path").styles(z({path:CS(e)},n))}function Ij(t,e){var n=vt(e,"selection"),r=Lj(e),i=t.maybeAppendByClassName(ms.selection,"path").styles(z({path:Cj(e),fill:r},n)),a=i.maybeAppendByClassName(ms.clipPath,"path").styles({path:Nj(e)}).node();i.style("clip-path",a)}var jj=function(t){rt(e,t);function e(n){return t.call(this,n,{type:"color",orientation:"horizontal",size:30,range:[0,1],length:200,block:!1,partition:[],color:["#fff","#000"],trackFill:"#e5e5e5"})||this}return e.prototype.render=function(n,r){var i=dt(r).maybeAppendByClassName(ms.trackGroup,"g");Rj(i,n);var a=dt(r).maybeAppendByClassName(ms.selectionGroup,"g");Ij(a,n)},e}(Pe);function Dj(t){return{min:Math.min.apply(Math,q([],N(t.map(function(e){return e.value})),!1)),max:Math.max.apply(Math,q([],N(t.map(function(e){return e.value})),!1))}}var $j=function(t){rt(e,t);function e(n){var r=t.call(this,n,_j)||this;return r.eventToOffsetScale=new Yt({}),r.innerRibbonScale=new Yt({}),r.cacheLabelBBox=null,r.cacheHandleBBox=null,r.onHovering=function(i){var a=r.attributes,o=a.data,s=a.block;i.stopPropagation();var c=r.getValueByCanvasPoint(i);if(s){var l=$y(o.map(function(f){var d=f.value;return d}),c).range;r.showIndicator((l[0]+l[1])/2,"".concat(l[0],"-").concat(l[1])),r.dispatchIndicated(c,l)}else{var u=r.getTickValue(c);r.showIndicator(u),r.dispatchIndicated(u)}},r.onDragStart=function(i){return function(a){a.stopPropagation(),r.attributes.slidable&&(r.target=i,r.prevValue=r.getTickValue(r.getValueByCanvasPoint(a)),document.addEventListener("mousemove",r.onDragging),document.addEventListener("touchmove",r.onDragging),document.addEventListener("mouseleave",r.onDragEnd),document.addEventListener("mouseup",r.onDragEnd),document.addEventListener("mouseup",r.onDragEnd),document.addEventListener("touchend",r.onDragEnd))}},r.onDragging=function(i){var a=r.target;r.updateMouse();var o=N(r.selection,2),s=o[0],c=o[1],l=r.getTickValue(r.getValueByCanvasPoint(i)),u=l-r.prevValue;a==="start"?s!==l&&r.updateSelection(l,c):a==="end"?c!==l&&r.updateSelection(s,l):a==="ribbon"&&u!==0&&(r.prevValue=l,r.updateSelection(u,u,!0))},r.onDragEnd=function(){r.style.cursor="pointer",document.removeEventListener("mousemove",r.onDragging),document.removeEventListener("touchmove",r.onDragging),document.removeEventListener("mouseup",r.onDragEnd),document.removeEventListener("touchend",r.onDragEnd)},r}return Object.defineProperty(e.prototype,"handleOffsetRatio",{get:function(){return this.ifHorizontal(.5,.5)},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var n=this.attributes,r=n.width,i=n.height;return new Qt(0,0,r,i)},e.prototype.render=function(n,r){var i=this,a=n.showLabel;this.renderTitle(dt(r));var o=this.availableSpace,s=o.x,c=o.y,l=dt(r).maybeAppendByClassName(Me.contentGroup,"g").styles({x:s,y:c}),u=l.maybeAppendByClassName(Me.labelGroup,"g").styles({zIndex:1});on(!!a,u,function(d){i.renderLabel(d)});var f=l.maybeAppendByClassName(Me.ribbonGroup,"g").styles({zIndex:0});this.handlesGroup=l.maybeAppendByClassName(Me.handlesGroup,"g").styles({zIndex:2}),this.renderHandles(),this.renderRibbon(f),this.renderIndicator(l),this.adjustLabel(),this.adjustHandles()},Object.defineProperty(e.prototype,"range",{get:function(){var n=this.attributes,r=n.data,i=n.domain;return i?{min:i[0],max:i[1]}:Dj(r)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"ribbonScale",{get:function(){var n=this.range,r=n.min,i=n.max;return this.innerRibbonScale.update({domain:[r,i],range:[0,1]}),this.innerRibbonScale},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"ribbonRange",{get:function(){var n=N(this.selection,2),r=n[0],i=n[1],a=this.ribbonScale;return[a.map(r),a.map(i)]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"selection",{get:function(){var n=this.range,r=n.min,i=n.max,a=this.attributes.defaultValue,o=a===void 0?[r,i]:a,s=N(o,2),c=s[0],l=s[1];return[c,l]},enumerable:!1,configurable:!0}),e.prototype.ifHorizontal=function(n,r){return ir(this.attributes.orientation,typeof n=="function"?n():n,typeof r=="function"?r():r)},e.prototype.renderTitle=function(n){var r=this.attributes,i=r.showTitle,a=r.titleText,o=r.width,s=r.height,c=vt(this.attributes,"title"),l=z(z({},c),{width:o,height:s,text:a}),u=this;n.selectAll(Me.title.class).data(i?[a]:[]).join(function(f){return f.append(function(){return new MS({style:l})}).attr("className",Me.title.name).each(function(){u.title=this})},function(f){return f.update(l)},function(f){return f.each(function(){u.title=void 0}).remove()})},Object.defineProperty(e.prototype,"availableSpace",{get:function(){if(this.title)return this.title.getAvailableSpace();var n=this.attributes,r=n.width,i=n.height;return new Qt(0,0,r,i)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"labelFixedSpacing",{get:function(){var n=this.attributes.showTick;return n?5:0},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"labelPosition",{get:function(){var n=this.attributes,r=n.orientation,i=n.labelDirection,a={vertical:{positive:"right",negative:"left"},horizontal:{positive:"bottom",negative:"top"}};return a[r][i]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"labelBBox",{get:function(){var n,r=this.attributes.showLabel;if(!r)return new Qt(0,0,0,0);if(this.cacheLabelBBox)return this.cacheLabelBBox;var i=((n=this.label.querySelector(Rt.labelGroup.class))===null||n===void 0?void 0:n.children.slice(-1)[0]).getBBox(),a=i.width,o=i.height;return this.cacheLabelBBox=new Qt(0,0,a,o),this.cacheLabelBBox},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"labelShape",{get:function(){var n=this.attributes,r=n.showLabel,i=n.labelSpacing,a=i===void 0?0:i;if(!r)return{width:0,height:0,size:0,length:0};var o=this.labelBBox,s=o.width,c=o.height,l=this.ifHorizontal(c,s)+a+this.labelFixedSpacing,u=this.ifHorizontal(s,c);return{width:s,height:c,size:l,length:u}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"ribbonBBox",{get:function(){var n=this.attributes,r=n.showHandle,i=n.ribbonSize,a=this.availableSpace,o=a.width,s=a.height,c=this.labelShape,l=c.size,u=c.length,f=N(this.ifHorizontal([s,o],[o,s]),2),d=f[0],h=f[1],p=r?this.handleShape:{size:0,length:0},v=p.size,g=p.length,y=this.handleOffsetRatio,m=0,b=this.labelPosition;i?m=i:["bottom","right"].includes(b)?m=Math.min(d-l,(d-v)/y):d*(1-y)>v?m=Math.max(d-l,0):m=Math.max((d-l-v)/y,0);var x=Math.max(g,u),w=h-x,O=N(this.ifHorizontal([w,m],[m,w]),2),S=O[0],_=O[1],M=["top","left"].includes(b)?l:0,E=N(this.ifHorizontal([x/2,M],[M,x/2]),2),P=E[0],T=E[1];return new Qt(P,T,S,_)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"ribbonShape",{get:function(){var n=this.ribbonBBox,r=n.width,i=n.height;return this.ifHorizontal({size:i,length:r},{size:r,length:i})},enumerable:!1,configurable:!0}),e.prototype.renderRibbon=function(n){var r=this.attributes,i=r.data,a=r.type,o=r.orientation,s=r.color,c=r.block,l=vt(this.attributes,"ribbon"),u=this.range,f=u.min,d=u.max,h=this.ribbonBBox,p=h.x,v=h.y,g=this.ribbonShape,y=g.length,m=g.size,b=Nr({x:p,y:v,length:y,size:m,type:a,orientation:o,color:s,block:c,partition:i.map(function(x){return(x.value-f)/(d-f)}),range:this.ribbonRange},l);this.ribbon=n.maybeAppendByClassName(Me.ribbon,function(){return new jj({style:b})}).update(b)},e.prototype.getHandleClassName=function(n){return"".concat(Me.prefix("".concat(n,"-handle")))},e.prototype.renderHandles=function(){var n=this.attributes,r=n.showHandle,i=n.orientation,a=vt(this.attributes,"handle"),o=N(this.selection,2),s=o[0],c=o[1],l=z(z({},a),{orientation:i}),u=a.shape,f=u===void 0?"slider":u,d=f==="basic"?Oj:hS,h=this;this.handlesGroup.selectAll(Me.handle.class).data(r?[{value:s,type:"start"},{value:c,type:"end"}]:[],function(p){return p.type}).join(function(p){return p.append(function(){return new d({style:l})}).attr("className",function(v){var g=v.type;return"".concat(Me.handle," ").concat(h.getHandleClassName(g))}).each(function(v){var g=v.type,y=v.value;this.update({labelText:y});var m="".concat(g,"Handle");h[m]=this,this.addEventListener("pointerdown",h.onDragStart(g))})},function(p){return p.update(l).each(function(v){var g=v.value;this.update({labelText:g})})},function(p){return p.each(function(v){var g=v.type,y="".concat(g,"Handle");h[y]=void 0}).remove()})},e.prototype.adjustHandles=function(){var n=N(this.selection,2),r=n[0],i=n[1];this.setHandlePosition("start",r),this.setHandlePosition("end",i)},e.prototype.adjustTitle=function(){var n=this.attributes,r=n.titlePosition,i=n.orientation,a=N(this.getElementsByClassName(Me.title.name),1),o=a[0],s=this.handlesGroup.select(".".concat(this.getHandleClassName("start"))).node();if(!(!o||!s)&&!(r!=="top-left"||i!=="horizontal")){var c=N(s.getLocalBounds().min,1),l=c[0],u=N(o.getLocalBounds().min,1),f=u[0],d=l-f;o.style.x=+(this.style.x||0)+d}},Object.defineProperty(e.prototype,"handleBBox",{get:function(){if(this.cacheHandleBBox)return this.cacheHandleBBox;if(!this.attributes.showHandle)return new Qt(0,0,0,0);var n=this.startHandle.getBBox(),r=n.width,i=n.height,a=this.endHandle.getBBox(),o=a.width,s=a.height,c=N([Math.max(r,o),Math.max(i,s)],2),l=c[0],u=c[1];return this.cacheHandleBBox=new Qt(0,0,l,u),this.cacheHandleBBox},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"handleShape",{get:function(){var n=this.handleBBox,r=n.width,i=n.height,a=N(this.ifHorizontal([i,r],[r,i]),2),o=a[0],s=a[1];return{width:r,height:i,size:o,length:s}},enumerable:!1,configurable:!0}),e.prototype.setHandlePosition=function(n,r){var i=this.attributes.handleFormatter,a=this.ribbonBBox,o=a.x,s=a.y,c=this.ribbonShape.size,l=this.getOffset(r),u=N(this.ifHorizontal([o+l,s+c*this.handleOffsetRatio],[o+c*this.handleOffsetRatio,s+l]),2),f=u[0],d=u[1],h=this.handlesGroup.select(".".concat(this.getHandleClassName(n))).node();h==null||h.update({x:f,y:d,formatter:i})},e.prototype.renderIndicator=function(n){var r=vt(this.attributes,"indicator");this.indicator=n.maybeAppendByClassName(Me.indicator,function(){return new Aj({})}).update(r)},Object.defineProperty(e.prototype,"labelData",{get:function(){var n=this,r=this.attributes.data;return r.reduce(function(i,a,o,s){var c,l,u=(c=a==null?void 0:a.id)!==null&&c!==void 0?c:o.toString();if(i.push(z(z({},a),{id:u,index:o,type:"value",label:(l=a==null?void 0:a.label)!==null&&l!==void 0?l:a.value.toString(),value:n.ribbonScale.map(a.value)})),o'),title:'
'),item:'
  • - - - {name} - - {value} -
  • `)},style:Bj(o)})||this,r.timestamp=-1,r.prevCustomContentKey=r.attributes.contentKey,r.initShape(),r.render(r.attributes,r),r}return Object.defineProperty(e.prototype,"HTMLTooltipElement",{get:function(){return this.element},enumerable:!1,configurable:!0}),e.prototype.getContainer=function(){return this.element},Object.defineProperty(e.prototype,"elementSize",{get:function(){var n=this.element.offsetWidth,r=this.element.offsetHeight;return{width:n,height:r}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"HTMLTooltipItemsElements",{get:function(){var n=this.attributes,r=n.data,i=n.template;return r.map(function(a,o){var s=a.name,c=s===void 0?"":s,l=a.color,u=l===void 0?"black":l,f=a.index,d=$t(a,["name","color","index"]),h=z({name:c,color:u,index:f??o},d);return rg(Nk(i.item,h))})},enumerable:!1,configurable:!0}),e.prototype.render=function(n,r){this.renderHTMLTooltipElement(),this.updatePosition()},e.prototype.destroy=function(){var n;(n=this.element)===null||n===void 0||n.remove(),t.prototype.destroy.call(this)},e.prototype.show=function(n,r){var i=this;if(n!==void 0&&r!==void 0){var a=this.element.style.visibility==="hidden",o=function(){i.attributes.x=n??i.attributes.x,i.attributes.y=r??i.attributes.y,i.updatePosition()};a?this.closeTransition(o):o()}this.element.style.visibility="visible"},e.prototype.hide=function(n,r){n===void 0&&(n=0),r===void 0&&(r=0);var i=this.attributes.enterable;i&&this.isCursorEntered(n,r)||(this.element.style.visibility="hidden")},e.prototype.initShape=function(){var n=this.attributes.template;this.element=rg(n.container),this.id&&this.element.setAttribute("id",this.id)},e.prototype.renderCustomContent=function(){if(!(this.prevCustomContentKey!==void 0&&this.prevCustomContentKey===this.attributes.contentKey)){this.prevCustomContentKey=this.attributes.contentKey;var n=this.attributes.content;n&&(typeof n=="string"?this.element.innerHTML=n:this.element.replaceChildren(n))}},e.prototype.renderHTMLTooltipElement=function(){var n,r,i=this.attributes,a=i.template,o=i.title,s=i.enterable,c=i.style,l=i.content,u=gh(a.prefixCls),f=this.element;if(this.element.style.pointerEvents=s?"auto":"none",l)this.renderCustomContent();else{o?(f.innerHTML=a.title,f.getElementsByClassName(u.TITLE)[0].innerHTML=o):(r=(n=f.getElementsByClassName(u.TITLE))===null||n===void 0?void 0:n[0])===null||r===void 0||r.remove();var d=this.HTMLTooltipItemsElements,h=document.createElement("ul");h.className=u.LIST,h.replaceChildren.apply(h,q([],N(d),!1));var p=this.element.querySelector(".".concat(u.LIST));p?p.replaceWith(h):f.appendChild(h)}TI(f,c)},e.prototype.getRelativeOffsetFromCursor=function(n){var r=this.attributes,i=r.position,a=r.offset,o=n||i,s=o.split("-"),c={left:[-1,0],right:[1,0],top:[0,-1],bottom:[0,1]},l=this.elementSize,u=l.width,f=l.height,d=[-u/2,-f/2];return s.forEach(function(h){var p=N(d,2),v=p[0],g=p[1],y=N(c[h],2),m=y[0],b=y[1];d=[v+(u/2+a[0])*m,g+(f/2+a[1])*b]}),d},e.prototype.setOffsetPosition=function(n){var r=N(n,2),i=r[0],a=r[1],o=this.attributes,s=o.x,c=s===void 0?0:s,l=o.y,u=l===void 0?0:l,f=o.container,d=f.x,h=f.y;this.element.style.left="".concat(+c+d+i,"px"),this.element.style.top="".concat(+u+h+a,"px")},e.prototype.updatePosition=function(){var n=this.attributes.showDelay,r=n===void 0?60:n,i=Date.now();this.timestamp>0&&i-this.timestampm+x,top:gb+w},S=[];u.split("-").forEach(function(M){O[M]?S.push(y[M]):S.push(M)});var _=S.join("-");return this.getRelativeOffsetFromCursor(_)},e.prototype.isCursorEntered=function(n,r){if(this.element){var i=this.element.getBoundingClientRect(),a=i.x,o=i.y,s=i.width,c=i.height;return new Qt(a,o,s,c).isPointIn(n,r)}return!1},e.prototype.closeTransition=function(n){var r=this,i=this.element.style.transition;this.element.style.transition="none",n(),setTimeout(function(){r.element.style.transition=i},10)},e.tag="tooltip",e}(Pe),zj=function(t){rt(e,t);function e(n){var r=t.call(this,n)||this;r.layoutEvents=[ht.BOUNDS_CHANGED,ht.INSERTED,ht.REMOVED],r.$margin=Te(0),r.$padding=Te(0);var i=n.style||{},a=i.margin,o=a===void 0?0:a,s=i.padding,c=s===void 0?0:s;return r.margin=o,r.padding=c,r.isMutationObserved=!0,r.bindEvents(),r}return Object.defineProperty(e.prototype,"margin",{get:function(){return this.$margin},set:function(n){this.$margin=Te(n)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"padding",{get:function(){return this.$padding},set:function(n){this.$padding=Te(n)},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var n=this.attributes,r=n.x,i=r===void 0?0:r,a=n.y,o=a===void 0?0:a,s=n.width,c=n.height,l=N(this.$margin,4),u=l[0],f=l[1],d=l[2],h=l[3];return new Qt(i-h,o-u,s+h+f,c+u+d)},e.prototype.appendChild=function(n,r){return n.isMutationObserved=!0,t.prototype.appendChild.call(this,n,r),n},e.prototype.getAvailableSpace=function(){var n=this.attributes,r=n.width,i=n.height,a=N(this.$padding,4),o=a[0],s=a[1],c=a[2],l=a[3],u=N(this.$margin,4),f=u[0],d=u[3];return new Qt(l+d,o+f,r-l-s,i-o-c)},e.prototype.layout=function(){if(!(!this.attributes.display||!this.isConnected)&&!this.children.some(function(r){return!r.isConnected}))try{var n=vI(this.getAvailableSpace(),this.children.map(function(r){return r.getBBox()}),this.attributes);this.children.forEach(function(r,i){var a=n[i],o=a.x,s=a.y;r.attr({x:o,y:s})})}catch{}},e.prototype.bindEvents=function(){var n=this;this.layoutEvents.forEach(function(r){n.addEventListener(r,function(i){i.target.isMutationObserved=!0,n.layout()})})},e.prototype.attributeChangedCallback=function(n,r,i){n==="margin"?this.margin=i:n==="padding"&&(this.padding=i),this.layout()},e}(Ce),Zf=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i0&&(a=e),r<0&&(a=r),n>0&&(o=n),i<0&&(o=i),[a,o]}function Yj(t,e=[]){const[n=0,r=0,i=n,a=r]=e,o=t.parentNode,s=o.getEulerAngles();o.setEulerAngles(0);const{min:c,halfExtents:l}=t.getLocalBounds(),[u,f]=c,[d,h]=l;return o.setEulerAngles(s),{x:u-a,y:f-n,width:d*2+a+r,height:h*2+n+i}}const Wj=(t,e,n)=>{const r=Jt(t,e),i=Jt(e,n),a=Jt(n,t);return(Math.pow(r,2)+Math.pow(i,2)-Math.pow(a,2))/(2*r*i)};function Hj(t,e,n,r){const[[i,a],[o,s]]=e,[c,l]=Gj(t);if(i===o&&a===s)return Jr()([[0,0],[c,l]]);const u=[[i-o,a-s]].concat(n.length?n:[[0,0]]),f=[r[0]-o,r[1]-s],[d,h]=u;if(Wj(f,d,h)>0){const p=(()=>{const{min:v,max:g}=t.getLocalBounds(),y=d[0]+(d[1]-f[1])*(d[1]-0)/(d[0]-f[0]);return g[0]{const e=t.attributes,{className:n,class:r,transform:i,rotate:a,labelTransform:o,labelTransformOrigin:s,x:c,y:l,x0:u=c,y0:f=l,text:d,background:h,connector:p,startMarker:v,endMarker:g,coordCenter:y,innerHTML:m}=e,b=Zf(e,["className","class","transform","rotate","labelTransform","labelTransformOrigin","x","y","x0","y0","text","background","connector","startMarker","endMarker","coordCenter","innerHTML"]);if([c,l,u,f].some(L=>!de(L))){t.children.forEach(L=>L.remove());return}const x=Q(b,"background"),{padding:w}=x,O=Zf(x,["padding"]),S=Q(b,"connector"),{points:_=[]}=S,M=Zf(S,["points"]),E=[[+u,+f],[+c,+l]];let P;m?P=st(t).maybeAppend("html","html",n).style("zIndex",0).style("innerHTML",m).call(at,Object.assign({transform:o,transformOrigin:s},b)).node():P=st(t).maybeAppend("text","text").style("zIndex",0).style("text",d).call(at,Object.assign({textBaseline:"middle",transform:o,transformOrigin:s},b)).node();const T=st(t).maybeAppend("background","rect").style("zIndex",-1).call(at,Yj(P,w)).call(at,h?O:{}).node(),A=Hj(T,E,_,y),k=v&&new Bt({id:"startMarker",style:Object.assign({x:0,y:0},Q(b,"startMarker"))}),C=g&&new Bt({id:"endMarker",style:Object.assign({x:0,y:0},Q(b,"endMarker"))});st(t).maybeAppend("connector","path").style("zIndex",0).style("path",A).style("markerStart",k).style("markerEnd",C).call(at,p?M:{})}),NS=(t,e)=>{const{coordinate:n}=e;return(r,i,a)=>{const{color:o,text:s="",fontSize:c,rotate:l=0,transform:u=""}=i,f={text:String(s),stroke:o,fill:o,fontSize:c},[[d,h]]=r;return st(new LS).style("x",d).style("y",h).call(at,a).style("transform",`${u}rotate(${+l})`).style("coordCenter",n.getCenter()).call(at,f).call(at,t).node()}};NS.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var yh=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const e=t.attributes,n=yh(e,["class","x","y"]),r=Q(n,"marker"),{size:i=24}=r,a=()=>Vj(i/2),o=st(t).maybeAppend("marker",()=>new Bt({})).call(l=>l.node().update(Object.assign({symbol:a},r))).node(),[s,c]=Xj(o);st(t).maybeAppend("text","text").style("x",s).style("y",c).call(at,n)}),RS=(t,e)=>{const n=yh(t,[]);return(r,i,a)=>{const{color:o}=a,s=yh(a,["color"]),{color:c=o,text:l=""}=i,u={text:String(l),stroke:c,fill:c},[[f,d]]=r;return st(new Uj).call(at,s).style("x",f).style("y",d).call(at,u).call(at,n).node()}};RS.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var qj=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i!e(f)))a=!0;else{if(n.push(l),r.push(u),a&&o){a=!1;const[f,d]=o;i.push([f,l,d,u])}o=[l,u]}}return[n.concat(r),i]}const Fy=Fa(t=>{const{areaPath:e,connectPath:n,areaStyle:r,connectStyle:i}=t.attributes,a=t.ownerDocument;st(t).maybeAppend("connect-path",()=>a.createElement("path",{})).style("d",n).call(at,i),st(t).maybeAppend("area-path",()=>a.createElement("path",{})).style("d",e).call(at,r)}),Un=(t,e)=>{const{curve:n,gradient:r=!1,defined:i=l=>!Number.isNaN(l)&&l!==void 0&&l!==null,connect:a=!1}=t,o=qj(t,["curve","gradient","defined","connect"]),{coordinate:s,document:c}=e;return(l,u,f)=>{const{color:d}=f,{color:h=d,seriesColor:p,seriesX:v,seriesY:g}=u,y=qt(s),m=nO(s,u),b=r&&p?tO(p,v,g,r,void 0,y):h,x=Object.assign(Object.assign(Object.assign(Object.assign({},f),{stroke:b,fill:b}),m&&{transform:m}),o),[w,O]=Kj(l,i),S=Q(x,"connect"),_=!!O.length,M=E=>st(c.createElement("path",{})).style("d",E||"").call(at,x).node();if(Ht(s)){const E=P=>{const T=s.getCenter(),A=P.slice(0,P.length/2),k=P.slice(P.length/2);return OL().angle((C,L)=>ja(se(A[L],T))).outerRadius((C,L)=>Jt(A[L],T)).innerRadius((C,L)=>Jt(k[L],T)).defined((C,L)=>[...A[L],...k[L]].every(i)).curve(n)(k)};return!_||a&&!Object.keys(S).length?M(E(w)):_&&!a?M(E(l)):st(new Fy).style("areaStyle",x).style("connectStyle",Object.assign(Object.assign({},S),o)).style("areaPath",E(l)).style("connectPath",O.map(E).join("")).node()}else{const E=P=>{const T=P.slice(0,P.length/2),A=P.slice(P.length/2);return y?Vd().y((k,C)=>T[C][1]).x1((k,C)=>T[C][0]).x0((k,C)=>A[C][0]).defined((k,C)=>[...T[C],...A[C]].every(i)).curve(n)(T):Vd().x((k,C)=>T[C][0]).y1((k,C)=>T[C][1]).y0((k,C)=>A[C][1]).defined((k,C)=>[...T[C],...A[C]].every(i)).curve(n)(T)};return!_||a&&!Object.keys(S).length?M(E(w)):_&&!a?M(E(l)):st(new Fy).style("areaStyle",x).style("connectStyle",Object.assign(Object.assign({},S),o)).style("areaPath",E(l)).style("connectPath",O.map(E).join("")).node()}}};Un.props={defaultMarker:"smooth",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const IS=(t,e)=>{const{coordinate:n}=e;return(...r)=>{const i=Ht(n)?jp:Ys;return Un(Object.assign({curve:i},t),e)(...r)}};IS.props=Object.assign(Object.assign({},Un.props),{defaultMarker:"square"});var Zj=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const n=Zj(t,[]),{coordinate:r}=e;return(...i)=>{const a=Ht(r)?ew:qt(r)?ow:aw;return Un(Object.assign({curve:a},n),e)(...i)}};jS.props=Object.assign(Object.assign({},Un.props),{defaultMarker:"smooth"});const DS=(t,e)=>(...n)=>Un(Object.assign({curve:sw},t),e)(...n);DS.props=Object.assign(Object.assign({},Un.props),{defaultMarker:"hvh"});const $S=(t,e)=>(...n)=>Un(Object.assign({curve:cw},t),e)(...n);$S.props=Object.assign(Object.assign({},Un.props),{defaultMarker:"vh"});const BS=(t,e)=>(...n)=>Un(Object.assign({curve:lw},t),e)(...n);BS.props=Object.assign(Object.assign({},Un.props),{defaultMarker:"hv"});const FS=(t,e)=>{const{arrow:n=!1}=t;return(...r)=>u0(Object.assign(Object.assign({},t),{arrow:n}),e)(...r)};FS.props={defaultMarker:"line",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var zy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const n=zy(t,[]),{document:r}=e;return(i,a,o)=>{const{color:s}=o,c=zy(o,["color"]),{color:l=s,transform:u}=a,[f,d]=i,h=jn();return h.moveTo(f[0],f[1]),h.bezierCurveTo(f[0]/2+d[0]/2,f[1],f[0]/2+d[0]/2,d[1],d[0],d[1]),st(r.createElement("path",{})).call(at,c).style("d",h.toString()).style("stroke",l).style("transform",u).call(at,n).node()}};zS.props={defaultMarker:"smooth",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var Gy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{cornerRatio:n=1/3}=t,r=Gy(t,["cornerRatio"]),{coordinate:i,document:a}=e;return(o,s,c)=>{const{defaultColor:l}=c,u=Gy(c,["defaultColor"]),{color:f=l,transform:d}=s,[h,p]=o,v=Qj(h,p,i,n);return st(a.createElement("path",{})).call(at,u).style("d",v.toString()).style("stroke",f).style("transform",d).call(at,r).node()}};GS.props={defaultMarker:"vhv",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var Yy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const n=Yy(t,[]),{coordinate:r,document:i}=e;return(a,o,s)=>{const{color:c}=s,l=Yy(s,["color"]),{color:u=c,transform:f}=o,[d,h]=a,p=jn();if(p.moveTo(d[0],d[1]),Ht(r)){const v=r.getCenter();p.quadraticCurveTo(v[0],v[1],h[0],h[1])}else{const v=F2(d,h),g=Jt(d,h)/2;vs(p,d,h,v,g)}return st(i.createElement("path",{})).call(at,l).style("d",p.toString()).style("stroke",u).style("transform",f).call(at,n).node()}};YS.props={defaultMarker:"smooth",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};function WS(t={}){const{shapes:e}=t;return[{name:"color"},{name:"opacity"},{name:"shape",range:e},{name:"enterType"},{name:"enterDelay",scaleKey:"enter"},{name:"enterDuration",scaleKey:"enter"},{name:"enterEasing"},{name:"key",scale:"identity"},{name:"groupKey",scale:"identity"},{name:"label",scale:"identity"}]}function Ue(t={}){return[...WS(t),{name:"title",scale:"identity"}]}function ui(){return[{type:wu,channel:"color"},{type:Su,channel:["x","y"]}]}function io(){return[{type:wu,channel:"x"},{type:Su,channel:["y"]}]}function Jj(){return[{type:wu,channel:"color"},{type:Su,channel:["position"]}]}function ao(t={}){return WS(t)}function pe(){return[{type:Mx}]}function ge(){return[]}function Qf(t,e){return t.getBandWidth(t.invert(e))}function ta(t,e,n={}){const{x:r,y:i,series:a}=e,{x:o,y:s,series:c}=t,{style:{bandOffset:l=c?0:.5,bandOffsetX:u=l,bandOffsetY:f=l}={}}=n,d=!!(o!=null&&o.getBandWidth),h=!!(s!=null&&s.getBandWidth),p=!!(c!=null&&c.getBandWidth);return!d&&!h?v=>v:(v,g)=>{const y=d?Qf(o,r[g]):0,m=h?Qf(s,i[g]):0,x=p&&a?(Qf(c,a[g])/2+ +a[g])*y:0,[w,O]=v;return[w+u*y+x,O+f*m]}}function zl(t){return parseFloat(t)/100}function w0(t,e,n,r){const{x:i,y:a}=n,{innerWidth:o,innerHeight:s}=r.getOptions(),c=Array.from(t,l=>{const u=i[l],f=a[l],d=typeof u=="string"?zl(u)*o:+u,h=typeof f=="string"?zl(f)*s:+f;return[[d,h]]});return[t,c]}function cr(t){return typeof t=="function"?t:e=>e[t]}function Jf(t,e){return Array.from(t,cr(e))}function O0(t,e){const{source:n=u=>u.source,target:r=u=>u.target,value:i=u=>u.value}=e,{links:a,nodes:o}=t,s=Jf(a,n),c=Jf(a,r),l=Jf(a,i);return{links:a.map((u,f)=>({target:c[f],source:s[f],value:l[f]})),nodes:o||Array.from(new Set([...s,...c]),u=>({key:u}))}}var t9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{coordinate:n,document:r}=e;return(i,a,o)=>{const{color:s}=o,c=t9(o,["color"]),{color:l=s,src:u="",size:f=32,transform:d=""}=a;let{width:h=f,height:p=f}=t;const[[v,g]]=i,[y,m]=n.getSize();h=typeof h=="string"?zl(h)*y:h,p=typeof p=="string"?zl(p)*m:p;const b=v-Number(h)/2,x=g-Number(p)/2;return st(r.createElement("image",{})).call(at,c).style("x",b).style("y",x).style("img",u).style("stroke",l).style("transform",d).call(at,t).style("width",h).style("height",p).node()}};HS.props={defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var e9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);iJt(o,r));return i.forEach((o,s)=>{if(s===0){n.moveTo(o[0],o[1]);return}const c=a[s],l=t[s-1],u=a[s-1];u!==void 0&&Math.abs(c-u)<1e-10?vs(n,l,o,r,c):n.lineTo(o[0],o[1])}),n.closePath(),n}return W6(n,t)}const VS=(t,e)=>{const{coordinate:n,document:r}=e;return(i,a,o)=>{const{color:s}=o,c=e9(o,["color"]),{color:l=s,transform:u}=a,f=n9(i,n);return st(r.createElement("path",{})).call(at,c).style("d",f.toString()).style("stroke",l).style("fill",l).style("transform",u).call(at,t).node()}};VS.props={defaultMarker:"square",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var Wy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const n=Wy(t,[]),{coordinate:r,document:i}=e;return(a,o,s)=>{const{color:c}=s,l=Wy(s,["color"]),{color:u=c,transform:f}=o,d=r9(a,r);return st(i.createElement("path",{})).call(at,l).style("d",d.toString()).style("fill",u||c).style("stroke",u||c).style("transform",f).call(at,n).node()}};XS.props={defaultMarker:"square",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var i9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{coordinate:n,document:r}=e;return(i,a,o)=>{const{color:s,transform:c}=a,{color:l,fill:u=l,stroke:f=l}=o,d=i9(o,["color","fill","stroke"]),h=a9(i,n);return st(r.createElement("path",{})).call(at,d).style("d",h.toString()).style("stroke",f).style("fill",s||u).style("transform",c).call(at,t).node()}};US.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var o9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{coordinate:n,document:r}=e;return(i,a,o)=>{const{color:s,transform:c}=a,l=4,{color:u,fill:f=u,stroke:d=u}=o,h=o9(o,["color","fill","stroke"]),p=s9(i,n,l);return st(r.createElement("path",{})).call(at,h).style("d",p.toString()).style("stroke",d).style("fill",s||f).style("transform",c).call(at,t).node()}};qS.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var Hy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ir[0]).y(r=>r[1])(t);const n=e.getCenter();return Cu()({startAngle:0,endAngle:Math.PI*2,outerRadius:Jt(t[0],n),innerRadius:Jt(t[1],n)})}function u9(t,e){if(!Ht(t))return e;const[n,r]=t.getCenter();return`translate(${n}, ${r}) ${e||""}`}const S0=(t,e)=>{const{arrow:n,arrowSize:r=4}=t,i=Hy(t,["arrow","arrowSize"]),{coordinate:a,document:o}=e;return(s,c,l)=>{const{color:u,lineWidth:f}=l,d=Hy(l,["color","lineWidth"]),{color:h=u,size:p=f}=c,v=n?c9(o,r,Object.assign({fill:i.stroke||h,stroke:i.stroke||h},Q(i,"arrow"))):null,g=l9(s,a),y=u9(a,c.transform);return st(o.createElement("path",{})).call(at,d).style("d",g).style("stroke",h).style("lineWidth",p).style("transform",y).style("markerEnd",v).call(at,i).node()}};S0.props={defaultMarker:"line",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var Vy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ie[0]).y(e=>e[1])(t)}function h9(t,e,n,r,i=0){const[[a,o],[s,c]]=e;if(qt(t)){const d=a+n,h=s+r,p=d+i;return[[d,o],[p,o],[p,c],[h,c]]}const l=o-n,u=c-r,f=l-i;return[[a,l],[a,f],[s,f],[s,u]]}const KS=(t,e)=>{const{offset:n=0,offset1:r=n,offset2:i=n,connectLength1:a,endMarker:o=!0}=t,s=Vy(t,["offset","offset1","offset2","connectLength1","endMarker"]),{coordinate:c}=e;return(l,u,f)=>{const{color:d,connectLength1:h}=f,p=Vy(f,["color","connectLength1"]),{color:v,transform:g}=u,y=h9(c,l,r,i,a??h),m=Q(Object.assign(Object.assign({},s),f),"endMarker");return st(new Xe).call(at,p).style("path",d9(y)).style("stroke",v||d).style("transform",g).style("markerEnd",o?new Bt({className:"marker",style:Object.assign(Object.assign({},m),{symbol:f9})}):null).call(at,s).node()}};KS.props={defaultMarker:"line",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};function ZS(t){return t.replace(/-(\w)/g,function(e,n){return n.toUpperCase()})}function p9(t){return t.replace(/([A-Z])/g,"-$1").toLowerCase()}function v9(t,e,n,r){const i=e.length/2,a=e.slice(0,i),o=e.slice(i);let s=to(a,(h,p)=>Math.abs(h[1]-o[p][1]));s=Math.max(Math.min(s,i-2),1);const c=h=>[a[h][0],(a[h][1]+o[h][1])/2],l=c(s),u=c(s-1),f=c(s+1),d=Nn(se(f,u))/Math.PI*180;return{x:l[0],y:l[1],transform:`rotate(${d})`,textAlign:"center",textBaseline:"middle"}}function QS(t,e,n,r){const{bounds:i}=n,[[a,o],[s,c]]=i,l=s-a,u=c-o,f=d=>{const{x:h,y:p}=d,v=ag(n.x,l),g=ag(n.y,u);return Object.assign(Object.assign({},d),{x:(v||h)+a,y:(g||p)+o})};return f(t==="left"?{x:0,y:u/2,textAnchor:"start",textBaseline:"middle"}:t==="right"?{x:l,y:u/2,textAnchor:"end",textBaseline:"middle"}:t==="top"?{x:l/2,y:0,textAnchor:"center",textBaseline:"top"}:t==="bottom"?{x:l/2,y:u,textAnchor:"center",textBaseline:"bottom"}:t==="top-left"?{x:0,y:0,textAnchor:"start",textBaseline:"top"}:t==="top-right"?{x:l,y:0,textAnchor:"end",textBaseline:"top"}:t==="bottom-left"?{x:0,y:u,textAnchor:"start",textBaseline:"bottom"}:t==="bottom-right"?{x:l,y:u,textAnchor:"end",textBaseline:"bottom"}:{x:l/2,y:u/2,textAnchor:"center",textBaseline:"middle"})}function JS(t,e,n,r){const{y:i,y1:a,autoRotate:o,rotateToAlignArc:s}=n,c=r.getCenter(),l=Qi(r,e,[i,a]),{innerRadius:u,outerRadius:f,startAngle:d,endAngle:h}=l,p=t==="inside"?(d+h)/2:h,v=_0(p,o,s),g=(()=>{const[y,m]=e,b=u+(f-u)*.5,[x,w]=t==="inside"?bs(c,p,b):F2(y,m);return{x,y:w}})();return Object.assign(Object.assign({},g),{textAlign:t==="inside"?"center":"start",textBaseline:"middle",rotate:v})}function bs(t,e,n){return[t[0]+Math.sin(e)*n,t[1]-Math.cos(e)*n]}function _0(t,e,n){if(!e)return 0;const r=n?0:Math.sin(t)<0?90:-90;return t/Math.PI*180+r}function g9(t,e,n,r){const{y:i,y1:a,autoRotate:o,rotateToAlignArc:s,radius:c=.5,offset:l=0}=n,u=Qi(r,e,[i,a]),{startAngle:f,endAngle:d}=u,h=r.getCenter(),p=(f+d)/2,g={textAlign:"center",textBaseline:"middle",rotate:_0(p,o,s)},{innerRadius:y,outerRadius:m}=u,x=y+(m-y)*c+l,[w,O]=bs(h,p,x);return Object.assign({x:w,y:O},g)}function Xy(t){return t===void 0?null:t}function t_(t,e,n,r){const{bounds:i}=n,[a]=i;return{x:Xy(a[0]),y:Xy(a[1])}}function yr(t,e,n,r){const{bounds:i}=n;return i.length===1?t_(t,e,n):(Nu(r)?JS:eo(r)?g9:QS)(t,e,n,r)}function y9(t,e,n,r,i){const[a,o]=bs(t,e,n),[s,c]=bs(t,e,r),l=Math.sin(e)>0?1:-1;return[[a,o],[s,c],[s+l*i,c]]}function e_(t,e,n){const r=Qi(n,t,[e.y,e.y1]),{innerRadius:i,outerRadius:a}=r;return i+(a-i)}function n_(t,e,n){const r=Qi(n,t,[e.y,e.y1]),{startAngle:i,endAngle:a}=r;return(i+a)/2}function M0(t,e,n,r){const{autoRotate:i,rotateToAlignArc:a,offset:o=0,connector:s=!0,connectorLength:c=o,connectorLength2:l=0,connectorDistance:u=0}=n,f=r.getCenter(),d=n_(e,n,r),h=Math.sin(d)>0?1:-1,p=_0(d,i,a),v={textAlign:h>0||Nu(r)?"start":"end",textBaseline:"middle",rotate:p},g=e_(e,n,r),y=g+(s?c:o),[[m,b],[x,w],[O,S]]=y9(f,d,g,y,s?l:0),_=s?+u*h:0,M=O+_,E=S,P={connector:s,connectorPoints:[[x-M,w-E],[O-M,S-E]]};return Object.assign(Object.assign({x0:m,y0:b,x:O+_,y:S},v),P)}function m9(t,e,n,r){const{bounds:i}=n;return i.length===1?t_(t,e,n):(Nu(r)?JS:eo(r)?M0:QS)(t,e,n,r)}var b9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i0?1:-1,h=c[0]+(f+ +o)*d,{x:p}=s,v=h-p;return s.x+=v,s.connectorPoints[0][0]-=v,s}var w9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i0?1:-1,[v,g]=bs(u,h,d);return s.x=v+(a+o)*p,s.y=g,s}const S9=Object.freeze(Object.defineProperty({__proto__:null,area:v9,bottom:yr,bottomLeft:yr,bottomRight:yr,inside:yr,left:yr,outside:m9,right:yr,spider:x9,surround:O9,top:yr,topLeft:yr,topRight:yr},Symbol.toStringTag,{value:"Module"}));var Uy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{coordinate:n,theme:r}=e,{render:i}=t;return(a,o)=>{const{text:s,x:c,y:l,transform:u="",transformOrigin:f,className:d=""}=o,h=Uy(o,["text","x","y","transform","transformOrigin","className"]),p=M9(a,o,n,r,t),{rotate:v=0,transform:g=""}=p,y=Uy(p,["rotate","transform"]);return st(new LS).call(at,y).style("text",`${s}`).style("className",`${d} g2-label`).style("innerHTML",i?i(s,o.datum,o.index):void 0).style("labelTransform",`${g} rotate(${+v}) ${u}`.trim()).style("labelTransformOrigin",f).style("coordCenter",n.getCenter()).call(at,h).node()}};r_.props={defaultMarker:"point"};var qy=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{arrow:n,colorAttribute:r}=t,i=qy(t,["arrow","colorAttribute"]),{coordinate:a,document:o}=e;return(s,c,l)=>{const{color:u,stroke:f}=l,d=qy(l,["color","stroke"]),{d:h,color:p=u}=c,[v,g]=a.getSize();return st(o.createElement("path",{})).call(at,d).style("d",typeof h=="function"?h({width:v,height:g}):h).style(r,p).call(at,i).node()}};E0.props={defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const i_=(t,e)=>E0(Object.assign({colorAttribute:"fill"},t),e);i_.props={defaultMarker:"hvh",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const a_=(t,e)=>E0(Object.assign({fill:"none",colorAttribute:"stroke"},t),e);a_.props={defaultMarker:"hvh",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var E9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{document:n}=e;return(r,i,a)=>{const{transform:o}=i,{color:s}=a,c=E9(a,["color"]),{color:l=s}=i,[u,...f]=r,d=jn();return d.moveTo(...u),f.forEach(([h,p])=>{d.lineTo(h,p)}),d.closePath(),st(n.createElement("path",{})).call(at,c).style("d",d.toString()).style("stroke",l||s).style("fill",l||s).style("fillOpacity",.4).style("transform",o).call(at,t).node()}};o_.props={defaultMarker:"square",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};function s_(t){var e,n,r,i=t||1;function a(s,c){++e>i&&(r=n,o(1),++e),n[s]=c}function o(s){e=0,n=Object.create(null),s||(r=Object.create(null))}return o(),{clear:o,has:function(s){return n[s]!==void 0||r[s]!==void 0},get:function(s){var c=n[s];if(c!==void 0)return c;if((c=r[s])!==void 0)return a(s,c),c},set:function(s,c){n[s]!==void 0?n[s]=c:a(s,c)}}}s_(3);function P9(t,e=(...r)=>`${r[0]}`,n=16){const r=s_(n);return(...i)=>{const a=e(...i);let o=r.get(a);return r.has(a)?r.get(a):(o=t(...i),r.set(a,o),o)}}function A9(t){return typeof t=="string"?t.split(" ").map(e=>{const[n,r]=e.split(":");return[+n,r]}):t}function Gl(t,e,n){const r=t?t():document.createElement("canvas");return r.width=e,r.height=n,r}const k9=P9((t,e,n)=>{const r=Gl(n,t*2,t*2),i=r.getContext("2d"),a=t,o=t;if(e===1)i.beginPath(),i.arc(a,o,t,0,2*Math.PI,!1),i.fillStyle="rgba(0,0,0,1)",i.fill();else{const s=i.createRadialGradient(a,o,t*e,a,o,t);s.addColorStop(0,"rgba(0,0,0,1)"),s.addColorStop(1,"rgba(0,0,0,0)"),i.fillStyle=s,i.fillRect(0,0,2*t,2*t)}return r},t=>`${t}`);function T9(t,e){const r=Gl(e,256,1).getContext("2d"),i=r.createLinearGradient(0,0,256,1);return A9(t).forEach(([a,o])=>{i.addColorStop(a,o)}),r.fillStyle=i,r.fillRect(0,0,256,1),r.getImageData(0,0,256,1).data}function C9(t,e,n,r,i,a){const{blur:o}=i;let s=r.length;for(;s--;){const{x:c,y:l,value:u,radius:f}=r[s],d=Math.min(u,n),h=c-f,p=l-f,v=k9(f,1-o,a),g=(d-e)/(n-e);t.globalAlpha=Math.max(g,.001),t.drawImage(v,h,p)}return t}function L9(t,e,n,r,i){const{minOpacity:a,opacity:o,maxOpacity:s,useGradientOpacity:c}=i,l=0,u=0,f=e,d=n,h=t.getImageData(l,u,f,d),p=h.data,v=p.length;for(let g=3;g{const i=t[r];return e(i,r)||(n[r]=i),n},{})}const c_=(t,e)=>{const{gradient:n,opacity:r,maxOpacity:i,minOpacity:a,blur:o,useGradientOpacity:s}=t,c=R9(t,["gradient","opacity","maxOpacity","minOpacity","blur","useGradientOpacity"]),{coordinate:l,createCanvas:u,document:f}=e;return(d,h,p)=>{const{transform:v}=h,[g,y]=l.getSize(),m=d.map(S=>({x:S[0],y:S[1],value:S[2],radius:S[3]})),b=bn(d,S=>S[2]),x=Ct(d,S=>S[2]),O=g&&y?N9(g,y,b,x,m,I9({gradient:n,opacity:r,minOpacity:a,maxOpacity:i,blur:o,useGradientOpacity:s},S=>S===void 0),u):{canvas:null};return st(f.createElement("image",{})).call(at,p).style("x",0).style("y",0).style("width",g).style("height",y).style("src",O.canvas).style("transform",v).call(at,c).node()}};c_.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};var j9=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{render:n}=t,r=j9(t,["render"]);return i=>{const[[a,o]]=i;return n(Object.assign(Object.assign({},r),{x:a,y:o}),e)}};l_.props={defaultMarker:"point",defaultEnterAnimation:"fadeIn",defaultUpdateAnimation:"morphing",defaultExitAnimation:"fadeOut"};const Ky=5e3;function Zy(t,e,n){return t+(e-t)*n}function D9(t,e,n,r){return e===0?[[t+1/2*n/Math.PI/2,r/2],[t+1/2*n/Math.PI,r],[t+n/4,r]]:e===1?[[t+1/2*n/Math.PI/2*(Math.PI-2),r],[t+1/2*n/Math.PI/2*(Math.PI-1),r/2],[t+n/4,0]]:e===2?[[t+1/2*n/Math.PI/2,-r/2],[t+1/2*n/Math.PI,-r],[t+n/4,-r]]:[[t+1/2*n/Math.PI/2*(Math.PI-2),-r],[t+1/2*n/Math.PI/2*(Math.PI-1),-r/2],[t+n/4,0]]}function $9(t,e,n,r,i,a,o){const s=Math.ceil(2*t/n*4)*4,c=[];let l=r;for(;l<-Math.PI*2;)l+=Math.PI*2;for(;l>0;)l-=Math.PI*2;l=l/Math.PI/2*n;const u=a-t+l-t*2;c.push(["M",u,e]);let f=0;for(let d=0;dQy[t]||Qy.circle,u_=(t,e)=>{if(!e)return;const{coordinate:n}=e,{liquidOptions:r,styleOptions:i}=t,{liquidShape:a,percent:o}=r,{background:s,outline:c={},wave:l={}}=i,u=Jy(i,["background","outline","wave"]),{border:f=2,distance:d=0}=c,h=Jy(c,["border","distance"]),{length:p=192,count:v=3}=l;return(g,y,m)=>{const{document:b}=e.canvas,{color:x,fillOpacity:w}=m,O=Object.assign(Object.assign({fill:x},m),u),S=b.createElement("g",{}),[_,M]=n.getCenter(),E=n.getSize(),P=Math.min(...E)/2,A=(Ve(a)?a:H9(a))(_,M,P,...E);if(Object.keys(s).length){const L=b.createElement("path",{style:Object.assign({path:A,fill:"#fff"},s)});S.appendChild(L)}if(o>0){const L=b.createElement("path",{style:{path:A}});S.appendChild(L),S.style.clipPath=L,B9(_,M,1-o,v,O,S,L.getBBox().y,P*2,p,!0,b)}const k=b.createElement("path",{style:{path:A,fill:"transparent",lineWidth:f+2*d,stroke:"#fff"}}),C=b.createElement("path",{style:Object.assign(Object.assign(Object.assign({path:A,stroke:x,strokeOpacity:w,lineWidth:f},O),h),{fill:"transparent"})});return S.appendChild(k),S.appendChild(C),S}};u_.props={};function tm(t,e){return t.getBandWidth(t.invert(e))}const em={rect:Ji,hollow:Yu,funnel:n0,pyramid:aO},f_=()=>(t,e,n,r)=>{const{x:i,y:a,y1:o,series:s,size:c}=n,l=e.x,u=e.series,[f]=r.getSize(),d=c?c.map(v=>+v/f):null,h=c?(v,g,y)=>{const m=v+g/2,b=d[y];return[m-b/2,m+b/2]}:(v,g,y)=>[v,v+g],p=Array.from(t,v=>{const g=tm(l,i[v]),y=u?tm(u,s==null?void 0:s[v]):1,m=g*y,b=(+(s==null?void 0:s[v])||0)*g,x=+i[v]+b,[w,O]=h(x,m,v),S=+a[v],_=+o[v];return[[w,S],[O,S],[O,_],[w,_]].map(A=>r.map(A))});return[t,p]};f_.props={defaultShape:"rect",defaultLabelShape:"label",composite:!1,shape:em,channels:[...Ue({shapes:Object.keys(em)}),{name:"x",scale:"band",required:!0},{name:"y",required:!0},{name:"series",scale:"band"},{name:"size"}],preInference:[...pe(),{type:js},{type:qi}],postInference:[...ge(),...io()],interaction:{shareTooltip:!0}};const nm={rect:Ji,hollow:Yu},d_=()=>(t,e,n,r)=>{const{x:i,x1:a,y:o,y1:s}=n,c=Array.from(t,l=>{const u=[+i[l],+o[l]],f=[+a[l],+o[l]],d=[+a[l],+s[l]],h=[+i[l],+s[l]];return[u,f,d,h].map(p=>r.map(p))});return[t,c]};d_.props={defaultShape:"rect",defaultLabelShape:"label",composite:!1,shape:nm,channels:[...Ue({shapes:Object.keys(nm)}),{name:"x",required:!0},{name:"y",required:!0}],preInference:[...pe(),{type:js}],postInference:[...ge(),...io()],interaction:{shareTooltip:!0}};const rm={line:oO,smooth:sO,hv:cO,vh:lO,hvh:uO,trail:fO},V9=(t,e,n,r)=>{var i,a;const{series:o,x:s,y:c}=n,{x:l,y:u}=e;if(s===void 0||c===void 0)throw new Error("Missing encode for x or y channel.");const f=o?Array.from(te(t,g=>o[g]).values()):[t],d=f.map(g=>g[0]).filter(g=>g!==void 0),h=(((i=l==null?void 0:l.getBandWidth)===null||i===void 0?void 0:i.call(l))||0)/2,p=(((a=u==null?void 0:u.getBandWidth)===null||a===void 0?void 0:a.call(u))||0)/2,v=Array.from(f,g=>g.map(y=>r.map([+s[y]+h,+c[y]+p])));return[d,v,f]},X9=(t,e,n,r)=>{const i=Object.entries(n).filter(([o])=>o.startsWith("position")).map(([,o])=>o);if(i.length===0)throw new Error("Missing encode for position channel.");const a=Array.from(t,o=>{const s=i.map(u=>+u[o]),c=r.map(s),l=[];for(let u=0;u(t,e,n,r)=>(Ru(r)?X9:V9)(t,e,n,r);h_.props={defaultShape:"line",defaultLabelShape:"label",composite:!1,shape:rm,channels:[...Ue({shapes:Object.keys(rm)}),{name:"x"},{name:"y"},{name:"position",independent:!0},{name:"size"},{name:"series",scale:"band"}],preInference:[...pe(),{type:Nx},{type:wp}],postInference:[...ge(),...io(),...Jj()],interaction:{shareTooltip:!0,seriesTooltip:!0,crosshairs:!0}};const im={hollow:RO,hollowDiamond:LO,hollowHexagon:NO,hollowSquare:IO,hollowTriangleDown:DO,hollowTriangle:jO,hollowBowtie:CO,point:HO,plus:WO,diamond:FO,square:VO,triangle:UO,hexagon:zO,cross:BO,bowtie:$O,hyphen:GO,line:YO,tick:XO,triangleDown:qO},p_=t=>(e,n,r,i)=>{const{x:a,y:o,x1:s,y1:c,size:l,dx:u,dy:f}=r,[d,h]=i.getSize(),p=ta(n,r,t),v=y=>{const m=+((u==null?void 0:u[y])||0),b=+((f==null?void 0:f[y])||0),x=s?(+a[y]+ +s[y])/2:+a[y],w=c?(+o[y]+ +c[y])/2:+o[y],O=x+m,S=w+b;return[O,S]},g=l?Array.from(e,y=>{const[m,b]=v(y),x=+l[y],w=x/d,O=x/h,S=[m-w,b-O],_=[m+w,b+O];return[i.map(p(S,y)),i.map(p(_,y))]}):Array.from(e,y=>[i.map(p(v(y),y))]);return[e,g]};p_.props={defaultShape:"hollow",defaultLabelShape:"label",composite:!1,shape:im,channels:[...Ue({shapes:Object.keys(im)}),{name:"x",required:!0},{name:"y",required:!0},{name:"series",scale:"band"},{name:"size",quantitative:"sqrt"},{name:"dx",scale:"identity"},{name:"dy",scale:"identity"}],preInference:[...pe(),{type:qi},{type:Ou}],postInference:[...ge(),{type:_x},...ui()]};const am={text:NS,badge:RS},v_=t=>{const{cartesian:e=!1}=t;return e?w0:(n,r,i,a)=>{const{x:o,y:s}=i,c=ta(r,i,t),l=Array.from(n,u=>{const f=[+o[u],+s[u]];return[a.map(c(f,u))]});return[n,l]}};v_.props={defaultShape:"text",defaultLabelShape:"label",composite:!1,shape:am,channels:[...Ue({shapes:Object.keys(am)}),{name:"x",required:!0},{name:"y",required:!0},{name:"text",scale:"identity"},{name:"fontSize"},{name:"rotate"}],preInference:[...pe(),{type:Mu},{type:_u}],postInference:[...ge(),...ui()]};const om={cell:Ji,hollow:Yu},g_=()=>(t,e,n,r)=>{const{x:i,y:a}=n,o=e.x,s=e.y,c=Array.from(t,l=>{const u=o.getBandWidth(o.invert(+i[l])),f=s.getBandWidth(s.invert(+a[l])),d=+i[l],h=+a[l],p=[d,h],v=[d+u,h],g=[d+u,h+f],y=[d,h+f];return[p,v,g,y].map(m=>r.map(m))});return[t,c]};g_.props={defaultShape:"cell",defaultLabelShape:"label",shape:om,composite:!1,channels:[...Ue({shapes:Object.keys(om)}),{name:"x",required:!0,scale:"band"},{name:"y",required:!0,scale:"band"}],preInference:[...pe(),{type:qi},{type:Ou},{type:Op}],postInference:[...ge(),...ui()]};const sm={area:IS,smooth:jS,hvh:DS,vh:$S,hv:BS},y_=()=>(t,e,n,r)=>{var i,a;const{x:o,y:s,y1:c,series:l}=n,{x:u,y:f}=e,d=l?Array.from(te(t,y=>l[y]).values()):[t],h=d.map(y=>y[0]).filter(y=>y!==void 0),p=(((i=u==null?void 0:u.getBandWidth)===null||i===void 0?void 0:i.call(u))||0)/2,v=(((a=f==null?void 0:f.getBandWidth)===null||a===void 0?void 0:a.call(f))||0)/2,g=Array.from(d,y=>{const m=y.length,b=new Array(m*2);for(let x=0;x(e,n,r,i)=>{const{x:a,y:o,x1:s=a,y1:c=o}=r,l=ta(n,r,t),u=e.map(f=>[i.map(l([+a[f],+o[f]],f)),i.map(l([+s[f],+c[f]],f))]);return[e,u]};P0.props={defaultShape:"link",defaultLabelShape:"label",composite:!1,shape:cm,channels:[...Ue({shapes:Object.keys(cm)}),{name:"x",required:!0},{name:"y",required:!0}],preInference:[...pe(),{type:Ax},{type:kx}],postInference:[...ge(),...ui()]};const lm={image:HS},m_=t=>{const{cartesian:e}=t;return e?w0:(n,r,i,a)=>{const{x:o,y:s}=i,c=ta(r,i,t),l=Array.from(n,u=>{const f=[+o[u],+s[u]];return[a.map(c(f,u))]});return[n,l]}};m_.props={defaultShape:"image",defaultLabelShape:"label",composite:!1,shape:lm,channels:[...Ue({shapes:Object.keys(lm)}),{name:"x",required:!0},{name:"y",required:!0},{name:"src",scale:"identity"},{name:"size"}],preInference:[...pe(),{type:Mu},{type:_u}],postInference:[...ge(),...ui()]};const um={polygon:VS,ribbon:XS},b_=()=>(t,e,n,r)=>{const i=Object.entries(n).filter(([s])=>s.startsWith("x")).map(([,s])=>s),a=Object.entries(n).filter(([s])=>s.startsWith("y")).map(([,s])=>s),o=t.map(s=>{const c=[];for(let l=0;l(t,e,n,r)=>{const{x:i,y:a,y1:o,y2:s,y3:c,y4:l,series:u}=n,f=e.x,d=e.series,h=Array.from(t,p=>{const v=f.getBandWidth(f.invert(+i[p])),g=d?d.getBandWidth(d.invert(+(u==null?void 0:u[p]))):1,y=v*g,m=(+(u==null?void 0:u[p])||0)*v,b=+i[p]+m+y/2,[x,w,O,S,_]=[+a[p],+o[p],+s[p],+c[p],+l[p]];return[[b-y/2,_],[b+y/2,_],[b,_],[b,S],[b-y/2,S],[b+y/2,S],[b+y/2,w],[b-y/2,w],[b-y/2,O],[b+y/2,O],[b,w],[b,x],[b-y/2,x],[b+y/2,x]].map(E=>r.map(E))});return[t,h]};x_.props={defaultShape:"box",defaultLabelShape:"label",composite:!1,shape:fm,channels:[...Ue({shapes:Object.keys(fm)}),{name:"x",scale:"band",required:!0},{name:"y",required:!0},{name:"series",scale:"band"}],preInference:[...pe(),{type:qi}],postInference:[...ge(),...io()],interaction:{shareTooltip:!0}};const dm={vector:u0},w_=()=>(t,e,n,r)=>{const{x:i,y:a,size:o,rotate:s}=n,[c,l]=r.getSize(),u=t.map(f=>{const d=+s[f]/180*Math.PI,h=+o[f],p=h/c,v=h/l,g=p*Math.cos(d),y=-v*Math.sin(d);return[r.map([+i[f]-g/2,+a[f]-y/2]),r.map([+i[f]+g/2,+a[f]+y/2])]});return[t,u]};w_.props={defaultShape:"vector",defaultLabelShape:"label",composite:!1,shape:dm,channels:[...Ue({shapes:Object.keys(dm)}),{name:"x",required:!0},{name:"y",required:!0},{name:"rotate",required:!0,scale:"identity"},{name:"size",required:!0}],preInference:[...pe()],postInference:[...ge(),...ui()]};const hm={line:S0},O_=t=>(e,n,r,i)=>{const{y:a}=r,o=ta(n,r,X({style:{bandOffset:0}},t)),s=Array.from(e,c=>{const l=[0,a[c]],u=[1,a[c]];return[l,u].map(f=>i.map(o(f,c)))});return[e,s]};O_.props={defaultShape:"line",defaultLabelShape:"label",composite:!1,shape:hm,channels:[...ao({shapes:Object.keys(hm)}),{name:"y",required:!0}],preInference:[...pe(),{type:Ex}],postInference:[...ge()]};const pm={line:S0},S_=t=>(e,n,r,i)=>{const{x:a}=r,o=ta(n,r,X({style:{bandOffset:0}},t)),s=Array.from(e,c=>{const l=[a[c],1],u=[a[c],0];return[l,u].map(f=>i.map(o(f,c)))});return[e,s]};S_.props={defaultShape:"line",defaultLabelShape:"label",composite:!1,shape:pm,channels:[...ao({shapes:Object.keys(pm)}),{name:"x",required:!0}],preInference:[...pe(),{type:Px}],postInference:[...ge()]};const vm={connector:KS},__=(...t)=>P0(...t);__.props={defaultShape:"connector",defaultLabelShape:"label",composite:!1,shape:vm,channels:[...ao({shapes:Object.keys(vm)}),{name:"x",required:!0},{name:"y",required:!0}],preInference:[...pe()],postInference:[...ge()]};function gm(t,e,n,r){if(e)return()=>[0,1];const{[t]:i,[`${t}1`]:a}=n;return o=>{var s;const c=((s=r.getBandWidth)===null||s===void 0?void 0:s.call(r,r.invert(+a[o])))||0;return[i[o],a[o]+c]}}function A0(t={}){const{extendX:e=!1,extendY:n=!1}=t;return(r,i,a,o)=>{const s=gm("x",e,a,i.x),c=gm("y",n,a,i.y),l=Array.from(r,u=>{const[f,d]=s(u),[h,p]=c(u);return[[f,h],[d,h],[d,p],[f,p]].map(b=>o.map(b))});return[r,l]}}const ym={range:Ji},M_=()=>A0();M_.props={defaultShape:"range",defaultLabelShape:"label",composite:!1,shape:ym,channels:[...ao({shapes:Object.keys(ym)}),{name:"x",required:!0},{name:"y",required:!0}],preInference:[...pe()],postInference:[...ge()]};const mm={range:Ji},E_=()=>A0({extendY:!0});E_.props={defaultShape:"range",defaultLabelShape:"label",composite:!1,shape:mm,channels:[...ao({shapes:Object.keys(mm)}),{name:"x",required:!0}],preInference:[...pe(),{type:Tx}],postInference:[...ge()]};const bm={range:Ji},P_=()=>A0({extendX:!0});P_.props={defaultShape:"range",defaultLabelShape:"label",composite:!1,shape:bm,channels:[...ao({shapes:Object.keys(bm)}),{name:"y",required:!0}],preInference:[...pe(),{type:Cx}],postInference:[...ge()]};function U9(t){return t.target.depth}function q9(t){return t.depth}function K9(t,e){return e-1-t.height}function Yl(t,e){return t.sourceLinks.length?t.depth:e-1}function Z9(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?bn(t.sourceLinks,U9)-1:0}function Nc(t){return function(){return t}}function xm(t,e){return Wl(t.source,e.source)||t.index-e.index}function wm(t,e){return Wl(t.target,e.target)||t.index-e.index}function Wl(t,e){return t.y0-e.y0}function td(t){return t.value}function Q9(t){return t.index}function J9(t){return t.nodes}function tD(t){return t.links}function Om(t,e){const n=t.get(e);if(!n)throw new Error("missing: "+e);return n}function Sm({nodes:t}){for(const e of t){let n=e.y0,r=n;for(const i of e.sourceLinks)i.y0=n+i.width/2,n+=i.width;for(const i of e.targetLinks)i.y1=r+i.width/2,r+=i.width}}function eD(){let t=0,e=0,n=1,r=1,i=24,a=8,o,s=Q9,c=Yl,l,u,f,d=J9,h=tD,p=6;function v(L){const I={nodes:d(L),links:h(L)};return g(I),y(I),m(I),b(I),O(I),Sm(I),I}v.update=function(L){return Sm(L),L},v.nodeId=function(L){return arguments.length?(s=typeof L=="function"?L:Nc(L),v):s},v.nodeAlign=function(L){return arguments.length?(c=typeof L=="function"?L:Nc(L),v):c},v.nodeDepth=function(L){return arguments.length?(l=L,v):l},v.nodeSort=function(L){return arguments.length?(u=L,v):u},v.nodeWidth=function(L){return arguments.length?(i=+L,v):i},v.nodePadding=function(L){return arguments.length?(a=o=+L,v):a},v.nodes=function(L){return arguments.length?(d=typeof L=="function"?L:Nc(L),v):d},v.links=function(L){return arguments.length?(h=typeof L=="function"?L:Nc(L),v):h},v.linkSort=function(L){return arguments.length?(f=L,v):f},v.size=function(L){return arguments.length?(t=e=0,n=+L[0],r=+L[1],v):[n-t,r-e]},v.extent=function(L){return arguments.length?(t=+L[0][0],n=+L[1][0],e=+L[0][1],r=+L[1][1],v):[[t,e],[n,r]]},v.iterations=function(L){return arguments.length?(p=+L,v):p};function g({nodes:L,links:I}){L.forEach((j,D)=>{j.index=D,j.sourceLinks=[],j.targetLinks=[]});const R=new Map(L.map(j=>[s(j),j]));if(I.forEach((j,D)=>{j.index=D;let{source:$,target:B}=j;typeof $!="object"&&($=j.source=Om(R,$)),typeof B!="object"&&(B=j.target=Om(R,B)),$.sourceLinks.push(j),B.targetLinks.push(j)}),f!=null)for(const{sourceLinks:j,targetLinks:D}of L)j.sort(f),D.sort(f)}function y({nodes:L}){for(const I of L)I.value=I.fixedValue===void 0?Math.max(Cn(I.sourceLinks,td),Cn(I.targetLinks,td)):I.fixedValue}function m({nodes:L}){const I=L.length;let R=new Set(L),j=new Set,D=0;for(;R.size;){if(R.forEach($=>{$.depth=D;for(const{target:B}of $.sourceLinks)j.add(B)}),++D>I)throw new Error("circular link");R=j,j=new Set}if(l){const $=Math.max(Ct(L,F=>F.depth)+1,0);let B;for(let F=0;F{$.height=D;for(const{source:B}of $.targetLinks)j.add(B)}),++D>I)throw new Error("circular link");R=j,j=new Set}}function x({nodes:L}){const I=Math.max(Ct(L,D=>D.depth)+1,0),R=(n-t-i)/(I-1),j=new Array(I).fill(0).map(()=>[]);for(const D of L){const $=Math.max(0,Math.min(I-1,Math.floor(c.call(null,D,I))));D.layer=$,D.x0=t+$*R,D.x1=D.x0+i,j[$]?j[$].push(D):j[$]=[D]}if(u)for(const D of j)D.sort(u);return j}function w(L){const I=bn(L,R=>(r-e-(R.length-1)*o)/Cn(R,td));for(const R of L){let j=e;for(const D of R){D.y0=j,D.y1=j+D.value*I,j=D.y1+o;for(const $ of D.sourceLinks)$.width=$.value*I}j=(r-j+o)/(R.length+1);for(let D=0;DR.length)-1)),w(I);for(let R=0;R0))continue;const U=(F/Y-B.y0)*I;B.y0+=U,B.y1+=U,T(B)}u===void 0&&$.sort(Wl),$.length&&M($,R)}}function _(L,I,R){for(let j=L.length,D=j-2;D>=0;--D){const $=L[D];for(const B of $){let F=0,Y=0;for(const{target:K,value:V}of B.sourceLinks){const W=V*(K.layer-B.layer);F+=C(B,K)*W,Y+=W}if(!(Y>0))continue;const U=(F/Y-B.y0)*I;B.y0+=U,B.y1+=U,T(B)}u===void 0&&$.sort(Wl),$.length&&M($,R)}}function M(L,I){const R=L.length>>1,j=L[R];P(L,j.y0-o,R-1,I),E(L,j.y1+o,R+1,I),P(L,r,L.length-1,I),E(L,e,0,I)}function E(L,I,R,j){for(;R1e-6&&(D.y0+=$,D.y1+=$),I=D.y1+o}}function P(L,I,R,j){for(;R>=0;--R){const D=L[R],$=(D.y1-I)*j;$>1e-6&&(D.y0-=$,D.y1-=$),I=D.y0-o}}function T({sourceLinks:L,targetLinks:I}){if(f===void 0){for(const{source:{sourceLinks:R}}of I)R.sort(wm);for(const{target:{targetLinks:R}}of L)R.sort(xm)}}function A(L){if(f===void 0)for(const{sourceLinks:I,targetLinks:R}of L)I.sort(wm),R.sort(xm)}function k(L,I){let R=L.y0-(L.sourceLinks.length-1)*o/2;for(const{target:j,width:D}of L.sourceLinks){if(j===I)break;R+=D+o}for(const{source:j,width:D}of I.targetLinks){if(j===L)break;R-=D}return R}function C(L,I){let R=I.y0-(I.targetLinks.length-1)*o/2;for(const{source:j,width:D}of I.targetLinks){if(j===L)break;R+=D+o}for(const{target:j,width:D}of L.sourceLinks){if(j===I)break;R-=D}return R}return v}const nD={nodeAlign:"justify",nodeWidth:.008,nodePadding:.03,nodes:t=>t.nodes,links:t=>t.links,nodeSort:void 0,linkSort:void 0,iterations:6},rD={left:q9,right:K9,center:Z9,justify:Yl};function iD(t){const e=typeof t;return e==="string"?rD[t]||Yl:e==="function"?t:Yl}const A_=t=>e=>{const{nodeId:n,nodeSort:r,nodeAlign:i,nodeWidth:a,nodePadding:o,nodeDepth:s,nodes:c,links:l,linkSort:u,iterations:f}=Object.assign({},nD,t),d=eD().nodeSort(r).linkSort(u).links(l).nodes(c).nodeWidth(a).nodePadding(o).nodeDepth(s).nodeAlign(iD(i)).iterations(f).extent([[0,0],[1,1]]);typeof n=="function"&&d.nodeId(n);const h=d(e),{nodes:p,links:v}=h,g=p.map(m=>{const{x0:b,x1:x,y0:w,y1:O}=m;return Object.assign(Object.assign({},m),{x:[b,x,x,b],y:[w,w,O,O]})}),y=v.map(m=>{const{source:b,target:x}=m,w=b.x1,O=x.x0,S=m.width/2;return Object.assign(Object.assign({},m),{x:[w,w,O,O],y:[m.y0+S,m.y0-S,m.y1+S,m.y1-S]})});return{nodes:g,links:y}};A_.props={};function fr(t,e,n={},r=!1){if(Lr(t)||Array.isArray(t)&&r)return t;const i=Q(t,e);return X(n,i)}function Hl(t,e={}){return Lr(t)||Array.isArray(t)||!k_(t)?t:X(e,t)}function k_(t){if(Object.keys(t).length===0)return!0;const{title:e,items:n}=t;return e!==void 0||n!==void 0}function dr(t,e){return typeof t=="object"?Q(t,e):t}var aD=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);it.key,nodeWidth:.02,nodePadding:.02},sD={type:"polygon",axis:!1,legend:!1,encode:{shape:"polygon",x:"x",y:"y"},scale:{x:{type:"identity"},y:{type:"identity"}},style:{stroke:"#000"}},cD={type:"polygon",axis:!1,legend:!1,encode:{shape:"ribbon",x:"x",y:"y"},style:{fillOpacity:.5,stroke:void 0}},lD={textAlign:t=>t.x[0]<.5?"start":"end",position:t=>t.x[0]<.5?"right":"left",fontSize:10},T_=t=>{const{data:e,encode:n={},scale:r,style:i={},layout:a={},nodeLabels:o=[],linkLabels:s=[],animate:c={},tooltip:l={}}=t,{links:u,nodes:f}=O0(e,n),d=Q(n,"node"),h=Q(n,"link"),{key:p=M=>M.key,color:v=p}=d,{links:g,nodes:y}=A_(Object.assign(Object.assign(Object.assign({},oD),{nodeId:cr(p)}),a))({links:u,nodes:f}),m=Q(i,"label"),{text:b=p,spacing:x=5}=m,w=aD(m,["text","spacing"]),O=cr(p),S=fr(l,"node",{title:O,items:[{field:"value"}]},!0),_=fr(l,"link",{title:"",items:[M=>({name:"source",value:O(M.source)}),M=>({name:"target",value:O(M.target)})]});return[X({},sD,{data:y,encode:Object.assign(Object.assign({},d),{color:v}),scale:r,style:Q(i,"node"),labels:[Object.assign(Object.assign(Object.assign({},lD),{text:b,dx:M=>M.x[0]<.5?x:-x}),w),...o],tooltip:S,animate:dr(c,"node"),axis:!1}),X({},cD,{data:g,encode:h,labels:s,style:Object.assign({fill:h.color?void 0:"#aaa",strokeWidth:0},Q(i,"link")),tooltip:_,animate:dr(c,"link")})]};T_.props={};function uD(t,e){return e.value-t.value}function fD(t,e){return e.frequency-t.frequency}function dD(t,e){return`${t.id}`.localeCompare(`${e.id}`)}function hD(t,e){return`${t.name}`.localeCompare(`${e.name}`)}const pD=Object.freeze(Object.defineProperty({__proto__:null,frequency:fD,id:dD,name:hD,weight:uD},Symbol.toStringTag,{value:"Module"})),vD={y:0,thickness:.05,weight:!1,marginRatio:.1,id:t=>t.id,source:t=>t.source,target:t=>t.target,sourceWeight:t=>t.value||1,targetWeight:t=>t.value||1,sortBy:null};function gD(t){const{y:e,thickness:n,weight:r,marginRatio:i,id:a,source:o,target:s,sourceWeight:c,targetWeight:l,sortBy:u}=Object.assign(Object.assign({},vD),t);function f(g){const y=g.nodes.map(b=>Object.assign({},b)),m=g.edges.map(b=>Object.assign({},b));return d(y,m),h(y),p(y,m),v(y,m),{nodes:y,edges:m}}function d(g,y){y.forEach(x=>{x.source=o(x),x.target=s(x),x.sourceWeight=c(x),x.targetWeight=l(x)});const m=te(y,x=>x.source),b=te(y,x=>x.target);return g.forEach(x=>{x.id=a(x);const w=m.has(x.id)?m.get(x.id):[],O=b.has(x.id)?b.get(x.id):[];x.frequency=w.length+O.length,x.value=Cn(w,S=>S.sourceWeight)+Cn(O,S=>S.targetWeight)}),{nodes:g,edges:y}}function h(g,y){const m=typeof u=="function"?u:pD[u];m&&g.sort(m)}function p(g,y){const m=g.length;if(!m)throw La("Invalid nodes: it's empty!");if(!r){const w=1/m;return g.forEach((O,S)=>{O.x=(S+.5)*w,O.y=e}),{nodes:g,edges:y}}const b=i/(2*m),x=g.reduce((w,O)=>w+=O.value,0);return g.reduce((w,O)=>{O.weight=O.value/x,O.width=O.weight*(1-i),O.height=n;const S=b+w,_=S+O.width,M=e-n/2,E=M+n;return O.x=[S,_,_,S],O.y=[M,M,E,E],w+O.width+2*b},0),{nodes:g,edges:y}}function v(g,y){const m=new Map(g.map(w=>[w.id,w]));if(!r)return y.forEach(w=>{const O=o(w),S=s(w),_=m.get(O),M=m.get(S);_&&M&&(w.x=[_.x,M.x],w.y=[_.y,M.y])}),{nodes:g,edges:y};y.forEach(w=>{w.x=[0,0,0,0],w.y=[e,e,e,e]});const b=te(y,w=>w.source),x=te(y,w=>w.target);g.forEach(w=>{const{edges:O,width:S,x:_,y:M,value:E,id:P}=w,T=b.get(P)||[],A=x.get(P)||[];let k=0;T.map(C=>{const L=C.sourceWeight/E*S;C.x[0]=_[0]+k,C.x[1]=_[0]+k+L,k+=L}),A.forEach(C=>{const L=C.targetWeight/E*S;C.x[3]=_[0]+k,C.x[2]=_[0]+k+L,k+=L})})}return f}const k0=t=>e=>gD(t)(e);k0.props={};var _m=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);it.key,source:t=>t.source,target:t=>t.target,sourceWeight:t=>t.value||1,targetWeight:t=>t.value||1,sortBy:null},yD={type:"polygon",axis:!1,legend:!1,encode:{shape:"polygon",x:"x",y:"y"},scale:{x:{type:"identity"},y:{type:"identity"}},style:{opacity:1,fillOpacity:1,lineWidth:1}},mD={type:"polygon",axis:!1,legend:!1,encode:{shape:"ribbon",x:"x",y:"y"},style:{opacity:.5,lineWidth:1,strokeWidth:1}},bD={position:"outside",fontSize:10},C_=(t,e)=>{const{data:n,encode:r={},scale:i,style:a={},layout:o={},nodeLabels:s=[],linkLabels:c=[],animate:l={},tooltip:u={}}=t,{nodes:f,links:d}=O0(n,r),h=Q(r,"node"),p=Q(r,"link"),{key:v=C=>C.key,color:g=v}=h,{linkEncodeColor:y=C=>C.source}=p,{nodeWidthRatio:m=ed.thickness,nodePaddingRatio:b=ed.marginRatio}=o,x=_m(o,["nodeWidthRatio","nodePaddingRatio"]),{nodes:w,edges:O}=k0(Object.assign(Object.assign(Object.assign(Object.assign({},ed),{id:cr(v),thickness:m,marginRatio:b}),x),{weight:!0}))({nodes:f,edges:d}),S=Q(a,"label"),{text:_=v}=S,M=_m(S,["text"]),E=fr(u,"node",{title:"",items:[C=>({name:C.key,value:C.value})]},!0),P=fr(u,"link",{title:"",items:[C=>({name:`${C.source} -> ${C.target}`,value:C.value})]}),{height:T,width:A}=e,k=Math.min(T,A);return[X({},mD,{data:O,encode:Object.assign(Object.assign({},p),{color:y}),labels:c,style:Object.assign({fill:y?void 0:"#aaa"},Q(a,"link")),tooltip:P,animate:dr(l,"link")}),X({},yD,{data:w,encode:Object.assign(Object.assign({},h),{color:g}),scale:i,style:Q(a,"node"),coordinate:{type:"polar",outerRadius:(k-20)/k,startAngle:-Math.PI*2,endAngle:0},labels:[Object.assign(Object.assign(Object.assign({},bD),{text:_}),M),...s],tooltip:E,animate:dr(l,"node"),axis:!1})]};C_.props={};const Mm={path:i_,hollow:a_},L_=t=>(e,n,r,i)=>[e,e.map(()=>[[0,0]])];L_.props={defaultShape:"path",defaultLabelShape:"label",shape:Mm,composite:!1,channels:[...Ue({shapes:Object.keys(Mm)}),{name:"d",scale:"identity"}],preInference:[...pe()],postInference:[...ge()]};function xD(t,e){return t.parent===e.parent?1:2}function wD(t){return t.reduce(OD,0)/t.length}function OD(t,e){return t+e.x}function SD(t){return 1+t.reduce(_D,0)}function _D(t,e){return Math.max(t,e.y)}function MD(t){for(var e;e=t.children;)t=e[0];return t}function ED(t){for(var e;e=t.children;)t=e[e.length-1];return t}function PD(){var t=xD,e=1,n=1,r=!1;function i(a){var o,s=0;a.eachAfter(function(d){var h=d.children;h?(d.x=wD(h),d.y=SD(h)):(d.x=o?s+=t(d,o):0,d.y=0,o=d)});var c=MD(a),l=ED(a),u=c.x-t(c,l)/2,f=l.x+t(l,c)/2;return a.eachAfter(r?function(d){d.x=(d.x-a.x)*e,d.y=(a.y-d.y)*n}:function(d){d.x=(d.x-u)/(f-u)*e,d.y=(1-(a.y?d.y/a.y:1))*n})}return i.separation=function(a){return arguments.length?(t=a,i):t},i.size=function(a){return arguments.length?(r=!1,e=+a[0],n=+a[1],i):r?null:[e,n]},i.nodeSize=function(a){return arguments.length?(r=!0,e=+a[0],n=+a[1],i):r?[e,n]:null},i}function AD(t){var e=0,n=t.children,r=n&&n.length;if(!r)e=1;else for(;--r>=0;)e+=n[r].value;t.value=e}function kD(){return this.eachAfter(AD)}function TD(t,e){let n=-1;for(const r of this)t.call(e,r,++n,this);return this}function CD(t,e){for(var n=this,r=[n],i,a,o=-1;n=r.pop();)if(t.call(e,n,++o,this),i=n.children)for(a=i.length-1;a>=0;--a)r.push(i[a]);return this}function LD(t,e){for(var n=this,r=[n],i=[],a,o,s,c=-1;n=r.pop();)if(i.push(n),a=n.children)for(o=0,s=a.length;o=0;)n+=r[i].value;e.value=n})}function ID(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}function jD(t){for(var e=this,n=DD(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r}function DD(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;for(t=n.pop(),e=r.pop();t===e;)i=t,t=n.pop(),e=r.pop();return i}function $D(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}function BD(){return Array.from(this)}function FD(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}function zD(){var t=this,e=[];return t.each(function(n){n!==t&&e.push({source:n.parent,target:n})}),e}function*GD(){var t=this,e,n=[t],r,i,a;do for(e=n.reverse(),n=[];t=e.pop();)if(yield t,r=t.children)for(i=0,a=r.length;i=0;--s)i.push(a=o[s]=new Ya(o[s])),a.parent=r,a.depth=r.depth+1;return n.eachBefore(N_)}function YD(){return Qs(this).eachBefore(VD)}function WD(t){return t.children}function HD(t){return Array.isArray(t)?t[1]:null}function VD(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function N_(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Ya(t){this.data=t,this.depth=this.height=0,this.parent=null}Ya.prototype=Qs.prototype={constructor:Ya,count:kD,each:TD,eachAfter:LD,eachBefore:CD,find:ND,sum:RD,sort:ID,path:jD,ancestors:$D,descendants:BD,leaves:FD,links:zD,copy:YD,[Symbol.iterator]:GD};function rl(t){return t==null?null:R_(t)}function R_(t){if(typeof t!="function")throw new Error;return t}function Mi(){return 0}function ua(t){return function(){return t}}const XD=1664525,UD=1013904223,Em=4294967296;function qD(){let t=1;return()=>(t=(XD*t+UD)%Em)/Em}function KD(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}function ZD(t,e){let n=t.length,r,i;for(;n;)i=e()*n--|0,r=t[n],t[n]=t[i],t[i]=r;return t}function QD(t,e){for(var n=0,r=(t=ZD(Array.from(t),e)).length,i=[],a,o;n0&&n*n>r*r+i*i}function nd(t,e){for(var n=0;n1e-6?(P+Math.sqrt(P*P-4*E*T))/(2*E):T/P);return{x:r+O+S*A,y:i+_+M*A,r:A}}function Pm(t,e,n){var r=t.x-e.x,i,a,o=t.y-e.y,s,c,l=r*r+o*o;l?(a=e.r+n.r,a*=a,c=t.r+n.r,c*=c,a>c?(i=(l+c-a)/(2*l),s=Math.sqrt(Math.max(0,c/l-i*i)),n.x=t.x-i*r-s*o,n.y=t.y-i*o+s*r):(i=(l+a-c)/(2*l),s=Math.sqrt(Math.max(0,a/l-i*i)),n.x=e.x+i*r-s*o,n.y=e.y+i*o+s*r)):(n.x=e.x+n.r,n.y=e.y)}function Am(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function km(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Ic(t){this._=t,this.next=null,this.previous=null}function n7(t,e){if(!(a=(t=KD(t)).length))return 0;var n,r,i,a,o,s,c,l,u,f,d;if(n=t[0],n.x=0,n.y=0,!(a>1))return n.r;if(r=t[1],n.x=-r.r,r.x=n.r,r.y=0,!(a>2))return n.r+r.r;Pm(r,n,i=t[2]),n=new Ic(n),r=new Ic(r),i=new Ic(i),n.next=i.previous=r,r.next=n.previous=i,i.next=r.previous=n;t:for(c=3;cl7(n(x,w,i))),m=y.map(Nm),b=new Set(y).add("");for(const x of m)b.has(x)||(b.add(x),y.push(x),m.push(Nm(x)),a.push(id));o=(x,w)=>y[w],s=(x,w)=>m[w]}for(u=0,c=a.length;u=0&&(h=a[y],h.data===id);--y)h.data=null}if(f.parent=o7,f.eachBefore(function(y){y.depth=y.parent.depth+1,--c}).eachBefore(N_),f.parent=null,c>0)throw new Error("cycle");return f}return r.id=function(i){return arguments.length?(t=rl(i),r):t},r.parentId=function(i){return arguments.length?(e=rl(i),r):e},r.path=function(i){return arguments.length?(n=rl(i),r):n},r}function l7(t){t=`${t}`;let e=t.length;return bh(t,e-1)&&!bh(t,e-2)&&(t=t.slice(0,-1)),t[0]==="/"?t:`/${t}`}function Nm(t){let e=t.length;if(e<2)return"";for(;--e>1&&!bh(t,e););return t.slice(0,e)}function bh(t,e){if(t[e]==="/"){let n=0;for(;e>0&&t[--e]==="\\";)++n;if(!(n&1))return!0}return!1}function u7(t,e){return t.parent===e.parent?1:2}function ad(t){var e=t.children;return e?e[0]:t.t}function od(t){var e=t.children;return e?e[e.length-1]:t.t}function f7(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function d7(t){for(var e=0,n=0,r=t.children,i=r.length,a;--i>=0;)a=r[i],a.z+=e,a.m+=e,e+=a.s+(n+=a.c)}function h7(t,e,n){return t.a.parent===e.parent?t.a:n}function il(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}il.prototype=Object.create(Ya.prototype);function p7(t){for(var e=new il(t,0),n,r=[e],i,a,o,s;n=r.pop();)if(a=n._.children)for(n.children=new Array(s=a.length),o=s-1;o>=0;--o)r.push(i=n.children[o]=new il(a[o],o)),i.parent=n;return(e.parent=new il(null,0)).children=[e],e}function v7(){var t=u7,e=1,n=1,r=null;function i(l){var u=p7(l);if(u.eachAfter(a),u.parent.m=-u.z,u.eachBefore(o),r)l.eachBefore(c);else{var f=l,d=l,h=l;l.eachBefore(function(m){m.xd.x&&(d=m),m.depth>h.depth&&(h=m)});var p=f===d?1:t(f,d)/2,v=p-f.x,g=e/(d.x+p+v),y=n/(h.depth||1);l.eachBefore(function(m){m.x=(m.x+v)*g,m.y=m.depth*y})}return l}function a(l){var u=l.children,f=l.parent.children,d=l.i?f[l.i-1]:null;if(u){d7(l);var h=(u[0].z+u[u.length-1].z)/2;d?(l.z=d.z+t(l._,d._),l.m=l.z-h):l.z=h}else d&&(l.z=d.z+t(l._,d._));l.parent.A=s(l,d,l.parent.A||f[0])}function o(l){l._.x=l.z+l.parent.m,l.m+=l.parent.m}function s(l,u,f){if(u){for(var d=l,h=l,p=u,v=d.parent.children[0],g=d.m,y=h.m,m=p.m,b=v.m,x;p=od(p),d=ad(d),p&&d;)v=ad(v),h=od(h),h.a=l,x=p.z+m-d.z-g+t(p._,d._),x>0&&(f7(h7(p,l,f),l,x),g+=x,y+=x),m+=p.m,g+=d.m,b+=v.m,y+=h.m;p&&!od(h)&&(h.t=p,h.m+=m-y),d&&!ad(v)&&(v.t=d,v.m+=g-b,f=l)}return f}function c(l){l.x*=e,l.y=l.depth*n}return i.separation=function(l){return arguments.length?(t=l,i):t},i.size=function(l){return arguments.length?(r=!1,e=+l[0],n=+l[1],i):r?null:[e,n]},i.nodeSize=function(l){return arguments.length?(r=!0,e=+l[0],n=+l[1],i):r?[e,n]:null},i}function Qu(t,e,n,r,i){for(var a=t.children,o,s=-1,c=a.length,l=t.value&&(i-n)/t.value;++sm&&(m=l),O=g*g*w,b=Math.max(m/O,O/y),b>x){g-=l;break}x=b}o.push(c={value:g,dice:h1?r:1)},n}(D_);function g7(){var t=B_,e=!1,n=1,r=1,i=[0],a=Mi,o=Mi,s=Mi,c=Mi,l=Mi;function u(d){return d.x0=d.y0=0,d.x1=n,d.y1=r,d.eachBefore(f),i=[0],e&&d.eachBefore(a7),d}function f(d){var h=i[d.depth],p=d.x0+h,v=d.y0+h,g=d.x1-h,y=d.y1-h;g=d-1){var m=a[f];m.x0=p,m.y0=v,m.x1=g,m.y1=y;return}for(var b=l[f],x=h/2+b,w=f+1,O=d-1;w>>1;l[S]y-v){var E=h?(p*M+g*_)/h:g;u(f,w,_,p,v,E,y),u(w,d,M,E,v,g,y)}else{var P=h?(v*M+y*_)/h:y;u(f,w,_,p,v,g,P),u(w,d,M,p,P,g,y)}}}function m7(t,e,n,r,i){(t.depth&1?Qu:Zu)(t,e,n,r,i)}const b7=function t(e){function n(r,i,a,o,s){if((c=r._squarify)&&c.ratio===e)for(var c,l,u,f,d=-1,h,p=c.length,v=r.value;++d1?r:1)},n}(D_);function x7(t,e){return Array.isArray(t)?typeof e=="function"?mh().path(e)(t):mh()(t):Qs(t)}function F_(t,e=[t.data.name]){t.id=t.id||t.data.name,t.path=e,t.children&&t.children.forEach(n=>{n.id=`${t.id}/${n.data.name}`,n.path=[...e,n.data.name],F_(n,n.path)})}function z_(t){const e=je(t,["data","name"]);e.replaceAll&&(t.path=e.replaceAll(".","/").split("/")),t.children&&t.children.forEach(n=>{z_(n)})}function w7(t,e){const n={treemapBinary:y7,treemapDice:Zu,treemapSlice:Qu,treemapSliceDice:m7,treemapSquarify:B_,treemapResquarify:b7},r=t==="treemapSquarify"?n[t].ratio(e):n[t];if(!r)throw new TypeError("Invalid tile method!");return r}function G_(t,e,n){const{value:r}=n,i=w7(e.tile,e.ratio),a=x7(t,e.path);Le(t)?z_(a):F_(a),r?a.sum(c=>e.ignoreParentValue&&c.children?0:cr(r)(c)).sort(e.sort):a.count(),g7().tile(i).size(e.size).round(e.round).paddingInner(e.paddingInner).paddingOuter(e.paddingOuter).paddingTop(e.paddingTop).paddingRight(e.paddingRight).paddingBottom(e.paddingBottom).paddingLeft(e.paddingLeft)(a);const o=a.descendants().map(c=>Object.assign(c,{id:c.id.replace(/^\//,""),x:[c.x0,c.x1],y:[c.y0,c.y1]}));return[o.filter(typeof e.layer=="function"?e.layer:c=>c.height===e.layer),o]}var O7=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i({tile:"treemapSquarify",ratio:.5*(1+Math.sqrt(5)),size:[t,e],round:!1,ignoreParentValue:!0,padding:0,paddingInner:0,paddingOuter:0,paddingTop:0,paddingRight:0,paddingBottom:0,paddingLeft:0,sort:(n,r)=>r.value-n.value,layer:0}),_7=(t,e)=>({type:"rect",axis:!1,encode:{x:"x",y:"y",key:"id",color:n=>n.path[1]},scale:{x:{domain:[0,t],range:[0,1]},y:{domain:[0,e],range:[0,1]}},style:{stroke:"#fff"},state:{active:{opacity:.6},inactive:{opacity:1}}}),M7={fontSize:10,text:t=>Ns(t.path),position:"inside",fill:"#000",textOverflow:"clip",wordWrap:!0,maxLines:1,wordWrapWidth:t=>t.x1-t.x0},E7={title:t=>{var e,n;return(n=(e=t.path)===null||e===void 0?void 0:e.join)===null||n===void 0?void 0:n.call(e,".")},items:[{field:"value"}]},P7={title:t=>Ns(t.path),items:[{field:"value"}]},Y_=(t,e)=>{const{width:n,height:r,options:i}=e,{data:a,encode:o={},scale:s,style:c={},layout:l={},labels:u=[],tooltip:f={}}=t,d=O7(t,["data","encode","scale","style","layout","labels","tooltip"]),h=je(i,["interaction","treemapDrillDown"]),p=X({},S7(n,r),l,{layer:h?m=>m.depth===1:l.layer}),[v,g]=G_(a,p,o),y=Q(c,"label");return X({},_7(n,r),Object.assign(Object.assign({data:v,scale:s,style:c,labels:[Object.assign(Object.assign({},M7),y),...u]},d),{encode:o,tooltip:Hl(f,E7),axis:!1}),h?{interaction:Object.assign(Object.assign({},d.interaction),{treemapDrillDown:h?Object.assign(Object.assign({},h),{originData:g,layout:p}):void 0}),encode:Object.assign({color:m=>Ns(m.path)},o),tooltip:Hl(f,P7)}:{})};Y_.props={};var A7=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i({size:[t,e],padding:0,sort:(n,r)=>r.value-n.value}),T7=(t,e,n)=>({type:"point",axis:!1,legend:!1,scale:{x:{domain:[0,t]},y:{domain:[0,e]},size:{type:"identity"}},encode:{x:"x",y:"y",size:"r",shape:"point"},style:{fill:n.color?void 0:r=>r.height===0?"#ddd":"#fff",stroke:n.color?void 0:r=>r.height===0?"":"#000"}}),C7={text:"",position:"inside",textOverflow:"clip",wordWrap:!0,maxLines:1,wordWrapWidth:t=>t.r*2},L7={title:t=>t.data.name,items:[{field:"value"}]},N7=(t,e,n)=>{const{value:r}=n,i=Le(t)?mh().path(e.path)(t):Qs(t);return r?i.sum(a=>cr(r)(a)).sort(e.sort):i.count(),i7().size(e.size).padding(e.padding)(i),i.descendants()},W_=(t,e)=>{const{width:n,height:r}=e,{data:i,encode:a={},scale:o={},style:s={},layout:c={},labels:l=[],tooltip:u={}}=t,f=A7(t,["data","encode","scale","style","layout","labels","tooltip"]),d=T7(n,r,a),h=N7(i,X({},k7(n,r),c),X({},d.encode,a)),p=Q(s,"label");return X({},d,Object.assign(Object.assign({data:h,encode:a,scale:o,style:s,labels:[Object.assign(Object.assign({},C7),p),...l]},f),{tooltip:Hl(u,L7),axis:!1}))};W_.props={};var Rm=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ie[n])}function I7(t,e){return Ct(t,n=>e[n])}function H_(t,e){const n=T0(t,e)*2.5-C0(t,e)*1.5;return bn(t,r=>e[r]>=n?e[r]:NaN)}function T0(t,e){return xu(t,.25,n=>e[n])}function j7(t,e){return xu(t,.5,n=>e[n])}function C0(t,e){return xu(t,.75,n=>e[n])}function V_(t,e){const n=C0(t,e)*2.5-T0(t,e)*1.5;return Ct(t,r=>e[r]<=n?e[r]:NaN)}function D7(){return(t,e)=>{const{encode:n}=e,{y:r,x:i}=n,{value:a}=r,{value:o}=i;return[Array.from(te(t,l=>o[+l]).values()).flatMap(l=>{const u=H_(l,a),f=V_(l,a);return l.filter(d=>a[d]f)}),e]}}const X_=t=>{const{data:e,encode:n,style:r={},tooltip:i={},transform:a,animate:o}=t,s=Rm(t,["data","encode","style","tooltip","transform","animate"]),{point:c=!0}=r,l=Rm(r,["point"]),{y:u}=n,f={y:u,y1:u,y2:u,y3:u,y4:u},d={y1:T0,y2:j7,y3:C0},h=fr(i,"box",{items:[{channel:"y",name:"min"},{channel:"y1",name:"q1"},{channel:"y2",name:"q2"},{channel:"y3",name:"q3"},{channel:"y4",name:"max"}]},!0),p=fr(i,"point",{title:{channel:"x"},items:[{name:"outlier",channel:"y"}]});if(!c)return Object.assign({type:"box",data:e,transform:[Object.assign(Object.assign({type:"groupX",y:R7},d),{y4:I7})],encode:Object.assign(Object.assign({},n),f),style:l,tooltip:h},s);const v=Q(l,"box"),g=Q(l,"point");return[Object.assign({type:"box",data:e,transform:[Object.assign(Object.assign({type:"groupX",y:H_},d),{y4:V_})],encode:Object.assign(Object.assign({},n),f),style:v,tooltip:h,animate:dr(o,"box")},s),{type:"point",data:e,transform:[{type:D7}],encode:n,style:Object.assign({},g),tooltip:p,animate:dr(o,"point")}]};X_.props={};const $7={shape:l_},U_=t=>{const{cartesian:e}=t;return e?w0:(n,r,i,a)=>{const{x:o,y:s}=i,c=ta(r,i,t),l=Array.from(n,u=>{const f=[+o[u],+s[u]];return[a.map(c(f,u))]});return[n,l]}};U_.props={defaultShape:"shape",defaultLabelShape:"label",composite:!1,shape:$7,channels:[{name:"x",required:!0},{name:"y",required:!0}],preInference:[...pe(),{type:Mu},{type:_u},{type:Lx}]};function B7(t,e){var n,r=1;t==null&&(t=0),e==null&&(e=0);function i(){var a,o=n.length,s,c=0,l=0;for(a=0;a=(f=(s+l)/2))?s=f:l=f,(g=n>=(d=(c+u)/2))?c=d:u=d,i=a,!(a=a[y=g<<1|v]))return i[y]=o,t;if(h=+t._x.call(null,a.data),p=+t._y.call(null,a.data),e===h&&n===p)return o.next=a,i?i[y]=o:t._root=o,t;do i=i?i[y]=new Array(4):t._root=new Array(4),(v=e>=(f=(s+l)/2))?s=f:l=f,(g=n>=(d=(c+u)/2))?c=d:u=d;while((y=g<<1|v)===(m=(p>=d)<<1|h>=f));return i[m]=a,i[y]=o,t}function z7(t){var e,n,r=t.length,i,a,o=new Array(r),s=new Array(r),c=1/0,l=1/0,u=-1/0,f=-1/0;for(n=0;nu&&(u=i),af&&(f=a));if(c>u||l>f)return this;for(this.cover(c,l).cover(u,f),n=0;nt||t>=i||r>e||e>=a;)switch(l=(eu||(s=p.y0)>f||(c=p.x1)=y)<<1|t>=g)&&(p=d[d.length-1],d[d.length-1]=d[d.length-1-v],d[d.length-1-v]=p)}else{var m=t-+this._x.call(null,h.data),b=e-+this._y.call(null,h.data),x=m*m+b*b;if(x=(d=(o+c)/2))?o=d:c=d,(v=f>=(h=(s+l)/2))?s=h:l=h,e=n,!(n=n[g=v<<1|p]))return this;if(!n.length)break;(e[g+1&3]||e[g+2&3]||e[g+3&3])&&(r=e,y=g)}for(;n.data!==t;)if(i=n,!(n=n.next))return this;return(a=n.next)&&delete n.next,i?(a?i.next=a:delete i.next,this):e?(a?e[g]=a:delete e[g],(n=e[0]||e[1]||e[2]||e[3])&&n===(e[3]||e[2]||e[1]||e[0])&&!n.length&&(r?r[y]=n:this._root=n),this):(this._root=a,this)}function X7(t){for(var e=0,n=t.length;e[e(w,O,o),w])),x;for(g=0,s=new Array(y);g{}};function Z_(){for(var t=0,e=arguments.length,n={},r;t=0&&(r=n.slice(i+1),n=n.slice(0,i)),n&&!e.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}al.prototype=Z_.prototype={constructor:al,on:function(t,e){var n=this._,r=a$(t+"",n),i,a=-1,o=r.length;if(arguments.length<2){for(;++a0)for(var n=new Array(i),r=0,i,a;r=0&&t._call.call(void 0,e),t=t._next;--Wa}function $m(){Wi=(Xl=xs.now())+Ju,Wa=Lo=0;try{c$()}finally{Wa=0,u$(),Wi=0}}function l$(){var t=xs.now(),e=t-Xl;e>Q_&&(Ju-=e,Xl=t)}function u$(){for(var t,e=Vl,n,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:Vl=n);No=t,wh(r)}function wh(t){if(!Wa){Lo&&(Lo=clearTimeout(Lo));var e=t-Wi;e>24?(t<1/0&&(Lo=setTimeout($m,t-xs.now()-Ju)),So&&(So=clearInterval(So))):(So||(Xl=xs.now(),So=setInterval(l$,Q_)),Wa=1,J_($m))}}const f$=1664525,d$=1013904223,Bm=4294967296;function h$(){let t=1;return()=>(t=(f$*t+d$)%Bm)/Bm}function p$(t){return t.x}function v$(t){return t.y}var g$=10,y$=Math.PI*(3-Math.sqrt(5));function m$(t){var e,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,o=.6,s=new Map,c=eM(f),l=Z_("tick","end"),u=h$();t==null&&(t=[]);function f(){d(),l.call("tick",e),n1?(g==null?s.delete(v):s.set(v,p(g)),e):s.get(v)},find:function(v,g,y){var m=0,b=t.length,x,w,O,S,_;for(y==null?y=1/0:y*=y,m=0;m1?(l.on(v,g),e):l.on(v)}}}function b$(){var t,e,n,r,i=mn(-30),a,o=1,s=1/0,c=.81;function l(h){var p,v=t.length,g=K_(t,p$,v$).visitAfter(f);for(r=h,p=0;p=s)return;(h.data!==e||h.next)&&(y===0&&(y=ya(n),x+=y*y),m===0&&(m=ya(n),x+=m*m),xt.source.x,t=>t.target.x],y:[t=>t.source.y,t=>t.target.y]},style:{stroke:"#999",strokeOpacity:.6}},M$={type:"point",axis:!1,legend:!1,encode:{x:"x",y:"y",size:5,color:"group",shape:"point"},style:{stroke:"#fff"}},E$={text:""};function P$(t,e,n){const{nodes:r,links:i}=t,{joint:a,nodeStrength:o,linkStrength:s}=e,{nodeKey:c=p=>p.id,linkKey:l=p=>p.id}=n,u=b$(),f=r$(i).id(cr(l));typeof o=="function"&&u.strength(o),typeof s=="function"&&f.strength(s);const d=m$(r).force("link",f).force("charge",u);a?d.force("center",B7()):d.force("x",x$()).force("y",w$()),d.stop();const h=Math.ceil(Math.log(d.alphaMin())/Math.log(1-d.alphaDecay()));for(let p=0;p{const{data:e,encode:n={},scale:r,style:i={},layout:a={},nodeLabels:o=[],linkLabels:s=[],animate:c={},tooltip:l={}}=t,{nodeKey:u=O=>O.id,linkKey:f=O=>O.id}=n,d=O$(n,["nodeKey","linkKey"]),h=Object.assign({nodeKey:u,linkKey:f},d),p=Q(h,"node"),v=Q(h,"link"),{links:g,nodes:y}=O0(e,h),{nodesData:m,linksData:b}=P$({links:g,nodes:y},X({},S$,a),h),x=fr(l,"link",{items:[O=>({name:"source",value:cr(f)(O.source)}),O=>({name:"target",value:cr(f)(O.target)})]}),w=fr(l,"node",{items:[O=>({name:"key",value:cr(u)(O)})]},!0);return[X({},_$,{data:b,encode:v,labels:s,style:Q(i,"link"),tooltip:x,animate:dr(c,"link")}),X({},M$,{data:m,encode:Object.assign({},p),scale:r,style:Q(i,"node"),tooltip:w,labels:[Object.assign(Object.assign({},E$),Q(i,"label")),...o],animate:dr(c,"link")})]};nM.props={};const rM=t=>e=>n=>{const{field:r="value",nodeSize:i,separation:a,sortBy:o,as:s=["x","y"]}=e,[c,l]=s,u=Qs(n,p=>p.children).sum(p=>p[r]).sort(o),f=t();f.size([1,1]),i&&f.nodeSize(i),a&&f.separation(a),f(u);const d=[];u.each(p=>{p[c]=p.x,p[l]=p.y,p.name=p.data.name,d.push(p)});const h=u.links();return h.forEach(p=>{p[c]=[p.source[c],p.target[c]],p[l]=[p.source[l],p.target[l]]}),{nodes:d,edges:h}},iM=t=>rM(PD)(t);iM.props={};const aM=t=>rM(v7)(t);aM.props={};const A$={sortBy:(t,e)=>e.value-t.value},k$={axis:!1,legend:!1,type:"point",encode:{x:"x",y:"y",size:2,shape:"point"}},T$={type:"link",encode:{x:"x",y:"y",shape:"smooth"}},C$={text:"",fontSize:10},oM=t=>{const{data:e,encode:n={},scale:r={},style:i={},layout:a={},nodeLabels:o=[],linkLabels:s=[],animate:c={},tooltip:l={}}=t,u=n==null?void 0:n.value,{nodes:f,edges:d}=aM(Object.assign(Object.assign(Object.assign({},A$),a),{field:u}))(e),h=fr(l,"node",{title:"name",items:["value"]},!0),p=fr(l,"link",{title:"",items:[v=>({name:"source",value:v.source.name}),v=>({name:"target",value:v.target.name})]});return[X({},T$,{data:d,encode:Q(n,"link"),scale:Q(r,"link"),labels:s,style:Object.assign({stroke:"#999"},Q(i,"link")),tooltip:p,animate:dr(c,"link")}),X({},k$,{data:f,scale:Q(r,"node"),encode:Q(n,"node"),labels:[Object.assign(Object.assign({},C$),Q(i,"label")),...o],style:Object.assign({},Q(i,"node")),tooltip:h,animate:dr(c,"node")})]};oM.props={};var Fm={},sd={},cd=34,_o=10,ld=13;function sM(t){return new Function("d","return {"+t.map(function(e,n){return JSON.stringify(e)+": d["+n+'] || ""'}).join(",")+"}")}function L$(t,e){var n=sM(t);return function(r,i){return e(n(r),i,t)}}function zm(t){var e=Object.create(null),n=[];return t.forEach(function(r){for(var i in r)i in e||n.push(e[i]=i)}),n}function en(t,e){var n=t+"",r=n.length;return r9999?"+"+en(t,6):en(t,4)}function R$(t){var e=t.getUTCHours(),n=t.getUTCMinutes(),r=t.getUTCSeconds(),i=t.getUTCMilliseconds();return isNaN(t)?"Invalid Date":N$(t.getUTCFullYear())+"-"+en(t.getUTCMonth()+1,2)+"-"+en(t.getUTCDate(),2)+(i?"T"+en(e,2)+":"+en(n,2)+":"+en(r,2)+"."+en(i,3)+"Z":r?"T"+en(e,2)+":"+en(n,2)+":"+en(r,2)+"Z":n||e?"T"+en(e,2)+":"+en(n,2)+"Z":"")}function I$(t){var e=new RegExp('["'+t+` -\r]`),n=t.charCodeAt(0);function r(f,d){var h,p,v=i(f,function(g,y){if(h)return h(g,y-1);p=g,h=d?L$(g,d):sM(g)});return v.columns=p||[],v}function i(f,d){var h=[],p=f.length,v=0,g=0,y,m=p<=0,b=!1;f.charCodeAt(p-1)===_o&&--p,f.charCodeAt(p-1)===ld&&--p;function x(){if(m)return sd;if(b)return b=!1,Fm;var O,S=v,_;if(f.charCodeAt(S)===cd){for(;v++=p?m=!0:(_=f.charCodeAt(v++))===_o?b=!0:_===ld&&(b=!0,f.charCodeAt(v)===_o&&++v),f.slice(S+1,O-1).replace(/""/g,'"')}for(;v{const{value:e,format:n=e.split(".").pop(),delimiter:r=",",autoType:i=!0}=t;return()=>$$(void 0,void 0,void 0,function*(){const a=yield fetch(e);if(n==="csv"){const o=yield a.text();return I$(r).parse(o,i?j$:ji)}else if(n==="json")return yield a.json();throw new Error(`Unknown format: ${n}.`)})};cM.props={};function B$(t){return!t||Object.keys(t).length===0}const lM=t=>{const{fields:e,key:n="key",value:r="value"}=t;return i=>B$(e)?i:i.flatMap(a=>e.map(o=>Object.assign(Object.assign({},a),{[n]:o,[r]:a[o]})))};lM.props={};function F$(t){return t!=null&&!Number.isNaN(t)}const uM=t=>{const{callback:e=F$}=t;return n=>n.filter(e)};uM.props={};const fM=t=>{const{callback:e}=t;return n=>Array.isArray(n)?[...n].sort(e):n};fM.props={};function z$(t,e=[]){return e.reduce((n,r)=>(r in t&&(n[r]=t[r]),n),{})}const dM=t=>{const{fields:e}=t;return n=>n.map(r=>z$(r,e))};dM.props={};function G$(t){return Object.keys(t).length===0}const hM=t=>e=>{if(!t||G$(t))return e;const n=r=>Object.entries(r).reduce((i,[a,o])=>(i[t[a]||a]=o,i),{});return e.map(n)};hM.props={};function Y$(t,e){return t.map(n=>{if(Array.isArray(n)){const[r,i=e]=n;return[r,i]}return[n,e]})}const pM=t=>{const{fields:e=[]}=t,n=Y$(e,!0);return r=>{const i=(a,o)=>n.reduce((s,[c,l=!0])=>s!==0?s:l?a[c]o[c]?-1:+(a[c]!==o[c]),0);return[...r].sort(i)}};pM.props={};const vM=t=>{const{value:e}=t;return()=>e};vM.props={};const gM=t=>{const{callback:e=ji}=t;return n=>e(n)};gM.props={};const yM=t=>{const{callback:e=ji}=t;return n=>Array.isArray(n)?n.map(e):n};yM.props={};const ud=Math.PI/180,Ro=64,ol=2048;function W$(t){return t.text}function H$(){return"serif"}function Gm(){return"normal"}function V$(t){return t.value}function X$(){return~~(Math.random()*2)*90}function U$(){return 1}function q$(){}function K$(t,e,n,r){if(e.sprite)return;const i=t.context,a=t.ratio;i.clearRect(0,0,(Ro<<5)/a,ol/a);let o=0,s=0,c=0;const l=n.length;for(--r;++r>5<<5,h=~~Math.max(Math.abs(y+m),Math.abs(y-m))}else d=d+31>>5<<5;if(h>c&&(c=h),o+d>=Ro<<5&&(o=0,s+=c,c=0),s+h>=ol)break;i.translate((o+(d>>1))/a,(s+(h>>1))/a),e.rotate&&i.rotate(e.rotate*ud),i.fillText(e.text,0,0),e.padding&&(i.lineWidth=2*e.padding,i.strokeText(e.text,0,0)),i.restore(),e.width=d,e.height=h,e.xoff=o,e.yoff=s,e.x1=d>>1,e.y1=h>>1,e.x0=-e.x1,e.y0=-e.y1,e.hasText=!0,o+=d}const u=i.getImageData(0,0,(Ro<<5)/a,ol/a).data,f=[];for(;--r>=0;){if(e=n[r],!e.hasText)continue;const d=e.width,h=d>>5;let p=e.y1-e.y0;for(let y=0;y>5),x=u[(s+y)*(Ro<<5)+(o+m)<<2]?1<<31-m%32:0;f[b]|=x,v|=x}v?g=y:(e.y0++,p--,y--,s++)}e.y1=e.y0+g,e.sprite=f.slice(0,(e.y1-e.y0)*h)}}function Z$(t,e,n){n>>=5;const r=t.sprite,i=t.width>>5,a=t.x-(i<<4),o=a&127,s=32-o,c=t.y1-t.y0;let l=(t.y+t.y0)*n+(a>>5),u;for(let f=0;f>>o:0))&e[l+d])return!0;l+=n}return!1}function Q$(t,e){const n=t[0],r=t[1];e.x+e.x0r.x&&(r.x=e.x+e.x1),e.y+e.y1>r.y&&(r.y=e.y+e.y1)}function J$(t,e){return t.x+t.x1>e[0].x&&t.x+t.x0e[0].y&&t.y+t.y0>5)*t[1]),O=u.length,S=[],_=u.map(function(T,A,k){return T.text=e.call(this,T,A,k),T.font=n.call(this,T,A,k),T.style=h.call(this,T,A,k),T.weight=i.call(this,T,A,k),T.rotate=a.call(this,T,A,k),T.size=~~r.call(this,T,A,k),T.padding=o.call(this,T,A,k),T}).sort(function(T,A){return A.size-T.size});let M=-1,E=v.board?[{x:0,y:0},{x:m,y:b}]:void 0;f&&clearInterval(f),f=setInterval(P,0),P();function P(){const T=Date.now();for(;Date.now()-T>1,A.y=b*(c()+.5)>>1,K$(x,A,_,M),A.hasText&&y(w,A,E)&&(l.call(null,"word",{cloud:v,word:A}),S.push(A),E?v.hasImage||Q$(E,A):E=[{x:A.x+A.x0,y:A.y+A.y0},{x:A.x+A.x1,y:A.y+A.y1}],A.x-=t[0]>>1,A.y-=t[1]>>1)}v._tags=S,v._bounds=E,M>=O&&(v.stop(),l.call(null,"end",{cloud:v,words:S,bounds:E}))}return v},v.stop=function(){return f&&(clearInterval(f),f=null),v};function g(m){m.width=m.height=1;const b=Math.sqrt(m.getContext("2d").getImageData(0,0,1,1).data.length>>2);m.width=(Ro<<5)/b,m.height=ol/b;const x=m.getContext("2d");return x.fillStyle=x.strokeStyle="red",x.textAlign="center",{context:x,ratio:b}}function y(m,b,x){const w=b.x,O=b.y,S=Math.sqrt(t[0]*t[0]+t[1]*t[1]),_=s(t),M=c()<.5?1:-1;let E,P=-M,T,A;for(;(E=_(P+=M))&&(T=~~E[0],A=~~E[1],!(Math.min(Math.abs(T),Math.abs(A))>=S));)if(b.x=w+T,b.y=O+A,!(b.x+b.x0<0||b.y+b.y0<0||b.x+b.x1>t[0]||b.y+b.y1>t[1])&&(!x||!Z$(b,m,t[0]))&&(!x||J$(b,x))){const k=b.sprite,C=b.width>>5,L=t[0]>>5,I=b.x-(C<<4),R=I&127,j=32-R,D=b.y1-b.y0;let $,B=(b.y+b.y0)*L+(I>>5);for(let F=0;F>>R:0);B+=L}return delete b.sprite,!0}return!1}return v.createMask=m=>{const b=document.createElement("canvas"),[x,w]=t;if(!x||!w)return;const O=x>>5,S=Ym((x>>5)*w);b.width=x,b.height=w;const _=b.getContext("2d");_.drawImage(m,0,0,m.width,m.height,0,0,x,w);const M=_.getImageData(0,0,x,w).data;for(let E=0;E>5),A=E*x+P<<2,C=M[A]>=250&&M[A+1]>=250&&M[A+2]>=250?1<<31-P%32:0;S[T]|=C}v.board=S,v.hasImage=!0},v.timeInterval=function(m){d=m??1/0},v.words=function(m){u=m},v.size=function(m=[]){t=[+m[0],+m[1]]},v.text=function(m){e=$r(m)},v.font=function(m){n=$r(m)},v.fontWeight=function(m){i=$r(m)},v.rotate=function(m){a=$r(m)},v.spiral=function(m){s=nB[m]||m},v.fontSize=function(m){r=$r(m)},v.padding=function(m){o=$r(m)},v.random=function(m){c=$r(m)},v.on=function(m){l=$r(m)},v}var iB=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})};function aB(t,e){return{set(n,r,i){if(e[n]===void 0)return this;const a=r?r.call(null,e[n]):e[n];return i?i.call(null,a):typeof t[n]=="function"?t[n](a):t[n]=a,this},setAsync(n,r,i){return iB(this,void 0,void 0,function*(){if(e[n]===void 0)return this;const a=r?yield r.call(null,e[n]):e[n];return i?i.call(null,a):typeof t[n]=="function"?t[n](a):t[n]=a,this})}}}var oB=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},sB=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{if(t instanceof HTMLImageElement){e(t);return}if(typeof t=="string"){const r=new Image;r.crossOrigin="anonymous",r.src=t,r.onload=()=>e(r),r.onerror=()=>{console.error(`'image ${t} load failed !!!'`),n()};return}n()})}function uB(t,e){if(typeof t=="function")return t;if(Array.isArray(t)){const[n,r]=t;if(!e)return()=>(r+n)/2;const[i,a]=e;return a===i?()=>(r+n)/2:({value:o})=>(r-n)/(a-i)*(o-i)+n}return()=>t}const bM=t=>e=>oB(void 0,void 0,void 0,function*(){const n=Object.assign({},cB,t),r=rB();yield aB(r,n).set("fontSize",y=>{const m=e.map(b=>b.value);return uB(y,[bn(m),Ct(m)])}).set("font").set("fontStyle").set("fontWeight").set("padding").set("rotate").set("size").set("spiral").set("timeInterval").set("random").set("text").set("on").setAsync("imageMask",lB,r.createMask),r.words([...e]);const i=r.start(),[a,o]=n.size,s=[{x:0,y:0},{x:a,y:o}],{_bounds:c=s,_tags:l,hasImage:u}=i,f=l.map(y=>{var{x:m,y:b}=y,x=sB(y,["x","y"]);return Object.assign(Object.assign({},x),{x:m+a/2,y:b+o/2})}),[{x:d,y:h},{x:p,y:v}]=c,g={text:"",value:0,opacity:0,fontSize:0};return f.push(Object.assign(Object.assign({},g),{x:u?0:d,y:u?0:h}),Object.assign(Object.assign({},g),{x:u?a:p,y:u?o:v})),f});bM.props={};function Wm(t){return typeof t=="string"?e=>e[t]:t}const xM=t=>{const{join:e,on:n,select:r=[],as:i=r,unknown:a=NaN}=t,[o,s]=n,c=Wm(s),l=Wm(o),u=vp(e,([f])=>f,f=>c(f));return f=>f.map(d=>{const h=u.get(l(d));return Object.assign(Object.assign({},d),r.reduce((p,v,g)=>(p[i[g]]=h?h[v]:a,p),{}))})};xM.props={};const wM=t=>{const{start:e,end:n}=t;return r=>r.slice(e,n)};wM.props={};var OM={exports:{}},SM={exports:{}};(function(t){var e=t.exports;t.exports.isNumber=function(n){return typeof n=="number"},t.exports.findMin=function(n){if(n.length===0)return 1/0;for(var r=n[0],i=1;i=y.length)){var A=Math.max(T-f,0),k=T,C=Math.min(T+f,y.length-1),L=A-(T-f),I=T+f-C,R=x[-f-1+L]||0,j=x[-f-1+I]||0,D=w/(w-R-j);L>0&&(S+=D*(L-1)*O);var $=Math.max(0,T-f+1);a.inside(0,y.length-1,$)&&(y[$].y+=D*1*O),a.inside(0,y.length-1,k+1)&&(y[k+1].y-=D*2*O),a.inside(0,y.length-1,C+1)&&(y[C+1].y+=D*1*O)}});var _=S,M=0,E=0;return y.forEach(function(P){M+=P.y,_+=M,P.y=_,E+=_}),E>0&&y.forEach(function(P){P.y/=E}),y};function s(c,l){for(var u={},f=0,d=-l;d<=l;d++)f+=c(d/l),u[d]=f;return u}t.exports.getExpectedValueFromPdf=function(c){if(!(!c||c.length===0)){var l=0;return c.forEach(function(u){l+=u.x*u.y}),l}},t.exports.getXWithLeftTailArea=function(c,l){if(!(!c||c.length===0)){for(var u=0,f=0,d=0;d=l));d++);return c[f].x}},t.exports.getPerplexity=function(c){if(!(!c||c.length===0)){var l=0;return c.forEach(function(u){var f=Math.log(u.y);isFinite(f)&&(l+=u.y*f)}),l=-l/r,Math.pow(2,l)}}})(OM);var dB=OM.exports;const hB=ip(dB),_M=t=>{const{field:e,groupBy:n,as:r=["y","size"],min:i,max:a,size:o=10,width:s}=t,[c,l]=r;return u=>Array.from(te(u,d=>n.map(h=>d[h]).join("-")).values()).map(d=>{const h=hB.create(d.map(g=>g[e]),{min:i,max:a,size:o,width:s}),p=h.map(g=>g.x),v=h.map(g=>g.y);return Object.assign(Object.assign({},d[0]),{[c]:p,[l]:v})})};_M.props={};function pB(t,e,n,r){r=r||{};var i=r.maxIterations||100,a=r.tolerance||1e-10,o=t(e),s=t(n),c=n-e;if(o*s>0)throw"Initial bisect points must have opposite signs";if(o===0)return e;if(s===0)return n;for(var l=0;l=0&&(e=u),Math.abs(c)=p[h-1].fx){var P=!1;if(x.fx>E.fx?(Sr(w,1+u,b,-u,E),w.fx=t(w),w.fx=1)break;for(v=1;vs+a*i*c||l>=y)g=i;else{if(Math.abs(f)<=-o*c)return i;f*(g-v)>=0&&(g=v),v=i,y=l}return 0}for(var p=0;p<10;++p){if(Sr(r.x,1,n.x,i,e),l=r.fx=t(r.x,r.fxprime),f=Sa(r.fxprime,e),l>s+a*i*c||p&&l>=u)return h(d,i,u);if(Math.abs(f)<=-o*c)return i;if(f>=0)return h(i,d,l);u=l,d=i,i*=2}return i}function yB(t,e,n){var r={x:e.slice(),fx:0,fxprime:e.slice()},i={x:e.slice(),fx:0,fxprime:e.slice()},a=e.slice(),o,s,c=1,l;n=n||{},l=n.maxIterations||e.length*20,r.fx=t(r.x,r.fxprime),o=r.fxprime.slice(),_h(o,r.fxprime,-1);for(var u=0;u1){const c=xB(r);for(o=0;o-1){const p=t[u.parentIndex[h]],v=Math.atan2(u.x-p.x,u.y-p.y),g=Math.atan2(l.x-p.x,l.y-p.y);let y=g-v;y<0&&(y+=2*Math.PI);const m=g-y/2;let b=ws(f,{x:p.x+p.radius*Math.sin(m),y:p.y+p.radius*Math.cos(m)});b>p.radius*2&&(b=p.radius*2),(d===null||d.width>b)&&(d={circle:p,width:b,p1:u,p2:l})}d!==null&&(s.push(d),i+=Mh(d.circle.radius,d.width),l=u)}}else{let c=t[0];for(o=1;oMath.abs(c.radius-t[o].radius)){l=!0;break}l?i=a=0:(i=c.radius*c.radius*Math.PI,s.push({circle:c,p1:{x:c.x,y:c.y+c.radius},p2:{x:c.x-MM,y:c.y+c.radius},width:c.radius*2}))}return a/=2,e&&(e.area=i+a,e.arcArea=i,e.polygonArea=a,e.arcs=s,e.innerPoints=r,e.intersectionPoints=n),i+a}function mB(t,e){for(let n=0;ne[n].radius+MM)return!1;return!0}function bB(t){const e=[];for(let n=0;n=t+e)return 0;if(n<=Math.abs(t-e))return Math.PI*Math.min(t,e)*Math.min(t,e);const r=t-(n*n-e*e+t*t)/(2*n),i=e-(n*n-t*t+e*e)/(2*n);return Mh(t,r)+Mh(e,i)}function AM(t,e){const n=ws(t,e),r=t.radius,i=e.radius;if(n>=r+i||n<=Math.abs(r-i))return[];const a=(r*r-i*i+n*n)/(2*n),o=Math.sqrt(r*r-a*a),s=t.x+a*(e.x-t.x)/n,c=t.y+a*(e.y-t.y)/n,l=-(e.y-t.y)*(o/n),u=-(e.x-t.x)*(o/n);return[{x:s+l,y:c-u},{x:s-l,y:c+u}]}function xB(t){const e={x:0,y:0};for(let n=0;ns>c?1:-1),r=0;r=Math.min(e[o].size,e[s].size)?f=1:a.size<=1e-10&&(f=-1),i[o][s]=i[s][o]=f}),{distances:r,constraints:i}}function _B(t,e,n,r){let i=0,a;for(a=0;a0&&p<=f||d<0&&p>=f||(i+=2*v*v,e[2*a]+=4*v*(o-l),e[2*a+1]+=4*v*(s-u),e[2*c]+=4*v*(l-o),e[2*c+1]+=4*v*(u-s))}}return i}function MB(t,e){let n=PB(t,e);const r=e.lossFunction||N0;if(t.length>=8){const i=EB(t,e),a=r(i,t),o=r(n,t);a+1e-8=Math.min(r[p].size,r[v].size)&&(h=0),i[p].push({set:v,size:d.size,weight:h}),i[v].push({set:p,size:d.size,weight:h})}const o=[];for(a in i)if(i.hasOwnProperty(a)){let f=0;for(let d=0;do;r.push(` -A`,o,o,0,s?1:0,1,a.p1.x,a.p1.y)}return r.join(" ")}}const TM=t=>{const{sets:e="sets",size:n="size",as:r=["key","path"],padding:i=0}=t,[a,o]=r;return s=>{const c=s.map(f=>Object.assign(Object.assign({},f),{sets:f[e],size:f[n],[a]:f.sets.join("&")}));c.sort((f,d)=>f.sets.length-d.sets.length);const l=wB(c);let u;return c.map(f=>{const d=f[e],h=({width:p,height:v})=>{u=u||kB(l,p,v,i);const g=d.map(m=>u[m]);let y=CB(g);return/[zZ]$/.test(y)||(y+=" Z"),y};return Object.assign(Object.assign({},f),{[o]:h})})}};TM.props={};const CM=()=>t=>(console.log("G2 data section:",t),t);CM.props={};var LB=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},NB=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);iObject.assign(Object.assign({},i),{text:i[n],value:i[r]}))}const IB=(t,e)=>({size:[t,e]}),jB=(t,e)=>({axis:!1,type:"text",encode:{x:"x",y:"y",text:"text",rotate:"rotate",fontSize:"size"},scale:{x:{domain:[0,t],range:[0,1]},y:{domain:[0,e],range:[0,1]},fontSize:{type:"identity"},rotate:{type:"identity"}},style:{textAlign:"center"}}),LM=(t,e)=>LB(void 0,void 0,void 0,function*(){const{width:n,height:r}=e,{data:i,encode:a={},scale:o,style:s={},layout:c={}}=t,l=NB(t,["data","encode","scale","style","layout"]),u=RB(i,a),f=yield bM(Object.assign(Object.assign({},IB(n,r)),c))(u);return X({},jB(n,r),Object.assign(Object.assign({data:f,encode:a,scale:o,style:s},l),{axis:!1}))});LM.props={};var sl=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{shape:n,radius:r}=t,i=sl(t,["shape","radius"]),a=Q(i,"pointer"),o=Q(i,"pin"),{shape:s}=a,c=sl(a,["shape"]),{shape:l}=o,u=sl(o,["shape"]),{coordinate:f,theme:d}=e;return(h,p)=>{const v=h.map(k=>f.invert(k)),[g,y,m]=EL(f,"polar"),b=f.clone(),{color:x}=p,w=op({startAngle:g,endAngle:y,innerRadius:m,outerRadius:r});w.push(["cartesian"]),b.update({transformations:w});const O=v.map(k=>b.map(k)),[S,_]=rO(O),[M,E]=f.getCenter(),P=Object.assign(Object.assign({x1:S,y1:_,x2:M,y2:E,stroke:x},c),i),T=Object.assign(Object.assign({cx:M,cy:E,stroke:x},u),i),A=st(new Ce);return Lr(s)||(typeof s=="function"?A.append(()=>s(O,p,b,d)):A.append("line").call(at,P).node()),Lr(l)||(typeof l=="function"?A.append(()=>l(O,p,b,d)):A.append("circle").call(at,T).node()),A.node()}},Vm={coordinate:{type:"radial",innerRadius:.9,outerRadius:1,startAngle:-11/10*Math.PI,endAngle:1/10*Math.PI},axis:{x:!1},legend:!1,tooltip:!1,encode:{x:"x",y:"y",color:"color"},scale:{color:{range:["#30BF78","#D0D0D0"]}}},$B={style:{shape:DB,lineWidth:4,pointerLineCap:"round",pinR:10,pinFill:"#fff",radius:.6}},BB={type:"text",style:{x:"50%",y:"60%",textAlign:"center",textBaseline:"middle",fontSize:20,fontWeight:800,fill:"#888"}};function FB(t){if(de(t)){const e=Math.max(0,Math.min(t,1));return{percent:e,target:e,total:1}}return t}function zB(t,e){const{name:n="score",target:r,total:i,percent:a,thresholds:o=[]}=FB(t),s=a||r,c=a?1:i,l=Object.assign({y:{domain:[0,c]}},e);return o.length?{targetData:[{x:n,y:s,color:"target"}],totalData:o.map((u,f)=>({x:n,y:f>=1?u-o[f-1]:u,color:f})),target:s,total:c,scale:l}:{targetData:[{x:n,y:s,color:"target"}],totalData:[{x:n,y:s,color:"target"},{x:n,y:c-s,color:"total"}],target:s,total:c,scale:l}}function GB(t,{target:e,total:n}){const{content:r}=t;return r?r(e,n):e.toString()}const NM=t=>{const{data:e={},scale:n={},style:r={},animate:i={},transform:a=[]}=t,o=sl(t,["data","scale","style","animate","transform"]),{targetData:s,totalData:c,target:l,total:u,scale:f}=zB(e,n),d=Q(r,"text"),h=F5(r,["pointer","pin"]);return[X({},Vm,Object.assign({type:"interval",transform:[{type:"stackY"}],data:c,scale:f,style:Q(r,"arc"),animate:typeof i=="object"?Q(i,"arc"):i},o)),X({},Vm,$B,Object.assign({type:"point",data:s,scale:f,style:h,animate:typeof i=="object"?Q(i,"indicator"):i},o)),X({},BB,{style:Object.assign({text:GB(d,{target:l,total:u})},d),animate:typeof i=="object"?Q(i,"text"):i})]};NM.props={};const Xm={density:o_},RM=()=>(t,e,n,r)=>{const{x:i,series:a}=n,o=Object.entries(n).filter(([f])=>f.startsWith("y")).map(([,f])=>f),s=Object.entries(n).filter(([f])=>f.startsWith("size")).map(([,f])=>f);if(i===void 0||o===void 0||s===void 0)throw new Error("Missing encode for x or y or size channel.");const c=e.x,l=e.series,u=Array.from(t,f=>{const d=c.getBandWidth(c.invert(+i[f])),h=l?l.getBandWidth(l.invert(+(a==null?void 0:a[f]))):1,p=d*h,v=(+(a==null?void 0:a[f])||0)*d,g=+i[f]+v+p/2;return[...o.map((m,b)=>[g+ +s[b][f]/t.length,+o[b][f]]),...o.map((m,b)=>[g-+s[b][f]/t.length,+o[b][f]]).reverse()].map(m=>r.map(m))});return[t,u]};RM.props={defaultShape:"density",defaultLabelShape:"label",composite:!1,shape:Xm,channels:[...Ue({shapes:Object.keys(Xm)}),{name:"x",scale:"band",required:!0},{name:"y",required:!0},{name:"size",required:!0},{name:"series",scale:"band"},{name:"size",required:!0,scale:"identity"}],preInference:[...pe(),{type:js},{type:qi}],postInference:[...ge(),...io()],interaction:{shareTooltip:!0}};const Um={heatmap:c_},IM=t=>(e,n,r,i)=>{const{x:a,y:o,size:s,color:c}=r,l=Array.from(e,u=>{const f=s?+s[u]:40;return[...i.map([+a[u],+o[u]]),c[u],f]});return[[0],[l]]};IM.props={defaultShape:"heatmap",defaultLabelShape:"label",composite:!1,shape:Um,channels:[...Ue({shapes:Object.keys(Um)}),{name:"x",required:!0},{name:"y",required:!0},{name:"color",scale:"identity",required:!0},{name:"size"}],preInference:[...pe(),{type:qi},{type:Ou}],postInference:[...ge(),...ui()]};var YB=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{data:e={},style:n={},animate:r}=t,i=YB(t,["data","style","animate"]),a=Math.max(0,de(e)?e:e==null?void 0:e.percent),o=[{percent:a,type:"liquid"}],s=Object.assign(Object.assign({},Q(n,"text")),Q(n,"content")),c=Q(n,"outline"),l=Q(n,"wave"),u=Q(n,"background");return[X({},WB,Object.assign({type:"interval",data:o,style:{liquidOptions:{percent:a,liquidShape:n==null?void 0:n.shape},styleOptions:Object.assign(Object.assign({},n),{outline:c,wave:l,background:u})},animate:r},i)),X({},HB,{style:Object.assign({text:`${jl(a*100)} %`},s),animate:r})]};jM.props={};const DM=()=>["#5B8FF9","#5AD8A6","#5D7092","#F6BD16","#6F5EF9","#6DC8EC","#945FB9","#FF9845","#1E9493","#FF99C3"];DM.props={};const $M=()=>["#5B8FF9","#CDDDFD","#5AD8A6","#CDF3E4","#5D7092","#CED4DE","#F6BD16","#FCEBB9","#6F5EF9","#D3CEFD","#6DC8EC","#D3EEF9","#945FB9","#DECFEA","#FF9845","#FFE0C7","#1E9493","#BBDEDE","#FF99C3","#FFE0ED"];$M.props={};const BM=t=>new Ia(t);BM.props={};const FM=t=>new Yt(t);FM.props={};const zM=t=>new n2(t);zM.props={};const GM=t=>new o2(t);GM.props={};const YM=t=>new l2(t);YM.props={};const WM=t=>new kC(t);WM.props={};const HM=t=>new gC(t);HM.props={};const VM=t=>new f2(t);VM.props={};const XM=t=>new Au(t);XM.props={};const UM=t=>new m2(t);UM.props={};const qM=t=>new g2(t);qM.props={};const KM=t=>new pC(t);KM.props={};const ZM=t=>new Yd(t);ZM.props={};const QM=t=>new Ep(t);QM.props={};function R0({colorDefault:t,colorBlack:e,colorWhite:n,colorStroke:r,colorBackground:i,padding1:a,padding2:o,padding3:s,alpha90:c,alpha65:l,alpha45:u,alpha25:f,alpha10:d,category10:h,category20:p,sizeDefault:v=1,padding:g="auto",margin:y=16}){return{padding:g,margin:y,size:v,color:t,category10:h,category20:p,enter:{duration:300,fill:"both",delay:0},update:{duration:300,fill:"both",delay:0},exit:{duration:300,fill:"both",delay:0},view:{viewFill:i,plotFill:"transparent",mainFill:"transparent",contentFill:"transparent"},line:{line:{fill:"",strokeOpacity:1,lineWidth:1,lineCap:"round"}},point:{point:{r:3,fillOpacity:.95,lineWidth:0},hollow:{r:3,strokeOpacity:.95,lineWidth:1},plus:{r:3,strokeOpacity:.95,lineWidth:3},diamond:{r:3,strokeOpacity:.95,lineWidth:1}},interval:{rect:{fillOpacity:.95},hollow:{fill:"",strokeOpacity:1,lineWidth:2}},area:{area:{fillOpacity:.85,lineWidth:0}},polygon:{polygon:{fillOpacity:.95}},cell:{cell:{fillOpacity:.95},hollow:{fill:"",strokeOpacity:1,lineWidth:2}},rect:{rect:{fillOpacity:.95},hollow:{fill:"",strokeOpacity:1,lineWidth:2}},link:{link:{fill:"",strokeOpacity:1}},vector:{vector:{fillOpacity:1}},box:{box:{fillOpacity:.95,stroke:e,lineWidth:1}},text:{text:{fill:"#1D2129",fontSize:12,strokeWidth:0,connectorStroke:r,connectorStrokeOpacity:.45,connectorLineWidth:1,backgroundFill:r,backgroundFillOpacity:.15,backgroundPadding:[2,4],startMarkerSymbol:"circle",startMarkerSize:4,endMarkerSymbol:"circle",endMarkerSize:4},badge:{fill:"#1D2129",fillOpacity:.65,strokeWidth:0,fontSize:10,textAlign:"center",textBaseline:"middle",markerFill:r,markerFillOpacity:.25,markerStrokeOpacity:0}},lineX:{line:{stroke:r,strokeOpacity:.45,lineWidth:1}},lineY:{line:{stroke:r,strokeOpacity:.45,lineWidth:1}},rangeX:{range:{fill:r,fillOpacity:.15,lineWidth:0}},rangeY:{range:{fill:r,fillOpacity:.15,lineWidth:0}},connector:{connector:{stroke:r,strokeOpacity:.45,lineWidth:1,connectLength1:12,endMarker:!0,endMarkerSize:6,endMarkerFill:r,endMarkerFillOpacity:.95}},axis:{arrow:!1,gridLineDash:[3,4],gridLineWidth:.5,gridStroke:e,gridStrokeOpacity:d,labelAlign:"horizontal",labelFill:e,labelOpacity:u,labelFontSize:12,labelFontWeight:"normal",labelSpacing:a,line:!1,lineLineWidth:.5,lineStroke:e,lineStrokeOpacity:u,tickLength:4,tickLineWidth:1,tickStroke:e,tickOpacity:u,titleFill:e,titleOpacity:c,titleFontSize:12,titleFontWeight:"normal",titleSpacing:12,titleTransformOrigin:"center",lineArrowOffset:6,lineArrowSize:6},axisTop:{gridDirection:"positive",labelDirection:"negative",tickDirection:"negative",titlePosition:"top",titleSpacing:12,labelSpacing:4,titleTextBaseline:"middle"},axisBottom:{gridDirection:"negative",labelDirection:"positive",tickDirection:"positive",titlePosition:"bottom",titleSpacing:12,labelSpacing:4,titleTextBaseline:"bottom"},axisLeft:{gridDirection:"positive",labelDirection:"negative",labelSpacing:4,tickDirection:"negative",titlePosition:"left",titleSpacing:12,titleTextBaseline:"middle",titleDirection:"vertical",titleTransformOrigin:"center"},axisRight:{gridDirection:"negative",labelDirection:"positive",labelSpacing:4,tickDirection:"positive",titlePosition:"right",titleSpacing:12,titleTextBaseline:"top",titleDirection:"vertical",titleTransformOrigin:"center"},axisLinear:{girdClosed:!0,gridConnect:"arc",gridDirection:"negative",gridType:"surround",titlePosition:"top",titleSpacing:0},axisArc:{title:!1,titlePosition:"inner",line:!1,tick:!0,labelSpacing:4},axisRadar:{girdClosed:!0,gridStrokeOpacity:.3,gridType:"surround",label:!1,tick:!1,titlePosition:"start"},legendCategory:{backgroundFill:"transparent",itemBackgroundFill:"transparent",itemLabelFill:e,itemLabelFillOpacity:c,itemLabelFontSize:12,itemLabelFontWeight:"normal",itemMarkerFillOpacity:1,itemMarkerSize:8,itemSpacing:[a,a],itemValueFill:e,itemValueFillOpacity:.65,itemValueFontSize:12,itemValueFontWeight:"normal",navButtonFill:e,navButtonFillOpacity:.65,navPageNumFill:e,navPageNumFillOpacity:.45,navPageNumFontSize:12,padding:8,title:!1,titleFill:e,titleFillOpacity:.65,titleFontSize:12,titleFontWeight:"normal",titleSpacing:4,tickStroke:e,tickStrokeOpacity:.25,rowPadding:a,colPadding:o,maxRows:3,maxCols:3},legendContinuous:{handleHeight:12,handleLabelFill:e,handleLabelFillOpacity:u,handleLabelFontSize:12,handleLabelFontWeight:"normal",handleMarkerFill:e,handleMarkerFillOpacity:.6,handleMarkerLineWidth:1,handleMarkerStroke:e,handleMarkerStrokeOpacity:.25,handleWidth:10,labelFill:e,labelFillOpacity:u,labelFontSize:12,labelFontWeight:"normal",labelSpacing:3,tick:!0,tickLength:12,ribbonSize:12,ribbonFill:"#aaa",handle:!0,handleLabel:!1,handleShape:"slider",handleIconSize:12/1.8,indicator:!1,titleFontSize:12,titleSpacing:4,titleFontWeight:"normal",titleFillOpacity:c,tickStroke:e,tickStrokeOpacity:u},label:{fill:e,fillOpacity:.65,fontSize:12,fontWeight:"normal",stroke:void 0,offset:12,connectorStroke:e,connectorStrokeOpacity:.45,connectorLineWidth:1,connectorLength:12,connectorLength2:8,connectorDistance:4},innerLabel:{fill:n,fontSize:12,fillOpacity:.85,fontWeight:"normal",stroke:void 0,offset:0},htmlLabel:{fontSize:12,opacity:.65,color:e,fontWeight:"normal"},slider:{trackSize:16,trackFill:r,trackFillOpacity:1,selectionFill:t,selectionFillOpacity:.15,handleIconSize:10,handleIconFill:"#f7f7f7",handleIconFillOpacity:1,handleIconStroke:e,handleIconStrokeOpacity:.25,handleIconLineWidth:1,handleIconRadius:2,handleLabelFill:e,handleLabelFillOpacity:.45,handleLabelFontSize:12,handleLabelFontWeight:"normal"},scrollbar:{padding:[0,0,0,0],trackSize:6,isRound:!0,slidable:!0,scrollable:!0,trackFill:"#e5e5e5",trackFillOpacity:0,thumbFill:"#000",thumbFillOpacity:.15,thumbHighlightedFillOpacity:.2},title:{spacing:8,titleFill:e,titleFillOpacity:c,titleFontSize:16,titleFontWeight:"bold",titleTextBaseline:"top",subtitleFill:e,subtitleFillOpacity:l,subtitleFontSize:12,subtitleFontWeight:"normal",subtitleTextBaseline:"top"}}}const VB={colorBlack:"#1D2129",colorWhite:"#ffffff",colorStroke:"#416180",colorDefault:"#1783FF",colorBackground:"transparent",category10:["#1783FF","#00C9C9","#F0884D","#D580FF","#7863FF","#60C42D","#BD8F24","#FF80CA","#2491B3","#17C76F"],category20:["#1783FF","#00C9C9","#F0884D","#D580FF","#7863FF","#60C42D","#BD8F24","#FF80CA","#2491B3","#17C76F","#AABA01","#BC7CFC","#237CBC","#2DE379","#CE8032","#FF7AF4","#545FD3","#AFE410","#D8C608","#FFA1E0"],padding1:8,padding2:12,padding3:20,alpha90:.9,alpha65:.65,alpha45:.45,alpha25:.25,alpha10:.1},XB=R0(VB),I0=t=>X({},XB,t);I0.props={};const JM=t=>X({},I0(),{category10:"category10",category20:"category20"},t);JM.props={};const UB={colorBlack:"#fff",colorWhite:"#000",colorStroke:"#416180",colorDefault:"#1783FF",colorBackground:"#141414",category10:["#1783FF","#00C9C9","#F0884D","#D580FF","#7863FF","#60C42D","#BD8F24","#FF80CA","#2491B3","#17C76F"],category20:["#1783FF","#00C9C9","#F0884D","#D580FF","#7863FF","#60C42D","#BD8F24","#FF80CA","#2491B3","#17C76F","#AABA01","#BC7CFC","#237CBC","#2DE379","#CE8032","#FF7AF4","#545FD3","#AFE410","#D8C608","#FFA1E0"],padding1:8,padding2:12,padding3:20,alpha90:.9,alpha65:.65,alpha45:.45,alpha25:.25,alpha10:.25},qB=R0(UB),tE=t=>X({},qB,{tooltip:{crosshairsStroke:"#fff",crosshairsLineWidth:1,crosshairsStrokeOpacity:.25,css:{".g2-tooltip":{background:"#1f1f1f",opacity:.95},".g2-tooltip-title":{color:"#A6A6A6"},".g2-tooltip-list-item-name-label":{color:"#A6A6A6"},".g2-tooltip-list-item-value":{color:"#A6A6A6"}}}},t),eE=t=>Object.assign({},tE(),{category10:"category10",category20:"category20"},t);eE.props={};const KB={colorBlack:"#000",colorWhite:"#fff",colorStroke:"#888",colorDefault:"#4e79a7",colorBackground:"transparent",category10:["#4e79a7","#f28e2c","#e15759","#76b7b2","#59a14f","#edc949","#af7aa1","#ff9da7","#9c755f","#bab0ab"],category20:["#4e79a7","#f28e2c","#e15759","#76b7b2","#59a14f","#edc949","#af7aa1","#ff9da7","#9c755f","#bab0ab"],padding1:8,padding2:12,padding3:20,alpha90:.9,alpha65:.65,alpha45:.45,alpha25:.25,alpha10:.1},ZB=R0(KB),nE=t=>X({},ZB,{text:{text:{fontSize:10}},axis:{gridLineDash:[0,0],gridLineWidth:1,gridStroke:"#ddd",gridStrokeOpacity:1,labelOpacity:1,labelStrokeOpacity:1,labelFontSize:10,line:!0,lineLineWidth:1,lineStroke:"#888",lineStrokeOpacity:1,tickLength:5,tickStrokeOpacity:1,titleOpacity:1,titleStrokeOpacity:1,titleFillOpacity:1,titleFontSize:11,titleFontWeight:"bold"},axisLeft:{gridFilter:(e,n)=>n!==0},axisRight:{gridFilter:(e,n)=>n!==0},legendCategory:{itemLabelFillOpacity:1,itemLabelFontSize:10,itemValueFillOpacity:1,itemValueFontSize:10,titleFillOpacity:1,titleFontSize:11,titleFontWeight:"bold"},legendContinuous:{handleLabelFontSize:10,labelFillOpacity:.45,labelFontSize:10},label:{fontSize:10},innerLabel:{fontSize:10},htmlLabel:{fontSize:10},slider:{handleLabelFontSize:10,trackFillOpacity:.05}},t);nE.props={};function QB(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function Ul(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var n,r=t.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+t.slice(n+1)]}function JB(t){return t=Ul(Math.abs(t)),t?t[1]:NaN}function tF(t,e){return function(n,r){for(var i=n.length,a=[],o=0,s=t[0],c=0;i>0&&s>0&&(c+s+1>r&&(s=Math.max(1,r-c)),a.push(n.substring(i-=s,i+s)),!((c+=s+1)>r));)s=t[o=(o+1)%t.length];return a.reverse().join(e)}}function eF(t){return function(e){return e.replace(/[0-9]/g,function(n){return t[+n]})}}var nF=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Ph(t){if(!(e=nF.exec(t)))throw new Error("invalid format: "+t);var e;return new j0({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}Ph.prototype=j0.prototype;function j0(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}j0.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function rF(t){t:for(var e=t.length,n=1,r=-1,i;n0&&(r=0);break}return r>0?t.slice(0,r)+t.slice(i+1):t}var rE;function iF(t,e){var n=Ul(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(rE=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+Ul(t,Math.max(0,e+a-1))[0]}function qm(t,e){var n=Ul(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}const Km={"%":(t,e)=>(t*100).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:QB,e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>qm(t*100,e),r:qm,s:iF,X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function Zm(t){return t}var Qm=Array.prototype.map,Jm=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function aF(t){var e=t.grouping===void 0||t.thousands===void 0?Zm:tF(Qm.call(t.grouping,Number),t.thousands+""),n=t.currency===void 0?"":t.currency[0]+"",r=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?Zm:eF(Qm.call(t.numerals,String)),o=t.percent===void 0?"%":t.percent+"",s=t.minus===void 0?"−":t.minus+"",c=t.nan===void 0?"NaN":t.nan+"";function l(f){f=Ph(f);var d=f.fill,h=f.align,p=f.sign,v=f.symbol,g=f.zero,y=f.width,m=f.comma,b=f.precision,x=f.trim,w=f.type;w==="n"?(m=!0,w="g"):Km[w]||(b===void 0&&(b=12),x=!0,w="g"),(g||d==="0"&&h==="=")&&(g=!0,d="0",h="=");var O=v==="$"?n:v==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",S=v==="$"?r:/[%p]/.test(w)?o:"",_=Km[w],M=/[defgprs%]/.test(w);b=b===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b));function E(P){var T=O,A=S,k,C,L;if(w==="c")A=_(P)+A,P="";else{P=+P;var I=P<0||1/P<0;if(P=isNaN(P)?c:_(Math.abs(P),b),x&&(P=rF(P)),I&&+P==0&&p!=="+"&&(I=!1),T=(I?p==="("?p:s:p==="-"||p==="("?"":p)+T,A=(w==="s"?Jm[8+rE/3]:"")+A+(I&&p==="("?")":""),M){for(k=-1,C=P.length;++kL||L>57){A=(L===46?i+P.slice(k+1):P.slice(k))+A,P=P.slice(0,k);break}}}m&&!g&&(P=e(P,1/0));var R=T.length+P.length+A.length,j=R>1)+T+P+A+j.slice(R);break;default:P=j+T+P+A;break}return a(P)}return E.toString=function(){return f+""},E}function u(f,d){var h=l((f=Ph(f),f.type="f",f)),p=Math.max(-8,Math.min(8,Math.floor(JB(d)/3)))*3,v=Math.pow(10,-p),g=Jm[8+p/3];return function(y){return h(v*y)+g}}return{format:l,formatPrefix:u}}var jc,fi;oF({thousands:",",grouping:[3],currency:["$",""]});function oF(t){return jc=aF(t),fi=jc.format,jc.formatPrefix,jc}var sF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ir.getOptions().name===e))===null||n===void 0?void 0:n[0]}function uF(t){return t==="horizontal"||t===0}function fF(t){return t==="vertical"||t===-Math.PI/2}function oE(t,e,n){const{bbox:r}=t,{position:i="top",size:a,length:o}=e,s=["top","bottom","center"].includes(i),[c,l]=s?[r.height,r.width]:[r.width,r.height],{defaultSize:u,defaultLength:f}=n.props,d=a||u||c,h=o||f||l,p=s?"horizontal":"vertical",[v,g]=s?[h,d]:[d,h];return{orientation:p,width:v,height:g,size:d,length:h}}function dF(t){return t.find(e=>e.getOptions().domain.length>0).getOptions().domain}function ef(t){const e=["arrow","crosshairs","grid","handle","handleLabel","indicator","label","line","tick","tip","title","trunc"],{style:n}=t,r=sF(t,["style"]),i={};return Object.entries(r).forEach(([a,o])=>{e.includes(a)?i[`show${ii(a)}`]=o:i[a]=o}),Object.assign(Object.assign({},i),n)}var sE=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{if(!fw(e))return i;const a=t==="bottom"?[i,1]:[0,i],o=e.map(a);if(t==="bottom"){const s=o[0];return new Yt({domain:[0,n],range:[0,1]}).map(s)}else if(t==="left"){const s=o[1];return new Yt({domain:[0,r],range:[0,1]}).map(s)}return i}}function pF(t,e,n){if(t.getTicks)return t.getTicks();if(!n)return e;const[r,i]=Mr(e,o=>+o),{tickCount:a}=t.getOptions();return n(r,i,a)}function vF(t,e){if(Ht(e))return h=>h;const n=e.getOptions(),{innerWidth:r,innerHeight:i,insetTop:a,insetBottom:o,insetLeft:s,insetRight:c}=n,[l,u,f]=t==="left"||t==="right"?[a,o,i]:[s,c,r],d=new Yt({domain:[0,1],range:[l/f,1-u/f]});return h=>d.map(h)}function uE(t,e,n,r,i,a,o,s){var c;(n!==void 0||a!==void 0)&&t.update(Object.assign(Object.assign({},n&&{tickCount:n}),a&&{tickMethod:a}));const l=pF(t,e,a),u=i?l.filter(i):l,f=y=>y instanceof Date?String(y):typeof y=="object"&&y?y:String(y),d=r||((c=t.getFormatter)===null||c===void 0?void 0:c.call(t))||f,h=vF(o,s),p=hF(o,s),v=y=>["top","bottom","center","outer"].includes(y),g=y=>["left","right"].includes(y);return Ht(s)||qt(s)?u.map((y,m,b)=>{var x,w;const O=((x=t.getBandWidth)===null||x===void 0?void 0:x.call(t,y))/2||0,S=h(t.map(y)+O);return{value:Nu(s)&&o==="center"||qt(s)&&((w=t.getTicks)===null||w===void 0?void 0:w.call(t))&&v(o)||qt(s)&&g(o)?1-S:S,label:f(d(jl(y),m,b)),id:String(m)}}):u.map((y,m,b)=>{var x;const w=((x=t.getBandWidth)===null||x===void 0?void 0:x.call(t,y))/2||0,O=p(h(t.map(y)+w));return{value:g(o)?1-O:O,label:f(d(jl(y),m,b)),id:String(m)}})}function gF(t,e,n="xy"){const[r,i,a]=lE(e);return n==="xy"?t.includes("bottom")||t.includes("top")?i:r:n==="xz"?t.includes("bottom")||t.includes("top")?a:r:t.includes("bottom")||t.includes("top")?i:a}function yF(t=[],e){if(t.length>0)return t;const{labelAutoRotate:n,labelAutoHide:r,labelAutoEllipsis:i,labelAutoWrap:a}=e,o=[],s=(c,l)=>{l&&o.push(Object.assign(Object.assign({},c),l))};return s({type:"rotate",optionalAngles:[0,15,30,45,60,90]},n),s({type:"ellipsis",minLength:20},i),s({type:"hide"},r),s({type:"wrap",wordWrapWidth:100,maxLines:3,recoveryWhenFail:!0},a),o}function mF(t,e,n,r,i){const{x:a,y:o,width:s,height:c}=e,l=[a+s/2,o+c/2],u=Math.min(s,c)/2,[f,d]=Dp(i),[h,p]=lE(i),v=Math.min(h,p)/2,g={center:l,radius:u,startAngle:f,endAngle:d,gridLength:(r-n)*v};if(t==="inner"){const{insetLeft:y,insetTop:m}=i.getOptions();return Object.assign(Object.assign({},g),{center:[l[0]-y,l[1]-m],labelAlign:"perpendicular",labelDirection:"positive",tickDirection:"positive",gridDirection:"negative"})}return Object.assign(Object.assign({},g),{labelAlign:"parallel",labelDirection:"negative",tickDirection:"negative",gridDirection:"positive"})}function bF(t,e,n){return _L(e)||Ru(e)?!1:t===void 0?!!n.getTicks:t}function xF(t){const{depth:e}=t.getOptions();return e?{tickIsBillboard:!0,lineIsBillboard:!0,labelIsBillboard:!0,titleIsBillboard:!0,gridIsBillboard:!0}:{}}function wF(t,e,n,r,i){const{x:a,y:o,width:s,height:c}=n;if(t==="bottom")return{startPos:[a,o],endPos:[a+s,o]};if(t==="left")return{startPos:[a+s,o+c],endPos:[a+s,o]};if(t==="right")return{startPos:[a,o+c],endPos:[a,o]};if(t==="top")return{startPos:[a,o+c],endPos:[a+s,o+c]};if(t==="center"){if(e==="vertical")return{startPos:[a,o],endPos:[a,o+c]};if(e==="horizontal")return{startPos:[a,o],endPos:[a+s,o]};if(typeof e=="number"){const[l,u]=r.getCenter(),[f,d]=Iu(r),[h,p]=Dp(r),v=Math.min(s,c)/2,{insetLeft:g,insetTop:y}=r.getOptions(),m=f*v,b=d*v,[x,w]=[l+a-g,u+o-y],[O,S]=[Math.cos(e),Math.sin(e)],_=[x+b*O,w+b*S],M=[x+m*O,w+m*S],E=()=>{const{domain:T}=i.getOptions();return T.length},P=Ht(r)&&i?E():3;return{startPos:_,endPos:M,gridClosed:Math.abs(p-h-360)<1e-6,gridCenter:[x,w],gridControlAngles:new Array(P).fill(0).map((T,A,k)=>(p-h)/P*A)}}}return{}}const OF=t=>{const{order:e,size:n,position:r,orientation:i,labelFormatter:a,tickFilter:o,tickCount:s,tickMethod:c,important:l={},style:u={},indexBBox:f,title:d,grid:h=!1}=t,p=sE(t,["order","size","position","orientation","labelFormatter","tickFilter","tickCount","tickMethod","important","style","indexBBox","title","grid"]);return({scales:[v],value:g,coordinate:y,theme:m})=>{const{bbox:b}=g,{domain:x}=v.getOptions(),w=uE(v,x,s,a,o,c,r,y),O=f?w.map((A,k)=>{const C=f.get(k);return!C||C[0]!==A.label?A:Object.assign(Object.assign({},A),{bbox:C[1]})}):w,[S,_]=Iu(y),M=mF(r,b,S,_,y),{axis:E,axisArc:P={}}=m,T=ef(X({},E,P,M,Object.assign(Object.assign({type:"arc",data:O,titleText:tf(d),grid:h},p),l)));return new x0({style:Fb(T,["transform"])})}};function SF(t,e,n,r,i,a){const o=n.axis,s=["top","right","bottom","left"].includes(i)?n[`axis${bp(i)}`]:n.axisLinear,c=t.getOptions().name,l=n[`axis${ii(c)}`]||{};return Object.assign({},o,s,l)}function _F(t,e,n,r,i,a){const o=SF(t,e,n,r,i);return i==="center"?Object.assign(Object.assign(Object.assign(Object.assign({},o),{labelDirection:r==="right"?"negative":"positive"}),r==="center"?{labelTransform:"translate(50%,0)"}:null),{tickDirection:r==="right"?"negative":"positive",labelSpacing:r==="center"?0:4,titleSpacing:fF(a)?10:0,tick:r==="center"?!1:void 0}):o}const MF=t=>{const{direction:e="left",important:n={},labelFormatter:r,order:i,orientation:a,actualPosition:o,position:s,size:c,style:l={},title:u,tickCount:f,tickFilter:d,tickMethod:h,transform:p,indexBBox:v}=t,g=sE(t,["direction","important","labelFormatter","order","orientation","actualPosition","position","size","style","title","tickCount","tickFilter","tickMethod","transform","indexBBox"]);return({scales:y,value:m,coordinate:b,theme:x})=>{const{bbox:w}=m,[O]=y,{domain:S,xScale:_}=O.getOptions(),M=_F(O,b,x,e,s,a),E=Object.assign(Object.assign(Object.assign({},M),l),g),P=gF(o||s,b,t.plane),T=wF(s,a,w,b,_),A=xF(b),k=uE(O,S,f,r,d,h,s,b),C=v?k.map((R,j)=>{const D=v.get(j);return!D||D[0]!==R.label?R:Object.assign(Object.assign({},R),{bbox:D[1]})}):k,L=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},E),{type:"linear",data:C,crossSize:c,titleText:tf(u),labelOverlap:yF(p,E),grid:bF(E.grid,b,O),gridLength:P,line:!0,indexBBox:v}),E.line?null:{lineOpacity:0}),T),A),n);return L.labelOverlap.find(R=>R.type==="hide")&&(L.crossSize=!1),new x0({className:"axis",style:ef(L)})}},fE=t=>e=>{const{labelFormatter:n,labelFilter:r=()=>!0}=e;return i=>{var a;const{scales:[o]}=i,s=((a=o.getTicks)===null||a===void 0?void 0:a.call(o))||o.getOptions().domain,c=typeof n=="string"?fi(n):n,l=(f,d,h)=>r(s[d],d,s),u=Object.assign(Object.assign({},e),{labelFormatter:c,labelFilter:l,scale:o});return t(u)(i)}},di=fE(MF),dE=fE(OF);di.props={defaultPosition:"center",defaultSize:45,defaultOrder:0,defaultCrossPadding:[12,12],defaultPadding:[12,12]};dE.props={defaultPosition:"outer",defaultOrientation:"vertical",defaultSize:45,defaultOrder:0,defaultCrossPadding:[12,12],defaultPadding:[12,12]};const hE=t=>(...e)=>{const n=di(Object.assign({},{crossPadding:50},t))(...e);return cE(n,t),n};hE.props=Object.assign(Object.assign({},di.props),{defaultPosition:"bottom"});const pE=t=>(...e)=>{const n=di(Object.assign({},{crossPadding:10},t))(...e);return cE(n,t),n};pE.props=Object.assign(Object.assign({},di.props),{defaultPosition:"left"});var EF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i-Math.PI/2&&eMath.PI/2&&e(c-s)/i.count*f)})}const vE=t=>{const{important:e={}}=t,n=EF(t,["important"]);return r=>{const{theme:i,coordinate:a,scales:o}=r;return di(Object.assign(Object.assign(Object.assign({},n),PF(t.orientation)),{important:Object.assign(Object.assign({},AF(t,i,a,o)),e)}))(r)}};vE.props=Object.assign(Object.assign({},di.props),{defaultPosition:"center"});var kF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i0?r==null?void 0:r.getOptions().domain:c.data).map((d,h)=>{var p;return i?i.map(d||"point"):((p=s==null?void 0:s.style)===null||p===void 0?void 0:p.shape)||c.defaultShape||"point"});typeof l=="string"&&a.push([l,f])}if(a.length===0)return["point",["point"]];if(a.length===1||!n)return a[0];const{range:o}=n.getOptions();return a.map(([s,c])=>{let l=0;for(let u=0;uc[0]-s[0])[0][1]}function CF(t,e){const{scales:n,library:r,markState:i}=e,[a,o]=TF(n,i),{itemMarker:s,itemMarkerSize:c}=t,l=(d,h)=>{var p,v,g;const y=((g=(v=(p=r[`mark.${a}`])===null||p===void 0?void 0:p.props)===null||v===void 0?void 0:v.shape[d])===null||g===void 0?void 0:g.props.defaultMarker)||Ns(d.split(".")),m=typeof c=="function"?c(h):c;return()=>tI(y,{color:h.color})(0,0,m)},u=d=>`${o[d]}`;return lr(n,"shape")&&!s?(d,h)=>l(u(h),d):typeof s=="function"?(d,h)=>{const p=s(d.id,h);return typeof p=="string"?l(p,d):p}:(d,h)=>l(s||u(h),d)}function LF(t){const e=lr(t,"opacity");if(e){const{range:n}=e.getOptions();return(r,i)=>n[i]}}function NF(t,e){const n=lr(t,"size");return n instanceof o2?n.map(NaN)*2:e}function RF(t,e){const{labelFormatter:n=d=>`${d}`}=t,{scales:r,theme:i}=e,a=i.legendCategory.itemMarkerSize,o=NF(r,a),s={itemMarker:CF(Object.assign(Object.assign({},t),{itemMarkerSize:o}),e),itemMarkerSize:o,itemMarkerOpacity:LF(r)},c=typeof n=="string"?fi(n):n,l=lr(r,"color"),u=dF(r),f=l?d=>l.map(d):()=>e.theme.color;return Object.assign(Object.assign({},s),{data:u.map(d=>({id:d,label:c(d),color:f(d)}))})}function IF(t,e,n){const{position:r}=e;if(r==="center"){const{bbox:o}=t,{width:s,height:c}=o;return{width:s,height:c}}const{width:i,height:a}=oE(t,e,n);return{width:i,height:a}}const D0=t=>{const{labelFormatter:e,layout:n,order:r,orientation:i,position:a,size:o,title:s,cols:c,itemMarker:l}=t,u=kF(t,["labelFormatter","layout","order","orientation","position","size","title","cols","itemMarker"]),{gridRow:f}=u;return d=>{const{value:h,theme:p}=d,{bbox:v}=h,{width:g,height:y}=IF(h,t,D0),m=iE(a,n),b=Object.assign(Object.assign(Object.assign(Object.assign({orientation:["right","left","center"].includes(a)?"vertical":"horizontal",width:g,height:y,layout:c!==void 0?"grid":"flex"},c!==void 0&&{gridCol:c}),f!==void 0&&{gridRow:f}),{titleText:tf(s)}),RF(t,d)),{legendCategory:x={}}=p,w=ef(Object.assign({},x,b,u)),O=new lF({style:Object.assign(Object.assign({x:v.x,y:v.y,width:v.width,height:v.height},m),{subOptions:w})});return O.appendChild(new Ej({className:"legend-category",style:w})),O}};D0.props={defaultPosition:"top",defaultOrder:1,defaultSize:40,defaultCrossPadding:[12,12],defaultPadding:[12,12]};var jF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i({value:e/t,label:String(e)})}function FF(t,e,n,r,i){const a=e.thresholds,o=BF(r);return Object.assign(Object.assign({},t),{color:i,data:[n,...a,r].map(o)})}function zF(t,e,n){const i=[-1/0,...e.thresholds,1/0].map((a,o)=>({value:o,label:a}));return Object.assign(Object.assign({},t),{data:i,color:n,labelFilter:(a,o)=>o>0&&op!==void 0).find(p=>!(p instanceof Ep)));return Object.assign(Object.assign({},t),{domain:[d,h],data:l.getTicks().map(p=>({value:p})),color:new Array(Math.floor(o)).fill(0).map((p,v)=>{const g=(f-u)/(o-1)*v+u,y=l.map(g)||c,m=r?r.map(g):1;return y.replace(/rgb[a]*\(([\d]{1,3}) *, *([\d]{1,3}) *, *([\d]{1,3})[\S\s]*\)/,(b,x,w,O)=>`rgba(${x}, ${w}, ${O}, ${m})`)})})}function WF(t,e,n,r,i,a){const o=lr(t,"color"),s=$F(n,r,i);if(o instanceof Au){const{range:u}=o.getOptions(),[f,d]=Ah(o);return o instanceof g2||o instanceof m2?FF(s,o,f,d,u):zF(s,o,u)}const c=lr(t,"size"),l=lr(t,"opacity");return YF(s,o,c,l,e,a)}const hi=t=>{const{labelFormatter:e,layout:n,order:r,orientation:i,position:a,size:o,title:s,style:c,crossPadding:l,padding:u}=t,f=jF(t,["labelFormatter","layout","order","orientation","position","size","title","style","crossPadding","padding"]);return({scales:d,value:h,theme:p,scale:v})=>{const{bbox:g}=h,{x:y,y:m,width:b,height:x}=g,w=iE(a,n),{legendContinuous:O={}}=p,S=ef(Object.assign({},O,Object.assign(Object.assign({titleText:tf(s),labelAlign:"value",labelFormatter:typeof e=="string"?M=>fi(e)(M.label):e},WF(d,v,h,t,hi,p)),c),f)),_=new aE({style:Object.assign(Object.assign({x:y,y:m,width:b,height:x},w),{subOptions:S})});return _.appendChild(new $j({className:"legend-continuous",style:S})),_}};hi.props={defaultPosition:"top",defaultOrientation:"vertical",defaultOrder:1,defaultSize:60,defaultLength:200,defaultLegendSize:60,defaultPadding:[20,10],defaultCrossPadding:[12,12]};const gE=t=>(...e)=>hi(Object.assign({},{block:!0},t))(...e);gE.props=Object.assign(Object.assign({},hi.props),{defaultPosition:"top",defaultOrientation:"horizontal"});const $0=t=>e=>{const{scales:n}=e,r=lr(n,"size");return hi(Object.assign({},{type:"size",data:r.getTicks().map((i,a)=>({value:i,label:String(i)}))},t))(e)};$0.props=Object.assign(Object.assign({},hi.props),{defaultPosition:"top",defaultOrientation:"horizontal"});const yE=t=>$0(Object.assign({},{block:!0},t));yE.props=Object.assign(Object.assign({},hi.props),{defaultPosition:"top",defaultOrientation:"horizontal"});var HF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{if(!i)return d.node().remove();d.node().attr(Object.assign(Object.assign(Object.assign({},e1(0,f.max[1]+a,n,o)),{fontSize:12,textBaseline:"top",text:i}),l))})}}),mE=t=>({value:e,theme:n})=>{const{x:r,y:i,width:a,height:o}=e.bbox;return new VF({style:X({},n.title,Object.assign({x:r,y:i,width:a,height:o},t))})};mE.props={defaultPosition:"top",defaultOrder:2,defaultSize:36,defaultCrossPadding:[20,20],defaultPadding:[12,12]};function XF(t,e,n){return Math.min(n,Math.max(e,t))}function Ho(t){return!!t.getBandWidth}function Ha(t,e,n){if(!Ho(t))return t.invert(e);const{adjustedRange:r}=t,{domain:i}=t.getOptions(),a=n?-1:0,o=t.getStep(),s=n?r:r.map(u=>u+o),c=h5(s,e),l=XF(c+a,0,i.length-1);return i[l]}function Vr(t,e,n){if(!e)return t.getOptions().domain;if(!Ho(t)){const c=Er(e);if(!n)return c;const[l]=c,{range:u}=t.getOptions(),[f,d]=u,h=f>d?-1:1,p=t.invert(t.map(l)+h*n);return[l,p]}const{domain:r}=t.getOptions(),i=e[0],a=r.indexOf(i);if(n){const c=a+Math.round(r.length*n);return r.slice(a,c)}const o=e[e.length-1],s=r.indexOf(o);return r.slice(a,s+1)}function cl(t,e,n,r,i,a){const{x:o,y:s}=i,c=(h,p)=>{const[v,g]=a.invert(h);return[Ha(o,v,p),Ha(s,g,p)]},l=c([t,e],!0),u=c([n,r],!1),f=Vr(o,[l[0],u[0]]),d=Vr(s,[l[1],u[1]]);return[f,d]}function ql(t,e){const[n,r]=t,i=a=>a.getStep?a.getStep():0;return[e.map(n),e.map(r)+i(e)]}function UF(t,e,n){const{x:r,y:i}=e,[a,o]=t,s=ql(a,r),c=ql(o,i),l=[s[0],c[0]],u=[s[1],c[1]],[f,d]=n.map(l),[h,p]=n.map(u);return[f,d,h,p]}var qF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{orientation:e,labelFormatter:n,size:r,style:i={},position:a}=t,o=qF(t,["orientation","labelFormatter","size","style","position"]);return s=>{var c;const{scales:[l],value:u,theme:f,coordinate:d}=s,{bbox:h}=u,{width:p,height:v}=h,{slider:g={}}=f,y=((c=l.getFormatter)===null||c===void 0?void 0:c.call(l))||(_=>_+""),m=typeof n=="string"?fi(n):n,b=e==="horizontal",x=qt(d)&&b,{trackSize:w=g.trackSize}=i,[O,S]=KF(h,a,w);return new pS({className:"slider",style:Object.assign({},g,Object.assign(Object.assign({x:O,y:S,trackLength:b?p:v,orientation:e,formatter:_=>{const M=m||y,E=x?1-_:_,P=Ha(l,E,!0);return M(P)},sparklineData:QF(t,s)},i),o))})}};function ZF(t,e){const[n]=Array.from(t.entries()).filter(([i])=>i.type==="line"||i.type==="area").map(([i])=>{const{encode:a,slider:o}=i;if(o!=null&&o.x&&Object.keys(o.x).length===0){const s=c=>{const l=a[c];return[c,l?l.value:void 0]};return Object.fromEntries(e.map(s))}});if(!(n!=null&&n.series))return n==null?void 0:n.y;const r=n.series.reduce((i,a,o)=>(i[a]=i[a]||[],i[a].push(n.y[o]),i),{});return Object.values(r)}function QF(t,e){const{markState:n}=e;return Le(t.sparklineData)?t.sparklineData:ZF(n,["y","series"])}Js.props={defaultPosition:"bottom",defaultSize:24,defaultOrder:1,defaultCrossPadding:[12,12],defaultPadding:[12,12]};const bE=t=>Js(Object.assign(Object.assign({},t),{orientation:"horizontal"}));bE.props=Object.assign(Object.assign({},Js.props),{defaultPosition:"bottom"});const xE=t=>Js(Object.assign(Object.assign({},t),{orientation:"vertical"}));xE.props=Object.assign(Object.assign({},Js.props),{defaultPosition:"left"});var JF=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{orientation:e,labelFormatter:n,style:r}=t,i=JF(t,["orientation","labelFormatter","style"]);return({scales:[a],value:o,theme:s})=>{const{bbox:c}=o,{x:l,y:u,width:f,height:d}=c,{scrollbar:h={}}=s,{ratio:p,range:v}=a.getOptions(),g=e==="horizontal"?f:d,y=g/p,[m,b]=v,x=b>m?0:1;return new d8({className:"g2-scrollbar",style:Object.assign({},h,Object.assign(Object.assign(Object.assign(Object.assign({},r),{x:l,y:u,trackLength:g,value:x}),i),{orientation:e,contentLength:y,viewportLength:g}))})}};tc.props={defaultPosition:"bottom",defaultSize:24,defaultOrder:1,defaultCrossPadding:[12,12],defaultPadding:[12,12]};const wE=t=>tc(Object.assign(Object.assign({},t),{orientation:"horizontal"}));wE.props=Object.assign(Object.assign({},tc.props),{defaultPosition:"bottom"});const OE=t=>tc(Object.assign(Object.assign({},t),{orientation:"vertical"}));OE.props=Object.assign(Object.assign({},tc.props),{defaultPosition:"left"});const SE=t=>()=>new Ce;SE.props={};const B0=(t,e)=>{const{coordinate:r}=e;return(i,a,o)=>{const[s]=i,{transform:c="",fillOpacity:l=1,strokeOpacity:u=1,opacity:f=1}=s.style,[d,h]=qt(r)?["left bottom",`scale(1, ${1e-4})`]:["left top",`scale(${1e-4}, 1)`],p=[{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:0,strokeOpacity:0,opacity:0},{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:l,strokeOpacity:u,opacity:f,offset:.01},{transform:`${c} scale(1, 1)`.trimStart(),transformOrigin:d,fillOpacity:l,strokeOpacity:u,opacity:f}];return s.animate(p,Object.assign(Object.assign({},o),t))}},tz=(t,e)=>{const{coordinate:r}=e;return(i,a,o)=>{const[s]=i,{transform:c="",fillOpacity:l=1,strokeOpacity:u=1,opacity:f=1}=s.style,[d,h]=qt(r)?["left bottom",`scale(1, ${1e-4})`]:["left top",`scale(${1e-4}, 1)`],p=[{transform:`${c} scale(1, 1)`.trimStart(),transformOrigin:d},{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:l,strokeOpacity:u,opacity:f,offset:.99},{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:0,strokeOpacity:0,opacity:0}];return s.animate(p,Object.assign(Object.assign({},o),t))}},_E=(t,e)=>{const{coordinate:r}=e;return Ww.registerProperty({name:"scaleInYRadius",inherits:!1,initialValue:"",interpolable:!0,syntax:tt.NUMBER}),(i,a,o)=>{const[s]=i,c=u=>{const{__data__:f,style:d}=u,{radius:h=0,inset:p=0,fillOpacity:v=1,strokeOpacity:g=1,opacity:y=1}=d,{points:m,y:b,y1:x}=f,w=Qi(r,m,[b,x]),{innerRadius:O,outerRadius:S}=w,_=Cu().cornerRadius(h).padAngle(p*Math.PI/180),M=new Xe({}),E=r.getCenter(),P=k=>{M.attr({d:_(k),transform:`translate(${E[0]}, ${E[1]})`});const C=Wp(M);return M.style.transform="",C},T=[{scaleInYRadius:O+1e-4,fillOpacity:0,strokeOpacity:0,opacity:0},{scaleInYRadius:O+1e-4,fillOpacity:v,strokeOpacity:g,opacity:y,offset:.01},{scaleInYRadius:S,fillOpacity:v,strokeOpacity:g,opacity:y}],A=u.animate(T,Object.assign(Object.assign({},o),t));return A.onframe=function(){u.style.path=P(Object.assign(Object.assign({},w),{outerRadius:Number(u.style.scaleInYRadius)}))},A.onfinish=function(){u.style.path=P(Object.assign(Object.assign({},w),{outerRadius:S}))},A},l=u=>{const{style:f}=u,{transform:d="",fillOpacity:h=1,strokeOpacity:p=1,opacity:v=1}=f,[g,y]=qt(r)?["left top",`scale(${1e-4}, 1)`]:["left bottom",`scale(1, ${1e-4})`],m=[{transform:`${d} ${y}`.trimStart(),transformOrigin:g,fillOpacity:0,strokeOpacity:0,opacity:0},{transform:`${d} ${y}`.trimStart(),transformOrigin:g,fillOpacity:h,strokeOpacity:p,opacity:v,offset:.01},{transform:`${d} scale(1, 1)`.trimStart(),transformOrigin:g,fillOpacity:h,strokeOpacity:p,opacity:v}];return u.animate(m,Object.assign(Object.assign({},o),t))};return Ht(r)?c(s):l(s)}},ez=(t,e)=>{const{coordinate:r}=e;return(i,a,o)=>{const[s]=i,{transform:c="",fillOpacity:l=1,strokeOpacity:u=1,opacity:f=1}=s.style,[d,h]=qt(r)?["left top",`scale(${1e-4}, 1)`]:["left bottom",`scale(1, ${1e-4})`],p=[{transform:`${c} scale(1, 1)`.trimStart(),transformOrigin:d},{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:l,strokeOpacity:u,opacity:f,offset:.99},{transform:`${c} ${h}`.trimStart(),transformOrigin:d,fillOpacity:0,strokeOpacity:0,opacity:0}];return s.animate(p,Object.assign(Object.assign({},o),t))}},ME=t=>(e,n,r)=>{const[i]=e,{fillOpacity:a=1,strokeOpacity:o=1,opacity:s=1}=i.style,c=[{fillOpacity:0,strokeOpacity:0,opacity:0},{fillOpacity:a,strokeOpacity:o,opacity:s}];return i.animate(c,Object.assign(Object.assign({},r),t))};ME.props={};const EE=t=>(e,n,r)=>{const[i]=e,{fillOpacity:a=1,strokeOpacity:o=1,opacity:s=1}=i.style,c=[{fillOpacity:a,strokeOpacity:o,opacity:s},{fillOpacity:0,strokeOpacity:0,opacity:0}];return i.animate(c,Object.assign(Object.assign({},r),t))};EE.props={};function Va(t,e){const n={};for(const r of e){const i=t.style[r];i&&(n[r]=i)}return n}const Xa=["fill","stroke","fillOpacity","strokeOpacity","opacity","lineWidth"];function kh(t){const{min:e,max:n}=t.getLocalBounds(),[r,i]=e,[a,o]=n,s=o-i,c=a-r;return[r,i,c,s]}function nz(t){const[e,n,r,i]=t;return` - M ${e} ${n} - L ${e+r} ${n} - L ${e+r} ${n+i} - L ${e} ${n+i} - Z - `}function rz(t,e){const[n,r,i,a]=kh(t),o=a/i,s=Math.ceil(Math.sqrt(e/o)),c=Math.ceil(e/s),l=[],u=a/c;let f=0,d=e;for(;d>0;){const h=Math.min(d,s),p=i/h;for(let v=0;v{u.style.transform="none",xp(u,n)},u.style.transform="none",d}function cz(t,e,n,r){t.style.visibility="hidden";const i=r(t,e.length);return e.map((a,o)=>{const s=new Xe({style:Object.assign({path:i[o]},Va(t,Xa))});return F0(a,s,a,n)})}function lz(t,e,n,r){const i=r(e,t.length),{fillOpacity:a=1,strokeOpacity:o=1,opacity:s=1}=e.style,c=[{fillOpacity:0,strokeOpacity:0,opacity:0},{fillOpacity:0,strokeOpacity:0,opacity:0,offset:.99},{fillOpacity:a,strokeOpacity:o,opacity:s}],l=e.animate(c,n);return[...t.map((f,d)=>{const h=new Xe({style:{path:i[d],fill:e.style.fill}});return F0(f,f,h,n)}),l]}const AE=t=>(e,n,r)=>{const i=iz(t.split),a=Object.assign(Object.assign({},r),t),{length:o}=e,{length:s}=n;if(o===1&&s===1||o>1&&s>1){const[c]=e,[l]=n;return F0(c,c,l,a)}if(o===1&&s>1){const[c]=e;return cz(c,n,a,i)}if(o>1&&s===1){const[c]=n;return lz(e,c,a,i)}return null};AE.props={};const kE=(t,e)=>{Ww.registerProperty({name:"waveInArcAngle",inherits:!1,initialValue:"",interpolable:!0,syntax:tt.NUMBER});const{coordinate:r}=e;return(i,a,o)=>{const[s]=i;if(!Ht(r))return B0(t,e)(i,a,o);const c=r.getCenter(),{__data__:l,style:u}=s,{radius:f=0,inset:d=0,fillOpacity:h=1,strokeOpacity:p=1,opacity:v=1}=u,{points:g,y,y1:m}=l,b=Cu().cornerRadius(f).padAngle(d*Math.PI/180),x=Qi(r,g,[y,m]),{startAngle:w,endAngle:O}=x,S=new Xe({}),_=P=>{S.attr({d:b(P),transform:`translate(${c[0]}, ${c[1]})`});const T=Wp(S);return S.style.transform="",T},M=[{waveInArcAngle:w+1e-4,fillOpacity:0,strokeOpacity:0,opacity:0},{waveInArcAngle:w+1e-4,fillOpacity:h,strokeOpacity:p,opacity:v,offset:.01},{waveInArcAngle:O,fillOpacity:h,strokeOpacity:p,opacity:v}],E=s.animate(M,Object.assign(Object.assign({},o),t));return E.onframe=function(){s.style.path=_(Object.assign(Object.assign({},x),{endAngle:Number(s.style.waveInArcAngle)}))},E.onfinish=function(){s.style.path=_(Object.assign(Object.assign({},x),{endAngle:O}))},E}};kE.props={};const uz=t=>(n,r,i)=>{const[a]=n,{transform:o="",fillOpacity:s=1,strokeOpacity:c=1,opacity:l=1}=a.style,u="center center",f=[{transform:`${o} scale(${1e-4})`.trimStart(),transformOrigin:u,fillOpacity:0,strokeOpacity:0,opacity:0},{transform:`${o} scale(${1e-4})`.trimStart(),transformOrigin:u,fillOpacity:s,strokeOpacity:c,opacity:l,offset:.01},{transform:`${o} scale(1)`.trimStart(),transformOrigin:u,fillOpacity:s,strokeOpacity:c,opacity:l}];return a.animate(f,Object.assign(Object.assign({},i),t))},fz=t=>(n,r,i)=>{const[a]=n,{transform:o="",fillOpacity:s=1,strokeOpacity:c=1,opacity:l=1}=a.style,u="center center",f=[{transform:`${o} scale(1)`.trimStart(),transformOrigin:u},{transform:`${o} scale(${1e-4})`.trimStart(),transformOrigin:u,fillOpacity:s,strokeOpacity:c,opacity:l,offset:.99},{transform:`${o} scale(${1e-4})`.trimStart(),transformOrigin:u,fillOpacity:0,strokeOpacity:0,opacity:0}];return a.animate(f,Object.assign(Object.assign({},i),t))},TE=t=>(e,n,r)=>{var i,a;const[o]=e,s=((a=(i=o).getTotalLength)===null||a===void 0?void 0:a.call(i))||0,c=[{lineDash:[0,s]},{lineDash:[s,0]}];return o.animate(c,Object.assign(Object.assign({},r),t))};TE.props={};const CE=(t,e)=>(n,r,i)=>{const[a]=n,{height:o,width:s}=a.getBoundingClientRect(),c=new Xe({style:{path:`M0,0L${s},0L${s},${o}L0,${o}Z`}});return a.appendChild(c),a.style.clipPath=c,B0(t,e)([c],r,i)};CE.props={};const LE=(t,e)=>(n,r,i)=>{const[a]=n,{height:o,width:s}=a.getBoundingClientRect(),c=new Xe({style:{path:`M0,0L${s},0L${s},${o}L0,${o}Z`}});return a.appendChild(c),a.style.clipPath=c,_E(t,e)([c],r,i)};LE.props={};const i1="main-layer",Th="label-layer",xr="element",Ch="view",Kl="plot",a1="component",Lh="label",o1="area";function dz(t,e){var n=e.r;t.arc(n,n,n,0,Math.PI*2,!1)}function hz(t,e){var n=e.rx,r=e.ry,i=n,a=r;if(t.ellipse)t.ellipse(i,a,i,a,0,0,Math.PI*2,!1);else{var o=i>a?i:a,s=i>a?1:i/a,c=i>a?a/i:1;t.save(),t.scale(s,c),t.arc(o,o,o,0,Math.PI*2)}}function pz(t,e){var n=e.x1,r=e.y1,i=e.x2,a=e.y2,o=e.defX,s=o===void 0?0:o,c=e.defY,l=c===void 0?0:c,u=e.markerStart,f=e.markerEnd,d=e.markerStartOffset,h=e.markerEndOffset,p=0,v=0,g=0,y=0,m=0,b,x;u&&Mt(u)&&d&&(b=i-n,x=a-r,m=Math.atan2(x,b),p=Math.cos(m)*(d||0),v=Math.sin(m)*(d||0)),f&&Mt(f)&&h&&(b=n-i,x=r-a,m=Math.atan2(x,b),g=Math.cos(m)*(h||0),y=Math.sin(m)*(h||0)),t.moveTo(n-s+p,r-l+v),t.lineTo(i-s+g,a-l+y)}function vz(t,e){var n=e.defX,r=n===void 0?0:n,i=e.defY,a=i===void 0?0:i,o=e.markerStart,s=e.markerEnd,c=e.markerStartOffset,l=e.markerEndOffset,u=e.path,f=u.absolutePath,d=u.segments,h=0,p=0,v=0,g=0,y=0,m,b;if(o&&Mt(o)&&c){var x=N(o.parentNode.getStartTangent(),2),w=x[0],O=x[1];m=w[0]-O[0],b=w[1]-O[1],y=Math.atan2(b,m),h=Math.cos(y)*(c||0),p=Math.sin(y)*(c||0)}if(s&&Mt(s)&&l){var S=N(s.parentNode.getEndTangent(),2),w=S[0],O=S[1];m=w[0]-O[0],b=w[1]-O[1],y=Math.atan2(b,m),v=Math.cos(y)*(l||0),g=Math.sin(y)*(l||0)}for(var _=0;_R?I:R,Y=I>R?1:I/R,U=I>R?R/I:1;t.translate(C-r,L-a),t.rotate($),t.scale(Y,U),t.arc(0,0,F,j,D,!!(1-B)),t.scale(1/Y,1/U),t.rotate(-$),t.translate(-(C-r),-(L-a))}A&&t.lineTo(M[6]-r+v,M[7]-a+g);break}case"Z":t.closePath();break}}}function gz(t,e){var n=e.defX,r=n===void 0?0:n,i=e.defY,a=i===void 0?0:i,o=e.markerStart,s=e.markerEnd,c=e.markerStartOffset,l=e.markerEndOffset,u=e.points.points,f=u.length,d=u[0][0]-r,h=u[0][1]-a,p=u[f-1][0]-r,v=u[f-1][1]-a,g=0,y=0,m=0,b=0,x=0,w,O;o&&Mt(o)&&c&&(w=u[1][0]-u[0][0],O=u[1][1]-u[0][1],x=Math.atan2(O,w),g=Math.cos(x)*(c||0),y=Math.sin(x)*(c||0)),s&&Mt(s)&&l&&(w=u[f-1][0]-u[0][0],O=u[f-1][1]-u[0][1],x=Math.atan2(O,w),m=Math.cos(x)*(l||0),b=Math.sin(x)*(l||0)),t.moveTo(d+(g||m),h+(y||b));for(var S=1;S0?1:-1,l=i>0?1:-1,u=c+l===0,f=N(n.map(function(g){return ce(g,0,Math.min(Math.abs(a)/2,Math.abs(o)/2))}),4),d=f[0],h=f[1],p=f[2],v=f[3];t.moveTo(c*d,0),t.lineTo(a-c*h,0),h!==0&&t.arc(a-c*h,l*h,h,-l*Math.PI/2,c>0?0:Math.PI,u),t.lineTo(a,o-l*p),p!==0&&t.arc(a-c*p,o-l*p,p,c>0?0:Math.PI,l>0?Math.PI/2:1.5*Math.PI,u),t.lineTo(c*v,o),v!==0&&t.arc(c*v,o-l*v,v,l>0?Math.PI/2:-Math.PI/2,c>0?Math.PI:0,u),t.lineTo(0,l*d),d!==0&&t.arc(c*d,l*d,d,c>0?Math.PI:0,l>0?Math.PI*1.5:Math.PI/2,u)}}var bz=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.name="canvas-path-generator",n}return e.prototype.init=function(){var n,r=(n={},n[G.CIRCLE]=dz,n[G.ELLIPSE]=hz,n[G.RECT]=mz,n[G.LINE]=pz,n[G.POLYLINE]=yz,n[G.POLYGON]=gz,n[G.PATH]=vz,n[G.TEXT]=void 0,n[G.GROUP]=void 0,n[G.IMAGE]=void 0,n[G.HTML]=void 0,n[G.MESH]=void 0,n);this.context.pathGeneratorFactory=r},e.prototype.destroy=function(){delete this.context.pathGeneratorFactory},e}(ci),xz=yt(),wz=yt(),Oz=yt(),Sz=Nt(),_z=function(){function t(){var e=this;this.isHit=function(n,r,i,a){var o=e.context.pointInPathPickerFactory[n.nodeName];if(o){var s=Wn(Sz,i),c=Oe(wz,Gn(Oz,r[0],r[1],0),s),l=n.getGeometryBounds().halfExtents,u=n.parsedStyle.anchor;if(c[0]+=(u&&u[0]||0)*l[0]*2,c[1]+=(u&&u[1]||0)*l[1]*2,o(n,new Ee(c[0],c[1]),a,e.isPointInPath,e.context,e.runtime))return!0}return!1},this.isPointInPath=function(n,r){var i=e.runtime.offscreenCanvasCreator.getOrCreateContext(e.context.config.offscreenCanvas),a=e.context.pathGeneratorFactory[n.nodeName];return a&&(i.beginPath(),a(i,n.parsedStyle),i.closePath()),i.isPointInPath(r.x,r.y)}}return t.prototype.apply=function(e,n){var r=this,i,a=e.renderingService,o=e.renderingContext;this.context=e,this.runtime=n;var s=(i=o.root)===null||i===void 0?void 0:i.ownerDocument;a.hooks.pick.tapPromise(t.tag,function(c){return ka(r,void 0,void 0,function(){return Ta(this,function(l){return[2,this.pick(s,c)]})})}),a.hooks.pickSync.tap(t.tag,function(c){return r.pick(s,c)})},t.prototype.pick=function(e,n){var r,i,a=n.topmost,o=n.position,s=o.x,c=o.y,l=Gn(xz,s,c,0),u=e.elementsFromBBox(l[0],l[1],l[0],l[1]),f=[];try{for(var d=vn(u),h=d.next();!h.done;h=d.next()){var p=h.value,v=p.getWorldTransform(),g=this.isHit(p,l,v,!1);if(g){var y=Iw(p);if(y){var m=y.parsedStyle.clipPath,b=this.isHit(m,l,m.getWorldTransform(),!0);if(b){if(a)return n.picked=[p],n;f.push(p)}}else{if(a)return n.picked=[p],n;f.push(p)}}}}catch(x){r={error:x}}finally{try{h&&!h.done&&(i=d.return)&&i.call(d)}finally{if(r)throw r.error}}return n.picked=f,n},t.tag="CanvasPicker",t}();function Mz(t,e,n){var r=t.parsedStyle,i=r.r,a=r.fill,o=r.stroke,s=r.lineWidth,c=r.increasedLineWidthForHitTesting,l=r.pointerEvents,u=((s||0)+(c||0))/2,f=Pr(i,i,e.x,e.y),d=N(Ki(l,a,o),2),h=d[0],p=d[1];return h&&p||n?f<=i+u:h?f<=i:p?f>=i-u&&f<=i+u:!1}function Dc(t,e,n,r){return t/(n*n)+e/(r*r)}function Ez(t,e,n){var r=t.parsedStyle,i=r.rx,a=r.ry,o=r.fill,s=r.stroke,c=r.lineWidth,l=r.increasedLineWidthForHitTesting,u=r.pointerEvents,f=e.x,d=e.y,h=N(Ki(u,o,s),2),p=h[0],v=h[1],g=((c||0)+(l||0))/2,y=(f-i)*(f-i),m=(d-a)*(d-a);return p&&v||n?Dc(y,m,i+g,a+g)<=1:p?Dc(y,m,i,a)<=1:v?Dc(y,m,i-g,a-g)>=1&&Dc(y,m,i+g,a+g)<=1:!1}function Ei(t,e,n,r,i,a){return i>=t&&i<=t+n&&a>=e&&a<=e+r}function Pz(t,e,n,r,i,a,o){var s=i/2;return Ei(t-s,e-s,n,i,a,o)||Ei(t+n-s,e-s,i,r,a,o)||Ei(t+s,e+r-s,n,i,a,o)||Ei(t-s,e+s,i,r,a,o)}function $c(t,e,n,r,i,a,o,s){var c=(Math.atan2(s-e,o-t)+Math.PI*2)%(Math.PI*2),l={x:t+n*Math.cos(c),y:e+n*Math.sin(c)};return Pr(l.x,l.y,o,s)<=a/2}function Xr(t,e,n,r,i,a,o){var s=Math.min(t,n),c=Math.max(t,n),l=Math.min(e,r),u=Math.max(e,r),f=i/2;return a>=s-f&&a<=c+f&&o>=l-f&&o<=u+f?HL(t,e,n,r,a,o)<=i/2:!1}function NE(t,e,n,r,i){var a=t.length;if(a<2)return!1;for(var o=0;o0!=fd(s[1]-n)>0&&fd(e-(n-o[1])*(o[0]-s[0])/(o[1]-s[1])-o[0])<0&&(r=!r)}return r}function s1(t,e,n){for(var r=!1,i=0;ix&&M>w,v&&(v.resetTransform?v.resetTransform():v.setTransform(1,0,0,1,0,0),r.clearFullScreen&&r.clearRect(v,0,0,y*g,m*g,i.background))});var p=function(v,g){v.isVisible()&&!v.isCulled()&&(r.renderDisplayObject(v,g,r.context,r.restoreStack,n),r.saveDirtyAABB(v));var y=v.sortable.sorted||v.childNodes;y.forEach(function(m){p(m,g)})};o.hooks.endFrame.tap(t.tag,function(){var v=u.getContext(),g=u.getDPR();if(fp(r.dprMatrix,[g,g,1]),$e(r.vpMatrix,r.dprMatrix,a.getOrthoMatrix()),r.clearFullScreen)p(s.root,v);else{var y=r.safeMergeAABB.apply(r,q([r.mergeDirtyAABBs(r.renderQueue)],N(r.removedRBushNodeAABBs.map(function($){var B=$.minX,F=$.minY,Y=$.maxX,U=$.maxY,K=new be;return K.setMinMax([B,F,0],[Y,U,0]),K})),!1));if(r.removedRBushNodeAABBs=[],be.isEmpty(y)){r.renderQueue=[];return}var m=r.convertAABB2Rect(y),b=m.x,x=m.y,w=m.width,O=m.height,S=Oe(r.vec3a,[b,x,0],r.vpMatrix),_=Oe(r.vec3b,[b+w,x,0],r.vpMatrix),M=Oe(r.vec3c,[b,x+O,0],r.vpMatrix),E=Oe(r.vec3d,[b+w,x+O,0],r.vpMatrix),P=Math.min(S[0],_[0],E[0],M[0]),T=Math.min(S[1],_[1],E[1],M[1]),A=Math.max(S[0],_[0],E[0],M[0]),k=Math.max(S[1],_[1],E[1],M[1]),C=Math.floor(P),L=Math.floor(T),I=Math.ceil(A-P),R=Math.ceil(k-T);v.save(),r.clearRect(v,C,L,I,R,i.background),v.beginPath(),v.rect(C,L,I,R),v.clip(),v.setTransform(r.vpMatrix[0],r.vpMatrix[1],r.vpMatrix[4],r.vpMatrix[5],r.vpMatrix[12],r.vpMatrix[13]);var j=i.renderer.getConfig().enableDirtyRectangleRenderingDebug;j&&f.dispatchEvent(new Dt(an.DIRTY_RECTANGLE,{dirtyRect:{x:C,y:L,width:I,height:R}}));var D=r.searchDirtyObjects(y);D.sort(function($,B){return $.sortable.renderOrder-B.sortable.renderOrder}).forEach(function($){$&&$.isVisible()&&!$.isCulled()&&r.renderDisplayObject($,v,r.context,r.restoreStack,n)}),v.restore(),r.renderQueue.forEach(function($){r.saveDirtyAABB($)}),r.renderQueue=[]}r.restoreStack.forEach(function(){v.restore()}),r.restoreStack=[]}),o.hooks.render.tap(t.tag,function(v){r.clearFullScreen||r.renderQueue.push(v)})},t.prototype.clearRect=function(e,n,r,i,a,o){e.clearRect(n,r,i,a),o&&(e.fillStyle=o,e.fillRect(n,r,i,a))},t.prototype.renderDisplayObject=function(e,n,r,i,a){var o=e.nodeName,s=i[i.length-1];s&&!(e.compareDocumentPosition(s)&_e.DOCUMENT_POSITION_CONTAINS)&&(n.restore(),i.pop());var c=this.context.styleRendererFactory[o],l=this.pathGeneratorFactory[o],u=e.parsedStyle.clipPath;if(u){this.applyWorldTransform(n,u);var f=this.pathGeneratorFactory[u.nodeName];f&&(n.save(),i.push(e),n.beginPath(),f(n,u.parsedStyle),n.closePath(),n.clip())}c&&(this.applyWorldTransform(n,e),n.save(),this.applyAttributesToContext(n,e)),l&&(n.beginPath(),l(n,e.parsedStyle),e.nodeName!==G.LINE&&e.nodeName!==G.PATH&&e.nodeName!==G.POLYLINE&&n.closePath()),c&&(c.render(n,e.parsedStyle,e,r,this,a),n.restore()),e.renderable.dirty=!1},t.prototype.convertAABB2Rect=function(e){var n=e.getMin(),r=e.getMax(),i=Math.floor(n[0]),a=Math.floor(n[1]),o=Math.ceil(r[0]),s=Math.ceil(r[1]),c=o-i,l=s-a;return{x:i,y:a,width:c,height:l}},t.prototype.mergeDirtyAABBs=function(e){var n=new be;return e.forEach(function(r){var i=r.getRenderBounds();n.add(i);var a=r.renderable.dirtyRenderBounds;a&&n.add(a)}),n},t.prototype.searchDirtyObjects=function(e){var n=N(e.getMin(),2),r=n[0],i=n[1],a=N(e.getMax(),2),o=a[0],s=a[1],c=this.rBush.search({minX:r,minY:i,maxX:o,maxY:s});return c.map(function(l){var u=l.displayObject;return u})},t.prototype.saveDirtyAABB=function(e){var n=e.renderable;n.dirtyRenderBounds||(n.dirtyRenderBounds=new be);var r=e.getRenderBounds();r&&n.dirtyRenderBounds.update(r.center,r.halfExtents)},t.prototype.applyAttributesToContext=function(e,n){var r=n.parsedStyle,i=r.stroke,a=r.fill,o=r.opacity,s=r.lineDash,c=r.lineDashOffset;s&&e.setLineDash(s),nt(c)||(e.lineDashOffset=c),nt(o)||(e.globalAlpha*=o),!nt(i)&&!Array.isArray(i)&&!i.isNone&&(e.strokeStyle=n.attributes.stroke),!nt(a)&&!Array.isArray(a)&&!a.isNone&&(e.fillStyle=n.attributes.fill)},t.prototype.applyWorldTransform=function(e,n,r){var i=0,a=0,o=(n.parsedStyle||{}).anchor,s=o&&o[0]||0,c=o&&o[1]||0;if(s!==0||c!==0){var l=n.geometry.contentBounds,u=l&&l.halfExtents[0]*2||0,f=l&&l.halfExtents[1]*2||0;i=-(s*u),a=-(c*f)}r?(Ri(this.tmpMat4,n.getLocalTransform()),this.vec3a[0]=i,this.vec3a[1]=a,this.vec3a[2]=0,Ur(this.tmpMat4,this.tmpMat4,this.vec3a),$e(this.tmpMat4,r,this.tmpMat4),$e(this.tmpMat4,this.vpMatrix,this.tmpMat4)):(Ri(this.tmpMat4,n.getWorldTransform()),this.vec3a[0]=i,this.vec3a[1]=a,this.vec3a[2]=0,Ur(this.tmpMat4,this.tmpMat4,this.vec3a),$e(this.tmpMat4,this.vpMatrix,this.tmpMat4)),e.setTransform(this.tmpMat4[0],this.tmpMat4[1],this.tmpMat4[4],this.tmpMat4[5],this.tmpMat4[12],this.tmpMat4[13])},t.prototype.safeMergeAABB=function(){for(var e=[],n=0;n0,S=s.alpha===0,_=!!(b&&b.length),M=!nt(y)&&m>0,E=r.nodeName,P=g==="inner",T=O&&M&&(E===G.PATH||E===G.LINE||E===G.POLYLINE||S||P);w&&(e.globalAlpha=l*u,T||Zl(r,e,M),this.fill(e,r,s,c,i,a,o),T||this.clearShadowAndFilter(e,_,M)),O&&(e.globalAlpha=l*d,e.lineWidth=h,nt(x)||(e.miterLimit=x),nt(p)||(e.lineCap=p),nt(v)||(e.lineJoin=v),T&&(P&&(e.globalCompositeOperation="source-atop"),Zl(r,e,!0),P&&(this.stroke(e,r,f,i,a,o),e.globalCompositeOperation="source-over",this.clearShadowAndFilter(e,_,!0))),this.stroke(e,r,f,i,a,o))},t.prototype.clearShadowAndFilter=function(e,n,r){if(r&&(e.shadowColor="transparent",e.shadowBlur=0),n){var i=e.filter;!nt(i)&&i.indexOf("drop-shadow")>-1&&(e.filter=i.replace(/drop-shadow\([^)]*\)/,"").trim()||"none")}},t.prototype.fill=function(e,n,r,i,a,o,s){var c=this;Array.isArray(r)?r.forEach(function(l){e.fillStyle=c.getColor(l,n,e),i?e.fill(i):e.fill()}):(hs(r)&&(e.fillStyle=this.getPattern(r,n,e,a,o,s)),i?e.fill(i):e.fill())},t.prototype.stroke=function(e,n,r,i,a,o){var s=this;Array.isArray(r)?r.forEach(function(c){e.strokeStyle=s.getColor(c,n,e),e.stroke()}):(hs(r)&&(e.strokeStyle=this.getPattern(r,n,e,i,a,o)),e.stroke())},t.prototype.getPattern=function(e,n,r,i,a,o){var s,c;if(e.image.nodeName==="rect"){var l=e.image.parsedStyle,u=l.width,f=l.height;c=i.contextService.getDPR();var d=i.config.offscreenCanvas;s=o.offscreenCanvasCreator.getOrCreateCanvas(d),s.width=u*c,s.height=f*c;var h=o.offscreenCanvasCreator.getOrCreateContext(d),p=[];e.image.forEach(function(g){a.renderDisplayObject(g,h,i,p,o)}),p.forEach(function(){h.restore()})}var v=this.imagePool.getOrCreatePatternSync(e,r,s,c,function(){n.renderable.dirty=!0,i.renderingService.dirtify()});return v},t.prototype.getColor=function(e,n,r){var i;if(e.type===rr.LinearGradient||e.type===rr.RadialGradient){var a=n.getGeometryBounds(),o=a&&a.halfExtents[0]*2||1,s=a&&a.halfExtents[1]*2||1;i=this.imagePool.getOrCreateGradient(z(z({type:e.type},e.value),{width:o,height:s}),r)}return i},t}();function Zl(t,e,n){var r=t.parsedStyle,i=r.filter,a=r.shadowColor,o=r.shadowBlur,s=r.shadowOffsetX,c=r.shadowOffsetY;i&&i.length&&(e.filter=t.style.filter),n&&(e.shadowColor=a.toString(),e.shadowBlur=o||0,e.shadowOffsetX=s||0,e.shadowOffsetY=c||0)}var Fz=function(){function t(e){this.imagePool=e}return t.prototype.render=function(e,n,r){var i=n.width,a=n.height,o=n.img,s=n.shadowColor,c=n.shadowBlur,l,u=i,f=a;if(le(o)?l=this.imagePool.getImageSync(o):(u||(u=o.width),f||(f=o.height),l=o),l){var d=!nt(s)&&c>0;Zl(r,e,d);try{e.drawImage(l,0,0,u,f)}catch{}}},t}(),zz=function(){function t(){}return t.prototype.render=function(e,n,r,i,a,o){var s=n,c=s.lineWidth,l=s.textAlign,u=s.textBaseline,f=s.lineJoin,d=s.miterLimit,h=s.letterSpacing,p=s.stroke,v=s.fill,g=s.fillOpacity,y=s.strokeOpacity,m=s.opacity,b=s.metrics,x=s.dx,w=s.dy,O=s.shadowColor,S=s.shadowBlur,_=b.font,M=b.lines,E=b.height,P=b.lineHeight,T=b.lineMetrics;e.font=_,e.lineWidth=c,e.textAlign=l==="middle"?"center":l;var A=u;!o.enableCSSParsing&&A==="alphabetic"&&(A="bottom"),e.lineJoin=f,nt(d)||(e.miterLimit=d);var k=0;u==="middle"?k=-E/2-P/2:u==="bottom"||u==="alphabetic"||u==="ideographic"?k=-E:(u==="top"||u==="hanging")&&(k=-P);var C=x||0;k+=w||0,M.length===1&&(A==="bottom"?(A="middle",k-=.5*E):A==="top"&&(A="middle",k+=.5*E)),e.textBaseline=A;var L=!nt(O)&&S>0;Zl(r,e,L);for(var I=0;I=1?Math.ceil(i):1,this.dpr=i,this.$canvas&&(this.$canvas.width=this.dpr*e,this.$canvas.height=this.dpr*n,F4(this.$canvas,e,n)),this.renderingContext.renderReasons.add(Qr.CAMERA_CHANGED)},t.prototype.applyCursorStyle=function(e){this.$container&&this.$container.style&&(this.$container.style.cursor=e)},t.prototype.toDataURL=function(e){return e===void 0&&(e={}),ka(this,void 0,void 0,function(){var n,r;return Ta(this,function(i){return n=e.type,r=e.encoderOptions,[2,this.context.canvas.toDataURL(n,r)]})})},t}(),Qz=function(t){rt(e,t);function e(){var n=t.apply(this,q([],N(arguments),!1))||this;return n.name="canvas-context-register",n}return e.prototype.init=function(){this.context.ContextService=Zz},e.prototype.destroy=function(){delete this.context.ContextService},e}(ci),IE=function(t){rt(e,t);function e(n){var r=t.call(this,n)||this;return r.registerPlugin(new Qz),r.registerPlugin(new Kz),r.registerPlugin(new bz),r.registerPlugin(new Gz),r.registerPlugin(new Wz),r.registerPlugin(new $z),r.registerPlugin(new Xz),r}return e}(eN),Jz=function(){function t(e){this.dragndropPluginOptions=e}return t.prototype.apply=function(e){var n=this,r=e.renderingService,i=e.renderingContext,a=i.root.ownerDocument,o=a.defaultView,s=function(c){var l=c.target,u=l===a,f=u&&n.dragndropPluginOptions.isDocumentDraggable?a:l.closest&&l.closest("[draggable=true]");if(f){var d=!1,h=c.timeStamp,p=[c.clientX,c.clientY],v=null,g=[c.clientX,c.clientY],y=function(b){return ka(n,void 0,void 0,function(){var x,w,O,S,_,M;return Ta(this,function(E){switch(E.label){case 0:if(!d){if(x=b.timeStamp-h,w=nn([b.clientX,b.clientY],p),x<=this.dragndropPluginOptions.dragstartTimeThreshold||w<=this.dragndropPluginOptions.dragstartDistanceThreshold)return[2];b.type="dragstart",f.dispatchEvent(b),d=!0}return b.type="drag",b.dx=b.clientX-g[0],b.dy=b.clientY-g[1],f.dispatchEvent(b),g=[b.clientX,b.clientY],u?[3,2]:(O=this.dragndropPluginOptions.overlap==="pointer"?[b.canvasX,b.canvasY]:l.getBounds().center,[4,a.elementsFromPoint(O[0],O[1])]);case 1:S=E.sent(),_=S[S.indexOf(l)+1],M=(_==null?void 0:_.closest("[droppable=true]"))||(this.dragndropPluginOptions.isDocumentDroppable?a:null),v!==M&&(v&&(b.type="dragleave",b.target=v,v.dispatchEvent(b)),M&&(b.type="dragenter",b.target=M,M.dispatchEvent(b)),v=M,v&&(b.type="dragover",b.target=v,v.dispatchEvent(b))),E.label=2;case 2:return[2]}})})};o.addEventListener("pointermove",y);var m=function(b){if(d){b.detail={preventClick:!0};var x=b.clone();v&&(x.type="drop",x.target=v,v.dispatchEvent(x)),x.type="dragend",f.dispatchEvent(x),d=!1}o.removeEventListener("pointermove",y)};l.addEventListener("pointerup",m,{once:!0}),l.addEventListener("pointerupoutside",m,{once:!0})}};r.hooks.init.tap(t.tag,function(){o.addEventListener("pointerdown",s)}),r.hooks.destroy.tap(t.tag,function(){o.removeEventListener("pointerdown",s)})},t.tag="Dragndrop",t}(),jE=function(t){rt(e,t);function e(n){n===void 0&&(n={});var r=t.call(this)||this;return r.options=n,r.name="dragndrop",r}return e.prototype.init=function(){this.addRenderingPlugin(new Jz(z({overlap:"pointer",isDocumentDraggable:!1,isDocumentDroppable:!1,dragstartDistanceThreshold:0,dragstartTimeThreshold:0},this.options)))},e.prototype.destroy=function(){this.removeAllRenderingPlugins()},e.prototype.setOptions=function(n){Object.assign(this.plugins[0].dragndropPluginOptions,n)},e}(ci),tG="*",DE=function(){function t(){this._events={}}return t.prototype.on=function(e,n,r){return this._events[e]||(this._events[e]=[]),this._events[e].push({callback:n,once:!!r}),this},t.prototype.once=function(e,n){return this.on(e,n,!0)},t.prototype.emit=function(e){for(var n=this,r=[],i=1;i0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},HE=function(t,e,n){if(n||arguments.length===2)for(var r=0,i=e.length,a;rn;)t-=Math.PI*2;return t}var dG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},hG=function(t,e,n,r,i){var a=dG(t,2),o=a[0],s=a[1],c=Ja();return Vk(c,[o,s])},l1=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},pG=function(t,e,n,r,i){var a=new Yt({range:[e,e+r]}),o=new Yt({range:[n,n+i]});return{transform:function(s){var c=l1(s,2),l=c[0],u=c[1];return[a.map(l),o.map(u)]},untransform:function(s){var c=l1(s,2),l=c[0],u=c[1];return[a.invert(l),o.invert(u)]}}},vG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},gG=function(t,e,n,r,i){var a=vG(t,1),o=a[0];return o(e,n,r,i)},yG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},mG=function(t,e,n,r,i){var a=yG(t,1),o=a[0];return o},dd=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},bG=function(t,e,n,r,i){var a=dd(t,4),o=a[0],s=a[1],c=a[2],l=a[3],u=new Yt({range:[c,l]}),f=new Yt({range:[o,s]}),d=i/r,h=d>1?1:d,p=d>1?1/d:1;return{transform:function(v){var g=dd(v,2),y=g[0],m=g[1],b=f.map(y),x=u.map(m),w=x*Math.cos(b)*h,O=x*Math.sin(b)*p,S=w*.5+.5,_=O*.5+.5;return[S,_]},untransform:function(v){var g=dd(v,2),y=g[0],m=g[1],b=(y-.5)*2/h,x=(m-.5)*2/p,w=Math.sqrt(Math.pow(b,2)+Math.pow(x,2)),O=Math.atan2(x,b),S=VE(O,o,s),_=f.invert(S),M=u.invert(w);return[_,M]}}},u1=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},xG=function(t,e,n,r,i){return{transform:function(a){var o=u1(a,2),s=o[0],c=o[1];return[c,s]},untransform:function(a){var o=u1(a,2),s=o[0],c=o[1];return[c,s]}}},wG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},rf=function(t,e,n,r,i){var a=wG(t,2),o=a[0],s=a[1],c=Ja();return Uk(c,[o,s])},G0=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},Y0=function(t,e,n){if(n||arguments.length===2)for(var r=0,i=e.length,a;r0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},EG=function(t,e,n,r,i){var a=MG(t,1),o=a[0],s=Ja();return Xk(s,o)},hd=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},PG=function(t,e,n,r,i){var a=hd(t,4),o=a[0],s=a[1],c=a[2],l=a[3],u=(s-0)/(2*Math.PI)+1,f=(l-c)/u,d=f/(Math.PI*2),h=new Yt({range:[c,c+f*.99]}),p=new Yt({range:[o,s]}),v=i/r,g=v>1?1:v,y=v>1?1/v:1;return{transform:function(m){var b=hd(m,2),x=b[0],w=b[1],O=p.map(x),S=h.map(w),_=Math.cos(O)*(d*O+S)*g,M=Math.sin(O)*(d*O+S)*y,E=_*.5+.5,P=M*.5+.5;return[E,P]},untransform:function(m){var b=hd(m,2),x=b[0],w=b[1],O=(x-.5)*2/g,S=(w-.5)*2/y,_=Math.sqrt(Math.pow(O,2)+Math.pow(S,2)),M=Math.atan2(S,O)+Math.floor(_/f)*Math.PI*2,E=VE(M,o,s),P=_-d*E,T=p.invert(E),A=h.invert(P);return[T,A]}}},AG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},kG=function(t,e,n,r,i){var a=AG(t,4),o=a[0],s=a[1],c=a[2],l=a[3],u=new Yt({range:[c,l]});return{transform:function(f){for(var d=[],h=f.length,p=new l2({domain:new Array(h).fill(0).map(function(b,x){return x}),range:[o,s]}),v=0;v0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a};function XE(t){return 1/Math.tan(t)}var TG=function(t,e,n,r,i){var a=_a(t,1),o=a[0],s=XE(o);return{transform:function(c){var l=_a(c,2),u=l[0],f=l[1],d=u+f*s;return[d,f]},untransform:function(c){var l=_a(c,2),u=l[0],f=l[1],d=u-f*s;return[d,f]}}},CG=function(t,e,n,r,i){var a=_a(t,1),o=a[0],s=XE(o);return{transform:function(c){var l=_a(c,2),u=l[0],f=l[1],d=f+u*s;return[u,d]},untransform:function(c){var l=_a(c,2),u=l[0],f=l[1],d=f-u*s;return[u,d]}}},Ln=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a};function Os(t,e,n,r,i){var a=tc)return[m,b];var S=Os(O,0,l,0,c),_=Math.atan2(w,x),M=p+S*Math.cos(_),E=v+S*Math.sin(_);return[d.invert(M),h.invert(E)]},untransform:function(g){var y=Ln(g,2),m=y[0],b=y[1],x=d.map(m)-p,w=h.map(b)-v,O=Math.sqrt(x*x+w*w);if(O>c)return[m,b];var S=Ss(O,0,l,0,c),_=Math.atan2(w,x),M=p+S*Math.cos(_),E=v+S*Math.sin(_);return[d.invert(M),h.invert(E)]}}},f1=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},jG=function(t,e,n,r,i,a,o){var s=new Yt({range:[e,e+i]}),c=new Yt({range:[n,n+a]}),l=new Yt({range:[r,r+o]});return{transform:function(u){var f=f1(u,3),d=f[0],h=f[1],p=f[2];return[s.map(d),c.map(h),l.map(p)]},untransform:function(u){var f=f1(u,3),d=f[0],h=f[1],p=f[2];return[s.invert(d),c.invert(h),l.invert(p)]}}},DG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},$G=function(t,e,n,r,i,a,o){var s=DG(t,3),c=s[0],l=s[1],u=s[2];return up(Nt(),[c,l,u])},d1=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},BG=function(t,e,n,r,i,a,o){return{transform:function(s){var c=d1(s,3),l=c[0],u=c[1],f=c[2];return[u,l,f]},untransform:function(s){var c=d1(s,3),l=c[0],u=c[1],f=c[2];return[u,l,f]}}},FG=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},zG=function(t,e,n,r,i,a,o){var s=FG(t,3),c=s[0],l=s[1],u=s[2];return fp(Nt(),[c,l,u])},ia=function(t,e){var n=typeof Symbol=="function"&&t[Symbol.iterator];if(!n)return t;var r=n.call(t),i,a=[],o;try{for(;(e===void 0||e-- >0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},aa=function(t,e,n){if(n||arguments.length===2)for(var r=0,i=e.length,a;r=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},YG=function(){function t(e){this.options={x:0,y:0,width:300,height:150,transformations:[]},this.transformers={cartesian:pG,translate:hG,custom:gG,matrix:mG,polar:bG,transpose:xG,scale:rf,"shear.x":TG,"shear.y":CG,reflect:OG,"reflect.x":SG,"reflect.y":_G,rotate:EG,helix:PG,parallel:kG,fisheye:RG,"fisheye.x":LG,"fisheye.y":NG,"fisheye.circular":IG},this.update(e)}return t.prototype.update=function(e){this.options=zE({},this.options,e),this.recoordinate()},t.prototype.clone=function(){return new t(this.options)},t.prototype.getOptions=function(){return this.options},t.prototype.clear=function(){this.update({transformations:[]})},t.prototype.getSize=function(){var e=this.options,n=e.width,r=e.height;return[n,r]},t.prototype.getCenter=function(){var e=this.options,n=e.x,r=e.y,i=e.width,a=e.height;return[(n*2+i)/2,(r*2+a)/2]},t.prototype.transform=function(){for(var e=[],n=0;n0)&&!(i=r.next()).done;)a.push(i.value)}catch(s){o={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a},sa=function(t,e,n){if(n||arguments.length===2)for(var r=0,i=e.length,a;r=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},HG=function(){function t(e){this.options={x:0,y:0,z:0,width:300,height:150,depth:150,transformations:[]},this.transformers={cartesian3D:jG,translate3D:$G,scale3D:zG,transpose3D:BG},this.update(e)}return t.prototype.update=function(e){this.options=zE({},this.options,e),this.recoordinate()},t.prototype.clone=function(){return new t(this.options)},t.prototype.getOptions=function(){return this.options},t.prototype.clear=function(){this.update({transformations:[]})},t.prototype.getSize=function(){var e=this.options,n=e.width,r=e.height,i=e.depth;return[n,r,i]},t.prototype.getCenter=function(){var e=this.options,n=e.x,r=e.y,i=e.z,a=e.width,o=e.height,s=e.depth;return[(n*2+a)/2,(r*2+o)/2,(i*2+s)/2]},t.prototype.transform=function(){for(var e=[],n=0;nX({},t(e,...n),e)}function so(t){return(e,...n)=>X({},e,t(e,...n))}function W0(t,e){if(!t)return e;if(Array.isArray(t))return t;const{value:n=e}=t,r=VG(t,["value"]);return Object.assign(Object.assign({},r),{value:n})}var XG=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);it=>{const{children:e}=t;if(!Array.isArray(e))return[];const{x:n=0,y:r=0,width:i,height:a,data:o}=t;return e.map(s=>{var{data:c,x:l,y:u,width:f,height:d}=s,h=XG(s,["data","x","y","width","height"]);return Object.assign(Object.assign({},h),{data:W0(c,o),x:l??n,y:u??r,width:f??i,height:d??a})})};UE.props={};var UG=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);it=>{const{children:e}=t;if(!Array.isArray(e))return[];const{direction:n="row",ratio:r=e.map(()=>1),padding:i=0,data:a}=t,[o,s,c,l]=n==="col"?["y","height","width","x"]:["x","width","height","y"],u=r.reduce((v,g)=>v+g),f=t[s]-i*(e.length-1),d=r.map(v=>f*(v/u)),h=[];let p=t[o]||0;for(let v=0;vt=>{const{children:e}=t,n=pd(t,["children"]);if(!Array.isArray(e))return[];const{data:r,scale:i={},axis:a={},legend:o={},encode:s={},transform:c=[]}=n,l=pd(n,["data","scale","axis","legend","encode","transform"]),u=e.map(f=>{var{data:d,scale:h={},axis:p={},legend:v={},encode:g={},transform:y=[]}=f,m=pd(f,["data","scale","axis","legend","encode","transform"]);return Object.assign({data:W0(d,r),scale:X({},i,h),encode:X({},s,g),transform:[...c,...y],axis:p&&a?X({},a,p):!1,legend:v&&o?X({},o,v):!1},m)});return[Object.assign(Object.assign({},l),{marks:u,type:"standardView"})]};KE.props={};var qG=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ie=>{const{width:n,height:r,depth:i,paddingLeft:a,paddingRight:o,paddingTop:s,paddingBottom:c,padding:l,inset:u,insetLeft:f,insetTop:d,insetRight:h,insetBottom:p,margin:v,marginLeft:g,marginBottom:y,marginTop:m,marginRight:b,data:x,coordinate:w,theme:O,component:S,interaction:_,x:M,y:E,z:P,key:T,frame:A,labelTransform:k,parentKey:C,clip:L,viewStyle:I,title:R}=e,j=qG(e,["width","height","depth","paddingLeft","paddingRight","paddingTop","paddingBottom","padding","inset","insetLeft","insetTop","insetRight","insetBottom","margin","marginLeft","marginBottom","marginTop","marginRight","data","coordinate","theme","component","interaction","x","y","z","key","frame","labelTransform","parentKey","clip","viewStyle","title"]);return[Object.assign(Object.assign({type:"standardView",x:M,y:E,z:P,key:T,width:n,height:r,depth:i,padding:l,paddingLeft:a,paddingRight:o,paddingTop:s,inset:u,insetLeft:f,insetTop:d,insetRight:h,insetBottom:p,paddingBottom:c,theme:O,coordinate:w,component:S,interaction:_,frame:A,labelTransform:k,margin:v,marginLeft:g,marginBottom:y,marginTop:m,marginRight:b,parentKey:C,clip:L,style:I},!t&&{title:R}),{marks:[Object.assign(Object.assign(Object.assign({},j),{key:`${T}-0`,data:x}),t&&{title:R})]})]};ZE.props={};class ec{constructor(e){this.$value=e}static of(e){return new ec(e)}call(e,...n){return this.$value=e(this.$value,...n),this}value(){return this.$value}}var KG=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{encode:e,data:n,scale:r,shareSize:i=!1}=t,{x:a,y:o}=e,s=(c,l)=>{var u;if(c===void 0||!i)return{};const f=te(n,p=>p[c]),d=((u=r==null?void 0:r[l])===null||u===void 0?void 0:u.domain)||Array.from(f.keys()),h=d.map(p=>f.has(p)?f.get(p).length:1);return{domain:d,flex:h}};return{scale:{x:Object.assign(Object.assign({paddingOuter:0,paddingInner:.1,guide:a===void 0?null:{position:"top"}},a===void 0&&{paddingInner:0}),s(a,"x")),y:Object.assign(Object.assign({range:[0,1],paddingOuter:0,paddingInner:.1,guide:o===void 0?null:{position:"right"}},o===void 0&&{paddingInner:0}),s(o,"y"))}}}),H0=oo(t=>{const{data:e,scale:n}=t,r=[t];let i,a,o;for(;r.length;){const f=r.shift(),{children:d,encode:h={},scale:p={},legend:v={}}=f,{color:g}=h,{color:y}=p,{color:m}=v;g!==void 0&&(i=g),y!==void 0&&(a=y),m!==void 0&&(o=m),Array.isArray(d)&&r.push(...d)}const s=()=>{var f;const d=(f=n==null?void 0:n.color)===null||f===void 0?void 0:f.domain;if(d!==void 0)return[d];if(i===void 0)return[void 0];const h=typeof i=="function"?i:v=>v[i],p=e.map(h);return p.some(v=>typeof v=="number")?[Mr(p)]:[Array.from(new Set(p)),"ordinal"]},c=typeof i=="string"?i:"",[l,u]=s();return{encode:{color:i},scale:{color:X({},a,{domain:l,type:u})},legend:{color:X({title:c},o)}}}),V0=oo(()=>({animate:{enterType:"fadeIn"}})),X0=so(()=>({frame:!1,encode:{shape:"hollow"},style:{lineWidth:0}})),U0=so(()=>({type:"cell"})),QE=so(t=>{const{data:e}=t;return{data:{type:"inline",value:e,transform:[{type:"custom",callback:()=>{const{data:r,encode:i}=t,{x:a,y:o}=i,s=a?Array.from(new Set(r.map(u=>u[a]))):[],c=o?Array.from(new Set(r.map(u=>u[o]))):[];return(()=>{if(s.length&&c.length){const u=[];for(const f of s)for(const d of c)u.push({[a]:f,[o]:d});return u}if(s.length)return s.map(u=>({[a]:u}));if(c.length)return c.map(u=>({[o]:u}))})()}}]}}}),JE=so((t,e=QG,n=JG,r=tY,i={})=>{const{data:a,encode:o,children:s,scale:c,x:l=0,y:u=0,shareData:f=!1,key:d}=t,{value:h}=a,{x:p,y:v}=o,{color:g}=c,{domain:y}=g;return{children:(b,x,w)=>{const{x:O,y:S}=x,{paddingLeft:_,paddingTop:M,marginLeft:E,marginTop:P}=w,{domain:T}=O.getOptions(),{domain:A}=S.getOptions(),k=Ui(b),C=b.map(e),L=b.map(({x:B,y:F})=>[O.invert(B),S.invert(F)]),R=L.map(([B,F])=>Y=>{const{[p]:U,[v]:K}=Y;return(p!==void 0?U===B:!0)&&(v!==void 0?K===F:!0)}).map(B=>h.filter(B)),j=f?Ct(R,B=>B.length):void 0,D=L.map(([B,F])=>({columnField:p,columnIndex:T.indexOf(B),columnValue:B,columnValuesLength:T.length,rowField:v,rowIndex:A.indexOf(F),rowValue:F,rowValuesLength:A.length})),$=D.map(B=>Array.isArray(s)?s:[s(B)].flat(1));return k.flatMap(B=>{const[F,Y,U,K]=C[B],V=D[B],W=R[B];return $[B].map(et=>{var it,ct,{scale:ot,key:lt,facet:xt=!0,axis:Et={},legend:Xt={}}=et,ue=KG(et,["scale","key","facet","axis","legend"]);const Ke=((it=ot==null?void 0:ot.y)===null||it===void 0?void 0:it.guide)||Et.y,vr=((ct=ot==null?void 0:ot.x)===null||ct===void 0?void 0:ct.guide)||Et.x,gi={x:{tickCount:p?5:void 0},y:{tickCount:v?5:void 0}},Ge=xt?W:W.length===0?[]:h,wn={color:{domain:y}},_t={x:h1(vr,n)(V,Ge),y:h1(Ke,r)(V,Ge)};return Object.assign(Object.assign({key:`${lt}-${B}`,data:Ge,margin:0,x:F+_+l+E,y:Y+M+u+P,parentKey:d,width:U,height:K,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0,frame:!!Ge.length,dataDomain:j,scale:X(gi,ot,wn),axis:X({},Et,_t),legend:!1},ue),i)})})}}});function QG(t){const{points:e}=t;return kp(e)}function af(t,e){return e.length?X({title:!1,tick:null,label:null},t):X({title:!1,tick:null,label:null,grid:null},t)}function JG(t){return(e,n)=>{const{rowIndex:r,rowValuesLength:i,columnIndex:a,columnValuesLength:o}=e;if(r!==i-1)return af(t,n);const s=a!==o-1?!1:void 0,c=n.length?void 0:null;return X({title:s,grid:c},t)}}function tY(t){return(e,n)=>{const{rowIndex:r,columnIndex:i}=e;if(i!==0)return af(t,n);const a=r!==0?!1:void 0,o=n.length?void 0:null;return X({title:a,grid:o},t)}}function h1(t,e){return typeof t=="function"?t:t===null||t===!1?()=>null:e(t)}const tP=()=>t=>[ec.of(t).call(U0).call(H0).call(V0).call(ZG).call(X0).call(QE).call(JE).value()];tP.props={};var Nh=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i({scale:{x:{guide:null,paddingOuter:0,paddingInner:.1},y:{guide:null,range:[0,1],paddingOuter:0,paddingInner:.1}}})),nY=so(t=>{const{data:e,children:n,x:r=0,y:i=0,key:a}=t;return{children:(s,c,l)=>{const{x:u,y:f}=c,{paddingLeft:d,paddingTop:h,marginLeft:p,marginTop:v}=l,{domain:g}=u.getOptions(),{domain:y}=f.getOptions(),m=Ui(s),b=s.map(({points:S})=>kp(S)),x=s.map(({x:S,y:_})=>[u.invert(S),f.invert(_)]),w=x.map(([S,_])=>({columnField:S,columnIndex:g.indexOf(S),columnValue:S,columnValuesLength:g.length,rowField:_,rowIndex:y.indexOf(_),rowValue:_,rowValuesLength:y.length})),O=w.map(S=>Array.isArray(n)?n:[n(S)].flat(1));return m.flatMap(S=>{const[_,M,E,P]=b[S],[T,A]=x[S],k=w[S];return O[S].map(L=>{var I,R;const{scale:j,key:D,encode:$,axis:B,interaction:F}=L,Y=Nh(L,["scale","key","encode","axis","interaction"]),U=(I=j==null?void 0:j.y)===null||I===void 0?void 0:I.guide,K=(R=j==null?void 0:j.x)===null||R===void 0?void 0:R.guide,V={x:{facet:!1},y:{facet:!1}},W={x:iY(K)(k,e),y:aY(U)(k,e)},J={x:{tickCount:5},y:{tickCount:5}};return Object.assign({data:e,parentKey:a,key:`${D}-${S}`,x:_+d+r+p,y:M+h+i+v,width:E,height:P,margin:0,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0,frame:!0,scale:X(V,j),axis:X(J,B,W),legend:!1,encode:X({},$,{x:T,y:A}),interaction:X({},F,{legendFilter:!1})},Y)})})}}}),rY=so(t=>{const{encode:e}=t,n=Nh(t,["encode"]),{position:r=[],x:i=r,y:a=[...r].reverse()}=e,o=Nh(e,["position","x","y"]),s=[];for(const c of[i].flat(1))for(const l of[a].flat(1))s.push({$x:c,$y:l});return Object.assign(Object.assign({},n),{data:s,encode:Object.assign(Object.assign({},o),{x:"$x",y:"$y"}),scale:Object.assign(Object.assign({},[i].flat(1).length===1&&{x:{paddingInner:0}}),[a].flat(1).length===1&&{y:{paddingInner:0}})})});function iY(t){return typeof t=="function"?t:t===null?()=>null:(e,n)=>{const{rowIndex:r,rowValuesLength:i}=e;if(r!==i-1)return af(t,n)}}function aY(t){return typeof t=="function"?t:t===null?()=>null:(e,n)=>{const{columnIndex:r}=e;if(r!==0)return af(t,n)}}const oY=()=>t=>[ec.of(t).call(U0).call(H0).call(nY).call(rY).call(V0).call(X0).call(eY).value()];var sY=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i({scale:{x:{guide:{type:"axisArc"},paddingOuter:0,paddingInner:.1},y:{guide:null,range:[0,1],paddingOuter:0,paddingInner:.1}}})),lY=oo(t=>({coordinate:{type:"polar"}})),uY=t=>{const{encode:e}=t,n=sY(t,["encode"]),{position:r}=e;return Object.assign(Object.assign({},n),{encode:{x:r}})};function p1(t){return e=>null}function fY(t){const{points:e}=t,[n,r,i,a]=e,o=Jt(n,a),s=se(n,a),c=se(r,i),l=B2(s,c),u=1/Math.sin(l/2),f=o/(1+u),d=f*Math.sqrt(2),[h,p]=i,g=ja(s)+l/2,y=f*u,m=h+y*Math.sin(g),b=p-y*Math.cos(g);return[m-d/2,b-d/2,d,d]}const dY=()=>t=>[ec.of(t).call(U0).call(uY).call(H0).call(lY).call(QE).call(JE,fY,p1,p1,{frame:!1}).call(V0).call(X0).call(cY).value()];function hY(t,e,n){const i=n,a=[0,i],o=[-i+1,1];if(t==="normal")return a;if(t==="reverse")return o;if(t==="alternate")return e%2===0?a:o;if(t==="reverse-alternate")return e%2===0?o:a}function pY(t,e,n){const r=[t];for(;r.length;){const i=r.pop();i.animate=X({enter:{duration:e},update:{duration:e,easing:n,type:"morphing",fill:"both"},exit:{type:"fadeOut",duration:e}},i.animate||{});const{children:a}=i;Array.isArray(a)&&r.push(...a)}return t}const eP=()=>t=>{const{children:e=[],duration:n=1e3,iterationCount:r=1,direction:i="normal",easing:a="ease-in-out-sine"}=t,o=e.length;if(!Array.isArray(e)||o===0)return[];const{key:s}=e[0],c=e.map(l=>Object.assign(Object.assign({},l),{key:s})).map(l=>pY(l,n,a));return function*(){let l=0,u;for(;r==="infinite"||lt=>{const{type:e,data:n,scale:r,encode:i,style:a,animate:o,key:s,state:c}=t,l=vY(t,["type","data","scale","encode","style","animate","key","state"]);return[Object.assign(Object.assign({type:"geoView"},l),{children:[{type:"geoPath",key:`${s}-0`,data:{value:n},scale:r,encode:i,style:a,animate:o,state:c}]})]};nP.props={};var ut=1e-6,rP=1e-12,wt=Math.PI,fe=wt/2,v1=wt/4,xn=wt*2,De=180/wt,ae=wt/180,At=Math.abs,co=Math.atan,Ir=Math.atan2,mt=Math.cos,Fc=Math.ceil,iP=Math.exp,Jl=Math.log,vd=Math.pow,pt=Math.sin,kn=Math.sign||function(t){return t>0?1:t<0?-1:0},cn=Math.sqrt,q0=Math.tan;function aP(t){return t>1?0:t<-1?wt:Math.acos(t)}function In(t){return t>1?fe:t<-1?-fe:Math.asin(t)}function Tn(){}function tu(t,e){t&&y1.hasOwnProperty(t.type)&&y1[t.type](t,e)}var g1={Feature:function(t,e){tu(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++rwt&&(t-=Math.round(t/xn)*xn),[t,e]}$h.invert=$h;function oP(t,e,n){return(t%=xn)?e||n?Dh(x1(t),w1(e,n)):x1(t):e||n?w1(e,n):$h}function b1(t){return function(e,n){return e+=t,At(e)>wt&&(e-=Math.round(e/xn)*xn),[e,n]}}function x1(t){var e=b1(t);return e.invert=b1(-t),e}function w1(t,e){var n=mt(t),r=pt(t),i=mt(e),a=pt(e);function o(s,c){var l=mt(c),u=mt(s)*l,f=pt(s)*l,d=pt(c),h=d*n+u*r;return[Ir(f*i-h*a,u*n-d*r),In(h*i+f*a)]}return o.invert=function(s,c){var l=mt(c),u=mt(s)*l,f=pt(s)*l,d=pt(c),h=d*i-f*a;return[Ir(f*i+d*a,u*n+h*r),In(h*n-u*r)]},o}function gY(t){t=oP(t[0]*ae,t[1]*ae,t.length>2?t[2]*ae:0);function e(n){return n=t(n[0]*ae,n[1]*ae),n[0]*=De,n[1]*=De,n}return e.invert=function(n){return n=t.invert(n[0]*ae,n[1]*ae),n[0]*=De,n[1]*=De,n},e}function yY(t,e,n,r,i,a){if(n){var o=mt(e),s=pt(e),c=r*n;i==null?(i=e+r*xn,a=e-c/2):(i=O1(o,i),a=O1(o,a),(r>0?ia)&&(i+=r*xn));for(var l,u=i;r>0?u>a:u1&&t.push(t.pop().concat(t.shift()))},result:function(){var n=t;return t=[],e=null,n}}}function ll(t,e){return At(t[0]-e[0])=0;--s)i.point((f=u[s])[0],f[1]);else r(d.x,d.p.x,-1,i);d=d.p}d=d.o,u=d.z,h=!h}while(!d.v);i.lineEnd()}}}function S1(t){if(e=t.length){for(var e,n=0,r=t[0],i;++n=0?1:-1,E=M*_,P=E>wt,T=g*O;if(c.add(Ir(T*M*pt(E),y*S+T*mt(E))),o+=P?_+M*xn:_,P^p>=n^x>=n){var A=eu(Ua(h),Ua(b));jh(A);var k=eu(a,A);jh(k);var C=(P^_>=0?-1:1)*In(k[2]);(r>C||r===C&&(A[0]||A[1]))&&(s+=P^_>=0?1:-1)}}return(o<-ut||o0){for(c||(i.polygonStart(),c=!0),i.lineStart(),O=0;O<_;++O)i.point((E=M[O])[0],E[1]);i.lineEnd()}return}S>1&&x&2&&w.push(w.pop().concat(w.shift())),u.push(w.filter(bY))}}return d}}function bY(t){return t.length>1}function xY(t,e){return((t=t.x)[0]<0?t[1]-fe-ut:fe-t[1])-((e=e.x)[0]<0?e[1]-fe-ut:fe-e[1])}const _1=lP(function(){return!0},wY,SY,[-wt,-fe]);function wY(t){var e=NaN,n=NaN,r=NaN,i;return{lineStart:function(){t.lineStart(),i=1},point:function(a,o){var s=a>0?wt:-wt,c=At(a-e);At(c-wt)0?fe:-fe),t.point(r,n),t.lineEnd(),t.lineStart(),t.point(s,n),t.point(a,n),i=0):r!==s&&c>=wt&&(At(e-r)ut?co((pt(e)*(a=mt(r))*pt(n)-pt(r)*(i=mt(e))*pt(t))/(i*a*o)):(e+r)/2}function SY(t,e,n,r){var i;if(t==null)i=n*fe,r.point(-wt,i),r.point(0,i),r.point(wt,i),r.point(wt,0),r.point(wt,-i),r.point(0,-i),r.point(-wt,-i),r.point(-wt,0),r.point(-wt,i);else if(At(t[0]-e[0])>ut){var a=t[0]0,i=At(e)>ut;function a(u,f,d,h){yY(h,t,n,d,u,f)}function o(u,f){return mt(u)*mt(f)>e}function s(u){var f,d,h,p,v;return{lineStart:function(){p=h=!1,v=1},point:function(g,y){var m=[g,y],b,x=o(g,y),w=r?x?0:l(g,y):x?l(g+(g<0?wt:-wt),y):0;if(!f&&(p=h=x)&&u.lineStart(),x!==h&&(b=c(f,m),(!b||ll(f,b)||ll(m,b))&&(m[2]=1)),x!==h)v=0,x?(u.lineStart(),b=c(m,f),u.point(b[0],b[1])):(b=c(f,m),u.point(b[0],b[1],2),u.lineEnd()),f=b;else if(i&&f&&r^x){var O;!(w&d)&&(O=c(m,f,!0))&&(v=0,r?(u.lineStart(),u.point(O[0][0],O[0][1]),u.point(O[1][0],O[1][1]),u.lineEnd()):(u.point(O[1][0],O[1][1]),u.lineEnd(),u.lineStart(),u.point(O[0][0],O[0][1],3)))}x&&(!f||!ll(f,m))&&u.point(m[0],m[1]),f=m,h=x,d=w},lineEnd:function(){h&&u.lineEnd(),f=null},clean:function(){return v|(p&&h)<<1}}}function c(u,f,d){var h=Ua(u),p=Ua(f),v=[1,0,0],g=eu(h,p),y=zc(g,g),m=g[0],b=y-m*m;if(!b)return!d&&u;var x=e*y/b,w=-e*m/b,O=eu(v,g),S=Gc(v,x),_=Gc(g,w);gd(S,_);var M=O,E=zc(S,M),P=zc(M,M),T=E*E-P*(zc(S,S)-1);if(!(T<0)){var A=cn(T),k=Gc(M,(-E-A)/P);if(gd(k,S),k=Ih(k),!d)return k;var C=u[0],L=f[0],I=u[1],R=f[1],j;L0^k[1]<(At(k[0]-C)wt^(C<=k[0]&&k[0]<=L)){var F=Gc(M,(-E+A)/P);return gd(F,S),[k,Ih(F)]}}}function l(u,f){var d=r?t:wt-t,h=0;return u<-d?h|=1:u>d&&(h|=2),f<-d?h|=4:f>d&&(h|=8),h}return lP(o,s,a,r?[0,-t]:[-wt,t-wt])}function MY(t,e,n,r,i,a){var o=t[0],s=t[1],c=e[0],l=e[1],u=0,f=1,d=c-o,h=l-s,p;if(p=n-o,!(!d&&p>0)){if(p/=d,d<0){if(p0){if(p>f)return;p>u&&(u=p)}if(p=i-o,!(!d&&p<0)){if(p/=d,d<0){if(p>f)return;p>u&&(u=p)}else if(d>0){if(p0)){if(p/=h,h<0){if(p0){if(p>f)return;p>u&&(u=p)}if(p=a-s,!(!h&&p<0)){if(p/=h,h<0){if(p>f)return;p>u&&(u=p)}else if(h>0){if(p0&&(t[0]=o+u*d,t[1]=s+u*h),f<1&&(e[0]=o+f*d,e[1]=s+f*h),!0}}}}}var Io=1e9,Wc=-Io;function uP(t,e,n,r){function i(l,u){return t<=l&&l<=n&&e<=u&&u<=r}function a(l,u,f,d){var h=0,p=0;if(l==null||(h=o(l,f))!==(p=o(u,f))||c(l,u)<0^f>0)do d.point(h===0||h===3?t:n,h>1?r:e);while((h=(h+f+4)%4)!==p);else d.point(u[0],u[1])}function o(l,u){return At(l[0]-t)0?0:3:At(l[0]-n)0?2:1:At(l[1]-e)0?1:0:u>0?3:2}function s(l,u){return c(l.x,u.x)}function c(l,u){var f=o(l,1),d=o(u,1);return f!==d?f-d:f===0?u[1]-l[1]:f===1?l[0]-u[0]:f===2?l[1]-u[1]:u[0]-l[0]}return function(l){var u=l,f=sP(),d,h,p,v,g,y,m,b,x,w,O,S={point:_,lineStart:T,lineEnd:A,polygonStart:E,polygonEnd:P};function _(C,L){i(C,L)&&u.point(C,L)}function M(){for(var C=0,L=0,I=h.length;Lr&&(Y-B)*(r-F)>(U-F)*(t-B)&&++C:U<=r&&(Y-B)*(r-F)<(U-F)*(t-B)&&--C;return C}function E(){u=f,d=[],h=[],O=!0}function P(){var C=M(),L=O&&C,I=(d=px(d)).length;(L||I)&&(l.polygonStart(),L&&(l.lineStart(),a(null,null,1,l),l.lineEnd()),I&&cP(d,s,C,a,l),l.polygonEnd()),u=l,d=h=p=null}function T(){S.point=k,h&&h.push(p=[]),w=!0,x=!1,m=b=NaN}function A(){d&&(k(v,g),y&&x&&f.rejoin(),d.push(f.result())),S.point=_,x&&u.lineEnd()}function k(C,L){var I=i(C,L);if(h&&p.push([C,L]),w)v=C,g=L,y=I,w=!1,I&&(u.lineStart(),u.point(C,L));else if(I&&x)u.point(C,L);else{var R=[m=Math.max(Wc,Math.min(Io,m)),b=Math.max(Wc,Math.min(Io,b))],j=[C=Math.max(Wc,Math.min(Io,C)),L=Math.max(Wc,Math.min(Io,L))];MY(R,j,t,e,n,r)?(x||(u.lineStart(),u.point(R[0],R[1])),u.point(j[0],j[1]),I||u.lineEnd(),O=!1):I&&(u.lineStart(),u.point(C,L),O=!1)}m=C,b=L,x=I}return S}}function M1(t,e,n){var r=pa(t,e-ut,n).concat(e);return function(i){return r.map(function(a){return[i,a]})}}function E1(t,e,n){var r=pa(t,e-ut,n).concat(e);return function(i){return r.map(function(a){return[a,i]})}}function EY(){var t,e,n,r,i,a,o,s,c=10,l=c,u=90,f=360,d,h,p,v,g=2.5;function y(){return{type:"MultiLineString",coordinates:m()}}function m(){return pa(Fc(r/u)*u,n,u).map(p).concat(pa(Fc(s/f)*f,o,f).map(v)).concat(pa(Fc(e/c)*c,t,c).filter(function(b){return At(b%u)>ut}).map(d)).concat(pa(Fc(a/l)*l,i,l).filter(function(b){return At(b%f)>ut}).map(h))}return y.lines=function(){return m().map(function(b){return{type:"LineString",coordinates:b}})},y.outline=function(){return{type:"Polygon",coordinates:[p(r).concat(v(o).slice(1),p(n).reverse().slice(1),v(s).reverse().slice(1))]}},y.extent=function(b){return arguments.length?y.extentMajor(b).extentMinor(b):y.extentMinor()},y.extentMajor=function(b){return arguments.length?(r=+b[0][0],n=+b[1][0],s=+b[0][1],o=+b[1][1],r>n&&(b=r,r=n,n=b),s>o&&(b=s,s=o,o=b),y.precision(g)):[[r,s],[n,o]]},y.extentMinor=function(b){return arguments.length?(e=+b[0][0],t=+b[1][0],a=+b[0][1],i=+b[1][1],e>t&&(b=e,e=t,t=b),a>i&&(b=a,a=i,i=b),y.precision(g)):[[e,a],[t,i]]},y.step=function(b){return arguments.length?y.stepMajor(b).stepMinor(b):y.stepMinor()},y.stepMajor=function(b){return arguments.length?(u=+b[0],f=+b[1],y):[u,f]},y.stepMinor=function(b){return arguments.length?(c=+b[0],l=+b[1],y):[c,l]},y.precision=function(b){return arguments.length?(g=+b,d=M1(a,i,90),h=E1(e,t,g),p=M1(s,o,90),v=E1(r,n,g),y):g},y.extentMajor([[-180,-90+ut],[180,90-ut]]).extentMinor([[-180,-80-ut],[180,80+ut]])}function PY(){return EY()()}const _s=t=>t;var md=new Ii,Bh=new Ii,fP,dP,Fh,zh,_r={point:Tn,lineStart:Tn,lineEnd:Tn,polygonStart:function(){_r.lineStart=AY,_r.lineEnd=TY},polygonEnd:function(){_r.lineStart=_r.lineEnd=_r.point=Tn,md.add(At(Bh)),Bh=new Ii},result:function(){var t=md/2;return md=new Ii,t}};function AY(){_r.point=kY}function kY(t,e){_r.point=hP,fP=Fh=t,dP=zh=e}function hP(t,e){Bh.add(zh*t-Fh*e),Fh=t,zh=e}function TY(){hP(fP,dP)}var qa=1/0,nu=qa,Ms=-qa,ru=Ms,iu={point:CY,lineStart:Tn,lineEnd:Tn,polygonStart:Tn,polygonEnd:Tn,result:function(){var t=[[qa,nu],[Ms,ru]];return Ms=ru=-(nu=qa=1/0),t}};function CY(t,e){tMs&&(Ms=t),eru&&(ru=e)}var Gh=0,Yh=0,jo=0,au=0,ou=0,ma=0,Wh=0,Hh=0,Do=0,pP,vP,tr,er,An={point:Hi,lineStart:P1,lineEnd:A1,polygonStart:function(){An.lineStart=RY,An.lineEnd=IY},polygonEnd:function(){An.point=Hi,An.lineStart=P1,An.lineEnd=A1},result:function(){var t=Do?[Wh/Do,Hh/Do]:ma?[au/ma,ou/ma]:jo?[Gh/jo,Yh/jo]:[NaN,NaN];return Gh=Yh=jo=au=ou=ma=Wh=Hh=Do=0,t}};function Hi(t,e){Gh+=t,Yh+=e,++jo}function P1(){An.point=LY}function LY(t,e){An.point=NY,Hi(tr=t,er=e)}function NY(t,e){var n=t-tr,r=e-er,i=cn(n*n+r*r);au+=i*(tr+t)/2,ou+=i*(er+e)/2,ma+=i,Hi(tr=t,er=e)}function A1(){An.point=Hi}function RY(){An.point=jY}function IY(){gP(pP,vP)}function jY(t,e){An.point=gP,Hi(pP=tr=t,vP=er=e)}function gP(t,e){var n=t-tr,r=e-er,i=cn(n*n+r*r);au+=i*(tr+t)/2,ou+=i*(er+e)/2,ma+=i,i=er*t-tr*e,Wh+=i*(tr+t),Hh+=i*(er+e),Do+=i*3,Hi(tr=t,er=e)}function yP(t){this._context=t}yP.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._context.moveTo(t,e),this._point=1;break}case 1:{this._context.lineTo(t,e);break}default:{this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,xn);break}}},result:Tn};var Vh=new Ii,bd,mP,bP,$o,Bo,Es={point:Tn,lineStart:function(){Es.point=DY},lineEnd:function(){bd&&xP(mP,bP),Es.point=Tn},polygonStart:function(){bd=!0},polygonEnd:function(){bd=null},result:function(){var t=+Vh;return Vh=new Ii,t}};function DY(t,e){Es.point=xP,mP=$o=t,bP=Bo=e}function xP(t,e){$o-=t,Bo-=e,Vh.add(cn($o*$o+Bo*Bo)),$o=t,Bo=e}let k1,su,T1,C1;class L1{constructor(e){this._append=e==null?wP:$Y(e),this._radius=4.5,this._=""}pointRadius(e){return this._radius=+e,this}polygonStart(){this._line=0}polygonEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){this._line===0&&(this._+="Z"),this._point=NaN}point(e,n){switch(this._point){case 0:{this._append`M${e},${n}`,this._point=1;break}case 1:{this._append`L${e},${n}`;break}default:{if(this._append`M${e},${n}`,this._radius!==T1||this._append!==su){const r=this._radius,i=this._;this._="",this._append`m0,${r}a${r},${r} 0 1,1 0,${-2*r}a${r},${r} 0 1,1 0,${2*r}z`,T1=r,su=this._append,C1=this._,this._=i}this._+=C1;break}}}result(){const e=this._;return this._="",e.length?e:null}}function wP(t){let e=1;this._+=t[0];for(const n=t.length;e=0))throw new RangeError(`invalid digits: ${t}`);if(e>15)return wP;if(e!==k1){const n=10**e;k1=e,su=function(i){let a=1;this._+=i[0];for(const o=i.length;a=0))throw new RangeError(`invalid digits: ${s}`);n=c}return e===null&&(a=new L1(n)),o},o.projection(t).digits(n).context(e)}function of(t){return function(e){var n=new Xh;for(var r in t)n[r]=t[r];return n.stream=e,n}}function Xh(){}Xh.prototype={constructor:Xh,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function K0(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),r!=null&&t.clipExtent(null),fa(n,t.stream(iu)),e(iu.result()),r!=null&&t.clipExtent(r),t}function sf(t,e,n){return K0(t,function(r){var i=e[1][0]-e[0][0],a=e[1][1]-e[0][1],o=Math.min(i/(r[1][0]-r[0][0]),a/(r[1][1]-r[0][1])),s=+e[0][0]+(i-o*(r[1][0]+r[0][0]))/2,c=+e[0][1]+(a-o*(r[1][1]+r[0][1]))/2;t.scale(150*o).translate([s,c])},n)}function Z0(t,e,n){return sf(t,[[0,0],e],n)}function Q0(t,e,n){return K0(t,function(r){var i=+e,a=i/(r[1][0]-r[0][0]),o=(i-a*(r[1][0]+r[0][0]))/2,s=-a*r[0][1];t.scale(150*a).translate([o,s])},n)}function J0(t,e,n){return K0(t,function(r){var i=+e,a=i/(r[1][1]-r[0][1]),o=-a*r[0][0],s=(i-a*(r[1][1]+r[0][1]))/2;t.scale(150*a).translate([o,s])},n)}var N1=16,BY=mt(30*ae);function R1(t,e){return+e?zY(t,e):FY(t)}function FY(t){return of({point:function(e,n){e=t(e,n),this.stream.point(e[0],e[1])}})}function zY(t,e){function n(r,i,a,o,s,c,l,u,f,d,h,p,v,g){var y=l-r,m=u-i,b=y*y+m*m;if(b>4*e&&v--){var x=o+d,w=s+h,O=c+p,S=cn(x*x+w*w+O*O),_=In(O/=S),M=At(At(O)-1)e||At((y*A+m*k)/b-.5)>.3||o*d+s*h+c*p2?C[2]%360*ae:0,A()):[s*De,c*De,l*De]},P.angle=function(C){return arguments.length?(f=C%360*ae,A()):f*De},P.reflectX=function(C){return arguments.length?(d=C?-1:1,A()):d<0},P.reflectY=function(C){return arguments.length?(h=C?-1:1,A()):h<0},P.precision=function(C){return arguments.length?(O=R1(S,w=C*C),k()):cn(w)},P.fitExtent=function(C,L){return sf(P,C,L)},P.fitSize=function(C,L){return Z0(P,C,L)},P.fitWidth=function(C,L){return Q0(P,C,L)},P.fitHeight=function(C,L){return J0(P,C,L)};function A(){var C=I1(n,0,0,d,h,f).apply(null,e(a,o)),L=I1(n,r-C[0],i-C[1],d,h,f);return u=oP(s,c,l),S=Dh(e,L),_=Dh(u,S),O=R1(S,w),k()}function k(){return M=E=null,P}return function(){return e=t.apply(this,arguments),P.invert=e.invert&&T,A()}}function ev(t){var e=0,n=wt/3,r=tv(t),i=r(e,n);return i.parallels=function(a){return arguments.length?r(e=a[0]*ae,n=a[1]*ae):[e*De,n*De]},i}function HY(t){var e=mt(t);function n(r,i){return[r*e,pt(i)/e]}return n.invert=function(r,i){return[r/e,In(i*e)]},n}function SP(t,e){var n=pt(t),r=(n+pt(e))/2;if(At(r)=.12&&g<.234&&v>=-.425&&v<-.214?i:g>=.166&&g<.234&&v>=-.214&&v<-.115?o:n).invert(d)},u.stream=function(d){return t&&e===d?t:t=VY([n.stream(e=d),i.stream(d),o.stream(d)])},u.precision=function(d){return arguments.length?(n.precision(d),i.precision(d),o.precision(d),f()):n.precision()},u.scale=function(d){return arguments.length?(n.scale(d),i.scale(d*.35),o.scale(d),u.translate(n.translate())):n.scale()},u.translate=function(d){if(!arguments.length)return n.translate();var h=n.scale(),p=+d[0],v=+d[1];return r=n.translate(d).clipExtent([[p-.455*h,v-.238*h],[p+.455*h,v+.238*h]]).stream(l),a=i.translate([p-.307*h,v+.201*h]).clipExtent([[p-.425*h+ut,v+.12*h+ut],[p-.214*h-ut,v+.234*h-ut]]).stream(l),s=o.translate([p-.205*h,v+.212*h]).clipExtent([[p-.214*h+ut,v+.166*h+ut],[p-.115*h-ut,v+.234*h-ut]]).stream(l),f()},u.fitExtent=function(d,h){return sf(u,d,h)},u.fitSize=function(d,h){return Z0(u,d,h)},u.fitWidth=function(d,h){return Q0(u,d,h)},u.fitHeight=function(d,h){return J0(u,d,h)};function f(){return t=e=null,u}return u.scale(1070)}function MP(t){return function(e,n){var r=mt(e),i=mt(n),a=t(r*i);return a===1/0?[2,0]:[a*i*pt(e),a*pt(n)]}}function nc(t){return function(e,n){var r=cn(e*e+n*n),i=t(r),a=pt(i),o=mt(i);return[Ir(e*a,r*o),In(r&&n*a/r)]}}var nv=MP(function(t){return cn(2/(1+t))});nv.invert=nc(function(t){return 2*In(t/2)});function UY(){return pr(nv).scale(124.75).clipAngle(180-.001)}var rv=MP(function(t){return(t=aP(t))&&t/pt(t)});rv.invert=nc(function(t){return t});function qY(){return pr(rv).scale(79.4188).clipAngle(180-.001)}function rc(t,e){return[t,Jl(q0((fe+e)/2))]}rc.invert=function(t,e){return[t,2*co(iP(e))-fe]};function KY(){return EP(rc).scale(961/xn)}function EP(t){var e=pr(t),n=e.center,r=e.scale,i=e.translate,a=e.clipExtent,o=null,s,c,l;e.scale=function(f){return arguments.length?(r(f),u()):r()},e.translate=function(f){return arguments.length?(i(f),u()):i()},e.center=function(f){return arguments.length?(n(f),u()):n()},e.clipExtent=function(f){return arguments.length?(f==null?o=s=c=l=null:(o=+f[0][0],s=+f[0][1],c=+f[1][0],l=+f[1][1]),u()):o==null?null:[[o,s],[c,l]]};function u(){var f=wt*r(),d=e(gY(e.rotate()).invert([0,0]));return a(o==null?[[d[0]-f,d[1]-f],[d[0]+f,d[1]+f]]:t===rc?[[Math.max(d[0]-f,o),s],[Math.min(d[0]+f,c),l]]:[[o,Math.max(d[1]-f,s)],[c,Math.min(d[1]+f,l)]])}return u()}function Hc(t){return q0((fe+t)/2)}function PP(t,e){var n=mt(t),r=t===e?pt(t):Jl(n/mt(e))/Jl(Hc(e)/Hc(t)),i=n*vd(Hc(t),r)/r;if(!r)return rc;function a(o,s){i>0?s<-fe+ut&&(s=-fe+ut):s>fe-ut&&(s=fe-ut);var c=i/vd(Hc(s),r);return[c*pt(r*o),i-c*mt(r*o)]}return a.invert=function(o,s){var c=i-s,l=kn(r)*cn(o*o+c*c),u=Ir(o,At(c))*kn(c);return c*r<0&&(u-=wt*kn(o)*kn(c)),[u/r,2*co(vd(i/l,1/r))-fe]},a}function ZY(){return ev(PP).scale(109.5).parallels([30,30])}function Ps(t,e){return[t,e]}Ps.invert=Ps;function QY(){return pr(Ps).scale(152.63)}function AP(t,e){var n=mt(t),r=t===e?pt(t):(n-mt(e))/(e-t),i=n/r+t;if(At(r)ut&&--r>0);return[t/(.8707+(a=n*n)*(-.131979+a*(-.013791+a*a*a*(.003971-.001529*a)))),n]};function iW(){return pr(ov).scale(175.295)}function sv(t,e){return[mt(e)*pt(t),pt(e)]}sv.invert=nc(In);function aW(){return pr(sv).scale(249.5).clipAngle(90+ut)}function cv(t,e){var n=mt(e),r=1+mt(t)*n;return[n*pt(t)/r,pt(e)/r]}cv.invert=nc(function(t){return 2*co(t)});function oW(){return pr(cv).scale(250).clipAngle(142)}function lv(t,e){return[Jl(q0((fe+e)/2)),-t]}lv.invert=function(t,e){return[-e,2*co(iP(t))-fe]};function sW(){var t=EP(lv),e=t.center,n=t.rotate;return t.center=function(r){return arguments.length?e([-r[1],r[0]]):(r=e(),[r[1],-r[0]])},t.rotate=function(r){return arguments.length?n([r[0],r[1],r.length>2?r[2]+90:90]):(r=n(),[r[0],r[1],r[2]-90])},n([0,0,90]).scale(159.155)}const cW=Object.freeze(Object.defineProperty({__proto__:null,geoAlbers:_P,geoAlbersUsa:XY,geoAzimuthalEqualArea:UY,geoAzimuthalEqualAreaRaw:nv,geoAzimuthalEquidistant:qY,geoAzimuthalEquidistantRaw:rv,geoConicConformal:ZY,geoConicConformalRaw:PP,geoConicEqualArea:cu,geoConicEqualAreaRaw:SP,geoConicEquidistant:JY,geoConicEquidistantRaw:AP,geoEqualEarth:eW,geoEqualEarthRaw:iv,geoEquirectangular:QY,geoEquirectangularRaw:Ps,geoGnomonic:nW,geoGnomonicRaw:av,geoIdentity:rW,geoMercator:KY,geoMercatorRaw:rc,geoNaturalEarth1:iW,geoNaturalEarth1Raw:ov,geoOrthographic:aW,geoOrthographicRaw:sv,geoProjection:pr,geoProjectionMutator:tv,geoStereographic:oW,geoStereographicRaw:cv,geoTransverseMercator:sW,geoTransverseMercatorRaw:lv},Symbol.toStringTag,{value:"Module"}));var lW=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);idW(e).features)}}function dW(t){const e={Point:"geometry",MultiPoint:"geometry",LineString:"geometry",MultiLineString:"geometry",Polygon:"geometry",MultiPolygon:"geometry",GeometryCollection:"geometry",Feature:"feature",FeatureCollection:"featureCollection"};if(!t||!t.type)return null;const n=e[t.type];if(!n)return null;if(n==="geometry")return{type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:t}]};if(n==="feature")return{type:"FeatureCollection",features:[t]};if(n==="featureCollection")return t}function hW(t,e){var n;for(const[r,i]of Object.entries(e))(n=t[r])===null||n===void 0||n.call(t,i)}function pW(t,e,n,r){const i=()=>{const s=e.filter(kP);return s.find(l=>l.sphere)?{type:"Sphere"}:fW(s.filter(l=>!l.sphere).flatMap(l=>l.data.value))},{outline:a=i()}=r,{size:o="fitExtent"}=r;if(o==="fitExtent")return vW(t,a,n);if(o==="fitWidth")return gW(t,a,n)}function vW(t,e,n){const{x:r,y:i,width:a,height:o}=n;t.fitExtent([[r,i],[a,o]],e)}function gW(t,e,n){const{width:r,height:i}=n,[[a,o],[s,c]]=OP(t.fitWidth(r,e)).bounds(e),l=Math.ceil(c-o),u=Math.min(Math.ceil(s-a),l),f=t.scale()*(u-1)/u,[d,h]=t.translate(),p=h+(i-l)/2;t.scale(f).translate([d,p]).precision(.2)}function yW(t){const{data:e}=t;if(Array.isArray(e))return Object.assign(Object.assign({},t),{data:{value:e}});const{type:n}=e;return n==="graticule10"?Object.assign(Object.assign({},t),{data:{value:[PY()]}}):n==="sphere"?Object.assign(Object.assign({},t),{sphere:!0,data:{value:[{type:"Sphere"}]}}):t}function kP(t){return t.type==="geoPath"}const TP=()=>t=>{const{children:e,coordinate:n={}}=t;if(!Array.isArray(e))return[];const{type:r="equalEarth"}=n,i=lW(n,["type"]),a=uW(r),o=e.map(yW);let s;function c(){return[["custom",(f,d,h,p)=>{const v=a();pW(v,o,{x:f,y:d,width:h,height:p},i),hW(v,i),s=OP(v);const y=new Yt({domain:[f,f+h]}),m=new Yt({domain:[d,d+p]}),b=w=>{const O=v(w);if(!O)return[null,null];const[S,_]=O;return[y.map(S),m.map(_)]},x=w=>{if(!w)return null;const[O,S]=w,_=[y.invert(O),m.invert(S)];return v.invert(_)};return{transform:w=>b(w),untransform:w=>x(w)}}]]}function l(f){const{style:d,tooltip:h={}}=f;return Object.assign(Object.assign({},f),{type:"path",tooltip:Hl(h,{title:"id",items:[{channel:"color"}]}),style:Object.assign(Object.assign({},d),{d:p=>s(p)||[]})})}const u=f=>kP(f)?l(f):f;return[Object.assign(Object.assign({},t),{type:"view",scale:{x:{type:"identity"},y:{type:"identity"}},axis:!1,coordinate:{type:c},children:o.flatMap(u)})]};TP.props={};function CP(t,e){const{__data__:n}=t,{markKey:r,index:i,seriesIndex:a}=n,{markState:o}=e,s=Array.from(o.keys()).find(c=>c.key===r);if(s)return a?a.map(c=>s.data[c]):s.data[i]}function uv(t,e){if(e(t))return t;let n=t.parent;for(;n&&!e(n);)n=n.parent;return n}function mW(t){return uv(t,e=>e.className==="component")}function bW(t){return uv(t,e=>e.className==="element")}function xW(t){return uv(t,e=>e.className==="label")}function Se(t,e,n,r=i=>!0){return i=>{if(!r(i))return;n.emit(`plot:${t}`,i);const{target:a}=i;if(!a)return;const{className:o}=a;if(o==="plot")return;const s=bW(a),c=mW(a),l=xW(a),u=s||c||l;if(!u)return;const{className:f,markType:d}=u,h=Object.assign(Object.assign({},i),{nativeEvent:!0});f==="element"?(h.data={data:CP(u,e)},n.emit(`element:${t}`,h),n.emit(`${d}:${t}`,h)):f==="label"?(h.data={data:u.attributes.datum},n.emit(`label:${t}`,h),n.emit(`${o}:${t}`,h)):(n.emit(`component:${t}`,h),n.emit(`${o}:${t}`,h))}}function LP(){return(t,e,n)=>{const{container:r,view:i}=t,a=Se(Lt.CLICK,i,n,S=>S.detail===1),o=Se(Lt.DBLCLICK,i,n,S=>S.detail===2),s=Se(Lt.POINTER_TAP,i,n),c=Se(Lt.POINTER_DOWN,i,n),l=Se(Lt.POINTER_UP,i,n),u=Se(Lt.POINTER_OVER,i,n),f=Se(Lt.POINTER_OUT,i,n),d=Se(Lt.POINTER_MOVE,i,n),h=Se(Lt.POINTER_ENTER,i,n),p=Se(Lt.POINTER_LEAVE,i,n),v=Se(Lt.POINTER_UPOUTSIDE,i,n),g=Se(Lt.DRAG_START,i,n),y=Se(Lt.DRAG,i,n),m=Se(Lt.DRAG_END,i,n),b=Se(Lt.DRAG_ENTER,i,n),x=Se(Lt.DRAG_LEAVE,i,n),w=Se(Lt.DRAG_OVER,i,n),O=Se(Lt.DROP,i,n);return r.addEventListener("click",a),r.addEventListener("click",o),r.addEventListener("pointertap",s),r.addEventListener("pointerdown",c),r.addEventListener("pointerup",l),r.addEventListener("pointerover",u),r.addEventListener("pointerout",f),r.addEventListener("pointermove",d),r.addEventListener("pointerenter",h),r.addEventListener("pointerleave",p),r.addEventListener("pointerupoutside",v),r.addEventListener("dragstart",g),r.addEventListener("drag",y),r.addEventListener("dragend",m),r.addEventListener("dragenter",b),r.addEventListener("dragleave",x),r.addEventListener("dragover",w),r.addEventListener("drop",O),()=>{r.removeEventListener("click",a),r.removeEventListener("click",o),r.removeEventListener("pointertap",s),r.removeEventListener("pointerdown",c),r.removeEventListener("pointerup",l),r.removeEventListener("pointerover",u),r.removeEventListener("pointerout",f),r.removeEventListener("pointermove",d),r.removeEventListener("pointerenter",h),r.removeEventListener("pointerleave",p),r.removeEventListener("pointerupoutside",v),r.removeEventListener("dragstart",g),r.removeEventListener("drag",y),r.removeEventListener("dragend",m),r.removeEventListener("dragenter",b),r.removeEventListener("dragleave",x),r.removeEventListener("dragover",w),r.removeEventListener("drop",O)}}}LP.props={reapplyWhenUpdate:!0};function wW(){return{"component.axisRadar":vE,"component.axisLinear":di,"component.axisArc":dE,"component.legendContinuousBlock":gE,"component.legendContinuousBlockSize":yE,"component.legendContinuousSize":$0,"interaction.event":LP,"composition.mark":ZE,"composition.view":KE,"shape.label.label":r_}}var OW=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{if(typeof a!="string")return a;const o=`${t}.${a}`;return n[o]||La(`Unknown Component: ${o}`)};return[(a,o)=>{const{type:s}=a,c=OW(a,["type"]);s||La("Plot type is required!");const l=r(s);return l==null?void 0:l(c,o)},r]}function NP(t){const{canvas:e,group:n}=t;return(e==null?void 0:e.document)||(n==null?void 0:n.ownerDocument)||La("Cannot find library document")}var j1=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);in.type===e)}function Pi(t){return Xn(t,"polar").length>0}function _W(t){return Xn(t,"helix").length>0}function Ma(t){return Xn(t,"transpose").length%2===1}function MW(t){return Xn(t,"parallel").length>0}function IP(t){return Xn(t,"theta").length>0}function EW(t){return Xn(t,"reflect").length>0}function Ko(t){return Xn(t,"radial").length>0}function PW(t){return Xn(t,"radar").length>0}function AW(t){return Xn(t,"reflectY").length>0}function kW(t){return t.find(e=>e.type==="cartesian"||e.type==="cartesian3D")?t:[...t,{type:"cartesian"}]}function gt(t){for(var e=t.length/6|0,n=new Array(e),r=0;r>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):n===8?Vc(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):n===4?Vc(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=zW.exec(t))?new Be(e[1],e[2],e[3],1):(e=GW.exec(t))?new Be(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=YW.exec(t))?Vc(e[1],e[2],e[3],e[4]):(e=WW.exec(t))?Vc(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=HW.exec(t))?Y1(e[1],e[2]/100,e[3]/100,1):(e=VW.exec(t))?Y1(e[1],e[2]/100,e[3]/100,e[4]):D1.hasOwnProperty(t)?F1(D1[t]):t==="transparent"?new Be(NaN,NaN,NaN,0):null}function F1(t){return new Be(t>>16&255,t>>8&255,t&255,1)}function Vc(t,e,n,r){return r<=0&&(t=e=n=NaN),new Be(t,e,n,r)}function jP(t){return t instanceof lo||(t=dv(t)),t?(t=t.rgb(),new Be(t.r,t.g,t.b,t.opacity)):new Be}function ks(t,e,n,r){return arguments.length===1?jP(t):new Be(t,e,n,r??1)}function Be(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}cf(Be,ks,fv(lo,{brighter(t){return t=t==null?Ka:Math.pow(Ka,t),new Be(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?Vi:Math.pow(Vi,t),new Be(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Be(Ci(this.r),Ci(this.g),Ci(this.b),uu(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:z1,formatHex:z1,formatHex8:qW,formatRgb:G1,toString:G1}));function z1(){return`#${Ai(this.r)}${Ai(this.g)}${Ai(this.b)}`}function qW(){return`#${Ai(this.r)}${Ai(this.g)}${Ai(this.b)}${Ai((isNaN(this.opacity)?1:this.opacity)*255)}`}function G1(){const t=uu(this.opacity);return`${t===1?"rgb(":"rgba("}${Ci(this.r)}, ${Ci(this.g)}, ${Ci(this.b)}${t===1?")":`, ${t})`}`}function uu(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Ci(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function Ai(t){return t=Ci(t),(t<16?"0":"")+t.toString(16)}function Y1(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new Yn(t,e,n,r)}function DP(t){if(t instanceof Yn)return new Yn(t.h,t.s,t.l,t.opacity);if(t instanceof lo||(t=dv(t)),!t)return new Yn;if(t instanceof Yn)return t;t=t.rgb();var e=t.r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(e===a?o=(n-r)/s+(n0&&c<1?0:o,new Yn(o,s,c,t.opacity)}function KW(t,e,n,r){return arguments.length===1?DP(t):new Yn(t,e,n,r??1)}function Yn(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}cf(Yn,KW,fv(lo,{brighter(t){return t=t==null?Ka:Math.pow(Ka,t),new Yn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?Vi:Math.pow(Vi,t),new Yn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new Be(xd(t>=240?t-240:t+120,i,r),xd(t,i,r),xd(t<120?t+240:t-120,i,r),this.opacity)},clamp(){return new Yn(W1(this.h),Xc(this.s),Xc(this.l),uu(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=uu(this.opacity);return`${t===1?"hsl(":"hsla("}${W1(this.h)}, ${Xc(this.s)*100}%, ${Xc(this.l)*100}%${t===1?")":`, ${t})`}`}}));function W1(t){return t=(t||0)%360,t<0?t+360:t}function Xc(t){return Math.max(0,Math.min(1,t||0))}function xd(t,e,n){return(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)*255}const ZW=Math.PI/180,QW=180/Math.PI;var $P=-.14861,hv=1.78277,pv=-.29227,lf=-.90649,Ts=1.97294,H1=Ts*lf,V1=Ts*hv,X1=hv*pv-lf*$P;function JW(t){if(t instanceof Li)return new Li(t.h,t.s,t.l,t.opacity);t instanceof Be||(t=jP(t));var e=t.r/255,n=t.g/255,r=t.b/255,i=(X1*r+H1*e-V1*n)/(X1+H1-V1),a=r-i,o=(Ts*(n-i)-pv*a)/lf,s=Math.sqrt(o*o+a*a)/(Ts*i*(1-i)),c=s?Math.atan2(o,a)*QW-120:NaN;return new Li(c<0?c+360:c,s,i,t.opacity)}function hr(t,e,n,r){return arguments.length===1?JW(t):new Li(t,e,n,r??1)}function Li(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}cf(Li,hr,fv(lo,{brighter(t){return t=t==null?Ka:Math.pow(Ka,t),new Li(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?Vi:Math.pow(Vi,t),new Li(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=isNaN(this.h)?0:(this.h+120)*ZW,e=+this.l,n=isNaN(this.s)?0:this.s*e*(1-e),r=Math.cos(t),i=Math.sin(t);return new Be(255*(e+n*($P*r+hv*i)),255*(e+n*(pv*r+lf*i)),255*(e+n*(Ts*r)),this.opacity)}}));function tH(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}function eH(t){var e=t.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=r()=>t;function BP(t,e){return function(n){return t+n*e}}function nH(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}function rH(t,e){var n=e-t;return n?BP(t,n>180||n<-180?n-360*Math.round(n/360):n):vv(isNaN(t)?e:t)}function iH(t){return(t=+t)==1?Pa:function(e,n){return n-e?nH(e,n,t):vv(isNaN(e)?n:e)}}function Pa(t,e){var n=e-t;return n?BP(t,n):vv(isNaN(t)?e:t)}(function t(e){var n=iH(e);function r(i,a){var o=n((i=ks(i)).r,(a=ks(a)).r),s=n(i.g,a.g),c=n(i.b,a.b),l=Pa(i.opacity,a.opacity);return function(u){return i.r=o(u),i.g=s(u),i.b=c(u),i.opacity=l(u),i+""}}return r.gamma=t,r})(1);function aH(t){return function(e){var n=e.length,r=new Array(n),i=new Array(n),a=new Array(n),o,s;for(o=0;ooH(t[t.length-1]);var zP=new Array(3).concat("d8b365f5f5f55ab4ac","a6611adfc27d80cdc1018571","a6611adfc27df5f5f580cdc1018571","8c510ad8b365f6e8c3c7eae55ab4ac01665e","8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e","8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e","8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e","5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30","5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30").map(gt);const sH=Vt(zP);var GP=new Array(3).concat("af8dc3f7f7f77fbf7b","7b3294c2a5cfa6dba0008837","7b3294c2a5cff7f7f7a6dba0008837","762a83af8dc3e7d4e8d9f0d37fbf7b1b7837","762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837","762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837","762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837","40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b","40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b").map(gt);const cH=Vt(GP);var YP=new Array(3).concat("e9a3c9f7f7f7a1d76a","d01c8bf1b6dab8e1864dac26","d01c8bf1b6daf7f7f7b8e1864dac26","c51b7de9a3c9fde0efe6f5d0a1d76a4d9221","c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221","c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221","c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221","8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419","8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419").map(gt);const lH=Vt(YP);var WP=new Array(3).concat("998ec3f7f7f7f1a340","5e3c99b2abd2fdb863e66101","5e3c99b2abd2f7f7f7fdb863e66101","542788998ec3d8daebfee0b6f1a340b35806","542788998ec3d8daebf7f7f7fee0b6f1a340b35806","5427888073acb2abd2d8daebfee0b6fdb863e08214b35806","5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806","2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08","2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08").map(gt);const uH=Vt(WP);var HP=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(gt);const fH=Vt(HP);var VP=new Array(3).concat("ef8a62ffffff999999","ca0020f4a582bababa404040","ca0020f4a582ffffffbababa404040","b2182bef8a62fddbc7e0e0e09999994d4d4d","b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d","b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d","b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d","67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a","67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a").map(gt);const dH=Vt(VP);var XP=new Array(3).concat("fc8d59ffffbf91bfdb","d7191cfdae61abd9e92c7bb6","d7191cfdae61ffffbfabd9e92c7bb6","d73027fc8d59fee090e0f3f891bfdb4575b4","d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4","d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4","d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4","a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695","a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695").map(gt);const hH=Vt(XP);var UP=new Array(3).concat("fc8d59ffffbf91cf60","d7191cfdae61a6d96a1a9641","d7191cfdae61ffffbfa6d96a1a9641","d73027fc8d59fee08bd9ef8b91cf601a9850","d73027fc8d59fee08bffffbfd9ef8b91cf601a9850","d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850","d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850","a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837","a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837").map(gt);const pH=Vt(UP);var qP=new Array(3).concat("fc8d59ffffbf99d594","d7191cfdae61abdda42b83ba","d7191cfdae61ffffbfabdda42b83ba","d53e4ffc8d59fee08be6f59899d5943288bd","d53e4ffc8d59fee08bffffbfe6f59899d5943288bd","d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd","d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd","9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2","9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2").map(gt);const vH=Vt(qP);var KP=new Array(3).concat("e5f5f999d8c92ca25f","edf8fbb2e2e266c2a4238b45","edf8fbb2e2e266c2a42ca25f006d2c","edf8fbccece699d8c966c2a42ca25f006d2c","edf8fbccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b").map(gt);const gH=Vt(KP);var ZP=new Array(3).concat("e0ecf49ebcda8856a7","edf8fbb3cde38c96c688419d","edf8fbb3cde38c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b").map(gt);const yH=Vt(ZP);var QP=new Array(3).concat("e0f3dba8ddb543a2ca","f0f9e8bae4bc7bccc42b8cbe","f0f9e8bae4bc7bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081").map(gt);const mH=Vt(QP);var JP=new Array(3).concat("fee8c8fdbb84e34a33","fef0d9fdcc8afc8d59d7301f","fef0d9fdcc8afc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000").map(gt);const bH=Vt(JP);var tA=new Array(3).concat("ece2f0a6bddb1c9099","f6eff7bdc9e167a9cf02818a","f6eff7bdc9e167a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636").map(gt);const xH=Vt(tA);var eA=new Array(3).concat("ece7f2a6bddb2b8cbe","f1eef6bdc9e174a9cf0570b0","f1eef6bdc9e174a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858").map(gt);const wH=Vt(eA);var nA=new Array(3).concat("e7e1efc994c7dd1c77","f1eef6d7b5d8df65b0ce1256","f1eef6d7b5d8df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f").map(gt);const OH=Vt(nA);var rA=new Array(3).concat("fde0ddfa9fb5c51b8a","feebe2fbb4b9f768a1ae017e","feebe2fbb4b9f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a").map(gt);const SH=Vt(rA);var iA=new Array(3).concat("edf8b17fcdbb2c7fb8","ffffcca1dab441b6c4225ea8","ffffcca1dab441b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58").map(gt);const _H=Vt(iA);var aA=new Array(3).concat("f7fcb9addd8e31a354","ffffccc2e69978c679238443","ffffccc2e69978c67931a354006837","ffffccd9f0a3addd8e78c67931a354006837","ffffccd9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529").map(gt);const MH=Vt(aA);var oA=new Array(3).concat("fff7bcfec44fd95f0e","ffffd4fed98efe9929cc4c02","ffffd4fed98efe9929d95f0e993404","ffffd4fee391fec44ffe9929d95f0e993404","ffffd4fee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506").map(gt);const EH=Vt(oA);var sA=new Array(3).concat("ffeda0feb24cf03b20","ffffb2fecc5cfd8d3ce31a1c","ffffb2fecc5cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026").map(gt);const PH=Vt(sA);var cA=new Array(3).concat("deebf79ecae13182bd","eff3ffbdd7e76baed62171b5","eff3ffbdd7e76baed63182bd08519c","eff3ffc6dbef9ecae16baed63182bd08519c","eff3ffc6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b").map(gt);const AH=Vt(cA);var lA=new Array(3).concat("e5f5e0a1d99b31a354","edf8e9bae4b374c476238b45","edf8e9bae4b374c47631a354006d2c","edf8e9c7e9c0a1d99b74c47631a354006d2c","edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b").map(gt);const kH=Vt(lA);var uA=new Array(3).concat("f0f0f0bdbdbd636363","f7f7f7cccccc969696525252","f7f7f7cccccc969696636363252525","f7f7f7d9d9d9bdbdbd969696636363252525","f7f7f7d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000").map(gt);const TH=Vt(uA);var fA=new Array(3).concat("efedf5bcbddc756bb1","f2f0f7cbc9e29e9ac86a51a3","f2f0f7cbc9e29e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d").map(gt);const CH=Vt(fA);var dA=new Array(3).concat("fee0d2fc9272de2d26","fee5d9fcae91fb6a4acb181d","fee5d9fcae91fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d").map(gt);const LH=Vt(dA);var hA=new Array(3).concat("fee6cefdae6be6550d","feeddefdbe85fd8d3cd94701","feeddefdbe85fd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704").map(gt);const NH=Vt(hA);function RH(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(-4.54-t*(35.34-t*(2381.73-t*(6402.7-t*(7024.72-t*2710.57)))))))+", "+Math.max(0,Math.min(255,Math.round(32.49+t*(170.73+t*(52.82-t*(131.46-t*(176.58-t*67.37)))))))+", "+Math.max(0,Math.min(255,Math.round(81.24+t*(442.36-t*(2482.43-t*(6167.24-t*(6614.94-t*2475.67)))))))+")"}const IH=gv(hr(300,.5,0),hr(-240,.5,1));var jH=gv(hr(-100,.75,.35),hr(80,1.5,.8)),DH=gv(hr(260,.75,.35),hr(80,1.5,.8)),Uc=hr();function $H(t){(t<0||t>1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return Uc.h=360*t-100,Uc.s=1.5-1.5*e,Uc.l=.8-.9*e,Uc+""}var qc=ks(),BH=Math.PI/3,FH=Math.PI*2/3;function zH(t){var e;return t=(.5-t)*Math.PI,qc.r=255*(e=Math.sin(t))*e,qc.g=255*(e=Math.sin(t+BH))*e,qc.b=255*(e=Math.sin(t+FH))*e,qc+""}function GH(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-t*14825.05)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+t*707.56)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-t*6838.66)))))))+")"}function uf(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}}const YH=uf(gt("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));var WH=uf(gt("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),HH=uf(gt("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),VH=uf(gt("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));const Uh=Object.freeze(Object.defineProperty({__proto__:null,interpolateBlues:AH,interpolateBrBG:sH,interpolateBuGn:gH,interpolateBuPu:yH,interpolateCividis:RH,interpolateCool:DH,interpolateCubehelixDefault:IH,interpolateGnBu:mH,interpolateGreens:kH,interpolateGreys:TH,interpolateInferno:HH,interpolateMagma:WH,interpolateOrRd:bH,interpolateOranges:NH,interpolatePRGn:cH,interpolatePiYG:lH,interpolatePlasma:VH,interpolatePuBu:wH,interpolatePuBuGn:xH,interpolatePuOr:uH,interpolatePuRd:OH,interpolatePurples:CH,interpolateRainbow:$H,interpolateRdBu:fH,interpolateRdGy:dH,interpolateRdPu:SH,interpolateRdYlBu:hH,interpolateRdYlGn:pH,interpolateReds:LH,interpolateSinebow:zH,interpolateSpectral:vH,interpolateTurbo:GH,interpolateViridis:YH,interpolateWarm:jH,interpolateYlGn:MH,interpolateYlGnBu:_H,interpolateYlOrBr:EH,interpolateYlOrRd:PH,schemeAccent:CW,schemeBlues:cA,schemeBrBG:zP,schemeBuGn:KP,schemeBuPu:ZP,schemeCategory10:TW,schemeDark2:LW,schemeGnBu:QP,schemeGreens:lA,schemeGreys:uA,schemeOrRd:JP,schemeOranges:hA,schemePRGn:GP,schemePaired:NW,schemePastel1:RW,schemePastel2:IW,schemePiYG:YP,schemePuBu:eA,schemePuBuGn:tA,schemePuOr:WP,schemePuRd:nA,schemePurples:fA,schemeRdBu:HP,schemeRdGy:VP,schemeRdPu:rA,schemeRdYlBu:XP,schemeRdYlGn:UP,schemeReds:dA,schemeSet1:jW,schemeSet2:DW,schemeSet3:$W,schemeSpectral:qP,schemeTableau10:BW,schemeYlGn:aA,schemeYlGnBu:iA,schemeYlOrBr:oA,schemeYlOrRd:sA},Symbol.toStringTag,{value:"Module"}));function XH(t,e,n,r,i,a){const{guide:o={}}=n,s=nV(t,e,n);if(typeof s!="string")return n;const c=rV(s,t,e,n),l=JH(s,c,n);return Object.assign(Object.assign(Object.assign({},n),aV(s,t,e,n,r)),{domain:l,range:iV(s,t,e,n,l,i,a),expectedDomain:c,guide:o,name:t,type:s})}function UH(t,e){const n={};for(const r of t){const{values:i,name:a}=r,o=e[a];for(const s of i){const{name:c,value:l}=s;n[c]=l.map(u=>o.map(u))}}return n}function qH(t,e){var n;const{components:r=[]}=e,i=["scale","encode","axis","legend","data","transform"],a=Array.from(new Set(t.flatMap(s=>s.channels.map(c=>c.scale)))),o=new Map(a.map(s=>[s.name,s]));for(const s of r){const c=QH(s);for(const l of c){const u=o.get(l),f=((n=s.scale)===null||n===void 0?void 0:n[l])||{},{independent:d=!1}=f;if(u&&!d){const{guide:h}=u,p=typeof h=="boolean"?{}:h;u.guide=X({},p,s),Object.assign(u,f)}else{const h=Object.assign(Object.assign({},f),{expectedDomain:f.domain,name:l,guide:Fb(s,i)});a.push(h)}}}return a}function KH(t){if(!t||!Array.isArray(t))return[ji,ji];let e,n;return[a=>{var o;e=a.map.bind(a),n=(o=a.invert)===null||o===void 0?void 0:o.bind(a);const s=t.filter(([d])=>typeof d=="function"),c=t.filter(([d])=>typeof d!="function"),l=new Map(c);if(a.map=d=>{for(const[h,p]of s)if(h(d))return p;return l.has(d)?l.get(d):e(d)},!n)return a;const u=new Map(c.map(([d,h])=>[h,d])),f=new Map(s.map(([d,h])=>[h,d]));return a.invert=d=>f.has(d)?d:u.has(d)?u.get(d):n(d),a},a=>(e!==null&&(a.map=e),n!==null&&(a.invert=n),a)]}function U1(t,e){const n=Object.keys(t);for(const r of Object.values(e)){const{name:i}=r.getOptions();if(!(i in t))t[i]=r;else{const a=n.filter(c=>c.startsWith(i)).map(c=>+(c.replace(i,"")||0)),o=Ct(a)+1,s=`${i}${o}`;t[s]=r,r.getOptions().key=s}}return t}function q1(t,e){const[n]=Kt("scale",e),{relations:r}=t,[i]=KH(r),a=n(t);return i(a)}function ZH(t){const e=t.flatMap(n=>Array.from(n.values())).flatMap(n=>n.channels.map(r=>r.scale));K1(e,"x"),K1(e,"y")}function QH(t){const{channels:e=[],type:n,scale:r={}}=t,i=["shape","color","opacity","size"];return e.length!==0?e:n==="axisX"?["x"]:n==="axisY"?["y"]:n==="legends"?Object.keys(r).filter(a=>i.includes(a)):[]}function K1(t,e){const n=t.filter(({name:a,facet:o=!0})=>o&&a===e),r=n.flatMap(a=>a.domain),i=n.every(pA)?Mr(r):n.every(vA)?Array.from(new Set(r)):null;if(i!==null)for(const a of n)a.domain=i}function JH(t,e,n){const{ratio:r}=n;return r==null?e:pA({type:t})?tV(e,r,t):vA({type:t})?eV(e,r):e}function tV(t,e,n){const r=t.map(Number),i=new Yt({domain:r,range:[r[0],r[0]+(r[r.length-1]-r[0])*e]});return n==="time"?t.map(a=>new Date(i.map(a))):t.map(a=>i.map(a))}function eV(t,e){const n=Math.round(t.length*e);return t.slice(0,n)}function pA(t){const{type:e}=t;return typeof e!="string"?!1:["linear","log","pow","time"].includes(e)}function vA(t){const{type:e}=t;return typeof e!="string"?!1:["band","point","ordinal"].includes(e)}function nV(t,e,n){const{type:r,domain:i,range:a,quantitative:o,ordinal:s}=n;return r!==void 0?r:gV(e)?"identity":typeof a=="string"?"linear":(i||a||[]).length>2?wd(t,s):i!==void 0?tb([i])?wd(t,s):eb(e)?"time":Q1(t,a,o):tb(e)?wd(t,s):eb(e)?"time":Q1(t,a,o)}function rV(t,e,n,r){const{domain:i}=r;if(i!==void 0)return i;switch(t){case"linear":case"time":case"log":case"pow":case"sqrt":case"quantize":case"threshold":return J1(dV(n,r),r);case"band":case"ordinal":case"point":return gA(n);case"quantile":return hV(n);case"sequential":return J1(pV(n),r);default:return[]}}function iV(t,e,n,r,i,a,o){const{range:s}=r;if(typeof s=="string")return oV(s);if(s!==void 0)return s;const{rangeMin:c,rangeMax:l}=r;switch(t){case"linear":case"time":case"log":case"pow":case"sqrt":{const u=Z1(n,r,i,a,o),[f,d]=vV(e,u);return[c||f,l||d]}case"band":case"point":return[c||(e==="size"?5:0),l||(e==="size"?10:1)];case"ordinal":return Z1(n,r,i,a,o);case"sequential":return;case"constant":return[n[0][0]];default:return[]}}function aV(t,e,n,r,i){switch(t){case"linear":case"time":case"log":case"pow":case"sqrt":return lV(i,r);case"band":case"point":return uV(t,e,i,r);case"sequential":return cV(r);default:return r}}function Z1(t,e,n,r,i){const[a]=Kt("palette",i),{category10:o,category20:s}=r,c=G5(t.flat()).length<=o.length?o:s,{palette:l=c,offset:u}=e;if(Array.isArray(l))return l;try{return a({type:l})}catch{const d=sV(l,n,u);if(d)return d;throw new Error(`Unknown Component: ${l} `)}}function oV(t){return t.split("-")}function sV(t,e,n=r=>r){if(!t)return null;const r=ii(t),i=Uh[`scheme${r}`],a=Uh[`interpolate${r}`];if(!i&&!a)return null;if(i){if(!i.some(Array.isArray))return i;const o=i[e.length];if(o)return o}return e.map((o,s)=>a(n(s/e.length)))}function cV(t){const{palette:e="ylGnBu",offset:n}=t,r=ii(e),i=Uh[`interpolate${r}`];if(!i)throw new Error(`Unknown palette: ${r}`);return{interpolator:n?a=>i(n(a)):i}}function lV(t,e){const{interpolate:n=Fs,nice:r=!1,tickCount:i=5}=e;return Object.assign(Object.assign({},e),{interpolate:n,nice:r,tickCount:i})}function uV(t,e,n,r){if(r.padding!==void 0||r.paddingInner!==void 0||r.paddingOuter!==void 0)return Object.assign(Object.assign({},r),{unknown:NaN});const i=fV(t,e,n),{paddingInner:a=i,paddingOuter:o=i}=r;return Object.assign(Object.assign({},r),{paddingInner:a,paddingOuter:o,padding:i,unknown:NaN})}function fV(t,e,n){return e==="enterDelay"||e==="enterDuration"||e==="size"?0:t==="band"?IP(n)?0:.1:t==="point"?.5:0}function wd(t,e){return e||(yV(t)?"point":"ordinal")}function Q1(t,e,n){return n||(t!=="color"||e?"linear":"sequential")}function J1(t,e){if(t.length===0)return t;const{domainMin:n,domainMax:r}=e,[i,a]=t;return[n??i,r??a]}function dV(t,e){const{zero:n=!1}=e;let r=1/0,i=-1/0;for(const a of t)for(const o of a)zt(o)&&(r=Math.min(r,+o),i=Math.max(i,+o));return r===1/0?[]:n?[Math.min(0,r),i]:[r,i]}function gA(t){return Array.from(new Set(t.flat()))}function hV(t){return gA(t).sort()}function pV(t){let e=1/0,n=-1/0;for(const r of t)for(const i of r)zt(i)&&(e=Math.min(e,+i),n=Math.max(n,+i));return e===1/0?[]:[e<0?-n:e,n]}function vV(t,e){return t==="enterDelay"?[0,1e3]:t=="enterDuration"?[300,1e3]:t.startsWith("y")||t.startsWith("position")?[1,0]:t==="color"?[z5(e),yx(e)]:t==="opacity"?[0,1]:t==="size"?[1,10]:[0,1]}function tb(t){return yv(t,e=>{const n=typeof e;return n==="string"||n==="boolean"})}function eb(t){return yv(t,e=>e instanceof Date)}function gV(t){return yv(t,is)}function yv(t,e){for(const n of t)if(n.some(e))return!0;return!1}function yV(t){return t.startsWith("x")||t.startsWith("y")||t.startsWith("position")||t.startsWith("size")}function mV(t){return t.startsWith("x")||t.startsWith("y")||t.startsWith("position")||t==="enterDelay"||t==="enterDuration"||t==="updateDelay"||t==="updateDuration"||t==="exitDelay"||t==="exitDuration"}function bV(t){if(!t||!t.type)return!1;if(typeof t.type=="function")return!0;const{type:e,domain:n,range:r,interpolator:i}=t,a=n&&n.length>0,o=r&&r.length>0;return!!(["linear","sqrt","log","time","pow","threshold","quantize","quantile","ordinal","band","point"].includes(e)&&a&&o||["sequential"].includes(e)&&a&&(o||i)||["constant","identity"].includes(e)&&o)}const xV={linear:"linear",identity:"identity",log:"log",pow:"pow",sqrt:"sqrt",sequential:"sequential"},wV={threshold:"threshold",quantize:"quantize",quantile:"quantile"},OV={ordinal:"ordinal",band:"band",point:"point"},SV={constant:"constant"};var vi=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);iu!==null),s=[],c=RV(e,t,n);if(s.push(...c),i){const{props:u}=a("title"),{defaultPosition:f,defaultOrientation:d,defaultOrder:h,defaultSize:p,defaultCrossPadding:v}=u,g=typeof i=="string"?{title:i}:i;s.push(Object.assign({type:"title",position:f,orientation:d,order:h,crossPadding:v[0],defaultSize:p},g))}return kV(o,r).forEach(([u,f])=>{const{props:d}=a(u),{defaultPosition:h,defaultPlane:p="xy",defaultOrientation:v,defaultSize:g,defaultOrder:y,defaultLength:m,defaultPadding:b=[0,0],defaultCrossPadding:x=[0,0]}=d,w=X({},...f),{guide:O,field:S}=w,_=Array.isArray(O)?O:[O];for(const M of _){const[E,P]=LV(u,h,v,M,f,o,r);if(!E&&!P)continue;const T=E==="left"||E==="right",A=T?b[1]:b[0],k=T?x[1]:x[0],{size:C,order:L=y,length:I=m,padding:R=A,crossPadding:j=k}=M;s.push(Object.assign(Object.assign({title:S},M),{defaultSize:g,length:I,position:E,plane:p,orientation:P,padding:R,order:L,crossPadding:j,size:C,type:u,scales:f}))}}),s}function nb(t,e,n,r,i){const[a]=Kt("component",r),{scaleInstances:o,scale:s,bbox:c}=t,l=vi(t,["scaleInstances","scale","bbox"]),u={bbox:c,library:r};return a(l)({coordinate:e,library:r,markState:i,scales:o,theme:n,value:u,scale:s})}function MV(t){return t.map(e=>{const n=X(e,e.style);return delete n.style,n})}function yA(t,e){const n=["left","right","bottom","top"];return pp(t,({type:a,position:o,group:s})=>n.includes(o)?s===void 0?a.startsWith("legend")?`legend-${o}`:Symbol("independent"):s==="independent"?Symbol("independent"):s:Symbol("independent")).flatMap(([,a])=>{if(a.length===1)return a[0];if(e!==void 0){const u=a.filter(v=>v.length!==void 0).map(v=>v.length),f=Cn(u);if(f>e)return a.forEach(v=>v.group=Symbol("independent")),a;const d=e-f,h=a.length-u.length,p=d/h;a.forEach(v=>{v.length===void 0&&(v.length=p)})}const o=Ct(a,u=>u.size),s=Ct(a,u=>u.order),c=Ct(a,u=>u.crossPadding),l=a[0].position;return{type:"group",size:o,order:s,position:l,children:a,crossPadding:c}})}function EV(t,e){const n=["shape","size","color","opacity"],r=(d,h)=>d==="constant"&&h==="size",i=t.filter(({type:d,name:h})=>typeof d=="string"&&n.includes(h)&&!r(d,h)),a=i.filter(({type:d})=>d==="constant"),o=i.filter(({type:d})=>d!=="constant"),c=pp(o,d=>d.field?d.field:Symbol("independent")).map(([d,h])=>[d,[...h,...a]]).filter(([,d])=>d.some(h=>h.type!=="constant")),l=new Map(c);if(l.size===0)return[];const u=d=>d.sort(([h],[p])=>h.localeCompare(p));return Array.from(l).map(([,d])=>{const p=Y5(d).sort((v,g)=>g.length-v.length).map(v=>({combination:v,option:v.map(g=>[g.name,PV(g)])}));for(const{option:v,combination:g}of p)if(!v.every(y=>y[1]==="constant")&&v.every(y=>y[1]==="discrete"||y[1]==="constant"))return["legendCategory",g];for(const[v,g]of eG)for(const{option:y,combination:m}of p)if(g.some(b=>pl(u(b),u(y))))return[v,m];return null}).filter(zt)}function PV(t){const{type:e}=t;return typeof e!="string"?null:e in xV?"continuous":e in OV?"discrete":e in wV?"distribution":e in SV?"constant":null}function AV(t,e){return t.map(n=>{const{name:r}=n;if(_W(e)||IP(e)||Ma(e)&&(Pi(e)||Ko(e)))return null;if(r.startsWith("x"))return Pi(e)?["axisArc",[n]]:Ko(e)?["axisLinear",[n]]:[Ma(e)?"axisY":"axisX",[n]];if(r.startsWith("y"))return Pi(e)?["axisLinear",[n]]:Ko(e)?["axisArc",[n]]:[Ma(e)?"axisX":"axisY",[n]];if(r.startsWith("z"))return["axisZ",[n]];if(r.startsWith("position")){if(PW(e))return["axisRadar",[n]];if(!Pi(e))return["axisY",[n]]}return null}).filter(zt)}function kV(t,e){const n=t.filter(r=>bV(r));return[...EV(n),...AV(n,e)]}function qh(t){const e=Xn(t,"polar");if(e.length){const r=e[e.length-1],{startAngle:i,endAngle:a}=Mb(r);return[i,a]}const n=Xn(t,"radial");if(n.length){const r=n[n.length-1],{startAngle:i,endAngle:a}=Pb(r);return[i,a]}return[-Math.PI/2,Math.PI/2*3]}function TV(t){const e=/position(\d*)/g.exec(t);return e?+e[1]:null}function CV(t,e,n,r,i){const{name:a}=n[0];if(t==="axisRadar"){const o=r.filter(f=>f.name.startsWith("position")),s=TV(a);if(a===o.slice(-1)[0].name||s===null)return[null,null];const[c,l]=qh(i);return["center",(l-c)/(o.length-1)*s+c]}if(t==="axisY"&&MW(i))return Ma(i)?["center","horizontal"]:["center","vertical"];if(t==="axisLinear"){const[o]=qh(i);return["center",o]}return t==="axisArc"?e[0]==="inner"?["inner",null]:["outer",null]:Pi(i)?["center",null]:Ko(i)?["center",null]:t==="axisX"&&EW(i)||t==="axisX"&&AW(i)?["top",null]:e}function LV(t,e,n,r,i,a,o){const[s]=qh(o),c=[r.position||e,s??n];return typeof t=="string"&&t.startsWith("axis")?CV(t,c,i,a,o):typeof t=="string"&&t.startsWith("legend")&&Pi(o)&&r.position==="center"?["center","vertical"]:c}function NV(t,e,n=[]){return t==="x"?Ma(n)?`${e}Y`:`${e}X`:t==="y"?Ma(n)?`${e}X`:`${e}Y`:null}function RV(t,e,n){const[,r]=Kt("component",n),{coordinates:i}=t;function a(o,s,c,l){const u=NV(s,o,i);if(!l||!u)return;const{props:f}=r(u),{defaultPosition:d,defaultSize:h,defaultOrder:p,defaultCrossPadding:[v]}=f;return Object.assign(Object.assign({position:d,defaultSize:h,order:p,type:u,crossPadding:v},l),{scales:[c]})}return e.filter(o=>o.slider||o.scrollbar).flatMap(o=>{const{slider:s,scrollbar:c,name:l}=o;return[a("slider",l,o,s),a("scrollbar",l,o,c)]}).filter(o=>!!o)}function mA(t,e,n,r,i,a){const{type:o}=t;if(!["left","right","bottom","top"].includes(r)||typeof o!="string")return;const c=o;return(c.startsWith("axis")?BV:c.startsWith("group")?IV:c.startsWith("legendContinuous")?FV:c==="legendCategory"?zV:c.startsWith("slider")?$V:c==="title"?DV:c.startsWith("scrollbar")?jV:()=>{})(t,e,n,r,i,a)}function IV(t,e,n,r,i,a){const{children:o}=t,s=Ct(o,l=>l.crossPadding);o.forEach(l=>l.crossPadding=s),o.forEach(l=>mA(l,e,n,r,i,a));const c=Ct(o,l=>l.size);t.size=c,o.forEach(l=>l.size=c)}function jV(t,e,n,r,i,a){const{trackSize:o=6}=X({},i.scrollbar,t);t.size=o}function DV(t,e,n,r,i,a){const o=X({},i.title,t),{title:s,subtitle:c,spacing:l=0}=o,u=vi(o,["title","subtitle","spacing"]);if(s){const f=Q(u,"title"),d=fu(s,f);t.size=d.height}if(c){const f=Q(u,"subtitle"),d=fu(c,f);t.size+=l+d.height}}function $V(t,e,n,r,i,a){const o=()=>{const{slider:u}=i;return X({},u,t)},{trackSize:s,handleIconSize:c}=o(),l=Math.max(s,c*2.4);t.size=l}function BV(t,e,n,r,i,a){t.transform=t.transform||[{type:"hide"}];const o=r==="left"||r==="right",s=bA(t,r,i),{tickLength:c=0,labelSpacing:l=0,titleSpacing:u=0,labelAutoRotate:f}=s,d=vi(s,["tickLength","labelSpacing","titleSpacing","labelAutoRotate"]),h=ff(t,a),p=df(d,h),v=c+l;if(p&&p.length){const y=Ct(p,b=>b.width),m=Ct(p,b=>b.height);if(o)t.size=y+v;else{const{tickFilter:b,labelTransform:x}=t;WV(h,p,e,n,b)&&!x&&f!==!1&&f!==null?(t.labelTransform="rotate(90)",t.size=y+v):t.size=m+v}}else t.size=c;const g=hf(d);g&&(o?t.size+=u+g.width:t.size+=u+g.height)}function FV(t,e,n,r,i,a){const s=(()=>{const{legendContinuous:x}=i;return X({},x,t)})(),{labelSpacing:c=0,titleSpacing:l=0}=s,u=vi(s,["labelSpacing","titleSpacing"]),f=r==="left"||r==="right",d=Q(u,"ribbon"),{size:h}=d,p=Q(u,"handleIcon"),{size:v}=p,g=Math.max(h,v*2.4);t.size=g;const y=ff(t,a),m=df(u,y);if(m){const x=f?"width":"height",w=Ct(m,O=>O[x]);t.size+=w+c}const b=hf(u);b&&(f?t.size=Math.max(t.size,b.width):t.size+=l+b.height)}function zV(t,e,n,r,i,a){const s=(()=>{const{legendCategory:k}=i,{title:C}=t,[L,I]=Array.isArray(C)?[C,void 0]:[void 0,C];return X({title:L},k,Object.assign(Object.assign({},t),{title:I}))})(),{itemSpacing:c,itemMarkerSize:l,titleSpacing:u,rowPadding:f,colPadding:d,maxCols:h=1/0,maxRows:p=1/0}=s,v=vi(s,["itemSpacing","itemMarkerSize","titleSpacing","rowPadding","colPadding","maxCols","maxRows"]),{cols:g,length:y}=t,m=k=>Math.min(k,p),b=k=>Math.min(k,h),x=r==="left"||r==="right",w=y===void 0?e+(x?0:n[0]+n[1]):y,O=hf(v),S=ff(t,a),_=df(v,S,"itemLabel"),M=Math.max(_[0].height,l)+f,E=(k,C=0)=>l+k+c[0]+C;x?(()=>{let k=-1/0,C=0,L=1,I=0,R=-1/0,j=-1/0;const D=O?O.height:0,$=w-D;for(const{width:B}of _){const F=E(B,d);k=Math.max(k,F),C+M>$?(L++,R=Math.max(R,I),j=Math.max(j,C),I=1,C=M):(C+=M,I++)}L<=1&&(R=I,j=C),t.size=k*b(L),t.length=j+D,X(t,{cols:b(L),gridRow:R})})():typeof g=="number"?(()=>{const k=Math.ceil(_.length/g),C=Ct(_,L=>E(L.width))*g;t.size=M*m(k)-f,t.length=Math.min(C,w)})():(()=>{let k=1,C=0,L=-1/0;for(const{width:I}of _){const R=E(I,d);C+R>w?(L=Math.max(L,C),C=R,k++):C+=R}k===1&&(L=C),t.size=M*m(k)-f,t.length=L})(),O&&(x?t.size=Math.max(t.size,O.width):t.size+=u+O.height)}function ff(t,e){const[n]=Kt("scale",e),{scales:r,tickCount:i,tickMethod:a}=t,o=r.find(s=>s.type!=="constant"&&s.type!=="identity");return i!==void 0&&(o.tickCount=i),a!==void 0&&(o.tickMethod=a),n(o)}function df(t,e,n="label"){const{labelFormatter:r,tickFilter:i,label:a=!0}=t,o=vi(t,["labelFormatter","tickFilter","label"]);if(!a)return null;const s=GV(e,r,i),c=Q(o,n),l=s.map((d,h)=>Object.fromEntries(Object.entries(c).map(([p,v])=>[p,typeof v=="function"?v(d,h):v]))),u=s.map((d,h)=>{const p=l[h];return fu(d,p)});if(!l.some(d=>d.transform)){const d=s.map((h,p)=>p);t.indexBBox=new Map(d.map(h=>[h,[s[h],u[h]]]))}return u}function hf(t){const e=l=>l===!1||l===null,{title:n}=t,r=vi(t,["title"]);if(e(n)||n===void 0)return null;const i=Q(r,"title"),{direction:a,transform:o}=i,s=Array.isArray(n)?n.join(","):n;return typeof s!="string"?null:fu(s,Object.assign(Object.assign({},i),{transform:o||(a==="vertical"?"rotate(-90)":"")}))}function bA(t,e,n){const{title:r}=t,[i,a]=Array.isArray(r)?[r,void 0]:[void 0,r],{axis:o,[`axis${bp(e)}`]:s}=n;return X({title:i},o,s,Object.assign(Object.assign({},t),{title:a}))}function xA(t,e){const n=t.getTicks?t.getTicks():t.getOptions().domain;return e?n.filter(e):n}function GV(t,e,n){const i=xA(t,n).map(o=>typeof o=="number"?jl(o):o),a=e?typeof e=="string"?fi(e):e:t.getFormatter?t.getFormatter():o=>`${o}`;return i.map(a)}function YV(t,e){return t.getBandWidth?t.getBandWidth(e)/2:0}function WV(t,e,n,r,i){if(Cn(e,h=>h.width)>n)return!0;const o=t.clone();o.update({range:[0,n]});const s=xA(t,i),c=s.map(h=>o.map(h)+YV(o,h)),l=s.map((h,p)=>p),u=-r[0],f=n+r[1],d=(h,p)=>{const{width:v}=p;return[h-v/2,h+v/2]};for(let h=0;hf)return!0;const y=c[h+1];if(y){const[m]=d(y,e[h+1]);if(g>m)return!0}}return!1}function fu(t,e){const n=HV(t),r=vi(e,["filter"]);return n.attr(Object.assign(Object.assign({},r),{visibility:"none"})),n.getBBox()}function HV(t){return t instanceof ze?t:new ei({style:{text:`${t}`}})}function VV(t){const e=t.find(({type:n})=>n==="axisZ");if(e){const n=t.find(({type:i})=>i==="axisX");n.plane="xy";const r=t.find(({type:i})=>i==="axisY");r.plane="xy",e.plane="yz",e.origin=[n.bbox.x,n.bbox.y,0],e.eulerAngles=[0,-90,0],e.bbox.x=n.bbox.x,e.bbox.y=n.bbox.y,t.push(Object.assign(Object.assign({},n),{plane:"xz",showLabel:!1,showTitle:!1,origin:[n.bbox.x,n.bbox.y,0],eulerAngles:[-90,0,0]})),t.push(Object.assign(Object.assign({},r),{plane:"yz",showLabel:!1,showTitle:!1,origin:[r.bbox.x+r.bbox.width,r.bbox.y,0],eulerAngles:[0,-90,0]})),t.push(Object.assign(Object.assign({},e),{plane:"xz",actualPosition:"left",showLabel:!1,showTitle:!1,eulerAngles:[90,-90,0]}))}}function XV(t,e,n,r){var i,a;const{width:o,height:s,depth:c,x:l=0,y:u=0,z:f=0,inset:d=(i=n.inset)!==null&&i!==void 0?i:0,insetLeft:h=d,insetTop:p=d,insetBottom:v=d,insetRight:g=d,margin:y=(a=n.margin)!==null&&a!==void 0?a:0,marginLeft:m=y,marginBottom:b=y,marginTop:x=y,marginRight:w=y,padding:O=n.padding,paddingBottom:S=O,paddingLeft:_=O,paddingRight:M=O,paddingTop:E=O}=qV(t,e,n,r),P=1/4,T=(et,it,ct,ot,lt)=>{const{marks:xt}=e;if(xt.length===0)return[ot,lt];if(et-ot-lt-et*P>0)return[ot,lt];const ue=et*(1-P);return[it==="auto"?ue*ot/(ot+lt):ot,ct==="auto"?ue*lt/(ot+lt):lt]},A=et=>et==="auto"?20:et??20,k=A(E),C=A(S),L=rb(t,s-k-C,[k+x,C+b],["left","right"],e,n,r),{paddingLeft:I,paddingRight:R}=L,j=o-m-w,[D,$]=T(j,_,M,I,R),B=j-D-$,F=rb(t,B,[D+m,$+w],["bottom","top"],e,n,r),{paddingTop:Y,paddingBottom:U}=F,K=s-b-x,[V,W]=T(K,S,E,U,Y),J=K-V-W;return{width:o,height:s,depth:c,insetLeft:h,insetTop:p,insetBottom:v,insetRight:g,innerWidth:B,innerHeight:J,paddingLeft:D,paddingRight:$,paddingTop:W,paddingBottom:V,marginLeft:m,marginBottom:b,marginTop:x,marginRight:w,x:l,y:u,z:f}}function UV(t){const{height:e,width:n,padding:r=0,paddingLeft:i=r,paddingRight:a=r,paddingTop:o=r,paddingBottom:s=r,margin:c=16,marginLeft:l=c,marginRight:u=c,marginTop:f=c,marginBottom:d=c,inset:h=0,insetLeft:p=h,insetRight:v=h,insetTop:g=h,insetBottom:y=h}=t,m=w=>w==="auto"?20:w,b=n-m(i)-m(a)-l-u-p-v,x=e-m(o)-m(s)-f-d-g-y;return{width:b,height:x}}function qV(t,e,n,r){const{coordinates:i}=e;if(!Pi(i)&&!Ko(i))return e;const a=t.filter(y=>typeof y.type=="string"&&y.type.startsWith("axis"));if(a.length===0)return e;const o=a.map(y=>{const m=y.type==="axisArc"?"arc":"linear";return bA(y,m,n)}),s=Ct(o,y=>{var m;return(m=y.labelSpacing)!==null&&m!==void 0?m:0}),c=a.flatMap((y,m)=>{const b=o[m],x=ff(y,r);return df(b,x)}).filter(zt),l=Ct(c,y=>y.height)+s,u=a.flatMap((y,m)=>{const b=o[m];return hf(b)}).filter(y=>y!==null),f=u.length===0?0:Ct(u,y=>y.height),{inset:d=l,insetLeft:h=d,insetBottom:p=d,insetTop:v=d+f,insetRight:g=d}=e;return Object.assign(Object.assign({},e),{insetLeft:h,insetBottom:p,insetTop:v,insetRight:g})}function rb(t,e,n,r,i,a,o){const s=te(t,p=>p.position),{padding:c=a.padding,paddingLeft:l=c,paddingRight:u=c,paddingBottom:f=c,paddingTop:d=c}=i,h={paddingBottom:f,paddingLeft:l,paddingTop:d,paddingRight:u};for(const p of r){const v=`padding${bp(ZS(p))}`,g=s.get(p)||[],y=h[v],m=M=>{M.size===void 0&&(M.size=M.defaultSize)},b=M=>{M.type==="group"?(M.children.forEach(m),M.size=Ct(M.children,E=>E.size)):M.size=M.defaultSize},x=M=>{M.size||(y!=="auto"?b(M):(mA(M,e,n,p,a,o),m(M)))},w=M=>{M.type.startsWith("axis")&&M.labelAutoHide===void 0&&(M.labelAutoHide=!0)},O=p==="bottom"||p==="top",S=bn(g,M=>M.order),_=g.filter(M=>M.type.startsWith("axis")&&M.order==S);if(_.length&&(_[0].crossPadding=0),typeof y=="number")g.forEach(m),g.forEach(w);else if(g.length===0)h[v]=0;else{const M=O?e+n[0]+n[1]:e,E=yA(g,M);E.forEach(x);const P=E.reduce((T,{size:A,crossPadding:k=12})=>T+A+k,0);h[v]=P}}return h}function KV(t,e,n){const r=te(t,O=>`${O.plane||"xy"}-${O.position}`),{paddingLeft:i,paddingRight:a,paddingTop:o,paddingBottom:s,marginLeft:c,marginTop:l,marginBottom:u,marginRight:f,innerHeight:d,innerWidth:h,insetBottom:p,insetLeft:v,insetRight:g,insetTop:y,height:m,width:b,depth:x}=n,w={xy:Od({width:b,height:m,paddingLeft:i,paddingRight:a,paddingTop:o,paddingBottom:s,marginLeft:c,marginTop:l,marginBottom:u,marginRight:f,innerHeight:d,innerWidth:h,insetBottom:p,insetLeft:v,insetRight:g,insetTop:y}),yz:Od({width:x,height:m,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0,marginLeft:0,marginTop:0,marginBottom:0,marginRight:0,innerWidth:x,innerHeight:m,insetBottom:0,insetLeft:0,insetRight:0,insetTop:0}),xz:Od({width:b,height:x,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0,marginLeft:0,marginTop:0,marginBottom:0,marginRight:0,innerWidth:b,innerHeight:x,insetBottom:0,insetLeft:0,insetRight:0,insetTop:0})};for(const[O,S]of r.entries()){const[_,M]=O.split("-"),E=w[_][M],[P,T]=mx(S,A=>typeof A.type!="string"?!1:!!(M==="center"||A.type.startsWith("axis")&&["inner","outer"].includes(M)));P.length&&ZV(P,e,E,M),T.length&&oX(S,e,E)}}function Od({width:t,height:e,paddingLeft:n,paddingRight:r,paddingTop:i,paddingBottom:a,marginLeft:o,marginTop:s,marginBottom:c,marginRight:l,innerHeight:u,innerWidth:f,insetBottom:d,insetLeft:h,insetRight:p,insetTop:v}){const g=n+o,y=i+s,m=r+l,b=a+c,x=t-o-l,w=[g+h,y+v,f-h-p,u-v-d,"center",null,null];return{top:[g,0,f,y,"vertical",!0,oe,o,x],right:[t-m,y,m,u,"horizontal",!1,oe],bottom:[g,e-b,f,b,"vertical",!1,oe,o,x],left:[0,y,g,u,"horizontal",!0,oe],"top-left":[g,0,f,y,"vertical",!0,oe],"top-right":[g,0,f,y,"vertical",!0,oe],"bottom-left":[g,e-b,f,b,"vertical",!1,oe],"bottom-right":[g,e-b,f,b,"vertical",!1,oe],center:w,inner:w,outer:w}}function ZV(t,e,n,r){const[i,a]=mx(t,o=>!!(typeof o.type=="string"&&o.type.startsWith("axis")));QV(i,e,n,r),sX(a,e,n)}function QV(t,e,n,r){r==="center"?SL(e)?aX(t,e,n):Ht(e)?eX(t,e,n):Ru(e)&&nX(t,e,n,t[0].orientation):r==="inner"?JV(t,e,n):r==="outer"&&tX(t,e,n)}function JV(t,e,n){const[r,i,,a]=n,[o,s]=e.getCenter(),[c]=Iu(e),l=a/2,u=c*l,f=o-u,d=s-u;for(let h=0;hu%2===0).map(l=>l+r);for(let l=0;lu%2===1).map(l=>l+i);for(let l=0;ll==null?void 0:l(M.order,E.order));const x=M=>M==="title"||M==="group"||M.startsWith("legend"),w=(M,E,P)=>P===void 0?E:x(M)?P:E,O=(M,E,P)=>P===void 0?E:x(M)?P:E,S=c?h+y:h;for(let M=0,E=S;MM.type==="group");for(const M of _){const{bbox:E,children:P}=M,T=E[m],A=T/P.length,k=P.reduce((j,D)=>{var $;const B=($=D.layout)===null||$===void 0?void 0:$.justifyContent;return B||j},"flex-start"),C=P.map((j,D)=>{const{length:$=A,padding:B=0}=j;return $+(D===P.length-1?0:B)}),L=Cn(C),I=T-L,R=k==="flex-start"?0:k==="center"?I/2:I;for(let j=0,D=E[p]+R;jbX(o)?o:{type:xX(i,o),value:o});return[t,Object.assign(Object.assign({},e),{encode:a})]}function dX(t,e,n){const{encode:r}=e;if(!r)return[t,e];const i=ai(r,(a,o)=>{const{type:s}=a;return s!=="constant"||mV(o)?a:Object.assign(Object.assign({},a),{constant:!0})});return[t,Object.assign(Object.assign({},e),{encode:i})]}function hX(t,e,n){const{encode:r,data:i}=e;if(!r)return[t,e];const{library:a}=n,o=MX(a),s=ai(r,c=>o(i,c));return[t,Object.assign(Object.assign({},e),{encode:s})]}function pX(t,e,n){const{tooltip:r={}}=e;return Lr(r)?[t,e]:Array.isArray(r)?[t,Object.assign(Object.assign({},e),{tooltip:{items:r}})]:is(r)&&k_(r)?[t,Object.assign(Object.assign({},e),{tooltip:r})]:[t,Object.assign(Object.assign({},e),{tooltip:{items:[r]}})]}function vX(t,e,n){const{data:r,encode:i,tooltip:a={}}=e;if(Lr(a))return[t,e];const o=f=>{if(!f)return f;if(typeof f=="string")return t.map(d=>({name:f,value:r[d][f]}));if(is(f)){const{field:d,channel:h,color:p,name:v=d,valueFormatter:g=O=>O}=f,y=typeof g=="string"?fi(g):g,m=h&&i[h],b=m&&i[h].field,x=v||b||h,w=[];for(const O of t){const S=d?r[O][d]:m?i[h].value[O]:null;w[O]={name:x,color:p,value:y(S)}}return w}if(typeof f=="function"){const d=[];for(const h of t){const p=f(r[h],h,r,i);is(p)?d[h]=p:d[h]={value:p}}return d}return f},{title:s,items:c=[]}=a,l=Za(a,["title","items"]),u=Object.assign({title:o(s),items:Array.isArray(c)?c.map(o):[]},l);return[t,Object.assign(Object.assign({},e),{tooltip:u})]}function gX(t,e,n){const{encode:r}=e,i=Za(e,["encode"]);if(!r)return[t,e];const a=Object.entries(r),o=a.filter(([,c])=>{const{value:l}=c;return Array.isArray(l[0])}).flatMap(([c,l])=>{const u=[[c,new Array(t.length).fill(void 0)]],{value:f}=l,d=Za(l,["value"]);for(let h=0;h[h,Object.assign({type:"column",value:p},d)])}),s=Object.fromEntries([...a,...o]);return[t,Object.assign(Object.assign({},i),{encode:s})]}function yX(t,e,n){const{axis:r={},legend:i={},slider:a={},scrollbar:o={}}=e,s=(l,u)=>{if(typeof l=="boolean")return l?{}:null;const f=l[u];return f===void 0||f?f:null},c=typeof r=="object"?Array.from(new Set(["x","y",...Object.keys(r)])):["x","y"];return X(e,{scale:Object.assign(Object.assign({},Object.fromEntries(c.map(l=>{const u=s(o,l);return[l,Object.assign({guide:s(r,l),slider:s(a,l),scrollbar:u},u&&{ratio:u.ratio===void 0?.5:u.ratio})]}))),{color:{guide:s(i,"color")},size:{guide:s(i,"size")},shape:{guide:s(i,"shape")},opacity:{guide:s(i,"opacity")}})}),[t,e]}function mX(t,e,n){const{animate:r}=e;return r||r===void 0?[t,e]:(X(e,{animate:{enter:{type:null},exit:{type:null},update:{type:null}}}),[t,e])}function bX(t){if(typeof t!="object"||t instanceof Date||t===null)return!1;const{type:e}=t;return zt(e)}function xX(t,e){return typeof e=="function"?"transform":typeof e=="string"&&wX(t,e)?"field":"constant"}function wX(t,e){return Array.isArray(t)?t.some(n=>n[e]!==void 0):!1}function OX(t){if(de(t))return{type:"inline",value:t};if(!t)return{type:"inline",value:null};if(Array.isArray(t))return{type:"inline",value:t};const{type:e="inline"}=t,n=Za(t,["type"]);return Object.assign(Object.assign({},n),{type:e})}var OA=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},SX=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);izt(h)),h=>h.map(([p,v])=>Object.assign({name:p},v)),([h])=>{var p;const v=(p=/([^\d]+)\d*$/.exec(h))===null||p===void 0?void 0:p[1],g=u.find(y=>y.name===v);return g!=null&&g.independent?h:v}),d=u.filter(h=>{const{name:p,required:v}=h;if(f.find(([g])=>g===p))return!0;if(v)throw new Error(`Missing encoding for channel: ${p}.`);return!1}).flatMap(h=>{const{name:p,scale:v,scaleKey:g,range:y,quantitative:m,ordinal:b}=h;return f.filter(([w])=>w.startsWith(p)).map(([w,O],S)=>{const _=O.some(I=>I.visual),M=O.some(I=>I.constant),E=s[w]||{},{independent:P=!1,key:T=g||w,type:A=M?"constant":_?"identity":v}=E,k=SX(E,["independent","key","type"]),C=A==="constant",L=C?void 0:y;return{name:w,values:O,scaleKey:P||C?Symbol("independent"):T,scale:Object.assign(Object.assign({type:A,range:L},k),{quantitative:m,ordinal:b})}})});return[a,Object.assign(Object.assign({},e),{index:i,channels:d,tooltip:l})]})}function MX(t){const[e]=Kt("encode",t);return(n,r)=>r===void 0||n===void 0?null:Object.assign(Object.assign({},r),{type:"column",value:e(r)(n),field:PX(r)})}function EX(t,e,n){return OA(this,void 0,void 0,function*(){const{library:r}=n,[i]=Kt("transform",r),{preInference:a=[],postInference:o=[]}=e,{transform:s=[]}=t,c=[lX,wA,uX,fX,dX,hX,gX,mX,yX,pX,...a.map(i),...s.map(i),...o.map(i),vX];let l=[],u=t;for(const f of c)[l,u]=yield f(l,u,n);return[l,u]})}function PX(t){const{type:e,value:n}=t;return e==="field"&&typeof n=="string"?n:null}var kr=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},ni=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{var k;return(k=/mark\.(.*)/.exec(A))===null||k===void 0?void 0:k[1]}).filter(zt)),c=new Set(Object.keys(n).map(A=>{var k;return(k=/component\.(.*)/.exec(A))===null||k===void 0?void 0:k[1]}).filter(zt)),l=A=>{const{type:k}=A;if(typeof k=="function"){const{props:C={}}=k,{composite:L=!0}=C;if(L)return"mark"}return typeof k!="string"?k:s.has(k)||c.has(k)?"mark":k},u=A=>l(A)==="mark",f=A=>l(A)==="standardView",d=A=>{const{type:k}=A;return typeof k!="string"?!1:!!c.has(k)},h=A=>{if(f(A))return[A];const k=l(A);return a({type:k,static:d(A)})(A)},p=[],v=new Map,g=new Map,y=[t],m=[];for(;y.length;){const A=y.shift();if(f(A)){const k=g.get(A),[C,L]=k?MA(k,A,n):yield SA(A,n);v.set(C,A),p.push(C);const I=L.flatMap(h).map(R=>RP(R,n));if(y.push(...I),I.every(f)){const R=yield Promise.all(I.map(j=>_A(j,n)));ZH(R);for(let j=0;jA.key).join(A=>A.append("g").attr("className",Ch).attr("id",k=>k.key).call(ib).each(function(k,C,L){Zh(k,st(L),w,n,r),b.set(k,L)}),A=>A.call(ib).each(function(k,C,L){Zh(k,st(L),w,n,r),x.set(k,L)}),A=>A.each(function(k,C,L){const I=L.nameInteraction.values();for(const R of I)R.destroy()}).remove());const O=(A,k,C)=>Array.from(A.entries()).map(([L,I])=>{const R=C||new Map,j=(B,F=Y=>Y)=>R.set(B,F),D=v.get(L),$=kX(st(I),D,n,r);return{view:L,container:I,options:D,setState:j,update:(B,F)=>kr(this,void 0,void 0,function*(){const U=mp(Array.from(R.values()))(D);return yield $(U,B,()=>{Le(F)&&k(A,F,R)})})}}),S=(A=x,k,C)=>{var L;const I=O(A,S,C);for(const R of I){const{options:j,container:D}=R,$=D.nameInteraction;let B=du(j);k&&(B=B.filter(F=>k.includes(F[0])));for(const F of B){const[Y,U]=F,K=$.get(Y);if(K&&((L=K.destroy)===null||L===void 0||L.call(K)),U){const W=Kh(R.view,Y,U,o)(R,I,r.emitter);$.set(Y,{destroy:W})}}}},_=O(b,S);for(const A of _){const{options:k}=A,C=new Map;A.container.nameInteraction=C;for(const L of du(k)){const[I,R]=L;if(R){const D=Kh(A.view,I,R,o)(A,_,r.emitter);C.set(I,{destroy:D})}}}S();const{width:M,height:E}=t,P=[];for(const A of m){const k=new Promise(C=>kr(this,void 0,void 0,function*(){for(const L of A){const I=Object.assign({width:M,height:E},L);yield mv(I,e,n,r)}C()}));P.push(k)}r.views=p,(i=r.animations)===null||i===void 0||i.forEach(A=>A==null?void 0:A.cancel()),r.animations=w,r.emitter.emit(Lt.AFTER_PAINT);const T=w.filter(zt).map(WX).map(A=>A.finished);return Promise.all([...T,...P])})}function ib(t){t.style("transform",e=>`translate(${e.layout.x}, ${e.layout.y})`)}function AX(t){const[,e]=Kt("interaction",t);return n=>{const[r,i]=n;try{return[r,e(r)]}catch{return[r,i.type]}}}function kX(t,e,n,r){const i=AX(n),a=c=>c[1]&&c[1].props&&c[1].props.reapplyWhenUpdate,s=du(e).map(i).filter(a).map(c=>c[0]);return(c,l,u)=>kr(this,void 0,void 0,function*(){const f=[],[d,h]=yield SA(c,n);Zh(d,t,f,n,r);for(const p of s.filter(v=>v!==l))TX(p,t,c,d,n,r);for(const p of h)mv(p,t,n,r);return u(),{options:c,view:d}})}function TX(t,e,n,r,i,a){var o;const[s]=Kt("interaction",i),l=e.node().nameInteraction,u=du(n).find(([v])=>v===t),f=l.get(t);if(!f||((o=f.destroy)===null||o===void 0||o.call(f),!u[1]))return;const d=Kh(r,t,u[1],s),h={options:n,view:r,container:e.node(),update:v=>Promise.resolve(v)},p=d(h,[],a.emitter);l.set(t,{destroy:p})}function SA(t,e){return kr(this,void 0,void 0,function*(){const n=yield LX(t,e),r=CX(n);t.interaction=r.interaction,t.coordinate=r.coordinate,t.marks=[...r.marks,...r.components];const i=RP(r,e),a=yield _A(i,e);return MA(a,i,e)})}function CX(t){const{coordinate:e={},interaction:n={},style:r={},marks:i}=t,a=ni(t,["coordinate","interaction","style","marks"]),o=i.map(d=>d.coordinate||{}),s=i.map(d=>d.interaction||{}),c=i.map(d=>d.viewStyle||{}),l=[...o,e].reduceRight((d,h)=>X(d,h),{}),u=[n,...s].reduce((d,h)=>X(d,h),{}),f=[...c,r].reduce((d,h)=>X(d,h),{});return Object.assign(Object.assign({},a),{marks:i,coordinate:l,interaction:u,style:f})}function LX(t,e){return kr(this,void 0,void 0,function*(){const[n,r]=Kt("mark",e),i=new Set(Object.keys(e).map(d=>{var h;return(h=/component\.(.*)/.exec(d))===null||h===void 0?void 0:h[1]}).filter(zt)),{marks:a}=t,o=[],s=[],c=[...a],{width:l,height:u}=UV(t),f={options:t,width:l,height:u};for(;c.length;){const[d]=c.splice(0,1),h=yield kA(d,e),{type:p=La("G2Mark type is required."),key:v}=h;if(i.has(p))s.push(h);else{const{props:g={}}=r(p),{composite:y=!0}=g;if(!y)o.push(h);else{const{data:m}=h,b=Object.assign(Object.assign({},h),{data:m&&(Array.isArray(m)?m:m.value)}),x=yield n(b,f),w=Array.isArray(x)?x:[x];c.unshift(...w.map((O,S)=>Object.assign(Object.assign({},O),{key:`${v}-${S}`})))}}}return Object.assign(Object.assign({},t),{marks:o,components:s})})}function _A(t,e){return kr(this,void 0,void 0,function*(){const[n]=Kt("theme",e),[,r]=Kt("mark",e),{theme:i,marks:a,coordinates:o=[]}=t,s=n(AA(i)),c=new Map;for(const u of a){const{type:f}=u,{props:d={}}=r(f),h=yield _X(u,d,e);if(h){const[p,v]=h;c.set(p,v)}}const l=te(Array.from(c.values()).flatMap(u=>u.channels),({scaleKey:u})=>u);for(const u of l.values()){const f=u.reduce((b,{scale:x})=>X(b,x),{}),{scaleKey:d}=u[0],{values:h}=u[0],p=Array.from(new Set(h.map(b=>b.field).filter(zt))),v=X({guide:{title:p.length===0?void 0:p},field:p[0]},f),{name:g}=u[0],y=u.flatMap(({values:b})=>b.map(x=>x.value)),m=Object.assign(Object.assign({},XH(g,y,v,o,s,e)),{key:d});u.forEach(b=>b.scale=m)}return c})}function Kh(t,e,n,r){const i=t.theme,a=typeof e=="string"?i[e]||{}:{};return r(X(a,Object.assign({type:e},n)))}function MA(t,e,n){const[r]=Kt("mark",n),[i]=Kt("theme",n),[a]=Kt("labelTransform",n),{key:o,frame:s=!1,theme:c,clip:l,style:u={},labelTransform:f=[]}=e,d=i(AA(c)),h=Array.from(t.values()),p=qH(h,e),v=MV(_V(UX(Array.from(p),h,t),e,n)),g=XV(v,e,d,n),y=SW(g,e,n),m=s?X({mainLineWidth:1,mainStroke:"#000"},u):u;KV(yA(v),y,g),VV(v);const b={};for(const O of v){const{scales:S=[]}=O,_=[];for(const M of S){const{name:E}=M,P=q1(M,n);_.push(P),E==="y"&&P.update(Object.assign(Object.assign({},P.getOptions()),{xScale:b.x})),U1(b,{[E]:P})}O.scaleInstances=_}const x=[];for(const[O,S]of t.entries()){const{children:_,dataDomain:M,modifier:E,key:P}=O,{index:T,channels:A,tooltip:k}=S,C=Object.fromEntries(A.map(({name:W,scale:J})=>[W,J])),L=ai(C,W=>q1(W,n));U1(b,L);const I=UH(A,L),R=r(O),[j,D,$]=IX(R(T,L,I,y)),B=M||j.length,F=E?E(D,B,g):[],Y=W=>{var J,et;return(et=(J=k.title)===null||J===void 0?void 0:J[W])===null||et===void 0?void 0:et.value},U=W=>k.items.map(J=>J[W]),K=j.map((W,J)=>{const et=Object.assign({points:D[J],transform:F[J],index:W,markKey:P,viewKey:o},k&&{title:Y(W),items:U(W)});for(const[it,ct]of Object.entries(I))et[it]=ct[W],$&&(et[`series${ii(it)}`]=$[J].map(ot=>ct[ot]));return $&&(et.seriesIndex=$[J]),$&&k&&(et.seriesItems=$[J].map(it=>U(it)),et.seriesTitle=$[J].map(it=>Y(it))),et});S.data=K,S.index=j;const V=_==null?void 0:_(K,L,g);x.push(...V||[])}return[{layout:g,theme:d,coordinate:y,markState:t,key:o,clip:l,scale:b,style:m,components:v,labelTransform:mp(f.map(a))},x]}function Zh(t,e,n,r,i){return kr(this,void 0,void 0,function*(){const{components:a,theme:o,layout:s,markState:c,coordinate:l,key:u,style:f,clip:d,scale:h}=t,{x:p,y:v,width:g,height:y}=s,m=ni(s,["x","y","width","height"]),b=["view","plot","main","content"],x=b.map((R,j)=>j),w=["a","margin","padding","inset"],O=b.map(R=>vx(Object.assign({},o.view,f),R)),S=w.map(R=>Q(m,R)),_=R=>R.style("x",j=>A[j].x).style("y",j=>A[j].y).style("width",j=>A[j].width).style("height",j=>A[j].height).each(function(j,D,$){qX(st($),O[j])});let M=0,E=0,P=g,T=y;const A=x.map(R=>{const j=S[R],{left:D=0,top:$=0,bottom:B=0,right:F=0}=j;return M+=D,E+=$,P-=D+F,T-=$+B,{x:M,y:E,width:P,height:T}});e.selectAll(ar(o1)).data(x.filter(R=>zt(O[R])),R=>b[R]).join(R=>R.append("rect").attr("className",o1).style("zIndex",-2).call(_),R=>R.call(_),R=>R.remove());const k=BX(c),C=k?{duration:k[1]}:!1;for(const[,R]of pp(a,j=>`${j.type}-${j.position}`))R.forEach((j,D)=>j.index=D);const L=e.selectAll(ar(a1)).data(a,R=>`${R.type}-${R.position}-${R.index}`).join(R=>R.append("g").style("zIndex",({zIndex:j})=>j||-1).attr("className",a1).append(j=>nb(X({animate:C,scale:h},j),l,o,r,c)),R=>R.transition(function(j,D,$){const{preserve:B=!1}=j;if(B)return;const F=nb(X({animate:C,scale:h},j),l,o,r,c),{attributes:Y}=F,[U]=$.childNodes;return U.update(Y,!1)})).transitions();n.push(...L.flat().filter(zt));const I=e.selectAll(ar(Kl)).data([s],()=>u).join(R=>R.append("rect").style("zIndex",0).style("fill","transparent").attr("className",Kl).call(ab).call(ob,Array.from(c.keys())).call(sb,d),R=>R.call(ob,Array.from(c.keys())).call(j=>k?XX(j,k):ab(j)).call(sb,d)).transitions();n.push(...I.flat());for(const[R,j]of c.entries()){const{data:D}=j,{key:$,class:B,type:F}=R,Y=e.select(`#${$}`),U=GX(R,j,t,r,i),K=YX(R,j,t,r),V=HX(R,j,t,r),W=VX(R,j,t,r),J=FX(e,Y,B,"element"),et=Y.selectAll(ar(xr)).selectFacetAll(J).data(D,it=>it.key,it=>it.groupKey).join(it=>it.append(U).attr("className",xr).attr("markType",F).transition(function(ct,ot,lt){return K(ct,[lt])}),it=>it.call(ct=>{const ot=ct.parent(),lt=$5(xt=>{const[Et,Xt]=xt.getBounds().min;return[Et,Xt]});ct.transition(function(xt,Et,Xt){zX(Xt,ot,lt);const ue=U(xt,Et),Ke=V(xt,[Xt],[ue]);return Ke!==null||(Xt.nodeName===ue.nodeName&&ue.nodeName!=="g"?xp(Xt,ue):(Xt.parentNode.replaceChild(ue,Xt),ue.className=xr,ue.markType=F,ue.__data__=Xt.__data__)),Ke}).attr("markType",F).attr("className",xr)}),it=>it.each(function(ct,ot,lt){lt.__removed__=!0}).transition(function(ct,ot,lt){return W(ct,[lt])}).remove(),it=>it.append(U).attr("className",xr).attr("markType",F).transition(function(ct,ot,lt){const{__fromElements__:xt}=lt,Et=V(ct,xt,[lt]);return new Il(xt,null,lt.parentNode).transition(Et).remove(),Et}),it=>it.transition(function(ct,ot,lt){const Et=new Il([],lt.__toData__,lt.parentNode).append(U).attr("className",xr).attr("markType",F).nodes();return V(ct,[lt],Et)}).remove()).transitions();n.push(...et.flat())}NX(t,e,n,r,i)})}function NX(t,e,n,r,i){const[a]=Kt("labelTransform",r),{markState:o,labelTransform:s}=t,c=e.select(ar(Th)).node(),l=new Map,u=new Map,f=Array.from(o.entries()).flatMap(([v,g])=>{const{labels:y=[],key:m}=v,b=$X(v,g,t,r,i),x=e.select(`#${m}`).selectAll(ar(xr)).nodes().filter(w=>!w.__removed__);return y.flatMap((w,O)=>{const S=ni(w,["transform"]);return x.flatMap(_=>{const M=RX(S,O,_);return M.forEach(E=>{l.set(E,b),u.set(E,w)}),M})})}),d=st(c).selectAll(ar(Lh)).data(f,v=>v.key).join(v=>v.append(g=>l.get(g)(g)).attr("className",Lh),v=>v.each(function(g,y,m){const x=l.get(g)(g);xp(m,x)}),v=>v.remove()).nodes(),h=te(d,v=>u.get(v.__data__)),{coordinate:p}=t;for(const[v,g]of h){const{transform:y=[]}=v;mp(y.map(a))(g,p)}s&&s(d,p)}function RX(t,e,n){const{seriesIndex:r,seriesKey:i,points:a,key:o,index:s}=n.__data__,c=DX(n);if(!r)return[Object.assign(Object.assign({},t),{key:`${o}-${e}`,bounds:c,index:s,points:a,dependentElement:n})];const l=jX(t),u=r.map((f,d)=>Object.assign(Object.assign({},t),{key:`${i[d]}-${e}`,bounds:[a[d]],index:f,points:a,dependentElement:n}));return l?l(u):u}function IX([t,e,n]){if(n)return[t,e,n];const r=[],i=[];for(let a=0;azt(c)&&zt(l))&&(r.push(o),i.push(s))}return[r,i]}function jX(t){const{selector:e}=t;if(!e)return null;if(typeof e=="function")return e;if(e==="first")return n=>[n[0]];if(e==="last")return n=>[n[n.length-1]];throw new Error(`Unknown selector: ${e}`)}function DX(t){const e=t.cloneNode(),n=t.getAnimations();e.style.visibility="hidden",n.forEach(o=>{const s=o.effect.getKeyframes();e.attr(s[s.length-1])}),t.parentNode.appendChild(e);const r=e.getLocalBounds();e.destroy();const{min:i,max:a}=r;return[i,a]}function $X(t,e,n,r,i){const[a]=Kt("shape",r),{data:o}=t,{data:s,defaultLabelShape:c}=e,l=s.map(h=>h.points),{theme:u,coordinate:f}=n,d=Object.assign(Object.assign({},i),{document:NP(i),theme:u,coordinate:f});return h=>{const{index:p,points:v}=h,g=o[p],{formatter:y=C=>`${C}`,transform:m,style:b,render:x}=h,w=ni(h,["formatter","transform","style","render"]),O=ai(Object.assign(Object.assign({},w),b),C=>EA(C,g,p,o)),{shape:S=c,text:_}=O,M=ni(O,["shape","text"]),E=typeof y=="string"?fi(y):y,P=Object.assign(Object.assign({},M),{text:E(_,g,p,o),datum:g}),T=Object.assign({type:`label.${S}`,render:x},M),A=a(T,d),k=PA(u,"label",S,"label");return A(v,P,k,l)}}function EA(t,e,n,r){return typeof t=="function"?t(e,n,r):typeof t!="string"?t:e[t]!==void 0?e[t]:t}function BX(t){let e=-1/0,n=1/0;for(const[r,i]of t){const{animate:a={}}=r,{data:o}=i,{enter:s={},update:c={},exit:l={}}=a,{type:u,duration:f=300,delay:d=0}=c,{type:h,duration:p=300,delay:v=0}=s,{type:g,duration:y=300,delay:m=0}=l;for(const b of o){const{updateType:x=u,updateDuration:w=f,updateDelay:O=d,enterType:S=h,enterDuration:_=p,enterDelay:M=v,exitDuration:E=y,exitDelay:P=m,exitType:T=g}=b;(x===void 0||x)&&(e=Math.max(e,w+O),n=Math.min(n,O)),(T===void 0||T)&&(e=Math.max(e,E+P),n=Math.min(n,P)),(S===void 0||S)&&(e=Math.max(e,_+M),n=Math.min(n,M))}}return e===-1/0?null:[n,e-n]}function FX(t,e,n,r){return t.node().parentElement.findAll(a=>a.style.facet!==void 0&&a.style.facet===n&&a!==e.node()).flatMap(a=>a.getElementsByClassName(r))}function zX(t,e,n){if(!t.__facet__)return;const r=t.parentNode.parentNode,i=e.parentNode,[a,o]=n(r),[s,c]=n(i),l=`translate(${a-s}, ${o-c})`;B5(t,l),e.append(t)}function GX(t,e,n,r,i){const[a]=Kt("shape",r),{data:o}=t,{defaultShape:s,data:c,shape:l}=e,u=c.map(g=>g.points),{theme:f,coordinate:d}=n,{type:h,style:p={}}=t,v=Object.assign(Object.assign({},i),{document:NP(i),coordinate:d,theme:f});return g=>{const{shape:y=s}=p,{shape:m=y,points:b,seriesIndex:x,index:w}=g,O=ni(g,["shape","points","seriesIndex","index"]),S=Object.assign(Object.assign({},O),{index:w}),_=x?x.map(A=>o[A]):o[w],M=x||w,E=ai(p,A=>EA(A,_,M,o)),P=l[m]?l[m](E,v):a(Object.assign(Object.assign({},E),{type:TA(t,m)}),v),T=PA(f,h,m,s);return P(b,S,T,u)}}function PA(t,e,n,r){if(typeof e!="string")return;const{color:i}=t,a=t[e]||{},o=a[n]||a[r];return Object.assign({color:i},o)}function bv(t,e,n,r,i){var a,o;const[,s]=Kt("shape",i),[c]=Kt("animation",i),{defaultShape:l,shape:u}=n,{theme:f,coordinate:d}=r,p=`default${ii(t)}Animation`,{[p]:v}=((a=u[l])===null||a===void 0?void 0:a.props)||s(TA(e,l)).props,{[t]:g={}}=f,y=((o=e.animate)===null||o===void 0?void 0:o[t])||{},m={coordinate:d};return(b,x,w)=>{const{[`${t}Type`]:O,[`${t}Delay`]:S,[`${t}Duration`]:_,[`${t}Easing`]:M}=b,E=Object.assign({type:O||v},y);if(!E.type)return null;const A=c(E,m)(x,w,X(g,{delay:S,duration:_,easing:M}));return Array.isArray(A)?A:[A]}}function YX(t,e,n,r){return bv("enter",t,e,n,r)}function WX(t){return t.finished.then(()=>{t.cancel()}),t}function HX(t,e,n,r){return bv("update",t,e,n,r)}function VX(t,e,n,r){return bv("exit",t,e,n,r)}function AA(t={}){if(typeof t=="string")return{type:t};const{type:e="light"}=t,n=ni(t,["type"]);return Object.assign(Object.assign({},n),{type:e})}function du(t){const e={event:!0,tooltip:!0,sliderFilter:!0,legendFilter:!0,scrollbarFilter:!0},{interaction:n={}}=t;return Object.entries(X(e,n)).reverse()}function kA(t,e){return kr(this,void 0,void 0,function*(){const n={library:e},{data:r}=t,i=ni(t,["data"]);if(r==null)return t;const[,{data:a}]=yield wA([],{data:r},n);return Object.assign({data:a},i)})}function ab(t){t.style("x",e=>e.paddingLeft+e.marginLeft).style("y",e=>e.paddingTop+e.marginTop).style("width",e=>e.innerWidth).style("height",e=>e.innerHeight)}function XX(t,e){const[n,r]=e;t.transition(function(i,a,o){const{x:s,y:c,width:l,height:u}=o.style,{paddingLeft:f,paddingTop:d,innerWidth:h,innerHeight:p,marginLeft:v,marginTop:g}=i,y=[{x:s,y:c,width:l,height:u},{x:f+v,y:d+g,width:h,height:p}];return o.animate(y,{delay:n,duration:r,fill:"both"})})}function TA(t,e){const{type:n}=t;return typeof e=="string"?`${n}.${e}`:e}function ob(t,e){const n=a=>a.class!==void 0?`${a.class}`:"";t.nodes().length===0||(t.selectAll(ar(i1)).data(e,a=>a.key).join(a=>a.append("g").attr("className",i1).attr("id",o=>o.key).style("facet",n).style("fill","transparent").style("zIndex",o=>{var s;return(s=o.zIndex)!==null&&s!==void 0?s:0}),a=>a.style("facet",n).style("fill","transparent").style("zIndex",o=>{var s;return(s=o.zIndex)!==null&&s!==void 0?s:0}),a=>a.remove()),t.select(ar(Th)).node())||t.append("g").attr("className",Th).style("zIndex",0)}function ar(...t){return t.map(e=>`.${e}`).join("")}function sb(t,e){t.node()&&t.style("clipPath",n=>{if(!e)return null;const{paddingTop:r,paddingLeft:i,marginLeft:a,marginTop:o,innerWidth:s,innerHeight:c}=n;return new Zi({style:{x:i+a,y:r+o,width:s,height:c}})})}function UX(t,e,n){var r;for(const[l]of n.entries())if(l.type==="cell")return t.filter(u=>u.name!=="shape");if(e.length!==1||t.some(l=>l.name==="shape"))return t;const{defaultShape:i}=e[0];if(!["point","line","rect","hollow"].includes(i))return t;const o={point:"point",line:"hyphen",rect:"square",hollow:"hollow"},c={field:((r=t.find(l=>l.name==="color"))===null||r===void 0?void 0:r.field)||null,name:"shape",type:"constant",domain:[],range:[o[i]]};return[...t,c]}function qX(t,e){for(const[n,r]of Object.entries(e))t.style(n,r)}function KX(t){const e=X({},t),n=new Map([[e,null]]),r=new Map([[null,-1]]),i=[e];for(;i.length;){const a=i.shift();if(a.key===void 0){const s=n.get(a),c=r.get(a),l=s===null?"0":`${s.key}-${c}`;a.key=l}const{children:o=[]}=a;if(Array.isArray(o))for(let s=0;s{},r=i=>{throw i}){const{width:i=640,height:a=480,depth:o=0}=t,s=KX(t),{canvas:c=ZX(i,a),emitter:l=new DE,library:u}=e;e.canvas=c,e.emitter=l;const{width:f,height:d}=c.getConfig();(f!==i||d!==a)&&c.resize(i,a),l.emit(Lt.BEFORE_RENDER);const h=st(c.document.documentElement);return c.ready.then(()=>mv(Object.assign(Object.assign({},s),{width:i,height:a,depth:o}),h,u,e)).then(()=>{if(o){const[p,v]=c.document.documentElement.getPosition();c.document.documentElement.setPosition(p,v,-o/2)}c.requestAnimationFrame(()=>{l.emit(Lt.AFTER_RENDER),n==null||n()})}).catch(p=>{r==null||r(p)}),tU(c.getConfig().container)}function cb(t,e={},n=!1){const{canvas:r,emitter:i}=e;r&&(JX(r),n?r.destroy():r.destroyChildren()),i.off()}function JX(t){const e=t.getRoot().querySelectorAll(`.${Ch}`);e==null||e.forEach(n=>{const{nameInteraction:r=new Map}=n;(r==null?void 0:r.size)>0&&Array.from(r==null?void 0:r.values()).forEach(i=>{i==null||i.destroy()})})}function tU(t){return typeof t=="string"?document.getElementById(t):t}const eU={visibility:"visible",opacity:1,fillOpacity:1,strokeOpacity:1};function nU(t,e){var n;return(n=t.style[e])!==null&&n!==void 0?n:eU[e]}function xv(t,e,n,r){t.style[e]=n,r&&t.children.forEach(i=>xv(i,e,n,r))}function wv(t){xv(t,"visibility","hidden",!0)}function Ov(t){xv(t,"visibility","visible",!0)}var Zo=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i!e.__removed__)}function CA(t,e){return Qh(t,e).flatMap(({container:n})=>ri(n))}function Qh(t,e){return e.filter(n=>n!==t&&n.options.parentKey===t.options.key)}function jr(t){return st(t).select(`.${Kl}`).node()}function LA(t){if(t.nodeName!=="rect")return t.getRenderBounds();const{x:e,y:n,width:r,height:i}=t.style;return{min:[e,n],max:[e+r,n+i]}}function Sv(t,e){const{offsetX:n,offsetY:r}=e,i=LA(t),{min:[a,o],max:[s,c]}=i,l=ns,u=rc;return l||u?null:[n-a,r-o]}function Sd(t,e){const{offsetX:n,offsetY:r}=e,[i,a,o,s]=rU(t);return[Math.min(o,Math.max(i,n))-i,Math.min(s,Math.max(a,r))-a]}function rU(t){const e=t.getRenderBounds(),{min:[n,r],max:[i,a]}=e;return[n,r,i,a]}function NA(t){return e=>e.__data__.color}function _v(t){return e=>e.__data__.x}function Xi(t){const e=Array.isArray(t)?t:[t],n=new Map(e.flatMap(r=>Array.from(r.markState.keys()).map(a=>[hu(r.key,a.key),a.data])));return r=>{const{index:i,markKey:a,viewKey:o}=r.__data__;return n.get(hu(o,a))[i]}}function Tr(t,e=(r,i)=>r,n=(r,i,a)=>r.setAttribute(i,a)){const r="__states__",i="__ordinal__",a=u=>{const{[r]:f=[],[i]:d={}}=u,h=f.reduce((p,v)=>Object.assign(Object.assign({},p),t[v]),d);if(Object.keys(h).length!==0){for(const[p,v]of Object.entries(h)){const g=nU(u,p),y=e(v,u);n(u,p,y),p in d||(d[p]=g)}u[i]=d}},o=u=>{u[r]||(u[r]=[])};return{setState:(u,...f)=>{o(u),u[r]=[...f],a(u)},removeState:(u,...f)=>{o(u);for(const d of f){const h=u[r].indexOf(d);h!==-1&&u[r].splice(h,1)}a(u)},hasState:(u,f)=>(o(u),u[r].indexOf(f)!==-1)}}function iU(t){return t===void 0?!0:typeof t!="object"?!1:Object.keys(t).length===0}function hu(t,e){return`${t},${e}`}function Qa(t,e){const r=(Array.isArray(t)?t:[t]).flatMap(a=>a.marks.map(o=>[hu(a.key,o.key),o.state])),i={};for(const a of e){const[o,s]=Array.isArray(a)?a:[a,{}];i[o]=r.reduce((c,l)=>{const[u,f={}]=l,d=iU(f[o])?s:f[o];for(const[h,p]of Object.entries(d)){const v=c[h],g=(y,m,b,x)=>{const w=hu(x.__data__.viewKey,x.__data__.markKey);return u!==w?v==null?void 0:v(y,m,b,x):typeof p!="function"?p:p(y,m,b,x)};c[h]=g}return c},{})}return i}function ic(t,e){const n=new Map(t.map((i,a)=>[i,a])),r=e?t.map(e):t;return(i,a)=>{if(typeof i!="function")return i;const o=n.get(a),s=e?e(a):a;return i(s,o,r,a)}}function RA(t){var{link:e=!1,valueof:n=(u,f)=>u,coordinate:r}=t,i=Zo(t,["link","valueof","coordinate"]);const a="element-link";if(!e)return[()=>{},()=>{}];const o=u=>u.__data__.points,s=(u,f)=>{const[,d,h]=u,[p,,,v]=f;return[d,p,v,h]};return[u=>{var f;if(u.length<=1)return;const d=Er(u,(h,p)=>{const{x:v}=h.__data__,{x:g}=p.__data__;return v-g});for(let h=1;hn(M,v)),{fill:O=v.getAttribute("fill")}=w,S=Zo(w,["fill"]),_=new Xe({className:a,style:Object.assign({d:p.toString(),fill:O,zIndex:-2},S)});(f=v.link)===null||f===void 0||f.remove(),v.parentNode.appendChild(_),v.link=_}},u=>{var f;(f=u.link)===null||f===void 0||f.remove(),u.link=null}]}function IA(t,e,n){const r=i=>{const{transform:a}=t.style;return a?`${a} ${i}`:i};if(Ht(n)){const{points:i}=t.__data__,[a,o]=qt(n)?Gu(i):i,s=n.getCenter(),c=se(a,s),l=se(o,s),u=Nn(c),f=B2(c,l),d=u+f/2,h=e*Math.cos(d),p=e*Math.sin(d);return r(`translate(${h}, ${p})`)}return qt(n)?r(`translate(${e}, 0)`):r(`translate(0, ${-e})`)}function jA(t){var{document:e,background:n,scale:r,coordinate:i,valueof:a}=t,o=Zo(t,["document","background","scale","coordinate","valueof"]);const s="element-background";if(!n)return[()=>{},()=>{}];const c=(y,m,b)=>{const x=y.invert(m),w=m+y.getBandWidth(x)/2,O=y.getStep(x)/2,S=O*b;return[w-O+S,w+O-S]},l=(y,m)=>{const{x:b}=r;if(!Ho(b))return[0,1];const{__data__:x}=y,{x:w}=x,[O,S]=c(b,w,m);return[O,S]},u=(y,m)=>{const{y:b}=r;if(!Ho(b))return[0,1];const{__data__:x}=y,{y:w}=x,[O,S]=c(b,w,m);return[O,S]},f=(y,m)=>{const{padding:b}=m,[x,w]=l(y,b),[O,S]=u(y,b),_=[[x,O],[w,O],[w,S],[x,S]].map(T=>i.map(T)),{__data__:M}=y,{y:E,y1:P}=M;return iO(e,_,{y:E,y1:P},i,m)},d=(y,m)=>{const{transform:b="scale(1.2, 1.2)",transformOrigin:x="center center",stroke:w=""}=m,O=Zo(m,["transform","transformOrigin","stroke"]),S=Object.assign({transform:b,transformOrigin:x,stroke:w},O),_=y.cloneNode(!0);for(const[M,E]of Object.entries(S))_.style[M]=E;return _},h=()=>{const{x:y,y:m}=r;return[y,m].some(Ho)};return[y=>{y.background&&y.background.remove();const m=ai(o,T=>a(T,y)),{fill:b="#CCD6EC",fillOpacity:x=.3,zIndex:w=-2,padding:O=.001,strokeWidth:S=0}=m,_=Zo(m,["fill","fillOpacity","zIndex","padding","strokeWidth"]),M=Object.assign(Object.assign({},_),{fill:b,fillOpacity:x,zIndex:w,padding:O,strokeWidth:S}),P=(h()?f:d)(y,M);P.className=s,y.parentNode.parentNode.appendChild(P),y.background=P},y=>{var m;(m=y.background)===null||m===void 0||m.remove(),y.background=null},y=>y.className===s]}function Gr(t,e){const r=t.getRootNode().defaultView.getContextService().getDomElement();r!=null&&r.style&&(t.cursor=r.style.cursor,r.style.cursor=e)}function aU(t){Gr(t,t.cursor)}function Mv(t,e,n){return t.find(r=>Object.entries(e).every(([i,a])=>n(r)[i]===a))}var oU=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);if,link:i=!1,background:a=!1,delay:o=60,scale:s,coordinate:c,emitter:l,state:u={}}){var f;const d=e(t),h=new Set(d),p=te(d,r),v=ic(d,n),[g,y]=RA(Object.assign({elements:d,valueof:v,link:i,coordinate:c},Q(u.active,"link"))),[m,b,x]=jA(Object.assign({document:t.ownerDocument,scale:s,coordinate:c,background:a,valueof:v},Q(u.active,"background"))),w=X(u,{active:Object.assign({},((f=u.active)===null||f===void 0?void 0:f.offset)&&{transform:(...I)=>{const R=u.active.offset(...I),[,j]=I;return IA(d[j],R,c)}})}),{setState:O,removeState:S,hasState:_}=Tr(w,v);let M;const E=I=>{const{target:R,nativeEvent:j=!0}=I;if(!h.has(R))return;M&&clearTimeout(M);const D=r(R),$=p.get(D),B=new Set($);for(const F of d)B.has(F)?_(F,"active")||O(F,"active"):(O(F,"inactive"),y(F)),F!==R&&b(F);m(R),g($),j&&l.emit("element:highlight",{nativeEvent:j,data:{data:n(R),group:$.map(n)}})},P=()=>{M&&clearTimeout(M),M=setTimeout(()=>{T(),M=null},o)},T=(I=!0)=>{for(const R of d)S(R,"active","inactive"),b(R),y(R);I&&l.emit("element:unhighlight",{nativeEvent:I})},A=I=>{const{target:R}=I;a&&!x(R)||!a&&!h.has(R)||(o>0?P():T())},k=()=>{T()};t.addEventListener("pointerover",E),t.addEventListener("pointerout",A),t.addEventListener("pointerleave",k);const C=I=>{const{nativeEvent:R}=I;R||T(!1)},L=I=>{const{nativeEvent:R}=I;if(R)return;const{data:j}=I.data,D=Mv(d,j,n);D&&E({target:D,nativeEvent:!1})};return l.on("element:highlight",L),l.on("element:unhighlight",C),()=>{t.removeEventListener("pointerover",E),t.removeEventListener("pointerout",A),t.removeEventListener("pointerleave",k),l.off("element:highlight",L),l.off("element:unhighlight",C);for(const I of d)b(I),y(I)}}function pf(t){var{delay:e,createGroup:n,background:r=!1,link:i=!1}=t,a=oU(t,["delay","createGroup","background","link"]);return(o,s,c)=>{const{container:l,view:u,options:f}=o,{scale:d,coordinate:h}=u,p=jr(l);return sU(p,Object.assign({elements:ri,datum:Xi(u),groupKey:n?n(u):void 0,coordinate:h,scale:d,state:Qa(f,[["active",r?{}:{lineWidth:"1",stroke:"#000"}],"inactive"]),background:r,link:i,delay:e,emitter:c},a))}}pf.props={reapplyWhenUpdate:!0};function DA(t){return pf(Object.assign(Object.assign({},t),{createGroup:_v}))}DA.props={reapplyWhenUpdate:!0};function $A(t){return pf(Object.assign(Object.assign({},t),{createGroup:NA}))}$A.props={reapplyWhenUpdate:!0};var cU=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);if,link:i=!1,single:a=!1,coordinate:o,background:s=!1,scale:c,emitter:l,state:u={}}){var f;const d=e(t),h=new Set(d),p=te(d,r),v=ic(d,n),[g,y]=RA(Object.assign({link:i,elements:d,valueof:v,coordinate:o},Q(u.selected,"link"))),[m,b]=jA(Object.assign({document:t.ownerDocument,background:s,coordinate:o,scale:c,valueof:v},Q(u.selected,"background"))),x=X(u,{selected:Object.assign({},((f=u.selected)===null||f===void 0?void 0:f.offset)&&{transform:(...k)=>{const C=u.selected.offset(...k),[,L]=k;return IA(d[L],C,o)}})}),{setState:w,removeState:O,hasState:S}=Tr(x,v),_=(k=!0)=>{for(const C of d)O(C,"selected","unselected"),y(C),b(C);k&&l.emit("element:unselect",{nativeEvent:!0})},M=(k,C,L=!0)=>{if(S(C,"selected"))_();else{const I=r(C),R=p.get(I),j=new Set(R);for(const D of d)j.has(D)?w(D,"selected"):(w(D,"unselected"),y(D)),D!==C&&b(D);if(g(R),m(C),!L)return;l.emit("element:select",Object.assign(Object.assign({},k),{nativeEvent:L,data:{data:[n(C),...R.map(n)]}}))}},E=(k,C,L=!0)=>{const I=r(C),R=p.get(I),j=new Set(R);if(S(C,"selected")){if(!d.some($=>!j.has($)&&S($,"selected")))return _();for(const $ of R)w($,"unselected"),y($),b($)}else{const D=R.some($=>S($,"selected"));for(const $ of d)j.has($)?w($,"selected"):S($,"selected")||w($,"unselected");!D&&i&&g(R),m(C)}L&&l.emit("element:select",Object.assign(Object.assign({},k),{nativeEvent:L,data:{data:d.filter(D=>S(D,"selected")).map(n)}}))},P=k=>{const{target:C,nativeEvent:L=!0}=k;return h.has(C)?a?M(k,C,L):E(k,C,L):_()};t.addEventListener("click",P);const T=k=>{const{nativeEvent:C,data:L}=k;if(C)return;const I=a?L.data.slice(0,1):L.data;for(const R of I){const j=Mv(d,R,n);P({target:j,nativeEvent:!1})}},A=()=>{_(!1)};return l.on("element:select",T),l.on("element:unselect",A),()=>{for(const k of d)y(k);t.removeEventListener("click",P),l.off("element:select",T),l.off("element:unselect",A)}}function vf(t){var{createGroup:e,background:n=!1,link:r=!1}=t,i=cU(t,["createGroup","background","link"]);return(a,o,s)=>{const{container:c,view:l,options:u}=a,{coordinate:f,scale:d}=l,h=jr(c);return lU(h,Object.assign({elements:ri,datum:Xi(l),groupKey:e?e(l):void 0,coordinate:f,scale:d,state:Qa(u,[["selected",n?{}:{lineWidth:"1",stroke:"#000"}],"unselected"]),background:n,link:r,emitter:s},i))}}vf.props={reapplyWhenUpdate:!0};function BA(t){return vf(Object.assign(Object.assign({},t),{createGroup:_v}))}BA.props={reapplyWhenUpdate:!0};function FA(t){return vf(Object.assign(Object.assign({},t),{createGroup:NA}))}FA.props={reapplyWhenUpdate:!0};var uU=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},fU=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ii.type==="normalizeY");if(n)return n;const r={type:"normalizeY"};return e.push(r),t.transform=e,r}function hU(t,e,n){const[r]=Array.from(t.entries()).filter(([i])=>i.type===e).map(([i])=>{const{encode:a}=i,o=s=>{const c=a[s];return[s,c?c.value:void 0]};return Object.fromEntries(n.map(o))});return r}function zA(t){var{wait:e=20,leading:n,trailing:r=!1,labelFormatter:i=o=>`${o}`}=t,a=fU(t,["wait","leading","trailing","labelFormatter"]);return o=>{const{view:s,container:c,update:l,setState:u}=o,{markState:f,scale:d,coordinate:h}=s,p=hU(f,"line",["x","y","series"]);if(!p)return;const{y:v,x:g,series:y=[]}=p,m=v.map((I,R)=>R),b=Er(m.map(I=>g[I])),x=jr(c),w=c.getElementsByClassName(xr),O=c.getElementsByClassName(Lh),_=te(O,I=>I.__data__.key.split("-")[0]),M=new Us({style:Object.assign({x1:0,y1:0,x2:0,y2:x.getAttribute("height"),stroke:"black",lineWidth:1},Q(a,"rule"))}),E=new ei({style:Object.assign({x:0,y:x.getAttribute("height"),text:"",fontSize:10},Q(a,"label"))});M.append(E),x.appendChild(M);const P=(I,R,j)=>{const[D]=I.invert(j),$=R.invert(D);return b[p5(b,$)]},T=(I,R)=>{M.setAttribute("x1",I[0]),M.setAttribute("x2",I[0]),E.setAttribute("text",i(R))};let A;const k=I=>uU(this,void 0,void 0,function*(){const{x:R}=d,j=P(h,R,I);T(I,j),u("chartIndex",$=>{const B=X({},$),F=B.marks.find(W=>W.type==="line"),U=Ct(vp(m,W=>Ct(W,J=>+v[J])/bn(W,J=>+v[J]),W=>y[W]).values()),K=[1/U,U];X(F,{scale:{y:{domain:K}}});const V=dU(F);V.groupBy="color",V.basis=(W,J)=>{const et=W[Ca(it=>g[+it]).center(W,j)];return J[et]};for(const W of B.marks)W.animate=!1;return B}),A=(yield l("chartIndex")).view}),C=I=>{const{scale:R,coordinate:j}=A,{x:D,y:$}=R,B=P(j,D,I);T(I,B);for(const F of w){const{seriesIndex:Y,key:U}=F.__data__,K=Y[Ca(ot=>g[+ot]).center(Y,B)],V=[0,$.map(1)],W=[0,$.map(v[K]/v[Y[0]])],[,J]=j.map(V),[,et]=j.map(W),it=J-et;F.setAttribute("transform",`translate(0, ${it})`);const ct=_.get(U)||[];for(const ot of ct)ot.setAttribute("dy",it)}},L=Ni(I=>{const R=Sv(x,I);R&&C(R)},e,{leading:n,trailing:r});return k([0,0]),x.addEventListener("pointerenter",L),x.addEventListener("pointermove",L),x.addEventListener("pointerleave",L),()=>{M.remove(),x.removeEventListener("pointerenter",L),x.removeEventListener("pointermove",L),x.removeEventListener("pointerleave",L)}}}zA.props={reapplyWhenUpdate:!0};function pU(t){const{coordinate:e={}}=t,{transform:n=[]}=e,r=n.find(a=>a.type==="fisheye");if(r)return r;const i={type:"fisheye"};return n.push(i),e.transform=n,t.coordinate=e,i}function vU({wait:t=30,leading:e,trailing:n=!1}){return r=>{const{options:i,update:a,setState:o,container:s}=r,c=jr(s),l=Ni(u=>{const f=Sv(c,u);if(!f){o("fisheye"),a();return}o("fisheye",d=>{const h=X({},d,{interaction:{tooltip:{preserve:!0}}});for(const y of h.marks)y.animate=!1;const[p,v]=f,g=pU(h);return g.focusX=p,g.focusY=v,g.visual=!0,h}),a()},t,{leading:e,trailing:n});return c.addEventListener("pointerenter",l),c.addEventListener("pointermove",l),c.addEventListener("pointerleave",l),()=>{c.removeEventListener("pointerenter",l),c.removeEventListener("pointermove",l),c.removeEventListener("pointerleave",l)}}}var ac=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{var{color:o=WA(t)}=a,s=ac(a,["color"]);return Object.assign(Object.assign({},s),{color:o})}).map(YA);return Object.assign(Object.assign({},n&&{title:n}),{items:i})}function xU(t,e){const{color:n,series:r,facet:i=!1}=t,{color:a,series:o}=e,s=c=>c&&c.invert&&!(c instanceof Ia)&&!(c instanceof Ep);if(s(r))return r.clone().invert(o);if(o&&r instanceof Ia&&r.invert(o)!==a&&!i)return r.invert(o);if(s(n)){const c=n.invert(a);return Array.isArray(c)?null:c}return null}function WA(t){const e=t.getAttribute("fill"),n=t.getAttribute("stroke"),{__data__:r}=t,{color:i=e&&e!=="transparent"?e:n}=r;return i}function lb(t,e=n=>n){const n=new Map(t.map(r=>[e(r),r]));return Array.from(n.values())}function HA(t,e,n,r=t.map(a=>a.__data__),i={}){const a=c=>c instanceof Date?+c:c,o=lb(r.map(c=>c.title),a).filter(zt),s=r.flatMap((c,l)=>{const u=t[l],{items:f=[],title:d}=c,h=f.filter(zt),p=n!==void 0?n:f.length<=1;return h.map(v=>{var{color:g=WA(u)||i.color,name:y}=v,m=ac(v,["color","name"]);const b=xU(e,c),x=p?b||y:y||b;return Object.assign(Object.assign({},m),{color:g,name:x||d})})}).map(YA);return Object.assign(Object.assign({},o.length>0&&{title:o.join(",")}),{items:lb(s,c=>`(${a(c.name)}, ${a(c.value)}, ${a(c.color)})`)})}function wU(t,e,n){var{plotWidth:r,plotHeight:i,mainWidth:a,mainHeight:o,startX:s,startY:c,transposed:l,polar:u,insetLeft:f,insetTop:d}=n,h=ac(n,["plotWidth","plotHeight","mainWidth","mainHeight","startX","startY","transposed","polar","insetLeft","insetTop"]);const p=Object.assign({lineWidth:1,stroke:"#1b1e23",strokeOpacity:.5},h),v=e.map(M=>M[1]),g=e.map(M=>M[0]),y=rs(v),m=rs(g),b=()=>{if(u){const M=Math.min(a,o)/2,E=s+f+a/2,P=c+d+o/2,T=Nn(se([m,y],[E,P])),A=E+M*Math.cos(T),k=P+M*Math.sin(T);return[E,A,P,k]}return l?[s,s+r,y+c,y+c]:[m+s,m+s,c,c+i]},[x,w,O,S]=b(),_=()=>{const M=new Us({style:Object.assign({x1:x,x2:w,y1:O,y2:S},p)});return t.appendChild(M),M};if(g.length>0){const M=t.ruleY||_();M.style.x1=x,M.style.x2=w,M.style.y1=O,M.style.y2=S,t.ruleY=M}}function ub(t){t.ruleY&&(t.ruleY.remove(),t.ruleY=void 0)}function OU(t,{data:e,style:n,theme:r}){t.markers&&t.markers.forEach(a=>a.remove());const i=e.filter(a=>{const[{x:o,y:s}]=a;return zt(o)&&zt(s)}).map(a=>{const[{color:o,element:s},c]=a,l=o||s.style.fill||s.style.stroke||r.color;return new Xs({style:Object.assign({cx:c[0],cy:c[1],fill:l,r:4,stroke:"#fff",strokeWidth:2},n)})});for(const a of i)t.appendChild(a);t.markers=i}function fb(t){t.markers&&(t.markers.forEach(e=>e.remove()),t.markers=[])}function db(t,e){return Array.from(t.values()).some(n=>{var r;return(r=n.interaction)===null||r===void 0?void 0:r[e]})}function _d(t,e){return t===void 0?e:t}function VA(t){const{title:e,items:n}=t;return n.length===0&&e===void 0}function SU(t){return Array.from(t.values()).some(e=>{var n;return((n=e.interaction)===null||n===void 0?void 0:n.seriesTooltip)&&e.tooltip})}function hb(t,e){var{elements:n,sort:r,filter:i,scale:a,coordinate:o,crosshairs:s,render:c,groupName:l,emitter:u,wait:f=50,leading:d=!0,trailing:h=!1,startX:p=0,startY:v=0,body:g=!0,single:y=!0,position:m,enterable:b,mount:x,bounding:w,theme:O,disableNative:S=!1,marker:_=!0,preserve:M=!1,style:E={},css:P={}}=e,T=ac(e,["elements","sort","filter","scale","coordinate","crosshairs","render","groupName","emitter","wait","leading","trailing","startX","startY","body","single","position","enterable","mount","bounding","theme","disableNative","marker","preserve","style","css"]);const A=n(t),k=qt(o),C=Ht(o),L=X(E,T),{innerWidth:I,innerHeight:R,width:j,height:D,insetLeft:$,insetTop:B}=o.getOptions(),F=[],Y=[];for(const _t of A){const{__data__:Pt}=_t,{seriesX:ee,title:kt,items:ye}=Pt;ee?F.push(_t):(kt||ye)&&Y.push(_t)}const K=!!(k?a.y:a.x).getBandWidth&&Y.length>0;F.sort((_t,Pt)=>{const ee=k?0:1,kt=ye=>ye.getBounds().min[ee];return k?kt(Pt)-kt(_t):kt(_t)-kt(Pt)});const V=_t=>{const Pt=k?1:0,{min:ee,max:kt}=_t.getLocalBounds();return Er([ee[Pt],kt[Pt]])};Y.sort((_t,Pt)=>{const[ee,kt]=V(_t),[ye,xe]=V(Pt),Ze=(ee+kt)/2,ln=(ye+xe)/2;return k?ln-Ze:Ze-ln});const W=new Map(F.map(_t=>{const{__data__:Pt}=_t,{seriesX:ee}=Pt,kt=ee.map((xe,Ze)=>Ze),ye=Er(kt,xe=>ee[+xe]);return[_t,[ye,ee]]})),{x:J}=a,et=J!=null&&J.getBandWidth?J.getBandWidth()/2:0,it=_t=>{const[Pt]=o.invert(_t);return Pt-et},ct=(_t,Pt,ee)=>{const kt=it(_t),ye=ee.filter(zt),[xe,Ze]=Er([ye[0],ye[ye.length-1]]),ln=xe===Ze;if(!K&&(ktZe)&&!ln)return null;const Bn=Ca(gf=>ee[+gf]).center,Dr=Bn(Pt,kt);return Pt[Dr]},ot=(_t,Pt)=>{const kt=_t[k?1:0],ye=Pt.filter(ln=>{const[Bn,Dr]=V(ln);return kt>=Bn&&kt<=Dr});if(!K||ye.length>0)return ye;const xe=Ca(ln=>{const[Bn,Dr]=V(ln);return(Bn+Dr)/2}).center,Ze=xe(Pt,kt);return[Pt[Ze]].filter(zt)},lt=(_t,Pt)=>{const{__data__:ee}=_t;return Object.fromEntries(Object.entries(ee).filter(([kt])=>kt.startsWith("series")&&kt!=="series").map(([kt,ye])=>{const xe=ye[Pt];return[Db(kt.replace("series","")),xe]}))},xt=Ni(_t=>{const Pt=Sv(t,_t);if(!Pt)return;const ee=LA(t),kt=ee.min[0],ye=ee.min[1],xe=[Pt[0]-p,Pt[1]-v];if(!xe)return;const Ze=ot(xe,Y),ln=[],Bn=[];for(const me of F){const[fo,mf]=W.get(me),Dv=ct(xe,fo,mf);if(Dv!==null){ln.push(me);const $v=lt(me,Dv),{x:dk,y:hk}=$v,pk=o.map([(dk||0)+et,hk||0]);Bn.push([Object.assign(Object.assign({},$v),{element:me}),pk])}}const Dr=Array.from(new Set(Bn.map(me=>me[0].x))),gf=Dr[bu(Dr,me=>Math.abs(me-it(xe)))],yf=Bn.filter(me=>me[0].x===gf),fk=[...yf.map(me=>me[0]),...Ze.map(me=>me.__data__)],jv=[...ln,...Ze],uo=HA(jv,a,l,fk,O);if(r&&uo.items.sort((me,fo)=>r(me)-r(fo)),i&&(uo.items=uo.items.filter(i)),jv.length===0||VA(uo)){Et(_t);return}if(g&&GA({root:t,data:uo,x:Pt[0]+kt,y:Pt[1]+ye,render:c,event:_t,single:y,position:m,enterable:b,mount:x,bounding:w,css:P}),s){const me=yf.map(mf=>mf[1]),fo=Q(L,"crosshairs");wU(t,me,Object.assign(Object.assign({},fo),{plotWidth:I,plotHeight:R,mainWidth:j,mainHeight:D,insetLeft:$,insetTop:B,startX:p,startY:v,transposed:k,polar:C}))}if(_){const me=Q(L,"marker");OU(t,{data:yf,style:me,theme:O})}u.emit("tooltip:show",Object.assign(Object.assign({},_t),{nativeEvent:!0,data:{data:{x:Ha(a.x,it(xe),!0)}}}))},f,{leading:d,trailing:h}),Et=_t=>{Wr({root:t,single:y,emitter:u,event:_t}),s&&ub(t),_&&fb(t)},Xt=()=>{Jh({root:t,single:y}),s&&ub(t),_&&fb(t)},ue=({nativeEvent:_t,data:Pt})=>{if(_t)return;const{x:ee}=Pt.data,{x:kt}=a,ye=kt.map(ee),[xe,Ze]=o.map([ye,.5]),{min:[ln,Bn]}=t.getRenderBounds();xt({offsetX:xe+ln,offsetY:Ze+Bn})},Ke=()=>{Wr({root:t,single:y,emitter:u,nativeEvent:!1})},vr=()=>{wn(),Xt()},gi=()=>{Ge()},Ge=()=>{S||(t.addEventListener("pointerenter",xt),t.addEventListener("pointermove",xt),t.addEventListener("pointerleave",Et))},wn=()=>{S||(t.removeEventListener("pointerenter",xt),t.removeEventListener("pointermove",xt),t.removeEventListener("pointerleave",Et))};return Ge(),u.on("tooltip:show",ue),u.on("tooltip:hide",Ke),u.on("tooltip:disable",vr),u.on("tooltip:enable",gi),()=>{wn(),u.off("tooltip:show",ue),u.off("tooltip:hide",Ke),u.off("tooltip:disable",vr),u.off("tooltip:enable",gi),M?Wr({root:t,single:y,emitter:u,nativeEvent:!1}):Xt()}}function _U(t,{elements:e,scale:n,render:r,groupName:i,sort:a,filter:o,emitter:s,wait:c=50,leading:l=!0,trailing:u=!1,groupKey:f=M=>M,single:d=!0,position:h,enterable:p,datum:v,view:g,mount:y,bounding:m,theme:b,shared:x=!1,body:w=!0,disableNative:O=!1,preserve:S=!1,css:_={}}){const M=e(t),E=new Set(M),P=te(M,f),T=Ni(D=>{const{target:$}=D;if(!E.has($)){Wr({root:t,single:d,emitter:s,event:D});return}const B=f($),F=P.get(B),Y=F.length===1&&!x?bU(F[0]):HA(F,n,i,void 0,b);if(a&&Y.items.sort((V,W)=>a(V)-a(W)),o&&(Y.items=Y.items.filter(o)),VA(Y)){Wr({root:t,single:d,emitter:s,event:D});return}const{offsetX:U,offsetY:K}=D;w&&GA({root:t,data:Y,x:U,y:K,render:r,event:D,single:d,position:h,enterable:p,mount:y,bounding:m,css:_}),s.emit("tooltip:show",Object.assign(Object.assign({},D),{nativeEvent:!0,data:{data:CP($,g)}}))},c,{leading:l,trailing:u}),A=D=>{Wr({root:t,single:d,emitter:s,event:D})},k=()=>{O||(t.addEventListener("pointermove",T),t.addEventListener("pointerleave",A))},C=()=>{O||(t.removeEventListener("pointermove",T),t.removeEventListener("pointerleave",A))},L=({nativeEvent:D,data:$})=>{if(D)return;const B=Mv(M,$.data,v);if(!B)return;const F=B.getBBox(),{x:Y,y:U,width:K,height:V}=F;T({target:B,offsetX:Y+K/2,offsetY:U+V/2})},I=({nativeEvent:D}={})=>{D||Wr({root:t,single:d,emitter:s,nativeEvent:!1})},R=()=>{C(),Jh({root:t,single:d})},j=()=>{k()};return s.on("tooltip:show",L),s.on("tooltip:hide",I),s.on("tooltip:enable",j),s.on("tooltip:disable",R),k(),()=>{C(),s.off("tooltip:show",L),s.off("tooltip:hide",I),S?Wr({root:t,single:d,emitter:s,nativeEvent:!1}):Jh({root:t,single:d})}}function XA(t){const{shared:e,crosshairs:n,series:r,name:i,item:a=()=>({}),facet:o=!1}=t,s=ac(t,["shared","crosshairs","series","name","item","facet"]);return(c,l,u)=>{const{container:f,view:d}=c,{scale:h,markState:p,coordinate:v,theme:g}=d,y=db(p,"seriesTooltip"),m=db(p,"crosshairs"),b=jr(f),x=_d(r,y);if(x&&SU(p)&&!o)return hb(b,Object.assign(Object.assign({},s),{theme:g,elements:ri,scale:h,coordinate:v,crosshairs:_d(n,m),item:a,emitter:u}));if(x&&o){const w=l.filter(P=>P!==c&&P.options.parentKey===c.options.key),O=CA(c,l),S=w[0].view.scale,_=b.getBounds(),M=_.min[0],E=_.min[1];return Object.assign(S,{facet:!0}),hb(b.parentNode.parentNode,Object.assign(Object.assign({},s),{theme:g,elements:()=>O,scale:S,coordinate:v,crosshairs:_d(n,m),item:a,startX:M,startY:E,emitter:u}))}return _U(b,Object.assign(Object.assign({},s),{datum:Xi(d),elements:ri,scale:h,coordinate:v,groupKey:e?_v():void 0,item:a,emitter:u,view:d,theme:g,shared:e}))}}XA.props={reapplyWhenUpdate:!0};var ul=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})};const UA="legend-category",MU="legend-continuous",EU="items-item",PU="legend-category-item-marker",AU="legend-category-item-label";function qA(t){return t.getElementsByClassName(PU)[0]}function KA(t){return t.getElementsByClassName(AU)[0]}function ZA(t){return t.getElementsByClassName(EU)}function Ev(t){return t.getElementsByClassName(UA)}function QA(t){return t.getElementsByClassName(MU)}function kU(t,e){[...Ev(t),...QA(t)].forEach(r=>{e(r,i=>i)})}function tp(t){let e=t.parentNode;for(;e&&!e.__data__;)e=e.parentNode;return e.__data__}function TU(t,{legends:e,marker:n,label:r,datum:i,filter:a,emitter:o,channel:s,state:c={}}){const l=new Map,u=new Map,f=new Map,{unselected:d={markerStroke:"#aaa",markerFill:"#aaa",labelFill:"#aaa"}}=c,h={unselected:Q(d,"marker")},p={unselected:Q(d,"label")},{setState:v,removeState:g}=Tr(h,void 0),{setState:y,removeState:m}=Tr(p,void 0),b=Array.from(e(t));let x=b.map(i);const w=()=>{for(const _ of b){const M=i(_),E=n(_),P=r(_);x.includes(M)?(g(E,"unselected"),m(P,"unselected")):(v(E,"unselected"),y(P,"unselected"))}};for(const _ of b){const M=()=>{Gr(t,"pointer")},E=()=>{aU(t)},P=T=>ul(this,void 0,void 0,function*(){const A=i(_),k=x.indexOf(A);k===-1?x.push(A):x.splice(k,1),x.length===0&&x.push(...b.map(i)),yield a(x),w();const{nativeEvent:C=!0}=T;C&&(x.length===b.length?o.emit("legend:reset",{nativeEvent:C}):o.emit("legend:filter",Object.assign(Object.assign({},T),{nativeEvent:C,data:{channel:s,values:x}})))});_.addEventListener("click",P),_.addEventListener("pointerenter",M),_.addEventListener("pointerout",E),l.set(_,P),u.set(_,M),f.set(_,E)}const O=_=>ul(this,void 0,void 0,function*(){const{nativeEvent:M}=_;if(M)return;const{data:E}=_,{channel:P,values:T}=E;P===s&&(x=T,yield a(x),w())}),S=_=>ul(this,void 0,void 0,function*(){const{nativeEvent:M}=_;M||(x=b.map(i),yield a(x),w())});return o.on("legend:filter",O),o.on("legend:reset",S),()=>{for(const _ of b)_.removeEventListener("click",l.get(_)),_.removeEventListener("pointerenter",u.get(_)),_.removeEventListener("pointerout",f.get(_)),o.off("legend:filter",O),o.off("legend:reset",S)}}function CU(t,{legend:e,filter:n,emitter:r,channel:i}){const a=({detail:{value:o}})=>{n(o),r.emit({nativeEvent:!0,data:{channel:i,values:o}})};return e.addEventListener("valuechange",a),()=>{e.removeEventListener("valuechange",a)}}function JA(t,{legend:e,channel:n,value:r,ordinal:i,channels:a,allChannels:o,facet:s=!1}){return ul(this,void 0,void 0,function*(){const{view:c,update:l,setState:u}=t;u(e,f=>{const{marks:d}=f,h=d.map(p=>{if(p.type==="legends")return p;const{transform:v=[]}=p,g=v.findIndex(({type:b})=>b.startsWith("group")||b.startsWith("bin")),y=[...v];y.splice(g+1,0,{type:"filter",[n]:{value:r,ordinal:i}});const m=Object.fromEntries(a.map(b=>[b,{domain:c.scale[b].getOptions().domain}]));return X({},p,Object.assign(Object.assign({transform:y,scale:m},!i&&{animate:!1}),{legend:s?!1:Object.fromEntries(o.map(b=>[b,{preserve:!0}]))}))});return Object.assign(Object.assign({},f),{marks:h})}),yield l()})}function LU(t,e){for(const n of t)JA(n,Object.assign(Object.assign({},e),{facet:!0}))}function NU(){return(t,e,n)=>{const{container:r}=t,i=e.filter(f=>f!==t),a=i.length>0,o=f=>tp(f).scales.map(d=>d.name),s=[...Ev(r),...QA(r)],c=s.flatMap(o),l=a?Ni(LU,50,{trailing:!0}):Ni(JA,50,{trailing:!0}),u=s.map(f=>{const{name:d,domain:h}=tp(f).scales[0],p=o(f),v={legend:f,channel:d,channels:p,allChannels:c};return f.className===UA?TU(r,{legends:ZA,marker:qA,label:KA,datum:g=>{const{__data__:y}=g,{index:m}=y;return h[m]},filter:g=>{const y=Object.assign(Object.assign({},v),{value:g,ordinal:!0});l(a?i:t,y)},state:f.attributes.state,channel:d,emitter:n}):CU(r,{legend:f,filter:g=>{const y=Object.assign(Object.assign({},v),{value:g,ordinal:!1});l(a?i:t,y)},emitter:n,channel:d})});return()=>{u.forEach(f=>f())}}}function RU(){return(t,e,n)=>{const{container:r,view:i,options:a}=t,o=Ev(r),s=ri(r),c=h=>tp(h).scales[0].name,l=h=>{const{scale:{[h]:p}}=i;return p},u=Qa(a,["active","inactive"]),f=ic(s,Xi(i)),d=[];for(const h of o){const p=D=>{const{data:$}=h.attributes,{__data__:B}=D,{index:F}=B;return $[F].label},v=c(h),g=ZA(h),y=l(v),m=te(s,D=>y.invert(D.__data__[v])),{state:b={}}=h.attributes,{inactive:x={}}=b,{setState:w,removeState:O}=Tr(u,f),S={inactive:Q(x,"marker")},_={inactive:Q(x,"label")},{setState:M,removeState:E}=Tr(S),{setState:P,removeState:T}=Tr(_),A=D=>{for(const $ of g){const B=qA($),F=KA($);$===D||D===null?(E(B,"inactive"),T(F,"inactive")):(M(B,"inactive"),P(F,"inactive"))}},k=(D,$)=>{const B=p($),F=new Set(m.get(B));for(const U of s)F.has(U)?w(U,"active"):w(U,"inactive");A($);const{nativeEvent:Y=!0}=D;Y&&n.emit("legend:highlight",Object.assign(Object.assign({},D),{nativeEvent:Y,data:{channel:v,value:B}}))},C=new Map;for(const D of g){const $=B=>{k(B,D)};D.addEventListener("pointerover",$),C.set(D,$)}const L=D=>{for(const B of s)O(B,"inactive","active");A(null);const{nativeEvent:$=!0}=D;$&&n.emit("legend:unhighlight",{nativeEvent:$})},I=D=>{const{nativeEvent:$,data:B}=D;if($)return;const{channel:F,value:Y}=B;if(F!==v)return;const U=g.find(K=>p(K)===Y);U&&k({nativeEvent:!1},U)},R=D=>{const{nativeEvent:$}=D;$||L({nativeEvent:!1})};h.addEventListener("pointerleave",L),n.on("legend:highlight",I),n.on("legend:unhighlight",R);const j=()=>{h.removeEventListener(L),n.off("legend:highlight",I),n.off("legend:unhighlight",R);for(const[D,$]of C)D.removeEventListener($)};d.push(j)}return()=>d.forEach(h=>h())}}var fn=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);ii||ca||l{const e=t.attributes,{x:n,y:r,width:i,height:a,class:o,renders:s={},handleSize:c=10,document:l}=e,u=fn(e,["x","y","width","height","class","renders","handleSize","document"]);if(!l||i===void 0||a===void 0||n===void 0||r===void 0)return;const f=c/2,d=(Y,U,K)=>{Y.handle||(Y.handle=K.createElement("rect"),Y.append(Y.handle));const{handle:V}=Y;return V.attr(U),V},h=Q(Pf(u,"handleNW","handleNE"),"handleN"),{render:p=d}=h,v=fn(h,["render"]),g=Q(u,"handleE"),{render:y=d}=g,m=fn(g,["render"]),b=Q(Pf(u,"handleSE","handleSW"),"handleS"),{render:x=d}=b,w=fn(b,["render"]),O=Q(u,"handleW"),{render:S=d}=O,_=fn(O,["render"]),M=Q(u,"handleNW"),{render:E=d}=M,P=fn(M,["render"]),T=Q(u,"handleNE"),{render:A=d}=T,k=fn(T,["render"]),C=Q(u,"handleSE"),{render:L=d}=C,I=fn(C,["render"]),R=Q(u,"handleSW"),{render:j=d}=R,D=fn(R,["render"]),$=(Y,U)=>{const{id:K}=Y,V=Y.attributes,W=fn(V,["x","y"]),J=U(Y,Object.assign({x:0,y:0},W),l);J.id=K,J.style.draggable=!0},B=Y=>()=>{const U=Fa(K=>$(K,Y));return new U({})},F=st(t).attr("className",o).style("x",n).style("y",r).style("draggable",!0);F.maybeAppend("selection","rect").style("draggable",!0).style("fill","transparent").call(mr,Object.assign({width:i,height:a},Pf(u,"handle"))),F.maybeAppend("handle-n",B(p)).style("x",f).style("y",-f).style("width",i-c).style("height",c).style("fill","transparent").call(mr,v),F.maybeAppend("handle-e",B(y)).style("x",i-f).style("y",f).style("width",c).style("height",a-c).style("fill","transparent").call(mr,m),F.maybeAppend("handle-s",B(x)).style("x",f).style("y",a-f).style("width",i-c).style("height",c).style("fill","transparent").call(mr,w),F.maybeAppend("handle-w",B(S)).style("x",-f).style("y",f).style("width",c).style("height",a-c).style("fill","transparent").call(mr,_),F.maybeAppend("handle-nw",B(E)).style("x",-f).style("y",-f).style("width",c).style("height",c).style("fill","transparent").call(mr,P),F.maybeAppend("handle-ne",B(A)).style("x",i-f).style("y",-f).style("width",c).style("height",c).style("fill","transparent").call(mr,k),F.maybeAppend("handle-se",B(L)).style("x",i-f).style("y",a-f).style("width",c).style("height",c).style("fill","transparent").call(mr,I),F.maybeAppend("handle-sw",B(j)).style("x",-f).style("y",a-f).style("width",c).style("height",c).style("fill","transparent").call(mr,D)});function Pv(t,e){var{brushed:n=()=>{},brushended:r=()=>{},brushcreated:i=()=>{},brushstarted:a=()=>{},brushupdated:o=()=>{},extent:s=DU(t),brushRegion:c=(V,W,J,et,it)=>[V,W,J,et],reverse:l=!1,fill:u="#777",fillOpacity:f="0.3",stroke:d="#fff",selectedHandles:h=["handle-n","handle-e","handle-s","handle-w","handle-nw","handle-ne","handle-se","handle-sw"]}=e,p=fn(e,["brushed","brushended","brushcreated","brushstarted","brushupdated","extent","brushRegion","reverse","fill","fillOpacity","stroke","selectedHandles"]);let v=null,g=null,y=null,m=null,b=null,x=!1;const[w,O,S,_]=s;Gr(t,"crosshair"),t.style.draggable=!0;const M=(V,W,J)=>{if(a(J),m&&m.remove(),b&&b.remove(),v=[V,W],l)return E();P()},E=()=>{b=new Xe({style:Object.assign(Object.assign({},p),{fill:u,fillOpacity:f,stroke:d,pointerEvents:"none"})}),m=new pb({style:{x:0,y:0,width:0,height:0,draggable:!0,document:t.ownerDocument},className:"mask"}),t.appendChild(b),t.appendChild(m)},P=()=>{m=new pb({style:Object.assign(Object.assign({document:t.ownerDocument,x:0,y:0},p),{fill:u,fillOpacity:f,stroke:d,draggable:!0}),className:"mask"}),t.appendChild(m)},T=(V=!0)=>{m&&m.remove(),b&&b.remove(),v=null,g=null,y=null,x=!1,m=null,b=null,r(V)},A=(V,W,J=!0)=>{const[et,it,ct,ot]=jU(V[0],V[1],W[0],W[1],s),[lt,xt,Et,Xt]=c(et,it,ct,ot,s);return l?C(lt,xt,Et,Xt):k(lt,xt,Et,Xt),n(lt,xt,Et,Xt,J),[lt,xt,Et,Xt]},k=(V,W,J,et)=>{m.style.x=V,m.style.y=W,m.style.width=J-V,m.style.height=et-W},C=(V,W,J,et)=>{b.style.d=` - M${w},${O}L${S},${O}L${S},${_}L${w},${_}Z - M${V},${W}L${V},${et}L${J},${et}L${J},${W}Z - `,m.style.x=V,m.style.y=W,m.style.width=J-V,m.style.height=et-W},L=V=>{const W=(xt,Et,Xt,ue,Ke)=>xt+EtKe?Ke-Xt:xt,J=V[0]-y[0],et=V[1]-y[1],it=W(J,v[0],g[0],w,S),ct=W(et,v[1],g[1],O,_),ot=[v[0]+it,v[1]+ct],lt=[g[0]+it,g[1]+ct];A(ot,lt)},I={"handle-n":{vector:[0,1,0,0],cursor:"ns-resize"},"handle-e":{vector:[0,0,1,0],cursor:"ew-resize"},"handle-s":{vector:[0,0,0,1],cursor:"ns-resize"},"handle-w":{vector:[1,0,0,0],cursor:"ew-resize"},"handle-nw":{vector:[1,1,0,0],cursor:"nwse-resize"},"handle-ne":{vector:[0,1,1,0],cursor:"nesw-resize"},"handle-se":{vector:[0,0,1,1],cursor:"nwse-resize"},"handle-sw":{vector:[1,0,0,1],cursor:"nesw-resize"}},R=V=>D(V)||j(V),j=V=>{const{id:W}=V;return h.indexOf(W)===-1?!1:new Set(Object.keys(I)).has(W)},D=V=>V===m.getElementById("selection"),$=V=>{const{target:W}=V,[J,et]=Sd(t,V);if(!m||!R(W)){M(J,et,V),x=!0;return}R(W)&&(y=[J,et])},B=V=>{const{target:W}=V,J=Sd(t,V);if(!v)return;if(!y)return A(v,J);if(D(W))return L(J);const[et,it]=[J[0]-y[0],J[1]-y[1]],{id:ct}=W;if(I[ct]){const[ot,lt,xt,Et]=I[ct].vector;return A([v[0]+et*ot,v[1]+it*lt],[g[0]+et*xt,g[1]+it*Et])}},F=V=>{if(y){y=null;const{x:ct,y:ot,width:lt,height:xt}=m.style;v=[ct,ot],g=[ct+lt,ot+xt],o(ct,ot,ct+lt,ot+xt,V);return}g=Sd(t,V);const[W,J,et,it]=A(v,g);x=!1,i(W,J,et,it,V)},Y=V=>{const{target:W}=V;m&&!R(W)&&T()},U=V=>{const{target:W}=V;!m||!R(W)||x?Gr(t,"crosshair"):D(W)?Gr(t,"move"):j(W)&&Gr(t,I[W.id].cursor)},K=()=>{Gr(t,"default")};return t.addEventListener("dragstart",$),t.addEventListener("drag",B),t.addEventListener("dragend",F),t.addEventListener("click",Y),t.addEventListener("pointermove",U),t.addEventListener("pointerleave",K),{mask:m,move(V,W,J,et,it=!0){m||M(V,W,{}),v=[V,W],g=[J,et],A([V,W],[J,et],it)},remove(V=!0){m&&T(V)},destroy(){m&&T(!1),Gr(t,"default"),t.removeEventListener("dragstart",$),t.removeEventListener("drag",B),t.removeEventListener("dragend",F),t.removeEventListener("click",Y),t.removeEventListener("pointermove",U),t.removeEventListener("pointerleave",K)}}}function Av(t,e,n){return e.filter(r=>{if(r===t)return!1;const{interaction:i={}}=r.options;return Object.values(i).find(a=>a.brushKey===n)})}function $U(t,e,n){return Av(t,e,n).map(r=>jr(r.container))}function BU(t,e,n){return Av(t,e,n).map(r=>r.options)}function vb(t,e){var{elements:n,selectedHandles:r,siblings:i=B=>[],datum:a,brushRegion:o,extent:s,reverse:c,scale:l,coordinate:u,series:f=!1,key:d=B=>B,bboxOf:h=B=>{const{x:F,y:Y,width:U,height:K}=B.style;return{x:F,y:Y,width:U,height:K}},state:p={},emitter:v}=e,g=fn(e,["elements","selectedHandles","siblings","datum","brushRegion","extent","reverse","scale","coordinate","series","key","bboxOf","state","emitter"]);const y=n(t),m=i(t),b=m.flatMap(n),x=ic(y,a),w=Q(g,"mask"),{setState:O,removeState:S}=Tr(p,x),_=new Map,{width:M,height:E,x:P=0,y:T=0}=h(t),A=s||[0,0,M,E],k=()=>{for(const B of[...y,...b])S(B,"active","inactive")},C=(B,F,Y,U)=>{var K;for(const W of m)(K=W.brush)===null||K===void 0||K.remove();const V=new Set;for(const W of y){const{min:J,max:et}=W.getLocalBounds(),[it,ct]=J,[ot,lt]=et;IU([it,ct,ot,lt],[B,F,Y,U])?(O(W,"active"),V.add(d(W))):O(W,"inactive")}for(const W of b)V.has(d(W))?O(W,"active"):O(W,"inactive")},L=()=>{for(const B of y)S(B,"inactive");for(const B of _.values())B.remove();_.clear()},I=(B,F,Y,U)=>{const K=V=>{const W=V.cloneNode();return W.__data__=V.__data__,V.parentNode.appendChild(W),_.set(V,W),W};for(const V of y){const W=_.get(V)||K(V);W.style.clipPath=new Zi({style:{x:B+P,y:F+T,width:Y-B,height:U-F}}),O(V,"inactive"),O(W,"active")}},R=Pv(t,Object.assign(Object.assign({},w),{extent:A,brushRegion:o,reverse:c,selectedHandles:r,brushended:B=>{const F=f?L:k;B&&v.emit("brush:remove",{nativeEvent:!0}),F()},brushed:(B,F,Y,U,K)=>{const V=cl(B,F,Y,U,l,u);K&&v.emit("brush:highlight",{nativeEvent:!0,data:{selection:V}}),(f?I:C)(B,F,Y,U)},brushcreated:(B,F,Y,U,K)=>{const V=cl(B,F,Y,U,l,u);v.emit("brush:end",Object.assign(Object.assign({},K),{nativeEvent:!0,data:{selection:V}}))},brushupdated:(B,F,Y,U,K)=>{const V=cl(B,F,Y,U,l,u);v.emit("brush:end",Object.assign(Object.assign({},K),{nativeEvent:!0,data:{selection:V}}))},brushstarted:B=>{v.emit("brush:start",B)}})),j=({nativeEvent:B,data:F})=>{if(B)return;const{selection:Y}=F,[U,K,V,W]=UF(Y,l,u);R.move(U,K,V,W,!1)};v.on("brush:highlight",j);const D=({nativeEvent:B}={})=>{B||R.remove(!1)};v.on("brush:remove",D);const $=R.destroy.bind(R);return R.destroy=()=>{v.off("brush:highlight",j),v.off("brush:remove",D),$()},R}function kv(t){var{facet:e,brushKey:n}=t,r=fn(t,["facet","brushKey"]);return(i,a,o)=>{const{container:s,view:c,options:l}=i,u=jr(s),f={maskFill:"#777",maskFillOpacity:"0.3",maskStroke:"#fff",reverse:!1},d=["active",["inactive",{opacity:.5}]],{scale:h,coordinate:p}=c;if(e){const g=u.getBounds(),y=g.min[0],m=g.min[1],b=g.max[0],x=g.max[1];return vb(u.parentNode.parentNode,Object.assign(Object.assign({elements:()=>CA(i,a),datum:Xi(Qh(i,a).map(w=>w.view)),brushRegion:(w,O,S,_)=>[w,O,S,_],extent:[y,m,b,x],state:Qa(Qh(i,a).map(w=>w.options),d),emitter:o,scale:h,coordinate:p,selectedHandles:void 0},f),r))}const v=vb(u,Object.assign(Object.assign({elements:ri,key:g=>g.__data__.key,siblings:()=>$U(i,a,n),datum:Xi([c,...Av(i,a,n).map(g=>g.view)]),brushRegion:(g,y,m,b)=>[g,y,m,b],extent:void 0,state:Qa([l,...BU(i,a,n)],d),emitter:o,scale:h,coordinate:p,selectedHandles:void 0},f),r));return u.brush=v,()=>v.destroy()}}function Tv(t,e,n,r,i){const[,a,,o]=i;return[t,a,n,o]}function FU(t){return kv(Object.assign(Object.assign({},t),{brushRegion:Tv,selectedHandles:["handle-e","handle-w"]}))}function Cv(t,e,n,r,i){const[a,,o]=i;return[a,e,o,r]}function zU(t){return kv(Object.assign(Object.assign({},t),{brushRegion:Cv,selectedHandles:["handle-n","handle-s"]}))}var Lv=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i[-1/0,v,1/0,y]:(p,v,g,y)=>[Math.floor(l-r),v,Math.ceil(f-r),y]}}function UU(t,e){var{offsetY:n,offsetX:r,cross:i=!1}=e,a=Lv(e,["offsetY","offsetX","cross"]);const o=nk(t),s=ek(t),[,c]=s.getLocalBounds().min,[l,u]=o.min,[f,d]=o.max,h=d-u;return{brushRegion:Tv,hotZone:new Zi({className:tk,style:Object.assign({x:l,width:f-l,y:i?u:c-h,height:i?h:h*2},a)}),extent:i?(p,v,g,y)=>[p,-1/0,g,1/0]:(p,v,g,y)=>[p,Math.floor(u-n),g,Math.ceil(d-n)]}}function qU(t,e){var{axes:n,elements:r,points:i,horizontal:a,datum:o,offsetY:s,offsetX:c,reverse:l=!1,state:u={},emitter:f,coordinate:d}=e,h=Lv(e,["axes","elements","points","horizontal","datum","offsetY","offsetX","reverse","state","emitter","coordinate"]);const p=r(t),v=n(t),g=ic(p,o),{setState:y,removeState:m}=Tr(u,g),b=new Map,x=Q(h,"mask"),w=j=>Array.from(b.values()).every(([D,$,B,F])=>j.some(([Y,U])=>Y>=D&&Y<=B&&U>=$&&U<=F)),O=v.map(j=>j.attributes.scale),S=j=>j.length>2?[j[0],j[j.length-1]]:j,_=new Map,M=()=>{_.clear();for(let j=0;j{const $=[];for(const F of p){const Y=i(F);w(Y)?(y(F,"active"),$.push(F)):y(F,"inactive")}if(_.set(j,T($,j)),!D)return;const B=()=>{if(!A)return Array.from(_.values());const F=[];for(const[Y,U]of _){const K=O[Y],{name:V}=K.getOptions();V==="x"?F[0]=U:F[1]=U}return F};f.emit("brushAxis:highlight",{nativeEvent:!0,data:{selection:B()}})},P=j=>{for(const D of p)m(D,"active","inactive");M(),j&&f.emit("brushAxis:remove",{nativeEvent:!0})},T=(j,D)=>{const $=O[D],{name:B}=$.getOptions(),F=j.map(Y=>{const U=Y.__data__;return $.invert(U[B])});return S(Vr($,F))},A=v.some(a)&&v.some(j=>!a(j)),k=[];for(let j=0;j{const{nativeEvent:D}=j;D||k.forEach($=>$.remove(!1))},L=(j,D,$)=>{const[B,F]=j,Y=V=>V.getStep?V.getStep():0,U=I(B,D,$),K=I(F,D,$)+Y(D);return a($)?[U,-1/0,K,1/0]:[-1/0,U,1/0,K]},I=(j,D,$)=>{const{height:B,width:F}=d.getOptions(),Y=D.clone();return a($)?Y.update({range:[0,F]}):Y.update({range:[B,0]}),Y.map(j)},R=j=>{const{nativeEvent:D}=j;if(D)return;const{selection:$}=j.data;for(let B=0;B{k.forEach(j=>j.destroy()),f.off("brushAxis:remove",C),f.off("brushAxis:highlight",R)}}function KU(t){return(e,n,r)=>{const{container:i,view:a,options:o}=e,s=jr(i),{x:c,y:l}=s.getBBox(),{coordinate:u}=a;return qU(i,Object.assign({elements:ri,axes:HU,offsetY:l,offsetX:c,points:f=>f.__data__.points,horizontal:f=>{const{startPos:[d,h],endPos:[p,v]}=f.attributes;return d!==p&&h===v},datum:Xi(a),state:Qa(o,["active",["inactive",{opacity:.5}]]),coordinate:u,emitter:r},t))}}var ZU=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},rk=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{const{timeStamp:r}=n;return e!==null&&r-e{if(O)return;const{selection:_}=S;n(_,{nativeEvent:!1})};return s.on("brush:filter",w),()=>{m.destroy(),s.off("brush:filter",w),t.removeEventListener("click",x)}}function Nv(t){var{hideX:e=!0,hideY:n=!0}=t,r=rk(t,["hideX","hideY"]);return(i,a,o)=>{const{container:s,view:c,options:l,update:u,setState:f}=i,d=jr(s),h={maskFill:"#777",maskFillOpacity:"0.3",maskStroke:"#fff",unhighlightedOpacity:.5,reverse:!1};let p=!1,v=!1,g=c;const{scale:y,coordinate:m}=c;return JU(d,Object.assign(Object.assign({brushRegion:(b,x,w,O)=>[b,x,w,O],selection:(b,x,w,O)=>{const{scale:S,coordinate:_}=g;return cl(b,x,w,O,S,_)},filter:(b,x)=>ZU(this,void 0,void 0,function*(){if(v)return;v=!0;const[w,O]=b;f("brushFilter",_=>{const{marks:M}=_,E=M.map(P=>X({axis:Object.assign(Object.assign({},e&&{x:{transform:[{type:"hide"}]}}),n&&{y:{transform:[{type:"hide"}]}})},P,{scale:{x:{domain:w,nice:!1},y:{domain:O,nice:!1}}}));return Object.assign(Object.assign({},l),{marks:E,clip:!0})}),o.emit("brush:filter",Object.assign(Object.assign({},x),{data:{selection:[w,O]}})),g=(yield u()).view,v=!1,p=!0}),reset:b=>{if(v||!p)return;const{scale:x}=c,{x:w,y:O}=x,S=w.getOptions().domain,_=O.getOptions().domain;o.emit("brush:filter",Object.assign(Object.assign({},b),{data:{selection:[S,_]}})),p=!1,g=c,f("brushFilter"),u()},extent:void 0,emitter:o,scale:y,coordinate:m},h),r))}}function tq(t){return Nv(Object.assign(Object.assign({hideX:!0},t),{brushRegion:Tv}))}function eq(t){return Nv(Object.assign(Object.assign({hideY:!0},t),{brushRegion:Cv}))}var nq=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})};const rq="slider";function iq(t,e,n,r=!1,i="x",a="y"){const{marks:o}=t,s=o.map(c=>{var l,u;return X({axis:{x:{transform:[{type:"hide"}]},y:{transform:[{type:"hide"}]}}},c,{scale:e,[n]:Object.assign(Object.assign({},((l=c[n])===null||l===void 0?void 0:l[i])&&{[i]:Object.assign({preserve:!0},r&&{ratio:null})}),((u=c[n])===null||u===void 0?void 0:u[a])&&{[a]:{preserve:!0}}),animate:!1})});return Object.assign(Object.assign({},t),{marks:s,clip:!0,animate:!1})}function aq(t,e,n){const[r,i]=t,a=n?c=>1-c:c=>c,o=Ha(e,a(r),!0),s=Ha(e,a(i),!1);return Vr(e,[o,s])}function Kc(t){return[t[0],t[t.length-1]]}function ik({initDomain:t={},className:e=rq,prefix:n="slider",setValue:r=(l,u)=>l.setValues(u),hasState:i=!1,wait:a=50,leading:o=!0,trailing:s=!1,getInitValues:c=l=>{var u;const f=(u=l==null?void 0:l.attributes)===null||u===void 0?void 0:u.values;if(f[0]!==0||f[1]!==1)return f}}){return(l,u,f)=>{const{container:d,view:h,update:p,setState:v}=l,g=d.getElementsByClassName(e);if(!g.length)return()=>{};let y=!1;const{scale:m,coordinate:b,layout:x}=h,{paddingLeft:w,paddingTop:O,paddingBottom:S,paddingRight:_}=x,{x:M,y:E}=m,P=qt(b),T=L=>{const I=L==="vertical"?"y":"x",R=L==="vertical"?"x":"y";return P?[R,I]:[I,R]},A=new Map,k=new Set,C={x:t.x||M.getOptions().domain,y:t.y||E.getOptions().domain};for(const L of g){const{orientation:I}=L.attributes,[R,j]=T(I),D=`${n}${ii(R)}:filter`,$=R==="x",{ratio:B}=M.getOptions(),{ratio:F}=E.getOptions(),Y=W=>{if(W.data){const{selection:ot}=W.data,[lt=Kc(C.x),xt=Kc(C.y)]=ot;return $?[Vr(M,lt,B),Vr(E,xt,F)]:[Vr(E,xt,F),Vr(M,lt,B)]}const{value:J}=W.detail,et=m[R],it=aq(J,et,P&&I==="horizontal"),ct=C[j];return[it,ct]},U=Ni(W=>nq(this,void 0,void 0,function*(){const{initValue:J=!1}=W;if(y&&!J)return;y=!0;const{nativeEvent:et=!0}=W,[it,ct]=Y(W);if(C[R]=it,C[j]=ct,et){const ot=$?it:ct,lt=$?ct:it;f.emit(D,Object.assign(Object.assign({},W),{nativeEvent:et,data:{selection:[Kc(ot),Kc(lt)]}}))}v(L,ot=>Object.assign(Object.assign({},iq(ot,{[R]:{domain:it,nice:!1}},n,i,R,j)),{paddingLeft:w,paddingTop:O,paddingBottom:S,paddingRight:_})),yield p(),y=!1}),a,{leading:o,trailing:s}),K=W=>{const{nativeEvent:J}=W;if(J)return;const{data:et}=W,{selection:it}=et,[ct,ot]=it;L.dispatchEvent(new Dt("valuechange",{data:et,nativeEvent:!1}));const lt=$?ql(ct,M):ql(ot,E);r(L,lt)};f.on(D,K),L.addEventListener("valuechange",U),A.set(L,U),k.add([D,K]);const V=c(L);V&&L.dispatchEvent(new Dt("valuechange",{detail:{value:V},nativeEvent:!1,initValue:!0}))}return p(),()=>{for(const[L,I]of A)L.removeEventListener("valuechange",I);for(const[L,I]of k)f.off(L,I)}}}const gb="g2-scrollbar";function oq(t={}){return(e,n,r)=>{const{view:i,container:a}=e;if(!a.getElementsByClassName(gb).length)return()=>{};const{scale:s}=i,{x:c,y:l}=s,u={x:[...c.getOptions().domain],y:[...l.getOptions().domain]};return c.update({domain:c.getOptions().expectedDomain}),l.update({domain:l.getOptions().expectedDomain}),ik(Object.assign(Object.assign({},t),{initDomain:u,className:gb,prefix:"scrollbar",hasState:!0,setValue:(d,h)=>d.setValue(h[0]),getInitValues:d=>{const h=d.slider.attributes.values;if(h[0]!==0)return h}}))(e,n,r)}}var sq=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i${e}`}const lq={backgroundColor:"rgba(0,0,0,0.75)",color:"#fff",width:"max-content",padding:"1px 4px",fontSize:"12px",borderRadius:"2.5px",boxShadow:"0 3px 6px -4px rgba(0,0,0,0.12), 0 6px 16px 0 rgba(0,0,0,0.08), 0 9px 28px 8px rgba(0,0,0,0.05)"};function yb(t){return t.nodeName!=="text"?!1:!!t.isOverflowing()}function ak(t){var{offsetX:e=8,offsetY:n=8}=t,r=sq(t,["offsetX","offsetY"]);return i=>{const{container:a}=i,[o,s]=a.getBounds().min,c=Q(r,"tip"),l=new Set,u=d=>{const{target:h}=d;if(!yb(h)){d.stopPropagation();return}const{offsetX:p,offsetY:v}=d,g=p+e-o,y=v+n-s;if(h.tip){h.tip.style.x=g,h.tip.style.y=y;return}const{text:m}=h.style,b=new Bu({className:"poptip",style:{innerHTML:cq("div",m,Object.assign(Object.assign({},lq),c)),x:g,y}});a.appendChild(b),h.tip=b,l.add(b)},f=d=>{const{target:h}=d;if(!yb(h)){d.stopPropagation();return}h.tip&&(h.tip.remove(),h.tip=null,l.delete(h.tip))};return a.addEventListener("pointerover",u),a.addEventListener("pointerout",f),()=>{a.removeEventListener("pointerover",u),a.removeEventListener("pointerout",f),l.forEach(d=>d.remove())}}}ak.props={reapplyWhenUpdate:!0};var uq=function(t,e,n,r){function i(a){return a instanceof n?a:new n(function(o){o(a)})}return new(n||(n=Promise))(function(a,o){function s(u){try{l(r.next(u))}catch(f){o(f)}}function c(u){try{l(r.throw(u))}catch(f){o(f)}}function l(u){u.done?a(u.value):i(u.value).then(s,c)}l((r=r.apply(t,e||[])).next())})},fq=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);it.querySelectorAll(".element");function hq(t){return st(t).select(`.${Kl}`).node()}const pq={breadCrumbFill:"rgba(0, 0, 0, 0.85)",breadCrumbFontSize:12,breadCrumbY:12,activeFill:"rgba(0, 0, 0, 0.5)"};function vq(t={}){const{originData:e=[],layout:n}=t,r=fq(t,["originData","layout"]),i=X({},pq,r),a=Q(i,"breadCrumb"),o=Q(i,"active");return s=>{const{update:c,setState:l,container:u,options:f}=s,d=hq(u),h=f.marks[0],{state:p}=h,v=new Ce;d.appendChild(v);const g=(x,w)=>uq(this,void 0,void 0,function*(){if(v.removeChildren(),w){let O="",S=a.y,_=0;const M=[],E=d.getBBox().width,P=x.map((T,A)=>{O=`${O}${T}/`,M.push(T);const k=new ei({name:O.replace(/\/$/,""),style:Object.assign(Object.assign({text:T,x:_,path:[...M],depth:A},a),{y:S})});v.appendChild(k),_+=k.getBBox().width;const C=new ei({style:Object.assign(Object.assign({x:_,text:" / "},a),{y:S})});return v.appendChild(C),_+=C.getBBox().width,_>E&&(S=v.getBBox().height+a.y,_=0,k.attr({x:_,y:S}),_+=k.getBBox().width,C.attr({x:_,y:S}),_+=C.getBBox().width),A===Uv(x)-1&&C.remove(),k});P.forEach((T,A)=>{if(A===Uv(P)-1)return;const k=Object.assign({},T.attributes);T.attr("cursor","pointer"),T.addEventListener("mouseenter",()=>{T.attr(o)}),T.addEventListener("mouseleave",()=>{T.attr(k)}),T.addEventListener("click",()=>{g(je(T,["style","path"]),je(T,["style","depth"]))})})}kU(u,l),l("treemapDrillDown",O=>{const{marks:S}=O,_=x.join("/"),M=S.map(E=>{if(E.type!=="rect")return E;let P=e;if(w){const A=e.filter(R=>{const j=je(R,["id"]);return j&&(j.match(`${_}/`)||_.match(j))}).map(R=>({value:R.height===0?je(R,["value"]):void 0,name:je(R,["id"])})),{paddingLeft:k,paddingBottom:C,paddingRight:L}=n,I=Object.assign(Object.assign({},n),{paddingTop:(n.paddingTop||v.getBBox().height+10)/(w+1),paddingLeft:k/(w+1),paddingBottom:C/(w+1),paddingRight:L/(w+1),path:R=>R.name,layer:R=>R.depth===w+1});P=G_(A,I,{value:"value"})[0]}else P=e.filter(A=>A.depth===1);const T=[];return P.forEach(({path:A})=>{T.push(Ns(A))}),X({},E,{data:P,scale:{color:{domain:T}}})});return Object.assign(Object.assign({},O),{marks:M})}),yield c(void 0,["legendFilter"])}),y=x=>{const w=x.target;if(je(w,["markType"])!=="rect")return;const O=je(w,["__data__","key"]),S=Vv(e,_=>_.id===O);je(S,"height")&&g(je(S,"path"),je(S,"depth"))};d.addEventListener("click",y);const m=Rb(Object.assign(Object.assign({},p.active),p.inactive)),b=()=>{dq(d).forEach(w=>{const O=je(w,["style","cursor"]),S=Vv(e,_=>_.id===je(w,["__data__","key"]));if(O!=="pointer"&&(S!=null&&S.height)){w.style.cursor="pointer";const _=Fk(w.attributes,m);w.addEventListener("mouseenter",()=>{w.attr(p.active)}),w.addEventListener("mouseleave",()=>{w.attr(X(_,p.inactive))})}})};return b(),d.addEventListener("mousemove",b),()=>{v.remove(),d.removeEventListener("click",y),d.removeEventListener("mousemove",b)}}}function ep(t){const{min:e,max:n}=t;return[[e[0],e[1]],[n[0],n[1]]]}function mb(t,e){const[n,r]=t,[i,a]=e;return n>=i[0]&&n<=a[0]&&r>=i[1]&&r<=a[1]}function gq(t,e){const[n,r]=t;return!(mb(n,e)&&mb(r,e))}function yq(t,e){const[n,r]=t,[i,a]=e;return n[0]i[0]&&n[1]i[1]}const mq=t=>{const{priority:e}=t;return n=>{const r=[];return e&&n.sort(e),n.forEach(i=>{Ov(i);const a=i.getLocalBounds();r.some(s=>yq(ep(a),ep(s.getLocalBounds())))?wv(i):r.push(i)}),n}};function bq([t,e],[n,r]){return r>t&&e>n}function Zc(){const t=new Map;return[r=>t.get(r),(r,i)=>t.set(r,i)]}function xq(t){const e=t.cloneNode(!0),n=e.getElementById("connector");n&&e.removeChild(n);const{min:r,max:i}=e.getRenderBounds();return e.destroy(),{min:r,max:i}}const wq=t=>{const{maxIterations:e=10,maxError:n=.1,padding:r=1}=t;return i=>{const a=i.length;if(a<=1)return i;const[o,s]=Zc(),[c,l]=Zc(),[u,f]=Zc(),[d,h]=Zc();for(const p of i){const{min:v,max:g}=xq(p),[y,m]=v,[b,x]=g;s(p,m),l(p,m),f(p,x-m),h(p,[y,b])}for(let p=0;poe(c(g),c(y)));let v=0;for(let g=0;gok(t,Oq(r)));return e[n]}const _q=t=>{const{threshold:e=4.5,palette:n=["#000","#fff"]}=t;return r=>(r.forEach(i=>{const a=i.attr("dependentElement").parsedStyle.fill,o=i.parsedStyle.fill;ok(o,a)t=>(t.forEach(e=>{Ov(e);const n=e.attr("bounds"),r=e.getLocalBounds();gq(ep(r),n)&&wv(e)}),t);function Eq(){return{"data.fetch":cM,"data.inline":vM,"data.sortBy":pM,"data.sort":fM,"data.filter":uM,"data.pick":dM,"data.rename":hM,"data.fold":lM,"data.slice":wM,"data.custom":gM,"data.map":yM,"data.join":xM,"data.kde":_M,"data.log":CM,"transform.stackY":Sx,"transform.binX":G2,"transform.bin":Tp,"transform.dodgeX":Rx,"transform.jitter":_2,"transform.jitterX":M2,"transform.jitterY":E2,"transform.symmetryY":P2,"transform.diffY":A2,"transform.stackEnter":Ix,"transform.normalizeY":jx,"transform.select":ku,"transform.selectX":k2,"transform.selectY":T2,"transform.groupX":C2,"transform.groupY":L2,"transform.groupColor":N2,"transform.group":Gs,"transform.sortX":I2,"transform.sortY":D2,"transform.sortColor":j2,"transform.flexX":$2,"transform.pack":z2,"transform.sample":Y2,"transform.filter":W2,"coordinate.cartesian":_b,"coordinate.polar":Cs,"coordinate.transpose":ap,"coordinate.theta":Eb,"coordinate.parallel":sp,"coordinate.fisheye":Ab,"coordinate.radial":op,"coordinate.radar":kb,"encode.constant":Tb,"encode.field":Lb,"encode.transform":Cb,"encode.column":Nb,"mark.interval":f_,"mark.rect":d_,"mark.line":h_,"mark.point":p_,"mark.text":v_,"mark.cell":g_,"mark.area":y_,"mark.link":P0,"mark.image":m_,"mark.polygon":b_,"mark.box":x_,"mark.vector":w_,"mark.lineX":S_,"mark.lineY":O_,"mark.connector":__,"mark.range":M_,"mark.rangeX":E_,"mark.rangeY":P_,"mark.path":L_,"mark.shape":U_,"mark.density":RM,"mark.heatmap":IM,"palette.category10":DM,"palette.category20":$M,"scale.linear":FM,"scale.ordinal":zM,"scale.band":BM,"scale.identity":GM,"scale.point":YM,"scale.time":WM,"scale.log":HM,"scale.pow":VM,"scale.sqrt":KM,"scale.threshold":XM,"scale.quantile":UM,"scale.quantize":qM,"scale.sequential":ZM,"scale.constant":QM,"theme.classic":JM,"theme.classicDark":eE,"theme.academy":nE,"theme.light":I0,"theme.dark":tE,"component.axisX":hE,"component.axisY":pE,"component.legendCategory":D0,"component.legendContinuous":hi,"component.legends":SE,"component.title":mE,"component.sliderX":bE,"component.sliderY":xE,"component.scrollbarX":wE,"component.scrollbarY":OE,"animation.scaleInX":B0,"animation.scaleOutX":tz,"animation.scaleInY":_E,"animation.scaleOutY":ez,"animation.waveIn":kE,"animation.fadeIn":ME,"animation.fadeOut":EE,"animation.zoomIn":uz,"animation.zoomOut":fz,"animation.pathIn":TE,"animation.morphing":AE,"animation.growInX":CE,"animation.growInY":LE,"interaction.elementHighlight":pf,"interaction.elementHighlightByX":DA,"interaction.elementHighlightByColor":$A,"interaction.elementSelect":vf,"interaction.elementSelectByX":BA,"interaction.elementSelectByColor":FA,"interaction.fisheye":vU,"interaction.chartIndex":zA,"interaction.tooltip":XA,"interaction.legendFilter":NU,"interaction.legendHighlight":RU,"interaction.brushHighlight":kv,"interaction.brushXHighlight":FU,"interaction.brushYHighlight":zU,"interaction.brushAxisHighlight":KU,"interaction.brushFilter":Nv,"interaction.brushXFilter":tq,"interaction.brushYFilter":eq,"interaction.sliderFilter":ik,"interaction.scrollbarFilter":oq,"interaction.poptip":ak,"interaction.treemapDrillDown":vq,"composition.spaceLayer":UE,"composition.spaceFlex":qE,"composition.facetRect":tP,"composition.repeatMatrix":oY,"composition.facetCircle":dY,"composition.timingKeyframe":eP,"labelTransform.overlapHide":mq,"labelTransform.overlapDodgeY":wq,"labelTransform.overflowHide":Mq,"labelTransform.contrastReverse":_q}}function Pq(){return{"composition.geoView":TP,"composition.geoPath":nP}}function Aq(){return{"data.arc":k0,"data.cluster":iM,"mark.forceGraph":nM,"mark.tree":oM,"mark.pack":W_,"mark.sankey":T_,"mark.chord":C_,"mark.treemap":Y_}}function kq(){return{"data.venn":TM,"mark.boxplot":X_,"mark.gauge":NM,"mark.wordCloud":LM,"mark.liquid":jM}}function Tq(){return Object.assign(Object.assign(Object.assign(Object.assign({},Pq()),Aq()),kq()),Eq())}function Cq(t,e){class n extends t{constructor(i){super(Object.assign(Object.assign({},i),{lib:e}))}}return n}const Lq={},ca=t=>t?parseInt(t):0;function Nq(t){const e=getComputedStyle(t),n=t.clientWidth||ca(e.width),r=t.clientHeight||ca(e.height),i=ca(e.paddingLeft)+ca(e.paddingRight),a=ca(e.paddingTop)+ca(e.paddingBottom);return{width:n-i,height:r-a}}function Ed(t,e){const n=[t];for(;n.length;){const r=n.shift();e&&e(r);const i=r.children||[];for(const a of i)n.push(a)}}class Rv{constructor(e={},n){this.parentNode=null,this.children=[],this.index=0,this.type=n,this.value=e}map(e=n=>n){const n=e(this.value);return this.value=n,this}attr(e,n){return arguments.length===1?this.value[e]:this.map(r=>(r[e]=n,r))}append(e){const n=new e({});return n.children=[],this.push(n),n}push(e){return e.parentNode=this,e.index=this.children.length,this.children.push(e),this}remove(){const e=this.parentNode;if(e){const{children:n}=e,r=n.findIndex(i=>i===this);n.splice(r,1)}return this}getNodeByKey(e){let n=null;return Ed(this,i=>{e===i.attr("key")&&(n=i)}),n}getNodesByType(e){const n=[];return Ed(this,i=>{e===i.type&&n.push(i)}),n}getNodeByType(e){let n=null;return Ed(this,r=>{n||e===r.type&&(n=r)}),n}call(e,...n){return e(this.map(),...n),this}getRoot(){let e=this;for(;e&&e.parentNode;)e=e.parentNode;return e}}var sk=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{e=r,t=i}),e,t]}function Xq(t,e,{key:n=e}){t.prototype[e]=function(r){return arguments.length===0?this.attr(n):this.attr(n,r)}}function Uq(t,e,{key:n=e}){t.prototype[e]=function(r){if(arguments.length===0)return this.attr(n);if(Array.isArray(r))return this.attr(n,r);const i=[...this.attr(n)||[],r];return this.attr(n,i)}}function qq(t,e,{key:n=e}){t.prototype[e]=function(r,i){if(arguments.length===0)return this.attr(n);if(arguments.length===1&&typeof r!="string")return this.attr(n,r);const a=this.attr(n)||{};return a[r]=arguments.length===1?!0:i,this.attr(n,a)}}function Kq(t,e,n){t.prototype[e]=function(r){if(arguments.length===0)return this.attr(e);if(Array.isArray(r))return this.attr(e,{items:r});if(is(r)&&(r.title!==void 0||r.items!==void 0))return this.attr(e,r);if(r===null||r===!1)return this.attr(e,r);const i=this.attr(e)||{},{items:a=[]}=i;return a.push(r),i.items=a,this.attr(e,i)}}function Zq(t,e,{ctor:n}){t.prototype[e]=function(r){const i=this.append(n);return e==="mark"&&(i.type=r),i}}function Qq(t,e,{ctor:n}){t.prototype[e]=function(){return this.type=null,this.append(n)}}function vu(t){return e=>{for(const[n,r]of Object.entries(t)){const{type:i}=r;i==="value"?Xq(e,n,r):i==="array"?Uq(e,n,r):i==="object"?qq(e,n,r):i==="node"?Zq(e,n,r):i==="container"?Qq(e,n,r):i==="mix"&&Kq(e,n)}return e}}function Sb(t){return Object.fromEntries(Object.entries(t).map(([e,n])=>[e,{type:"node",ctor:n}]))}const uk={encode:{type:"object"},scale:{type:"object"},data:{type:"value"},transform:{type:"array"},style:{type:"object"},animate:{type:"object"},coordinate:{type:"object"},interaction:{type:"object"},label:{type:"array",key:"labels"},axis:{type:"object"},legend:{type:"object"},slider:{type:"object"},scrollbar:{type:"object"},state:{type:"object"},layout:{type:"object"},theme:{type:"object"},title:{type:"value"}},Jq=Object.assign(Object.assign({},uk),{tooltip:{type:"mix"},viewStyle:{type:"object"}}),tK=Object.assign(Object.assign({},uk),{labelTransform:{type:"array"}});var eK=function(t,e,n,r){var i=arguments.length,a=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,n):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(t,e,n,r);else for(var s=t.length-1;s>=0;s--)(o=t[s])&&(a=(i<3?o(a):i>3?o(e,n,a):o(e,n))||a);return i>3&&a&&Object.defineProperty(e,n,a),a};let gu=class extends Rv{changeData(e){var n;const r=this.getRoot();if(r)return this.attr("data",e),!((n=this.children)===null||n===void 0)&&n.length&&this.children.forEach(i=>{i.attr("data",e)}),r==null?void 0:r.render()}getView(){const e=this.getRoot(),{views:n}=e.getContext();if(n!=null&&n.length)return n.find(r=>r.key===this._key)}getScale(){var e;return(e=this.getView())===null||e===void 0?void 0:e.scale}getScaleByChannel(e){const n=this.getScale();if(n)return n[e]}getCoordinate(){var e;return(e=this.getView())===null||e===void 0?void 0:e.coordinate}getTheme(){var e;return(e=this.getView())===null||e===void 0?void 0:e.theme}getGroup(){const e=this._key;return e?this.getRoot().getContext().canvas.getRoot().getElementById(e):void 0}show(){const e=this.getGroup();e&&!e.isVisible()&&Ov(e)}hide(){const e=this.getGroup();e&&e.isVisible()&&wv(e)}};gu=eK([vu(tK)],gu);var nK=function(t,e,n,r){var i=arguments.length,a=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,n):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(t,e,n,r);else for(var s=t.length-1;s>=0;s--)(o=t[s])&&(a=(i<3?o(a):i>3?o(e,n,a):o(e,n))||a);return i>3&&a&&Object.defineProperty(e,n,a),a};let rp=class extends Rv{changeData(e){const n=this.getRoot();if(n)return this.attr("data",e),n==null?void 0:n.render()}getMark(){var e;const n=(e=this.getRoot())===null||e===void 0?void 0:e.getView();if(!n)return;const{markState:r}=n,i=Array.from(r.keys()).find(a=>a.key===this.attr("key"));return r.get(i)}getScale(){var e;const n=(e=this.getRoot())===null||e===void 0?void 0:e.getView();if(n)return n==null?void 0:n.scale}getScaleByChannel(e){var n,r;const i=(n=this.getRoot())===null||n===void 0?void 0:n.getView();if(i)return(r=i==null?void 0:i.scale)===null||r===void 0?void 0:r[e]}getGroup(){const e=this.attr("key");return e?this.getRoot().getContext().canvas.getRoot().getElementById(e):void 0}};rp=nK([vu(Jq)],rp);var rK=function(t,e,n,r){var i=arguments.length,a=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,n):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(t,e,n,r);else for(var s=t.length-1;s>=0;s--)(o=t[s])&&(a=(i<3?o(a):i>3?o(e,n,a):o(e,n))||a);return i>3&&a&&Object.defineProperty(e,n,a),a},iK=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,r=Object.getOwnPropertySymbols(t);i{this.forceFit()},300),this._renderer=i||new IE,this._plugins=a||[],this._container=Rq(n),this._emitter=new DE,this._context={library:Object.assign(Object.assign({},o),Lq),emitter:this._emitter,canvas:r},this._create()}render(){if(this._rendering)return this._addToTrailing();this._context.canvas||this._createCanvas(),this._context.canvas.getConfig().supportsCSSTransform=!0,this._bindAutoFit(),this._rendering=!0;const e=new Promise((a,o)=>QX(this._computedOptions(),this._context,this._createResolve(a),this._createReject(o))),[n,r,i]=Vq();return e.then(r).catch(i).then(()=>this._renderTrailing()),n}options(e){if(arguments.length===0)return Dq(this);const{type:n}=e;return n&&(this._previousDefinedType=n),Hq(this,e,this._previousDefinedType,this._marks,this._compositions),this}getContainer(){return this._container}getContext(){return this._context}on(e,n,r){return this._emitter.on(e,n,r),this}once(e,n){return this._emitter.once(e,n),this}emit(e,...n){return this._emitter.emit(e,...n),this}off(e,n){return this._emitter.off(e,n),this}clear(){const e=this.options();this.emit(Lt.BEFORE_CLEAR),this._reset(),cb(e,this._context,!1),this.emit(Lt.AFTER_CLEAR)}destroy(){const e=this.options();this.emit(Lt.BEFORE_DESTROY),this._unbindAutoFit(),this._reset(),cb(e,this._context,!0),this._container[ck]&&Iq(this._container),this.emit(Lt.AFTER_DESTROY)}forceFit(){this.options.autoFit=!0;const{width:e,height:n}=Pd(this.options(),this._container);if(e===this._width&&n===this._height)return Promise.resolve(this);this.emit(Lt.BEFORE_CHANGE_SIZE);const r=this.render();return r.then(()=>{this.emit(Lt.AFTER_CHANGE_SIZE)}),r}changeSize(e,n){if(e===this._width&&n===this._height)return Promise.resolve(this);this.emit(Lt.BEFORE_CHANGE_SIZE),this.attr("width",e),this.attr("height",n);const r=this.render();return r.then(()=>{this.emit(Lt.AFTER_CHANGE_SIZE)}),r}_create(){const{library:e}=this._context,n=a=>a.startsWith("mark.")||a==="component.axisX"||a==="component.axisY"||a==="component.legends",r=["mark.mark",...Object.keys(e).filter(n)];this._marks={};for(const a of r){const o=a.split(".").pop();class s extends rp{constructor(){super({},o)}}this._marks[o]=s,this[o]=function(c){const l=this.append(s);return o==="mark"&&(l.type=c),l}}const i=["composition.view",...Object.keys(e).filter(a=>a.startsWith("composition.")&&a!=="composition.mark")];this._compositions=Object.fromEntries(i.map(a=>{const o=a.split(".").pop();let s=class extends gu{constructor(){super({},o)}};return s=rK([vu(Sb(this._marks))],s),[o,s]}));for(const a of Object.values(this._compositions))vu(Sb(this._compositions))(a);for(const a of i){const o=a.split(".").pop();this[o]=function(){const s=this._compositions[o];return this.type=null,this.append(s)}}}_reset(){const e=["theme","type","width","height","autoFit"];this.type="view",this.value=Object.fromEntries(Object.entries(this.value).filter(([n])=>n.startsWith("margin")||n.startsWith("padding")||n.startsWith("inset")||e.includes(n))),this.children=[]}_renderTrailing(){this._trailing&&(this._trailing=!1,this.render().then(()=>{const e=this._trailingResolve.bind(this);this._trailingResolve=null,e(this)}).catch(e=>{const n=this._trailingReject.bind(this);this._trailingReject=null,n(e)}))}_createResolve(e){return()=>{this._rendering=!1,e(this)}}_createReject(e){return n=>{this._rendering=!1,e(n)}}_computedOptions(){const e=this.options(),{key:n=aK}=e,{width:r,height:i,depth:a}=Pd(e,this._container);return this._width=r,this._height=i,this._key=n,Object.assign(Object.assign({key:this._key},e),{width:r,height:i,depth:a})}_createCanvas(){const{width:e,height:n}=Pd(this.options(),this._container);this._plugins.push(new jE),this._plugins.forEach(r=>this._renderer.registerPlugin(r)),this._context.canvas=new Hw({container:this._container,width:e,height:n,renderer:this._renderer})}_addToTrailing(){var e;return(e=this._trailingResolve)===null||e===void 0||e.call(this,this),this._trailing=!0,new Promise((r,i)=>{this._trailingResolve=r,this._trailingReject=i})}_bindAutoFit(){const e=this.options(),{autoFit:n}=e;if(this._hasBindAutoFit){n||this._unbindAutoFit();return}n&&(this._hasBindAutoFit=!0,window.addEventListener("resize",this._onResize))}_unbindAutoFit(){this._hasBindAutoFit&&(this._hasBindAutoFit=!1,window.removeEventListener("resize",this._onResize))}}H.enableCSSParsing=!1;const sK=Object.assign({},Tq()),Ad=Cq(oK,sK),Iv=t=>(bk("data-v-a6d34c3f"),t=t(),xk(),t),cK={class:"__container_home_index"},lK={class:"statistic-icon-big"},uK=Iv(()=>Qo("div",{id:"releases_container"},null,-1)),fK=Iv(()=>Qo("div",{id:"protocols_container"},null,-1)),dK=Iv(()=>Qo("div",{id:"discoveries_container"},null,-1)),hK=vk({__name:"index",setup(t){gk(i=>({a8c0aff4:yi(Fv)+"22",db6f68ac:yi(Fv)}));const e=yk().name;let n=Bv({info:{},report:{}}),r=Bv({info:{}});return mk(()=>{setTimeout(async()=>{let i=(await Ok({})).data;r.info=(await Sk({})).data,n.info=i,n.report={application:{icon:"cil:applications-settings",value:n.info.appCount},services:{icon:"carbon:microservices-1",value:n.info.serviceCount},instances:{icon:"ri:instance-line",value:n.info.insCount}};const a=[],o=Object.values(n.info.releases).reduce((p,v)=>p+v,0);typeof n.info.releases=="object"&&Object.keys(n.info.releases).forEach(p=>{const v=n.info.releases[p];a.push({item:p,count:v,percent:v/o})});const s=new Ad({container:"releases_container",width:200,height:200,autoFit:!1});s.coordinate({type:"theta",outerRadius:.8,innerRadius:.5}),s.interval().data(a).transform({type:"stackY"}).encode("y","percent").encode("color","item").legend("color",{position:"bottom",layout:{justifyContent:"center"}}).label({position:"outside",text:p=>`${p.item}: ${(p.percent*100).toFixed(2)}%`}).tooltip(p=>({name:p.item,value:`${(p.percent*100).toFixed(2)}%`})),s.text().style("text","版本分布").style("x","50%").style("y","50%").style("fontSize",10).style("fill","#8c8c8c").style("textAlign","center").style("textBaseline","middle"),await s.render();const c=[],l=Object.values(n.info.protocols).reduce((p,v)=>p+v,0);typeof n.info.protocols=="object"&&Object.keys(n.info.protocols).forEach(p=>{const v=n.info.protocols[p];c.push({item:p,count:v,percent:v/l})});const u=new Ad({container:"protocols_container",width:200,height:200,autoFit:!1});u.coordinate({type:"theta",outerRadius:.8,innerRadius:.5}),u.interval().data(c).transform({type:"stackY"}).encode("y","percent").encode("color","item").legend("color",{position:"bottom",layout:{justifyContent:"center"}}).label({position:"outside",text:p=>`${p.item}: ${(p.percent*100).toFixed(2)}%`}).tooltip(p=>({name:p.item,value:`${(p.percent*100).toFixed(2)}%`})),u.text().style("text","协议分布").style("x","50%").style("y","50%").style("fontSize",10).style("fill","#8c8c8c").style("textAlign","center").style("textBaseline","middle"),await u.render();const f=[],d=Object.values(n.info.discoveries).reduce((p,v)=>p+v,0);typeof n.info.discoveries=="object"&&Object.keys(n.info.discoveries).forEach(p=>{const v=n.info.discoveries[p];f.push({item:p,count:v,percent:v/d})});const h=new Ad({container:"discoveries_container",width:200,height:200,autoFit:!1});h.coordinate({type:"theta",outerRadius:.8,innerRadius:.5}),h.interval().data(f).transform({type:"stackY"}).encode("y","percent").encode("color","item").legend("color",{position:"bottom",layout:{justifyContent:"center"}}).label({position:"outside",text:p=>`${p.item}: ${(p.percent*100).toFixed(2)}%`}).tooltip(p=>({name:p.item,value:`${(p.percent*100).toFixed(2)}%`})),h.text().style("text","服务发现类型分布").style("x","50%").style("y","50%").style("fontSize",10).style("fill","#8c8c8c").style("textAlign","center").style("textBaseline","middle"),await h.render()})}),(i,a)=>{const o=ho("a-statistic"),s=ho("a-flex"),c=ho("a-card"),l=ho("a-descriptions-item"),u=ho("a-descriptions");return po(),bf("div",cK,[Qo("h1",null,xf(i.$t(yi(e))),1),Fn(s,{wrap:"wrap",gap:"small",vertical:!1,justify:"space-between",align:"center"},{default:On(()=>[(po(!0),bf(zv,null,Gv(yi(n).report,(f,d)=>(po(),Yv(c,{class:"statistic-card"},{default:On(()=>[Fn(s,{gap:"middle",vertical:!1,justify:"space-between",align:"center"},{default:On(()=>[Fn(o,{value:f.value,class:"statistic"},{prefix:On(()=>[Fn(yi(Wv),{class:"statistic-icon",icon:"svg-spinners:pulse-ring"})]),title:On(()=>[Hv(xf(i.$t(d.toString())),1)]),_:2},1032,["value"]),Qo("div",lK,[Fn(yi(Wv),{icon:f.icon},null,8,["icon"])])]),_:2},1024)]),_:2},1024))),256))]),_:1}),Fn(s,{wrap:"wrap",gap:"middle",vertical:!1,justify:"space-between",align:"center"},{default:On(()=>[Fn(c,{class:"card chart"},{default:On(()=>[uK]),_:1}),Fn(c,{class:"card chart"},{default:On(()=>[fK]),_:1}),Fn(c,{class:"card chart"},{default:On(()=>[dK]),_:1})]),_:1}),Fn(c,{class:"card"},{default:On(()=>[Fn(u,{title:" ",bordered:"",column:{xxl:2,xl:2,lg:2,md:2,sm:1,xs:1},layout:"horizontal"},{default:On(()=>[(po(!0),bf(zv,null,Gv(yi(r).info,(f,d)=>(po(),Yv(l,{label:d},{default:On(()=>[Hv(xf(f),1)]),_:2},1032,["label"]))),256))]),_:1})]),_:1})])}}}),_K=wk(hK,[["__scopeId","data-v-a6d34c3f"]]);export{_K as default}; diff --git a/app/dubbo-ui/dist/admin/assets/index-frGZziTc.css b/app/dubbo-ui/dist/admin/assets/index-frGZziTc.css deleted file mode 100644 index 20083a836..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-frGZziTc.css +++ /dev/null @@ -1 +0,0 @@ -.routing-rule-container[data-v-142b26f8],.routing-rule-container .search-table-container[data-v-142b26f8]{height:100%}.routing-rule-container .search-table-container .rule-link[data-v-142b26f8]{padding:4px 10px 4px 4px;border-radius:4px;color:var(--5abc36e7)}.routing-rule-container .search-table-container .rule-link[data-v-142b26f8]:hover{cursor:pointer;background:#85838321} diff --git a/app/dubbo-ui/dist/admin/assets/index-hmLAZQYT.js b/app/dubbo-ui/dist/admin/assets/index-hmLAZQYT.js deleted file mode 100644 index a675c8390..000000000 --- a/app/dubbo-ui/dist/admin/assets/index-hmLAZQYT.js +++ /dev/null @@ -1,573 +0,0 @@ -(function(){const Cn=document.createElement("link").relList;if(Cn&&Cn.supports&&Cn.supports("modulepreload"))return;for(const In of document.querySelectorAll('link[rel="modulepreload"]'))Pn(In);new MutationObserver(In=>{for(const Nn of In)if(Nn.type==="childList")for(const Rn of Nn.addedNodes)Rn.tagName==="LINK"&&Rn.rel==="modulepreload"&&Pn(Rn)}).observe(document,{childList:!0,subtree:!0});function _n(In){const Nn={};return In.integrity&&(Nn.integrity=In.integrity),In.referrerPolicy&&(Nn.referrerPolicy=In.referrerPolicy),In.crossOrigin==="use-credentials"?Nn.credentials="include":In.crossOrigin==="anonymous"?Nn.credentials="omit":Nn.credentials="same-origin",Nn}function Pn(In){if(In.ep)return;In.ep=!0;const Nn=_n(In);fetch(In.href,Nn)}})();/** -* @vue/shared v3.4.15 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function makeMap($n,Cn){const _n=new Set($n.split(","));return Cn?Pn=>_n.has(Pn.toLowerCase()):Pn=>_n.has(Pn)}const EMPTY_OBJ={},EMPTY_ARR=[],NOOP=()=>{},NO=()=>!1,isOn$1=$n=>$n.charCodeAt(0)===111&&$n.charCodeAt(1)===110&&($n.charCodeAt(2)>122||$n.charCodeAt(2)<97),isModelListener=$n=>$n.startsWith("onUpdate:"),extend=Object.assign,remove=($n,Cn)=>{const _n=$n.indexOf(Cn);_n>-1&&$n.splice(_n,1)},hasOwnProperty$h=Object.prototype.hasOwnProperty,hasOwn$2=($n,Cn)=>hasOwnProperty$h.call($n,Cn),isArray$4=Array.isArray,isMap$1=$n=>toTypeString$1($n)==="[object Map]",isSet$1=$n=>toTypeString$1($n)==="[object Set]",isFunction$3=$n=>typeof $n=="function",isString$4=$n=>typeof $n=="string",isSymbol$1=$n=>typeof $n=="symbol",isObject$7=$n=>$n!==null&&typeof $n=="object",isPromise$1=$n=>(isObject$7($n)||isFunction$3($n))&&isFunction$3($n.then)&&isFunction$3($n.catch),objectToString$2=Object.prototype.toString,toTypeString$1=$n=>objectToString$2.call($n),toRawType=$n=>toTypeString$1($n).slice(8,-1),isPlainObject$3=$n=>toTypeString$1($n)==="[object Object]",isIntegerKey=$n=>isString$4($n)&&$n!=="NaN"&&$n[0]!=="-"&&""+parseInt($n,10)===$n,isReservedProp=makeMap(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),cacheStringFunction$1=$n=>{const Cn=Object.create(null);return _n=>Cn[_n]||(Cn[_n]=$n(_n))},camelizeRE$1=/-(\w)/g,camelize$1=cacheStringFunction$1($n=>$n.replace(camelizeRE$1,(Cn,_n)=>_n?_n.toUpperCase():"")),hyphenateRE$1=/\B([A-Z])/g,hyphenate$1=cacheStringFunction$1($n=>$n.replace(hyphenateRE$1,"-$1").toLowerCase()),capitalize$2=cacheStringFunction$1($n=>$n.charAt(0).toUpperCase()+$n.slice(1)),toHandlerKey=cacheStringFunction$1($n=>$n?`on${capitalize$2($n)}`:""),hasChanged=($n,Cn)=>!Object.is($n,Cn),invokeArrayFns=($n,Cn)=>{for(let _n=0;_n<$n.length;_n++)$n[_n](Cn)},def=($n,Cn,_n)=>{Object.defineProperty($n,Cn,{configurable:!0,enumerable:!1,value:_n})},looseToNumber=$n=>{const Cn=parseFloat($n);return isNaN(Cn)?$n:Cn},toNumber$1=$n=>{const Cn=isString$4($n)?Number($n):NaN;return isNaN(Cn)?$n:Cn};let _globalThis$1;const getGlobalThis$1=()=>_globalThis$1||(_globalThis$1=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function normalizeStyle$1($n){if(isArray$4($n)){const Cn={};for(let _n=0;_n<$n.length;_n++){const Pn=$n[_n],In=isString$4(Pn)?parseStringStyle(Pn):normalizeStyle$1(Pn);if(In)for(const Nn in In)Cn[Nn]=In[Nn]}return Cn}else if(isString$4($n)||isObject$7($n))return $n}const listDelimiterRE=/;(?![^(]*\))/g,propertyDelimiterRE=/:([^]+)/,styleCommentRE=/\/\*[^]*?\*\//g;function parseStringStyle($n){const Cn={};return $n.replace(styleCommentRE,"").split(listDelimiterRE).forEach(_n=>{if(_n){const Pn=_n.split(propertyDelimiterRE);Pn.length>1&&(Cn[Pn[0].trim()]=Pn[1].trim())}}),Cn}function normalizeClass($n){let Cn="";if(isString$4($n))Cn=$n;else if(isArray$4($n))for(let _n=0;_n<$n.length;_n++){const Pn=normalizeClass($n[_n]);Pn&&(Cn+=Pn+" ")}else if(isObject$7($n))for(const _n in $n)$n[_n]&&(Cn+=_n+" ");return Cn.trim()}const specialBooleanAttrs="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",isSpecialBooleanAttr=makeMap(specialBooleanAttrs);function includeBooleanAttr($n){return!!$n||$n===""}const toDisplayString$1=$n=>isString$4($n)?$n:$n==null?"":isArray$4($n)||isObject$7($n)&&($n.toString===objectToString$2||!isFunction$3($n.toString))?JSON.stringify($n,replacer,2):String($n),replacer=($n,Cn)=>Cn&&Cn.__v_isRef?replacer($n,Cn.value):isMap$1(Cn)?{[`Map(${Cn.size})`]:[...Cn.entries()].reduce((_n,[Pn,In],Nn)=>(_n[stringifySymbol(Pn,Nn)+" =>"]=In,_n),{})}:isSet$1(Cn)?{[`Set(${Cn.size})`]:[...Cn.values()].map(_n=>stringifySymbol(_n))}:isSymbol$1(Cn)?stringifySymbol(Cn):isObject$7(Cn)&&!isArray$4(Cn)&&!isPlainObject$3(Cn)?String(Cn):Cn,stringifySymbol=($n,Cn="")=>{var _n;return isSymbol$1($n)?`Symbol(${(_n=$n.description)!=null?_n:Cn})`:$n};/** -* @vue/reactivity v3.4.15 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let activeEffectScope;class EffectScope{constructor(Cn=!1){this.detached=Cn,this._active=!0,this.effects=[],this.cleanups=[],this.parent=activeEffectScope,!Cn&&activeEffectScope&&(this.index=(activeEffectScope.scopes||(activeEffectScope.scopes=[])).push(this)-1)}get active(){return this._active}run(Cn){if(this._active){const _n=activeEffectScope;try{return activeEffectScope=this,Cn()}finally{activeEffectScope=_n}}}on(){activeEffectScope=this}off(){activeEffectScope=this.parent}stop(Cn){if(this._active){let _n,Pn;for(_n=0,Pn=this.effects.length;_n=2))break}this._dirtyLevel<2&&(this._dirtyLevel=0),resetTracking()}return this._dirtyLevel>=2}set dirty(Cn){this._dirtyLevel=Cn?2:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let Cn=shouldTrack,_n=activeEffect;try{return shouldTrack=!0,activeEffect=this,this._runnings++,preCleanupEffect(this),this.fn()}finally{postCleanupEffect(this),this._runnings--,activeEffect=_n,shouldTrack=Cn}}stop(){var Cn;this.active&&(preCleanupEffect(this),postCleanupEffect(this),(Cn=this.onStop)==null||Cn.call(this),this.active=!1)}}function triggerComputed($n){return $n.value}function preCleanupEffect($n){$n._trackId++,$n._depsLength=0}function postCleanupEffect($n){if($n.deps&&$n.deps.length>$n._depsLength){for(let Cn=$n._depsLength;Cn<$n.deps.length;Cn++)cleanupDepEffect($n.deps[Cn],$n);$n.deps.length=$n._depsLength}}function cleanupDepEffect($n,Cn){const _n=$n.get(Cn);_n!==void 0&&Cn._trackId!==_n&&($n.delete(Cn),$n.size===0&&$n.cleanup())}let shouldTrack=!0,pauseScheduleStack=0;const trackStack=[];function pauseTracking(){trackStack.push(shouldTrack),shouldTrack=!1}function resetTracking(){const $n=trackStack.pop();shouldTrack=$n===void 0?!0:$n}function pauseScheduling(){pauseScheduleStack++}function resetScheduling(){for(pauseScheduleStack--;!pauseScheduleStack&&queueEffectSchedulers.length;)queueEffectSchedulers.shift()()}function trackEffect($n,Cn,_n){if(Cn.get($n)!==$n._trackId){Cn.set($n,$n._trackId);const Pn=$n.deps[$n._depsLength];Pn!==Cn?(Pn&&cleanupDepEffect(Pn,$n),$n.deps[$n._depsLength++]=Cn):$n._depsLength++}}const queueEffectSchedulers=[];function triggerEffects($n,Cn,_n){pauseScheduling();for(const Pn of $n.keys())if(Pn._dirtyLevel{const _n=new Map;return _n.cleanup=$n,_n.computed=Cn,_n},targetMap=new WeakMap,ITERATE_KEY=Symbol(""),MAP_KEY_ITERATE_KEY=Symbol("");function track($n,Cn,_n){if(shouldTrack&&activeEffect){let Pn=targetMap.get($n);Pn||targetMap.set($n,Pn=new Map);let In=Pn.get(_n);In||Pn.set(_n,In=createDep(()=>Pn.delete(_n))),trackEffect(activeEffect,In)}}function trigger$1($n,Cn,_n,Pn,In,Nn){const Rn=targetMap.get($n);if(!Rn)return;let Dn=[];if(Cn==="clear")Dn=[...Rn.values()];else if(_n==="length"&&isArray$4($n)){const Ln=Number(Pn);Rn.forEach((Fn,Bn)=>{(Bn==="length"||!isSymbol$1(Bn)&&Bn>=Ln)&&Dn.push(Fn)})}else switch(_n!==void 0&&Dn.push(Rn.get(_n)),Cn){case"add":isArray$4($n)?isIntegerKey(_n)&&Dn.push(Rn.get("length")):(Dn.push(Rn.get(ITERATE_KEY)),isMap$1($n)&&Dn.push(Rn.get(MAP_KEY_ITERATE_KEY)));break;case"delete":isArray$4($n)||(Dn.push(Rn.get(ITERATE_KEY)),isMap$1($n)&&Dn.push(Rn.get(MAP_KEY_ITERATE_KEY)));break;case"set":isMap$1($n)&&Dn.push(Rn.get(ITERATE_KEY));break}pauseScheduling();for(const Ln of Dn)Ln&&triggerEffects(Ln,2);resetScheduling()}function getDepFromReactive($n,Cn){var _n;return(_n=targetMap.get($n))==null?void 0:_n.get(Cn)}const isNonTrackableKeys=makeMap("__proto__,__v_isRef,__isVue"),builtInSymbols=new Set(Object.getOwnPropertyNames(Symbol).filter($n=>$n!=="arguments"&&$n!=="caller").map($n=>Symbol[$n]).filter(isSymbol$1)),arrayInstrumentations=createArrayInstrumentations();function createArrayInstrumentations(){const $n={};return["includes","indexOf","lastIndexOf"].forEach(Cn=>{$n[Cn]=function(..._n){const Pn=toRaw(this);for(let Nn=0,Rn=this.length;Nn{$n[Cn]=function(..._n){pauseTracking(),pauseScheduling();const Pn=toRaw(this)[Cn].apply(this,_n);return resetScheduling(),resetTracking(),Pn}}),$n}function hasOwnProperty$g($n){const Cn=toRaw(this);return track(Cn,"has",$n),Cn.hasOwnProperty($n)}class BaseReactiveHandler{constructor(Cn=!1,_n=!1){this._isReadonly=Cn,this._shallow=_n}get(Cn,_n,Pn){const In=this._isReadonly,Nn=this._shallow;if(_n==="__v_isReactive")return!In;if(_n==="__v_isReadonly")return In;if(_n==="__v_isShallow")return Nn;if(_n==="__v_raw")return Pn===(In?Nn?shallowReadonlyMap:readonlyMap:Nn?shallowReactiveMap:reactiveMap).get(Cn)||Object.getPrototypeOf(Cn)===Object.getPrototypeOf(Pn)?Cn:void 0;const Rn=isArray$4(Cn);if(!In){if(Rn&&hasOwn$2(arrayInstrumentations,_n))return Reflect.get(arrayInstrumentations,_n,Pn);if(_n==="hasOwnProperty")return hasOwnProperty$g}const Dn=Reflect.get(Cn,_n,Pn);return(isSymbol$1(_n)?builtInSymbols.has(_n):isNonTrackableKeys(_n))||(In||track(Cn,"get",_n),Nn)?Dn:isRef(Dn)?Rn&&isIntegerKey(_n)?Dn:Dn.value:isObject$7(Dn)?In?readonly(Dn):reactive(Dn):Dn}}class MutableReactiveHandler extends BaseReactiveHandler{constructor(Cn=!1){super(!1,Cn)}set(Cn,_n,Pn,In){let Nn=Cn[_n];if(!this._shallow){const Ln=isReadonly(Nn);if(!isShallow(Pn)&&!isReadonly(Pn)&&(Nn=toRaw(Nn),Pn=toRaw(Pn)),!isArray$4(Cn)&&isRef(Nn)&&!isRef(Pn))return Ln?!1:(Nn.value=Pn,!0)}const Rn=isArray$4(Cn)&&isIntegerKey(_n)?Number(_n)$n,getProto=$n=>Reflect.getPrototypeOf($n);function get$2($n,Cn,_n=!1,Pn=!1){$n=$n.__v_raw;const In=toRaw($n),Nn=toRaw(Cn);_n||(hasChanged(Cn,Nn)&&track(In,"get",Cn),track(In,"get",Nn));const{has:Rn}=getProto(In),Dn=Pn?toShallow:_n?toReadonly:toReactive$1;if(Rn.call(In,Cn))return Dn($n.get(Cn));if(Rn.call(In,Nn))return Dn($n.get(Nn));$n!==In&&$n.get(Cn)}function has($n,Cn=!1){const _n=this.__v_raw,Pn=toRaw(_n),In=toRaw($n);return Cn||(hasChanged($n,In)&&track(Pn,"has",$n),track(Pn,"has",In)),$n===In?_n.has($n):_n.has($n)||_n.has(In)}function size($n,Cn=!1){return $n=$n.__v_raw,!Cn&&track(toRaw($n),"iterate",ITERATE_KEY),Reflect.get($n,"size",$n)}function add($n){$n=toRaw($n);const Cn=toRaw(this);return getProto(Cn).has.call(Cn,$n)||(Cn.add($n),trigger$1(Cn,"add",$n,$n)),this}function set$1($n,Cn){Cn=toRaw(Cn);const _n=toRaw(this),{has:Pn,get:In}=getProto(_n);let Nn=Pn.call(_n,$n);Nn||($n=toRaw($n),Nn=Pn.call(_n,$n));const Rn=In.call(_n,$n);return _n.set($n,Cn),Nn?hasChanged(Cn,Rn)&&trigger$1(_n,"set",$n,Cn):trigger$1(_n,"add",$n,Cn),this}function deleteEntry($n){const Cn=toRaw(this),{has:_n,get:Pn}=getProto(Cn);let In=_n.call(Cn,$n);In||($n=toRaw($n),In=_n.call(Cn,$n)),Pn&&Pn.call(Cn,$n);const Nn=Cn.delete($n);return In&&trigger$1(Cn,"delete",$n,void 0),Nn}function clear(){const $n=toRaw(this),Cn=$n.size!==0,_n=$n.clear();return Cn&&trigger$1($n,"clear",void 0,void 0),_n}function createForEach($n,Cn){return function(Pn,In){const Nn=this,Rn=Nn.__v_raw,Dn=toRaw(Rn),Ln=Cn?toShallow:$n?toReadonly:toReactive$1;return!$n&&track(Dn,"iterate",ITERATE_KEY),Rn.forEach((Fn,Bn)=>Pn.call(In,Ln(Fn),Ln(Bn),Nn))}}function createIterableMethod($n,Cn,_n){return function(...Pn){const In=this.__v_raw,Nn=toRaw(In),Rn=isMap$1(Nn),Dn=$n==="entries"||$n===Symbol.iterator&&Rn,Ln=$n==="keys"&&Rn,Fn=In[$n](...Pn),Bn=_n?toShallow:Cn?toReadonly:toReactive$1;return!Cn&&track(Nn,"iterate",Ln?MAP_KEY_ITERATE_KEY:ITERATE_KEY),{next(){const{value:Hn,done:zn}=Fn.next();return zn?{value:Hn,done:zn}:{value:Dn?[Bn(Hn[0]),Bn(Hn[1])]:Bn(Hn),done:zn}},[Symbol.iterator](){return this}}}}function createReadonlyMethod($n){return function(...Cn){return $n==="delete"?!1:$n==="clear"?void 0:this}}function createInstrumentations(){const $n={get(Nn){return get$2(this,Nn)},get size(){return size(this)},has,add,set:set$1,delete:deleteEntry,clear,forEach:createForEach(!1,!1)},Cn={get(Nn){return get$2(this,Nn,!1,!0)},get size(){return size(this)},has,add,set:set$1,delete:deleteEntry,clear,forEach:createForEach(!1,!0)},_n={get(Nn){return get$2(this,Nn,!0)},get size(){return size(this,!0)},has(Nn){return has.call(this,Nn,!0)},add:createReadonlyMethod("add"),set:createReadonlyMethod("set"),delete:createReadonlyMethod("delete"),clear:createReadonlyMethod("clear"),forEach:createForEach(!0,!1)},Pn={get(Nn){return get$2(this,Nn,!0,!0)},get size(){return size(this,!0)},has(Nn){return has.call(this,Nn,!0)},add:createReadonlyMethod("add"),set:createReadonlyMethod("set"),delete:createReadonlyMethod("delete"),clear:createReadonlyMethod("clear"),forEach:createForEach(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(Nn=>{$n[Nn]=createIterableMethod(Nn,!1,!1),_n[Nn]=createIterableMethod(Nn,!0,!1),Cn[Nn]=createIterableMethod(Nn,!1,!0),Pn[Nn]=createIterableMethod(Nn,!0,!0)}),[$n,_n,Cn,Pn]}const[mutableInstrumentations,readonlyInstrumentations,shallowInstrumentations,shallowReadonlyInstrumentations]=createInstrumentations();function createInstrumentationGetter($n,Cn){const _n=Cn?$n?shallowReadonlyInstrumentations:shallowInstrumentations:$n?readonlyInstrumentations:mutableInstrumentations;return(Pn,In,Nn)=>In==="__v_isReactive"?!$n:In==="__v_isReadonly"?$n:In==="__v_raw"?Pn:Reflect.get(hasOwn$2(_n,In)&&In in Pn?_n:Pn,In,Nn)}const mutableCollectionHandlers={get:createInstrumentationGetter(!1,!1)},shallowCollectionHandlers={get:createInstrumentationGetter(!1,!0)},readonlyCollectionHandlers={get:createInstrumentationGetter(!0,!1)},reactiveMap=new WeakMap,shallowReactiveMap=new WeakMap,readonlyMap=new WeakMap,shallowReadonlyMap=new WeakMap;function targetTypeMap($n){switch($n){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function getTargetType($n){return $n.__v_skip||!Object.isExtensible($n)?0:targetTypeMap(toRawType($n))}function reactive($n){return isReadonly($n)?$n:createReactiveObject($n,!1,mutableHandlers,mutableCollectionHandlers,reactiveMap)}function shallowReactive($n){return createReactiveObject($n,!1,shallowReactiveHandlers,shallowCollectionHandlers,shallowReactiveMap)}function readonly($n){return createReactiveObject($n,!0,readonlyHandlers,readonlyCollectionHandlers,readonlyMap)}function createReactiveObject($n,Cn,_n,Pn,In){if(!isObject$7($n)||$n.__v_raw&&!(Cn&&$n.__v_isReactive))return $n;const Nn=In.get($n);if(Nn)return Nn;const Rn=getTargetType($n);if(Rn===0)return $n;const Dn=new Proxy($n,Rn===2?Pn:_n);return In.set($n,Dn),Dn}function isReactive($n){return isReadonly($n)?isReactive($n.__v_raw):!!($n&&$n.__v_isReactive)}function isReadonly($n){return!!($n&&$n.__v_isReadonly)}function isShallow($n){return!!($n&&$n.__v_isShallow)}function isProxy($n){return isReactive($n)||isReadonly($n)}function toRaw($n){const Cn=$n&&$n.__v_raw;return Cn?toRaw(Cn):$n}function markRaw($n){return def($n,"__v_skip",!0),$n}const toReactive$1=$n=>isObject$7($n)?reactive($n):$n,toReadonly=$n=>isObject$7($n)?readonly($n):$n;class ComputedRefImpl{constructor(Cn,_n,Pn,In){this._setter=_n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new ReactiveEffect(()=>Cn(this._value),()=>triggerRefValue(this,1),()=>this.dep&&scheduleEffects(this.dep)),this.effect.computed=this,this.effect.active=this._cacheable=!In,this.__v_isReadonly=Pn}get value(){const Cn=toRaw(this);return(!Cn._cacheable||Cn.effect.dirty)&&hasChanged(Cn._value,Cn._value=Cn.effect.run())&&triggerRefValue(Cn,2),trackRefValue(Cn),Cn.effect._dirtyLevel>=1&&triggerRefValue(Cn,1),Cn._value}set value(Cn){this._setter(Cn)}get _dirty(){return this.effect.dirty}set _dirty(Cn){this.effect.dirty=Cn}}function computed$1($n,Cn,_n=!1){let Pn,In;const Nn=isFunction$3($n);return Nn?(Pn=$n,In=NOOP):(Pn=$n.get,In=$n.set),new ComputedRefImpl(Pn,In,Nn||!In,_n)}function trackRefValue($n){shouldTrack&&activeEffect&&($n=toRaw($n),trackEffect(activeEffect,$n.dep||($n.dep=createDep(()=>$n.dep=void 0,$n instanceof ComputedRefImpl?$n:void 0))))}function triggerRefValue($n,Cn=2,_n){$n=toRaw($n);const Pn=$n.dep;Pn&&triggerEffects(Pn,Cn)}function isRef($n){return!!($n&&$n.__v_isRef===!0)}function ref($n){return createRef$1($n,!1)}function shallowRef($n){return createRef$1($n,!0)}function createRef$1($n,Cn){return isRef($n)?$n:new RefImpl($n,Cn)}class RefImpl{constructor(Cn,_n){this.__v_isShallow=_n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=_n?Cn:toRaw(Cn),this._value=_n?Cn:toReactive$1(Cn)}get value(){return trackRefValue(this),this._value}set value(Cn){const _n=this.__v_isShallow||isShallow(Cn)||isReadonly(Cn);Cn=_n?Cn:toRaw(Cn),hasChanged(Cn,this._rawValue)&&(this._rawValue=Cn,this._value=_n?Cn:toReactive$1(Cn),triggerRefValue(this,2))}}function triggerRef($n){triggerRefValue($n,2)}function unref($n){return isRef($n)?$n.value:$n}const shallowUnwrapHandlers={get:($n,Cn,_n)=>unref(Reflect.get($n,Cn,_n)),set:($n,Cn,_n,Pn)=>{const In=$n[Cn];return isRef(In)&&!isRef(_n)?(In.value=_n,!0):Reflect.set($n,Cn,_n,Pn)}};function proxyRefs($n){return isReactive($n)?$n:new Proxy($n,shallowUnwrapHandlers)}function toRefs($n){const Cn=isArray$4($n)?new Array($n.length):{};for(const _n in $n)Cn[_n]=propertyToRef($n,_n);return Cn}class ObjectRefImpl{constructor(Cn,_n,Pn){this._object=Cn,this._key=_n,this._defaultValue=Pn,this.__v_isRef=!0}get value(){const Cn=this._object[this._key];return Cn===void 0?this._defaultValue:Cn}set value(Cn){this._object[this._key]=Cn}get dep(){return getDepFromReactive(toRaw(this._object),this._key)}}class GetterRefImpl{constructor(Cn){this._getter=Cn,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function toRef($n,Cn,_n){return isRef($n)?$n:isFunction$3($n)?new GetterRefImpl($n):isObject$7($n)&&arguments.length>1?propertyToRef($n,Cn,_n):ref($n)}function propertyToRef($n,Cn,_n){const Pn=$n[Cn];return isRef(Pn)?Pn:new ObjectRefImpl($n,Cn,_n)}/** -* @vue/runtime-core v3.4.15 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/const stack=[];function warn$1($n,...Cn){pauseTracking();const _n=stack.length?stack[stack.length-1].component:null,Pn=_n&&_n.appContext.config.warnHandler,In=getComponentTrace();if(Pn)callWithErrorHandling(Pn,_n,11,[$n+Cn.join(""),_n&&_n.proxy,In.map(({vnode:Nn})=>`at <${formatComponentName(_n,Nn.type)}>`).join(` -`),In]);else{const Nn=[`[Vue warn]: ${$n}`,...Cn];In.length&&Nn.push(` -`,...formatTrace(In)),console.warn(...Nn)}resetTracking()}function getComponentTrace(){let $n=stack[stack.length-1];if(!$n)return[];const Cn=[];for(;$n;){const _n=Cn[0];_n&&_n.vnode===$n?_n.recurseCount++:Cn.push({vnode:$n,recurseCount:0});const Pn=$n.component&&$n.component.parent;$n=Pn&&Pn.vnode}return Cn}function formatTrace($n){const Cn=[];return $n.forEach((_n,Pn)=>{Cn.push(...Pn===0?[]:[` -`],...formatTraceEntry(_n))}),Cn}function formatTraceEntry({vnode:$n,recurseCount:Cn}){const _n=Cn>0?`... (${Cn} recursive calls)`:"",Pn=$n.component?$n.component.parent==null:!1,In=` at <${formatComponentName($n.component,$n.type,Pn)}`,Nn=">"+_n;return $n.props?[In,...formatProps($n.props),Nn]:[In+Nn]}function formatProps($n){const Cn=[],_n=Object.keys($n);return _n.slice(0,3).forEach(Pn=>{Cn.push(...formatProp(Pn,$n[Pn]))}),_n.length>3&&Cn.push(" ..."),Cn}function formatProp($n,Cn,_n){return isString$4(Cn)?(Cn=JSON.stringify(Cn),_n?Cn:[`${$n}=${Cn}`]):typeof Cn=="number"||typeof Cn=="boolean"||Cn==null?_n?Cn:[`${$n}=${Cn}`]:isRef(Cn)?(Cn=formatProp($n,toRaw(Cn.value),!0),_n?Cn:[`${$n}=Ref<`,Cn,">"]):isFunction$3(Cn)?[`${$n}=fn${Cn.name?`<${Cn.name}>`:""}`]:(Cn=toRaw(Cn),_n?Cn:[`${$n}=`,Cn])}function callWithErrorHandling($n,Cn,_n,Pn){let In;try{In=Pn?$n(...Pn):$n()}catch(Nn){handleError(Nn,Cn,_n)}return In}function callWithAsyncErrorHandling($n,Cn,_n,Pn){if(isFunction$3($n)){const Nn=callWithErrorHandling($n,Cn,_n,Pn);return Nn&&isPromise$1(Nn)&&Nn.catch(Rn=>{handleError(Rn,Cn,_n)}),Nn}const In=[];for(let Nn=0;Nn<$n.length;Nn++)In.push(callWithAsyncErrorHandling($n[Nn],Cn,_n,Pn));return In}function handleError($n,Cn,_n,Pn=!0){const In=Cn?Cn.vnode:null;if(Cn){let Nn=Cn.parent;const Rn=Cn.proxy,Dn=`https://vuejs.org/error-reference/#runtime-${_n}`;for(;Nn;){const Fn=Nn.ec;if(Fn){for(let Bn=0;Bn>>1,In=queue[Pn],Nn=getId(In);Nn<$n||Nn===$n&&In.pre?Cn=Pn+1:_n=Pn}return Cn}function queueJob($n){(!queue.length||!queue.includes($n,isFlushing&&$n.allowRecurse?flushIndex+1:flushIndex))&&($n.id==null?queue.push($n):queue.splice(findInsertionIndex($n.id),0,$n),queueFlush())}function queueFlush(){!isFlushing&&!isFlushPending&&(isFlushPending=!0,currentFlushPromise=resolvedPromise.then(flushJobs))}function invalidateJob($n){const Cn=queue.indexOf($n);Cn>flushIndex&&queue.splice(Cn,1)}function queuePostFlushCb($n){isArray$4($n)?pendingPostFlushCbs.push(...$n):(!activePostFlushCbs||!activePostFlushCbs.includes($n,$n.allowRecurse?postFlushIndex+1:postFlushIndex))&&pendingPostFlushCbs.push($n),queueFlush()}function flushPreFlushCbs($n,Cn,_n=isFlushing?flushIndex+1:0){for(;_ngetId(_n)-getId(Pn));if(pendingPostFlushCbs.length=0,activePostFlushCbs){activePostFlushCbs.push(...Cn);return}for(activePostFlushCbs=Cn,postFlushIndex=0;postFlushIndex$n.id==null?1/0:$n.id,comparator=($n,Cn)=>{const _n=getId($n)-getId(Cn);if(_n===0){if($n.pre&&!Cn.pre)return-1;if(Cn.pre&&!$n.pre)return 1}return _n};function flushJobs($n){isFlushPending=!1,isFlushing=!0,queue.sort(comparator);try{for(flushIndex=0;flushIndexisString$4(Wn)?Wn.trim():Wn)),Hn&&(In=_n.map(looseToNumber))}let Dn,Ln=Pn[Dn=toHandlerKey(Cn)]||Pn[Dn=toHandlerKey(camelize$1(Cn))];!Ln&&Nn&&(Ln=Pn[Dn=toHandlerKey(hyphenate$1(Cn))]),Ln&&callWithAsyncErrorHandling(Ln,$n,6,In);const Fn=Pn[Dn+"Once"];if(Fn){if(!$n.emitted)$n.emitted={};else if($n.emitted[Dn])return;$n.emitted[Dn]=!0,callWithAsyncErrorHandling(Fn,$n,6,In)}}function normalizeEmitsOptions($n,Cn,_n=!1){const Pn=Cn.emitsCache,In=Pn.get($n);if(In!==void 0)return In;const Nn=$n.emits;let Rn={},Dn=!1;if(!isFunction$3($n)){const Ln=Fn=>{const Bn=normalizeEmitsOptions(Fn,Cn,!0);Bn&&(Dn=!0,extend(Rn,Bn))};!_n&&Cn.mixins.length&&Cn.mixins.forEach(Ln),$n.extends&&Ln($n.extends),$n.mixins&&$n.mixins.forEach(Ln)}return!Nn&&!Dn?(isObject$7($n)&&Pn.set($n,null),null):(isArray$4(Nn)?Nn.forEach(Ln=>Rn[Ln]=null):extend(Rn,Nn),isObject$7($n)&&Pn.set($n,Rn),Rn)}function isEmitListener($n,Cn){return!$n||!isOn$1(Cn)?!1:(Cn=Cn.slice(2).replace(/Once$/,""),hasOwn$2($n,Cn[0].toLowerCase()+Cn.slice(1))||hasOwn$2($n,hyphenate$1(Cn))||hasOwn$2($n,Cn))}let currentRenderingInstance=null,currentScopeId=null;function setCurrentRenderingInstance($n){const Cn=currentRenderingInstance;return currentRenderingInstance=$n,currentScopeId=$n&&$n.type.__scopeId||null,Cn}function pushScopeId($n){currentScopeId=$n}function popScopeId(){currentScopeId=null}function withCtx($n,Cn=currentRenderingInstance,_n){if(!Cn||$n._n)return $n;const Pn=(...In)=>{Pn._d&&setBlockTracking(-1);const Nn=setCurrentRenderingInstance(Cn);let Rn;try{Rn=$n(...In)}finally{setCurrentRenderingInstance(Nn),Pn._d&&setBlockTracking(1)}return Rn};return Pn._n=!0,Pn._c=!0,Pn._d=!0,Pn}function markAttrsAccessed(){}function renderComponentRoot($n){const{type:Cn,vnode:_n,proxy:Pn,withProxy:In,props:Nn,propsOptions:[Rn],slots:Dn,attrs:Ln,emit:Fn,render:Bn,renderCache:Hn,data:zn,setupState:Wn,ctx:Yn,inheritAttrs:Gn}=$n;let Go,Xn;const Yo=setCurrentRenderingInstance($n);try{if(_n.shapeFlag&4){const Jo=In||Pn,Zo=Jo;Go=normalizeVNode(Bn.call(Zo,Jo,Hn,Nn,Wn,zn,Yn)),Xn=Ln}else{const Jo=Cn;Go=normalizeVNode(Jo.length>1?Jo(Nn,{attrs:Ln,slots:Dn,emit:Fn}):Jo(Nn,null)),Xn=Cn.props?Ln:getFunctionalFallthrough(Ln)}}catch(Jo){blockStack.length=0,handleError(Jo,$n,1),Go=createVNode(Comment$1)}let qo=Go;if(Xn&&Gn!==!1){const Jo=Object.keys(Xn),{shapeFlag:Zo}=qo;Jo.length&&Zo&7&&(Rn&&Jo.some(isModelListener)&&(Xn=filterModelListeners(Xn,Rn)),qo=cloneVNode(qo,Xn))}return _n.dirs&&(qo=cloneVNode(qo),qo.dirs=qo.dirs?qo.dirs.concat(_n.dirs):_n.dirs),_n.transition&&(qo.transition=_n.transition),Go=qo,setCurrentRenderingInstance(Yo),Go}const getFunctionalFallthrough=$n=>{let Cn;for(const _n in $n)(_n==="class"||_n==="style"||isOn$1(_n))&&((Cn||(Cn={}))[_n]=$n[_n]);return Cn},filterModelListeners=($n,Cn)=>{const _n={};for(const Pn in $n)(!isModelListener(Pn)||!(Pn.slice(9)in Cn))&&(_n[Pn]=$n[Pn]);return _n};function shouldUpdateComponent($n,Cn,_n){const{props:Pn,children:In,component:Nn}=$n,{props:Rn,children:Dn,patchFlag:Ln}=Cn,Fn=Nn.emitsOptions;if(Cn.dirs||Cn.transition)return!0;if(_n&&Ln>=0){if(Ln&1024)return!0;if(Ln&16)return Pn?hasPropsChanged(Pn,Rn,Fn):!!Rn;if(Ln&8){const Bn=Cn.dynamicProps;for(let Hn=0;Hn$n.__isSuspense;function queueEffectWithSuspense($n,Cn){Cn&&Cn.pendingBranch?isArray$4($n)?Cn.effects.push(...$n):Cn.effects.push($n):queuePostFlushCb($n)}const ssrContextKey=Symbol.for("v-scx"),useSSRContext=()=>inject(ssrContextKey);function watchEffect($n,Cn){return doWatch($n,null,Cn)}function watchPostEffect($n,Cn){return doWatch($n,null,{flush:"post"})}const INITIAL_WATCHER_VALUE={};function watch($n,Cn,_n){return doWatch($n,Cn,_n)}function doWatch($n,Cn,{immediate:_n,deep:Pn,flush:In,once:Nn,onTrack:Rn,onTrigger:Dn}=EMPTY_OBJ){if(Cn&&Nn){const rr=Cn;Cn=(...nr)=>{rr(...nr),Zo()}}const Ln=currentInstance,Fn=rr=>Pn===!0?rr:traverse(rr,Pn===!1?1:void 0);let Bn,Hn=!1,zn=!1;if(isRef($n)?(Bn=()=>$n.value,Hn=isShallow($n)):isReactive($n)?(Bn=()=>Fn($n),Hn=!0):isArray$4($n)?(zn=!0,Hn=$n.some(rr=>isReactive(rr)||isShallow(rr)),Bn=()=>$n.map(rr=>{if(isRef(rr))return rr.value;if(isReactive(rr))return Fn(rr);if(isFunction$3(rr))return callWithErrorHandling(rr,Ln,2)})):isFunction$3($n)?Cn?Bn=()=>callWithErrorHandling($n,Ln,2):Bn=()=>(Wn&&Wn(),callWithAsyncErrorHandling($n,Ln,3,[Yn])):Bn=NOOP,Cn&&Pn){const rr=Bn;Bn=()=>traverse(rr())}let Wn,Yn=rr=>{Wn=qo.onStop=()=>{callWithErrorHandling(rr,Ln,4),Wn=qo.onStop=void 0}},Gn;if(isInSSRComponentSetup)if(Yn=NOOP,Cn?_n&&callWithAsyncErrorHandling(Cn,Ln,3,[Bn(),zn?[]:void 0,Yn]):Bn(),In==="sync"){const rr=useSSRContext();Gn=rr.__watcherHandles||(rr.__watcherHandles=[])}else return NOOP;let Go=zn?new Array($n.length).fill(INITIAL_WATCHER_VALUE):INITIAL_WATCHER_VALUE;const Xn=()=>{if(!(!qo.active||!qo.dirty))if(Cn){const rr=qo.run();(Pn||Hn||(zn?rr.some((nr,ta)=>hasChanged(nr,Go[ta])):hasChanged(rr,Go)))&&(Wn&&Wn(),callWithAsyncErrorHandling(Cn,Ln,3,[rr,Go===INITIAL_WATCHER_VALUE?void 0:zn&&Go[0]===INITIAL_WATCHER_VALUE?[]:Go,Yn]),Go=rr)}else qo.run()};Xn.allowRecurse=!!Cn;let Yo;In==="sync"?Yo=Xn:In==="post"?Yo=()=>queuePostRenderEffect(Xn,Ln&&Ln.suspense):(Xn.pre=!0,Ln&&(Xn.id=Ln.uid),Yo=()=>queueJob(Xn));const qo=new ReactiveEffect(Bn,NOOP,Yo),Jo=getCurrentScope(),Zo=()=>{qo.stop(),Jo&&remove(Jo.effects,qo)};return Cn?_n?Xn():Go=qo.run():In==="post"?queuePostRenderEffect(qo.run.bind(qo),Ln&&Ln.suspense):qo.run(),Gn&&Gn.push(Zo),Zo}function instanceWatch($n,Cn,_n){const Pn=this.proxy,In=isString$4($n)?$n.includes(".")?createPathGetter(Pn,$n):()=>Pn[$n]:$n.bind(Pn,Pn);let Nn;isFunction$3(Cn)?Nn=Cn:(Nn=Cn.handler,_n=Cn);const Rn=setCurrentInstance(this),Dn=doWatch(In,Nn.bind(Pn),_n);return Rn(),Dn}function createPathGetter($n,Cn){const _n=Cn.split(".");return()=>{let Pn=$n;for(let In=0;In<_n.length&&Pn;In++)Pn=Pn[_n[In]];return Pn}}function traverse($n,Cn,_n=0,Pn){if(!isObject$7($n)||$n.__v_skip)return $n;if(Cn&&Cn>0){if(_n>=Cn)return $n;_n++}if(Pn=Pn||new Set,Pn.has($n))return $n;if(Pn.add($n),isRef($n))traverse($n.value,Cn,_n,Pn);else if(isArray$4($n))for(let In=0;In<$n.length;In++)traverse($n[In],Cn,_n,Pn);else if(isSet$1($n)||isMap$1($n))$n.forEach(In=>{traverse(In,Cn,_n,Pn)});else if(isPlainObject$3($n))for(const In in $n)traverse($n[In],Cn,_n,Pn);return $n}function withDirectives($n,Cn){if(currentRenderingInstance===null)return $n;const _n=getExposeProxy(currentRenderingInstance)||currentRenderingInstance.proxy,Pn=$n.dirs||($n.dirs=[]);for(let In=0;In{$n.isMounted=!0}),onBeforeUnmount(()=>{$n.isUnmounting=!0}),$n}const TransitionHookValidator=[Function,Array],BaseTransitionPropsValidators={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:TransitionHookValidator,onEnter:TransitionHookValidator,onAfterEnter:TransitionHookValidator,onEnterCancelled:TransitionHookValidator,onBeforeLeave:TransitionHookValidator,onLeave:TransitionHookValidator,onAfterLeave:TransitionHookValidator,onLeaveCancelled:TransitionHookValidator,onBeforeAppear:TransitionHookValidator,onAppear:TransitionHookValidator,onAfterAppear:TransitionHookValidator,onAppearCancelled:TransitionHookValidator},BaseTransitionImpl={name:"BaseTransition",props:BaseTransitionPropsValidators,setup($n,{slots:Cn}){const _n=getCurrentInstance(),Pn=useTransitionState();let In;return()=>{const Nn=Cn.default&&getTransitionRawChildren(Cn.default(),!0);if(!Nn||!Nn.length)return;let Rn=Nn[0];if(Nn.length>1){for(const Gn of Nn)if(Gn.type!==Comment$1){Rn=Gn;break}}const Dn=toRaw($n),{mode:Ln}=Dn;if(Pn.isLeaving)return emptyPlaceholder(Rn);const Fn=getKeepAliveChild(Rn);if(!Fn)return emptyPlaceholder(Rn);const Bn=resolveTransitionHooks(Fn,Dn,Pn,_n);setTransitionHooks(Fn,Bn);const Hn=_n.subTree,zn=Hn&&getKeepAliveChild(Hn);let Wn=!1;const{getTransitionKey:Yn}=Fn.type;if(Yn){const Gn=Yn();In===void 0?In=Gn:Gn!==In&&(In=Gn,Wn=!0)}if(zn&&zn.type!==Comment$1&&(!isSameVNodeType(Fn,zn)||Wn)){const Gn=resolveTransitionHooks(zn,Dn,Pn,_n);if(setTransitionHooks(zn,Gn),Ln==="out-in")return Pn.isLeaving=!0,Gn.afterLeave=()=>{Pn.isLeaving=!1,_n.update.active!==!1&&(_n.effect.dirty=!0,_n.update())},emptyPlaceholder(Rn);Ln==="in-out"&&Fn.type!==Comment$1&&(Gn.delayLeave=(Go,Xn,Yo)=>{const qo=getLeavingNodesForType(Pn,zn);qo[String(zn.key)]=zn,Go[leaveCbKey]=()=>{Xn(),Go[leaveCbKey]=void 0,delete Bn.delayedLeave},Bn.delayedLeave=Yo})}return Rn}}},BaseTransition=BaseTransitionImpl;function getLeavingNodesForType($n,Cn){const{leavingVNodes:_n}=$n;let Pn=_n.get(Cn.type);return Pn||(Pn=Object.create(null),_n.set(Cn.type,Pn)),Pn}function resolveTransitionHooks($n,Cn,_n,Pn){const{appear:In,mode:Nn,persisted:Rn=!1,onBeforeEnter:Dn,onEnter:Ln,onAfterEnter:Fn,onEnterCancelled:Bn,onBeforeLeave:Hn,onLeave:zn,onAfterLeave:Wn,onLeaveCancelled:Yn,onBeforeAppear:Gn,onAppear:Go,onAfterAppear:Xn,onAppearCancelled:Yo}=Cn,qo=String($n.key),Jo=getLeavingNodesForType(_n,$n),Zo=(ta,oa)=>{ta&&callWithAsyncErrorHandling(ta,Pn,9,oa)},rr=(ta,oa)=>{const ra=oa[1];Zo(ta,oa),isArray$4(ta)?ta.every(ea=>ea.length<=1)&&ra():ta.length<=1&&ra()},nr={mode:Nn,persisted:Rn,beforeEnter(ta){let oa=Dn;if(!_n.isMounted)if(In)oa=Gn||Dn;else return;ta[leaveCbKey]&&ta[leaveCbKey](!0);const ra=Jo[qo];ra&&isSameVNodeType($n,ra)&&ra.el[leaveCbKey]&&ra.el[leaveCbKey](),Zo(oa,[ta])},enter(ta){let oa=Ln,ra=Fn,ea=Bn;if(!_n.isMounted)if(In)oa=Go||Ln,ra=Xn||Fn,ea=Yo||Bn;else return;let la=!1;const ua=ta[enterCbKey$1]=ga=>{la||(la=!0,ga?Zo(ea,[ta]):Zo(ra,[ta]),nr.delayedLeave&&nr.delayedLeave(),ta[enterCbKey$1]=void 0)};oa?rr(oa,[ta,ua]):ua()},leave(ta,oa){const ra=String($n.key);if(ta[enterCbKey$1]&&ta[enterCbKey$1](!0),_n.isUnmounting)return oa();Zo(Hn,[ta]);let ea=!1;const la=ta[leaveCbKey]=ua=>{ea||(ea=!0,oa(),ua?Zo(Yn,[ta]):Zo(Wn,[ta]),ta[leaveCbKey]=void 0,Jo[ra]===$n&&delete Jo[ra])};Jo[ra]=$n,zn?rr(zn,[ta,la]):la()},clone(ta){return resolveTransitionHooks(ta,Cn,_n,Pn)}};return nr}function emptyPlaceholder($n){if(isKeepAlive($n))return $n=cloneVNode($n),$n.children=null,$n}function getKeepAliveChild($n){return isKeepAlive($n)?$n.children?$n.children[0]:void 0:$n}function setTransitionHooks($n,Cn){$n.shapeFlag&6&&$n.component?setTransitionHooks($n.component.subTree,Cn):$n.shapeFlag&128?($n.ssContent.transition=Cn.clone($n.ssContent),$n.ssFallback.transition=Cn.clone($n.ssFallback)):$n.transition=Cn}function getTransitionRawChildren($n,Cn=!1,_n){let Pn=[],In=0;for(let Nn=0;Nn<$n.length;Nn++){let Rn=$n[Nn];const Dn=_n==null?Rn.key:String(_n)+String(Rn.key!=null?Rn.key:Nn);Rn.type===Fragment?(Rn.patchFlag&128&&In++,Pn=Pn.concat(getTransitionRawChildren(Rn.children,Cn,Dn))):(Cn||Rn.type!==Comment$1)&&Pn.push(Dn!=null?cloneVNode(Rn,{key:Dn}):Rn)}if(In>1)for(let Nn=0;Nn!!$n.type.__asyncLoader,isKeepAlive=$n=>$n.type.__isKeepAlive;function onActivated($n,Cn){registerKeepAliveHook($n,"a",Cn)}function onDeactivated($n,Cn){registerKeepAliveHook($n,"da",Cn)}function registerKeepAliveHook($n,Cn,_n=currentInstance){const Pn=$n.__wdc||($n.__wdc=()=>{let In=_n;for(;In;){if(In.isDeactivated)return;In=In.parent}return $n()});if(injectHook(Cn,Pn,_n),_n){let In=_n.parent;for(;In&&In.parent;)isKeepAlive(In.parent.vnode)&&injectToKeepAliveRoot(Pn,Cn,_n,In),In=In.parent}}function injectToKeepAliveRoot($n,Cn,_n,Pn){const In=injectHook(Cn,$n,Pn,!0);onUnmounted(()=>{remove(Pn[Cn],In)},_n)}function injectHook($n,Cn,_n=currentInstance,Pn=!1){if(_n){const In=_n[$n]||(_n[$n]=[]),Nn=Cn.__weh||(Cn.__weh=(...Rn)=>{if(_n.isUnmounted)return;pauseTracking();const Dn=setCurrentInstance(_n),Ln=callWithAsyncErrorHandling(Cn,_n,$n,Rn);return Dn(),resetTracking(),Ln});return Pn?In.unshift(Nn):In.push(Nn),Nn}}const createHook=$n=>(Cn,_n=currentInstance)=>(!isInSSRComponentSetup||$n==="sp")&&injectHook($n,(...Pn)=>Cn(...Pn),_n),onBeforeMount=createHook("bm"),onMounted=createHook("m"),onBeforeUpdate=createHook("bu"),onUpdated=createHook("u"),onBeforeUnmount=createHook("bum"),onUnmounted=createHook("um"),onServerPrefetch=createHook("sp"),onRenderTriggered=createHook("rtg"),onRenderTracked=createHook("rtc");function onErrorCaptured($n,Cn=currentInstance){injectHook("ec",$n,Cn)}function renderList($n,Cn,_n,Pn){let In;const Nn=_n&&_n[Pn];if(isArray$4($n)||isString$4($n)){In=new Array($n.length);for(let Rn=0,Dn=$n.length;RnCn(Rn,Dn,void 0,Nn&&Nn[Dn]));else{const Rn=Object.keys($n);In=new Array(Rn.length);for(let Dn=0,Ln=Rn.length;Dn{const Nn=Pn.fn(...In);return Nn&&(Nn.key=Pn.key),Nn}:Pn.fn)}return $n}function renderSlot($n,Cn,_n={},Pn,In){if(currentRenderingInstance.isCE||currentRenderingInstance.parent&&isAsyncWrapper(currentRenderingInstance.parent)&¤tRenderingInstance.parent.isCE)return Cn!=="default"&&(_n.name=Cn),createVNode("slot",_n,Pn&&Pn());let Nn=$n[Cn];Nn&&Nn._c&&(Nn._d=!1),openBlock();const Rn=Nn&&ensureValidVNode$1(Nn(_n)),Dn=createBlock(Fragment,{key:_n.key||Rn&&Rn.key||`_${Cn}`},Rn||(Pn?Pn():[]),Rn&&$n._===1?64:-2);return!In&&Dn.scopeId&&(Dn.slotScopeIds=[Dn.scopeId+"-s"]),Nn&&Nn._c&&(Nn._d=!0),Dn}function ensureValidVNode$1($n){return $n.some(Cn=>isVNode$1(Cn)?!(Cn.type===Comment$1||Cn.type===Fragment&&!ensureValidVNode$1(Cn.children)):!0)?$n:null}const getPublicInstance=$n=>$n?isStatefulComponent($n)?getExposeProxy($n)||$n.proxy:getPublicInstance($n.parent):null,publicPropertiesMap=extend(Object.create(null),{$:$n=>$n,$el:$n=>$n.vnode.el,$data:$n=>$n.data,$props:$n=>$n.props,$attrs:$n=>$n.attrs,$slots:$n=>$n.slots,$refs:$n=>$n.refs,$parent:$n=>getPublicInstance($n.parent),$root:$n=>getPublicInstance($n.root),$emit:$n=>$n.emit,$options:$n=>resolveMergedOptions($n),$forceUpdate:$n=>$n.f||($n.f=()=>{$n.effect.dirty=!0,queueJob($n.update)}),$nextTick:$n=>$n.n||($n.n=nextTick.bind($n.proxy)),$watch:$n=>instanceWatch.bind($n)}),hasSetupBinding=($n,Cn)=>$n!==EMPTY_OBJ&&!$n.__isScriptSetup&&hasOwn$2($n,Cn),PublicInstanceProxyHandlers={get({_:$n},Cn){const{ctx:_n,setupState:Pn,data:In,props:Nn,accessCache:Rn,type:Dn,appContext:Ln}=$n;let Fn;if(Cn[0]!=="$"){const Wn=Rn[Cn];if(Wn!==void 0)switch(Wn){case 1:return Pn[Cn];case 2:return In[Cn];case 4:return _n[Cn];case 3:return Nn[Cn]}else{if(hasSetupBinding(Pn,Cn))return Rn[Cn]=1,Pn[Cn];if(In!==EMPTY_OBJ&&hasOwn$2(In,Cn))return Rn[Cn]=2,In[Cn];if((Fn=$n.propsOptions[0])&&hasOwn$2(Fn,Cn))return Rn[Cn]=3,Nn[Cn];if(_n!==EMPTY_OBJ&&hasOwn$2(_n,Cn))return Rn[Cn]=4,_n[Cn];shouldCacheAccess&&(Rn[Cn]=0)}}const Bn=publicPropertiesMap[Cn];let Hn,zn;if(Bn)return Cn==="$attrs"&&track($n,"get",Cn),Bn($n);if((Hn=Dn.__cssModules)&&(Hn=Hn[Cn]))return Hn;if(_n!==EMPTY_OBJ&&hasOwn$2(_n,Cn))return Rn[Cn]=4,_n[Cn];if(zn=Ln.config.globalProperties,hasOwn$2(zn,Cn))return zn[Cn]},set({_:$n},Cn,_n){const{data:Pn,setupState:In,ctx:Nn}=$n;return hasSetupBinding(In,Cn)?(In[Cn]=_n,!0):Pn!==EMPTY_OBJ&&hasOwn$2(Pn,Cn)?(Pn[Cn]=_n,!0):hasOwn$2($n.props,Cn)||Cn[0]==="$"&&Cn.slice(1)in $n?!1:(Nn[Cn]=_n,!0)},has({_:{data:$n,setupState:Cn,accessCache:_n,ctx:Pn,appContext:In,propsOptions:Nn}},Rn){let Dn;return!!_n[Rn]||$n!==EMPTY_OBJ&&hasOwn$2($n,Rn)||hasSetupBinding(Cn,Rn)||(Dn=Nn[0])&&hasOwn$2(Dn,Rn)||hasOwn$2(Pn,Rn)||hasOwn$2(publicPropertiesMap,Rn)||hasOwn$2(In.config.globalProperties,Rn)},defineProperty($n,Cn,_n){return _n.get!=null?$n._.accessCache[Cn]=0:hasOwn$2(_n,"value")&&this.set($n,Cn,_n.value,null),Reflect.defineProperty($n,Cn,_n)}};function useAttrs(){return getContext().attrs}function getContext(){const $n=getCurrentInstance();return $n.setupContext||($n.setupContext=createSetupContext($n))}function normalizePropsOrEmits($n){return isArray$4($n)?$n.reduce((Cn,_n)=>(Cn[_n]=null,Cn),{}):$n}let shouldCacheAccess=!0;function applyOptions($n){const Cn=resolveMergedOptions($n),_n=$n.proxy,Pn=$n.ctx;shouldCacheAccess=!1,Cn.beforeCreate&&callHook$1(Cn.beforeCreate,$n,"bc");const{data:In,computed:Nn,methods:Rn,watch:Dn,provide:Ln,inject:Fn,created:Bn,beforeMount:Hn,mounted:zn,beforeUpdate:Wn,updated:Yn,activated:Gn,deactivated:Go,beforeDestroy:Xn,beforeUnmount:Yo,destroyed:qo,unmounted:Jo,render:Zo,renderTracked:rr,renderTriggered:nr,errorCaptured:ta,serverPrefetch:oa,expose:ra,inheritAttrs:ea,components:la,directives:ua,filters:ga}=Cn;if(Fn&&resolveInjections(Fn,Pn,null),Rn)for(const sa in Rn){const ia=Rn[sa];isFunction$3(ia)&&(Pn[sa]=ia.bind(_n))}if(In){const sa=In.call(_n,_n);isObject$7(sa)&&($n.data=reactive(sa))}if(shouldCacheAccess=!0,Nn)for(const sa in Nn){const ia=Nn[sa],fa=isFunction$3(ia)?ia.bind(_n,_n):isFunction$3(ia.get)?ia.get.bind(_n,_n):NOOP,ma=!isFunction$3(ia)&&isFunction$3(ia.set)?ia.set.bind(_n):NOOP,ya=computed({get:fa,set:ma});Object.defineProperty(Pn,sa,{enumerable:!0,configurable:!0,get:()=>ya.value,set:ba=>ya.value=ba})}if(Dn)for(const sa in Dn)createWatcher(Dn[sa],Pn,_n,sa);if(Ln){const sa=isFunction$3(Ln)?Ln.call(_n):Ln;Reflect.ownKeys(sa).forEach(ia=>{provide(ia,sa[ia])})}Bn&&callHook$1(Bn,$n,"c");function ca(sa,ia){isArray$4(ia)?ia.forEach(fa=>sa(fa.bind(_n))):ia&&sa(ia.bind(_n))}if(ca(onBeforeMount,Hn),ca(onMounted,zn),ca(onBeforeUpdate,Wn),ca(onUpdated,Yn),ca(onActivated,Gn),ca(onDeactivated,Go),ca(onErrorCaptured,ta),ca(onRenderTracked,rr),ca(onRenderTriggered,nr),ca(onBeforeUnmount,Yo),ca(onUnmounted,Jo),ca(onServerPrefetch,oa),isArray$4(ra))if(ra.length){const sa=$n.exposed||($n.exposed={});ra.forEach(ia=>{Object.defineProperty(sa,ia,{get:()=>_n[ia],set:fa=>_n[ia]=fa})})}else $n.exposed||($n.exposed={});Zo&&$n.render===NOOP&&($n.render=Zo),ea!=null&&($n.inheritAttrs=ea),la&&($n.components=la),ua&&($n.directives=ua)}function resolveInjections($n,Cn,_n=NOOP){isArray$4($n)&&($n=normalizeInject($n));for(const Pn in $n){const In=$n[Pn];let Nn;isObject$7(In)?"default"in In?Nn=inject(In.from||Pn,In.default,!0):Nn=inject(In.from||Pn):Nn=inject(In),isRef(Nn)?Object.defineProperty(Cn,Pn,{enumerable:!0,configurable:!0,get:()=>Nn.value,set:Rn=>Nn.value=Rn}):Cn[Pn]=Nn}}function callHook$1($n,Cn,_n){callWithAsyncErrorHandling(isArray$4($n)?$n.map(Pn=>Pn.bind(Cn.proxy)):$n.bind(Cn.proxy),Cn,_n)}function createWatcher($n,Cn,_n,Pn){const In=Pn.includes(".")?createPathGetter(_n,Pn):()=>_n[Pn];if(isString$4($n)){const Nn=Cn[$n];isFunction$3(Nn)&&watch(In,Nn)}else if(isFunction$3($n))watch(In,$n.bind(_n));else if(isObject$7($n))if(isArray$4($n))$n.forEach(Nn=>createWatcher(Nn,Cn,_n,Pn));else{const Nn=isFunction$3($n.handler)?$n.handler.bind(_n):Cn[$n.handler];isFunction$3(Nn)&&watch(In,Nn,$n)}}function resolveMergedOptions($n){const Cn=$n.type,{mixins:_n,extends:Pn}=Cn,{mixins:In,optionsCache:Nn,config:{optionMergeStrategies:Rn}}=$n.appContext,Dn=Nn.get(Cn);let Ln;return Dn?Ln=Dn:!In.length&&!_n&&!Pn?Ln=Cn:(Ln={},In.length&&In.forEach(Fn=>mergeOptions$1(Ln,Fn,Rn,!0)),mergeOptions$1(Ln,Cn,Rn)),isObject$7(Cn)&&Nn.set(Cn,Ln),Ln}function mergeOptions$1($n,Cn,_n,Pn=!1){const{mixins:In,extends:Nn}=Cn;Nn&&mergeOptions$1($n,Nn,_n,!0),In&&In.forEach(Rn=>mergeOptions$1($n,Rn,_n,!0));for(const Rn in Cn)if(!(Pn&&Rn==="expose")){const Dn=internalOptionMergeStrats[Rn]||_n&&_n[Rn];$n[Rn]=Dn?Dn($n[Rn],Cn[Rn]):Cn[Rn]}return $n}const internalOptionMergeStrats={data:mergeDataFn,props:mergeEmitsOrPropsOptions,emits:mergeEmitsOrPropsOptions,methods:mergeObjectOptions,computed:mergeObjectOptions,beforeCreate:mergeAsArray,created:mergeAsArray,beforeMount:mergeAsArray,mounted:mergeAsArray,beforeUpdate:mergeAsArray,updated:mergeAsArray,beforeDestroy:mergeAsArray,beforeUnmount:mergeAsArray,destroyed:mergeAsArray,unmounted:mergeAsArray,activated:mergeAsArray,deactivated:mergeAsArray,errorCaptured:mergeAsArray,serverPrefetch:mergeAsArray,components:mergeObjectOptions,directives:mergeObjectOptions,watch:mergeWatchOptions,provide:mergeDataFn,inject:mergeInject};function mergeDataFn($n,Cn){return Cn?$n?function(){return extend(isFunction$3($n)?$n.call(this,this):$n,isFunction$3(Cn)?Cn.call(this,this):Cn)}:Cn:$n}function mergeInject($n,Cn){return mergeObjectOptions(normalizeInject($n),normalizeInject(Cn))}function normalizeInject($n){if(isArray$4($n)){const Cn={};for(let _n=0;_n<$n.length;_n++)Cn[$n[_n]]=$n[_n];return Cn}return $n}function mergeAsArray($n,Cn){return $n?[...new Set([].concat($n,Cn))]:Cn}function mergeObjectOptions($n,Cn){return $n?extend(Object.create(null),$n,Cn):Cn}function mergeEmitsOrPropsOptions($n,Cn){return $n?isArray$4($n)&&isArray$4(Cn)?[...new Set([...$n,...Cn])]:extend(Object.create(null),normalizePropsOrEmits($n),normalizePropsOrEmits(Cn??{})):Cn}function mergeWatchOptions($n,Cn){if(!$n)return Cn;if(!Cn)return $n;const _n=extend(Object.create(null),$n);for(const Pn in Cn)_n[Pn]=mergeAsArray($n[Pn],Cn[Pn]);return _n}function createAppContext(){return{app:null,config:{isNativeTag:NO,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let uid$1=0;function createAppAPI($n,Cn){return function(Pn,In=null){isFunction$3(Pn)||(Pn=extend({},Pn)),In!=null&&!isObject$7(In)&&(In=null);const Nn=createAppContext(),Rn=new WeakSet;let Dn=!1;const Ln=Nn.app={_uid:uid$1++,_component:Pn,_props:In,_container:null,_context:Nn,_instance:null,version:version$1,get config(){return Nn.config},set config(Fn){},use(Fn,...Bn){return Rn.has(Fn)||(Fn&&isFunction$3(Fn.install)?(Rn.add(Fn),Fn.install(Ln,...Bn)):isFunction$3(Fn)&&(Rn.add(Fn),Fn(Ln,...Bn))),Ln},mixin(Fn){return Nn.mixins.includes(Fn)||Nn.mixins.push(Fn),Ln},component(Fn,Bn){return Bn?(Nn.components[Fn]=Bn,Ln):Nn.components[Fn]},directive(Fn,Bn){return Bn?(Nn.directives[Fn]=Bn,Ln):Nn.directives[Fn]},mount(Fn,Bn,Hn){if(!Dn){const zn=createVNode(Pn,In);return zn.appContext=Nn,Hn===!0?Hn="svg":Hn===!1&&(Hn=void 0),Bn&&Cn?Cn(zn,Fn):$n(zn,Fn,Hn),Dn=!0,Ln._container=Fn,Fn.__vue_app__=Ln,getExposeProxy(zn.component)||zn.component.proxy}},unmount(){Dn&&($n(null,Ln._container),delete Ln._container.__vue_app__)},provide(Fn,Bn){return Nn.provides[Fn]=Bn,Ln},runWithContext(Fn){currentApp=Ln;try{return Fn()}finally{currentApp=null}}};return Ln}}let currentApp=null;function provide($n,Cn){if(currentInstance){let _n=currentInstance.provides;const Pn=currentInstance.parent&¤tInstance.parent.provides;Pn===_n&&(_n=currentInstance.provides=Object.create(Pn)),_n[$n]=Cn}}function inject($n,Cn,_n=!1){const Pn=currentInstance||currentRenderingInstance;if(Pn||currentApp){const In=Pn?Pn.parent==null?Pn.vnode.appContext&&Pn.vnode.appContext.provides:Pn.parent.provides:currentApp._context.provides;if(In&&$n in In)return In[$n];if(arguments.length>1)return _n&&isFunction$3(Cn)?Cn.call(Pn&&Pn.proxy):Cn}}function initProps($n,Cn,_n,Pn=!1){const In={},Nn={};def(Nn,InternalObjectKey,1),$n.propsDefaults=Object.create(null),setFullProps($n,Cn,In,Nn);for(const Rn in $n.propsOptions[0])Rn in In||(In[Rn]=void 0);_n?$n.props=Pn?In:shallowReactive(In):$n.type.props?$n.props=In:$n.props=Nn,$n.attrs=Nn}function updateProps($n,Cn,_n,Pn){const{props:In,attrs:Nn,vnode:{patchFlag:Rn}}=$n,Dn=toRaw(In),[Ln]=$n.propsOptions;let Fn=!1;if((Pn||Rn>0)&&!(Rn&16)){if(Rn&8){const Bn=$n.vnode.dynamicProps;for(let Hn=0;Hn{Ln=!0;const[zn,Wn]=normalizePropsOptions(Hn,Cn,!0);extend(Rn,zn),Wn&&Dn.push(...Wn)};!_n&&Cn.mixins.length&&Cn.mixins.forEach(Bn),$n.extends&&Bn($n.extends),$n.mixins&&$n.mixins.forEach(Bn)}if(!Nn&&!Ln)return isObject$7($n)&&Pn.set($n,EMPTY_ARR),EMPTY_ARR;if(isArray$4(Nn))for(let Bn=0;Bn-1,Wn[1]=Gn<0||Yn-1||hasOwn$2(Wn,"default"))&&Dn.push(Hn)}}}const Fn=[Rn,Dn];return isObject$7($n)&&Pn.set($n,Fn),Fn}function validatePropName($n){return $n[0]!=="$"}function getType($n){const Cn=$n&&$n.toString().match(/^\s*(function|class) (\w+)/);return Cn?Cn[2]:$n===null?"null":""}function isSameType($n,Cn){return getType($n)===getType(Cn)}function getTypeIndex($n,Cn){return isArray$4(Cn)?Cn.findIndex(_n=>isSameType(_n,$n)):isFunction$3(Cn)&&isSameType(Cn,$n)?0:-1}const isInternalKey=$n=>$n[0]==="_"||$n==="$stable",normalizeSlotValue=$n=>isArray$4($n)?$n.map(normalizeVNode):[normalizeVNode($n)],normalizeSlot$1=($n,Cn,_n)=>{if(Cn._n)return Cn;const Pn=withCtx((...In)=>normalizeSlotValue(Cn(...In)),_n);return Pn._c=!1,Pn},normalizeObjectSlots=($n,Cn,_n)=>{const Pn=$n._ctx;for(const In in $n){if(isInternalKey(In))continue;const Nn=$n[In];if(isFunction$3(Nn))Cn[In]=normalizeSlot$1(In,Nn,Pn);else if(Nn!=null){const Rn=normalizeSlotValue(Nn);Cn[In]=()=>Rn}}},normalizeVNodeSlots=($n,Cn)=>{const _n=normalizeSlotValue(Cn);$n.slots.default=()=>_n},initSlots=($n,Cn)=>{if($n.vnode.shapeFlag&32){const _n=Cn._;_n?($n.slots=toRaw(Cn),def(Cn,"_",_n)):normalizeObjectSlots(Cn,$n.slots={})}else $n.slots={},Cn&&normalizeVNodeSlots($n,Cn);def($n.slots,InternalObjectKey,1)},updateSlots=($n,Cn,_n)=>{const{vnode:Pn,slots:In}=$n;let Nn=!0,Rn=EMPTY_OBJ;if(Pn.shapeFlag&32){const Dn=Cn._;Dn?_n&&Dn===1?Nn=!1:(extend(In,Cn),!_n&&Dn===1&&delete In._):(Nn=!Cn.$stable,normalizeObjectSlots(Cn,In)),Rn=Cn}else Cn&&(normalizeVNodeSlots($n,Cn),Rn={default:1});if(Nn)for(const Dn in In)!isInternalKey(Dn)&&Rn[Dn]==null&&delete In[Dn]};function setRef($n,Cn,_n,Pn,In=!1){if(isArray$4($n)){$n.forEach((zn,Wn)=>setRef(zn,Cn&&(isArray$4(Cn)?Cn[Wn]:Cn),_n,Pn,In));return}if(isAsyncWrapper(Pn)&&!In)return;const Nn=Pn.shapeFlag&4?getExposeProxy(Pn.component)||Pn.component.proxy:Pn.el,Rn=In?null:Nn,{i:Dn,r:Ln}=$n,Fn=Cn&&Cn.r,Bn=Dn.refs===EMPTY_OBJ?Dn.refs={}:Dn.refs,Hn=Dn.setupState;if(Fn!=null&&Fn!==Ln&&(isString$4(Fn)?(Bn[Fn]=null,hasOwn$2(Hn,Fn)&&(Hn[Fn]=null)):isRef(Fn)&&(Fn.value=null)),isFunction$3(Ln))callWithErrorHandling(Ln,Dn,12,[Rn,Bn]);else{const zn=isString$4(Ln),Wn=isRef(Ln),Yn=$n.f;if(zn||Wn){const Gn=()=>{if(Yn){const Go=zn?hasOwn$2(Hn,Ln)?Hn[Ln]:Bn[Ln]:Ln.value;In?isArray$4(Go)&&remove(Go,Nn):isArray$4(Go)?Go.includes(Nn)||Go.push(Nn):zn?(Bn[Ln]=[Nn],hasOwn$2(Hn,Ln)&&(Hn[Ln]=Bn[Ln])):(Ln.value=[Nn],$n.k&&(Bn[$n.k]=Ln.value))}else zn?(Bn[Ln]=Rn,hasOwn$2(Hn,Ln)&&(Hn[Ln]=Rn)):Wn&&(Ln.value=Rn,$n.k&&(Bn[$n.k]=Rn))};In||Yn?Gn():(Gn.id=-1,queuePostRenderEffect(Gn,_n))}}}const queuePostRenderEffect=queueEffectWithSuspense;function createRenderer($n){return baseCreateRenderer($n)}function baseCreateRenderer($n,Cn){const _n=getGlobalThis$1();_n.__VUE__=!0;const{insert:Pn,remove:In,patchProp:Nn,createElement:Rn,createText:Dn,createComment:Ln,setText:Fn,setElementText:Bn,parentNode:Hn,nextSibling:zn,setScopeId:Wn=NOOP,insertStaticContent:Yn}=$n,Gn=(da,pa,Sa,Aa=null,Ra=null,Fa=null,za=void 0,Wa=null,Ya=!!pa.dynamicChildren)=>{if(da===pa)return;da&&!isSameVNodeType(da,pa)&&(Aa=wa(da),ba(da,Ra,Fa,!0),da=null),pa.patchFlag===-2&&(Ya=!1,pa.dynamicChildren=null);const{type:ja,ref:qa,shapeFlag:Xa}=pa;switch(ja){case Text$2:Go(da,pa,Sa,Aa);break;case Comment$1:Xn(da,pa,Sa,Aa);break;case Static:da==null&&Yo(pa,Sa,Aa,za);break;case Fragment:la(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya);break;default:Xa&1?Zo(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya):Xa&6?ua(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya):(Xa&64||Xa&128)&&ja.process(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya,$a)}qa!=null&&Ra&&setRef(qa,da&&da.ref,Fa,pa||da,!pa)},Go=(da,pa,Sa,Aa)=>{if(da==null)Pn(pa.el=Dn(pa.children),Sa,Aa);else{const Ra=pa.el=da.el;pa.children!==da.children&&Fn(Ra,pa.children)}},Xn=(da,pa,Sa,Aa)=>{da==null?Pn(pa.el=Ln(pa.children||""),Sa,Aa):pa.el=da.el},Yo=(da,pa,Sa,Aa)=>{[da.el,da.anchor]=Yn(da.children,pa,Sa,Aa,da.el,da.anchor)},qo=({el:da,anchor:pa},Sa,Aa)=>{let Ra;for(;da&&da!==pa;)Ra=zn(da),Pn(da,Sa,Aa),da=Ra;Pn(pa,Sa,Aa)},Jo=({el:da,anchor:pa})=>{let Sa;for(;da&&da!==pa;)Sa=zn(da),In(da),da=Sa;In(pa)},Zo=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya)=>{pa.type==="svg"?za="svg":pa.type==="math"&&(za="mathml"),da==null?rr(pa,Sa,Aa,Ra,Fa,za,Wa,Ya):oa(da,pa,Ra,Fa,za,Wa,Ya)},rr=(da,pa,Sa,Aa,Ra,Fa,za,Wa)=>{let Ya,ja;const{props:qa,shapeFlag:Xa,transition:Oa,dirs:Ma}=da;if(Ya=da.el=Rn(da.type,Fa,qa&&qa.is,qa),Xa&8?Bn(Ya,da.children):Xa&16&&ta(da.children,Ya,null,Aa,Ra,resolveChildrenNamespace(da,Fa),za,Wa),Ma&&invokeDirectiveHook(da,null,Aa,"created"),nr(Ya,da,da.scopeId,za,Aa),qa){for(const Qa in qa)Qa!=="value"&&!isReservedProp(Qa)&&Nn(Ya,Qa,null,qa[Qa],Fa,da.children,Aa,Ra,Ta);"value"in qa&&Nn(Ya,"value",null,qa.value,Fa),(ja=qa.onVnodeBeforeMount)&&invokeVNodeHook(ja,Aa,da)}Ma&&invokeDirectiveHook(da,null,Aa,"beforeMount");const Ua=needTransition(Ra,Oa);Ua&&Oa.beforeEnter(Ya),Pn(Ya,pa,Sa),((ja=qa&&qa.onVnodeMounted)||Ua||Ma)&&queuePostRenderEffect(()=>{ja&&invokeVNodeHook(ja,Aa,da),Ua&&Oa.enter(Ya),Ma&&invokeDirectiveHook(da,null,Aa,"mounted")},Ra)},nr=(da,pa,Sa,Aa,Ra)=>{if(Sa&&Wn(da,Sa),Aa)for(let Fa=0;Fa{for(let ja=Ya;ja{const Wa=pa.el=da.el;let{patchFlag:Ya,dynamicChildren:ja,dirs:qa}=pa;Ya|=da.patchFlag&16;const Xa=da.props||EMPTY_OBJ,Oa=pa.props||EMPTY_OBJ;let Ma;if(Sa&&toggleRecurse(Sa,!1),(Ma=Oa.onVnodeBeforeUpdate)&&invokeVNodeHook(Ma,Sa,pa,da),qa&&invokeDirectiveHook(pa,da,Sa,"beforeUpdate"),Sa&&toggleRecurse(Sa,!0),ja?ra(da.dynamicChildren,ja,Wa,Sa,Aa,resolveChildrenNamespace(pa,Ra),Fa):za||ia(da,pa,Wa,null,Sa,Aa,resolveChildrenNamespace(pa,Ra),Fa,!1),Ya>0){if(Ya&16)ea(Wa,pa,Xa,Oa,Sa,Aa,Ra);else if(Ya&2&&Xa.class!==Oa.class&&Nn(Wa,"class",null,Oa.class,Ra),Ya&4&&Nn(Wa,"style",Xa.style,Oa.style,Ra),Ya&8){const Ua=pa.dynamicProps;for(let Qa=0;Qa{Ma&&invokeVNodeHook(Ma,Sa,pa,da),qa&&invokeDirectiveHook(pa,da,Sa,"updated")},Aa)},ra=(da,pa,Sa,Aa,Ra,Fa,za)=>{for(let Wa=0;Wa{if(Sa!==Aa){if(Sa!==EMPTY_OBJ)for(const Wa in Sa)!isReservedProp(Wa)&&!(Wa in Aa)&&Nn(da,Wa,Sa[Wa],null,za,pa.children,Ra,Fa,Ta);for(const Wa in Aa){if(isReservedProp(Wa))continue;const Ya=Aa[Wa],ja=Sa[Wa];Ya!==ja&&Wa!=="value"&&Nn(da,Wa,ja,Ya,za,pa.children,Ra,Fa,Ta)}"value"in Aa&&Nn(da,"value",Sa.value,Aa.value,za)}},la=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya)=>{const ja=pa.el=da?da.el:Dn(""),qa=pa.anchor=da?da.anchor:Dn("");let{patchFlag:Xa,dynamicChildren:Oa,slotScopeIds:Ma}=pa;Ma&&(Wa=Wa?Wa.concat(Ma):Ma),da==null?(Pn(ja,Sa,Aa),Pn(qa,Sa,Aa),ta(pa.children||[],Sa,qa,Ra,Fa,za,Wa,Ya)):Xa>0&&Xa&64&&Oa&&da.dynamicChildren?(ra(da.dynamicChildren,Oa,Sa,Ra,Fa,za,Wa),(pa.key!=null||Ra&&pa===Ra.subTree)&&traverseStaticChildren(da,pa,!0)):ia(da,pa,Sa,qa,Ra,Fa,za,Wa,Ya)},ua=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya)=>{pa.slotScopeIds=Wa,da==null?pa.shapeFlag&512?Ra.ctx.activate(pa,Sa,Aa,za,Ya):ga(pa,Sa,Aa,Ra,Fa,za,Ya):aa(da,pa,Ya)},ga=(da,pa,Sa,Aa,Ra,Fa,za)=>{const Wa=da.component=createComponentInstance(da,Aa,Ra);if(isKeepAlive(da)&&(Wa.ctx.renderer=$a),setupComponent(Wa),Wa.asyncDep){if(Ra&&Ra.registerDep(Wa,ca),!da.el){const Ya=Wa.subTree=createVNode(Comment$1);Xn(null,Ya,pa,Sa)}}else ca(Wa,da,pa,Sa,Ra,Fa,za)},aa=(da,pa,Sa)=>{const Aa=pa.component=da.component;if(shouldUpdateComponent(da,pa,Sa))if(Aa.asyncDep&&!Aa.asyncResolved){sa(Aa,pa,Sa);return}else Aa.next=pa,invalidateJob(Aa.update),Aa.effect.dirty=!0,Aa.update();else pa.el=da.el,Aa.vnode=pa},ca=(da,pa,Sa,Aa,Ra,Fa,za)=>{const Wa=()=>{if(da.isMounted){let{next:qa,bu:Xa,u:Oa,parent:Ma,vnode:Ua}=da;{const ti=locateNonHydratedAsyncRoot(da);if(ti){qa&&(qa.el=Ua.el,sa(da,qa,za)),ti.asyncDep.then(()=>{da.isUnmounted||Wa()});return}}let Qa=qa,ri;toggleRecurse(da,!1),qa?(qa.el=Ua.el,sa(da,qa,za)):qa=Ua,Xa&&invokeArrayFns(Xa),(ri=qa.props&&qa.props.onVnodeBeforeUpdate)&&invokeVNodeHook(ri,Ma,qa,Ua),toggleRecurse(da,!0);const fi=renderComponentRoot(da),ei=da.subTree;da.subTree=fi,Gn(ei,fi,Hn(ei.el),wa(ei),da,Ra,Fa),qa.el=fi.el,Qa===null&&updateHOCHostEl(da,fi.el),Oa&&queuePostRenderEffect(Oa,Ra),(ri=qa.props&&qa.props.onVnodeUpdated)&&queuePostRenderEffect(()=>invokeVNodeHook(ri,Ma,qa,Ua),Ra)}else{let qa;const{el:Xa,props:Oa}=pa,{bm:Ma,m:Ua,parent:Qa}=da,ri=isAsyncWrapper(pa);if(toggleRecurse(da,!1),Ma&&invokeArrayFns(Ma),!ri&&(qa=Oa&&Oa.onVnodeBeforeMount)&&invokeVNodeHook(qa,Qa,pa),toggleRecurse(da,!0),Xa&&Ha){const fi=()=>{da.subTree=renderComponentRoot(da),Ha(Xa,da.subTree,da,Ra,null)};ri?pa.type.__asyncLoader().then(()=>!da.isUnmounted&&fi()):fi()}else{const fi=da.subTree=renderComponentRoot(da);Gn(null,fi,Sa,Aa,da,Ra,Fa),pa.el=fi.el}if(Ua&&queuePostRenderEffect(Ua,Ra),!ri&&(qa=Oa&&Oa.onVnodeMounted)){const fi=pa;queuePostRenderEffect(()=>invokeVNodeHook(qa,Qa,fi),Ra)}(pa.shapeFlag&256||Qa&&isAsyncWrapper(Qa.vnode)&&Qa.vnode.shapeFlag&256)&&da.a&&queuePostRenderEffect(da.a,Ra),da.isMounted=!0,pa=Sa=Aa=null}},Ya=da.effect=new ReactiveEffect(Wa,NOOP,()=>queueJob(ja),da.scope),ja=da.update=()=>{Ya.dirty&&Ya.run()};ja.id=da.uid,toggleRecurse(da,!0),ja()},sa=(da,pa,Sa)=>{pa.component=da;const Aa=da.vnode.props;da.vnode=pa,da.next=null,updateProps(da,pa.props,Aa,Sa),updateSlots(da,pa.children,Sa),pauseTracking(),flushPreFlushCbs(da),resetTracking()},ia=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya=!1)=>{const ja=da&&da.children,qa=da?da.shapeFlag:0,Xa=pa.children,{patchFlag:Oa,shapeFlag:Ma}=pa;if(Oa>0){if(Oa&128){ma(ja,Xa,Sa,Aa,Ra,Fa,za,Wa,Ya);return}else if(Oa&256){fa(ja,Xa,Sa,Aa,Ra,Fa,za,Wa,Ya);return}}Ma&8?(qa&16&&Ta(ja,Ra,Fa),Xa!==ja&&Bn(Sa,Xa)):qa&16?Ma&16?ma(ja,Xa,Sa,Aa,Ra,Fa,za,Wa,Ya):Ta(ja,Ra,Fa,!0):(qa&8&&Bn(Sa,""),Ma&16&&ta(Xa,Sa,Aa,Ra,Fa,za,Wa,Ya))},fa=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya)=>{da=da||EMPTY_ARR,pa=pa||EMPTY_ARR;const ja=da.length,qa=pa.length,Xa=Math.min(ja,qa);let Oa;for(Oa=0;Oaqa?Ta(da,Ra,Fa,!0,!1,Xa):ta(pa,Sa,Aa,Ra,Fa,za,Wa,Ya,Xa)},ma=(da,pa,Sa,Aa,Ra,Fa,za,Wa,Ya)=>{let ja=0;const qa=pa.length;let Xa=da.length-1,Oa=qa-1;for(;ja<=Xa&&ja<=Oa;){const Ma=da[ja],Ua=pa[ja]=Ya?cloneIfMounted(pa[ja]):normalizeVNode(pa[ja]);if(isSameVNodeType(Ma,Ua))Gn(Ma,Ua,Sa,null,Ra,Fa,za,Wa,Ya);else break;ja++}for(;ja<=Xa&&ja<=Oa;){const Ma=da[Xa],Ua=pa[Oa]=Ya?cloneIfMounted(pa[Oa]):normalizeVNode(pa[Oa]);if(isSameVNodeType(Ma,Ua))Gn(Ma,Ua,Sa,null,Ra,Fa,za,Wa,Ya);else break;Xa--,Oa--}if(ja>Xa){if(ja<=Oa){const Ma=Oa+1,Ua=MaOa)for(;ja<=Xa;)ba(da[ja],Ra,Fa,!0),ja++;else{const Ma=ja,Ua=ja,Qa=new Map;for(ja=Ua;ja<=Oa;ja++){const di=pa[ja]=Ya?cloneIfMounted(pa[ja]):normalizeVNode(pa[ja]);di.key!=null&&Qa.set(di.key,ja)}let ri,fi=0;const ei=Oa-Ua+1;let ti=!1,ni=0;const ui=new Array(ei);for(ja=0;ja=ei){ba(di,Ra,Fa,!0);continue}let gi;if(di.key!=null)gi=Qa.get(di.key);else for(ri=Ua;ri<=Oa;ri++)if(ui[ri-Ua]===0&&isSameVNodeType(di,pa[ri])){gi=ri;break}gi===void 0?ba(di,Ra,Fa,!0):(ui[gi-Ua]=ja+1,gi>=ni?ni=gi:ti=!0,Gn(di,pa[gi],Sa,null,Ra,Fa,za,Wa,Ya),fi++)}const mi=ti?getSequence(ui):EMPTY_ARR;for(ri=mi.length-1,ja=ei-1;ja>=0;ja--){const di=Ua+ja,gi=pa[di],wi=di+1{const{el:Fa,type:za,transition:Wa,children:Ya,shapeFlag:ja}=da;if(ja&6){ya(da.component.subTree,pa,Sa,Aa);return}if(ja&128){da.suspense.move(pa,Sa,Aa);return}if(ja&64){za.move(da,pa,Sa,$a);return}if(za===Fragment){Pn(Fa,pa,Sa);for(let Xa=0;XaWa.enter(Fa),Ra);else{const{leave:Xa,delayLeave:Oa,afterLeave:Ma}=Wa,Ua=()=>Pn(Fa,pa,Sa),Qa=()=>{Xa(Fa,()=>{Ua(),Ma&&Ma()})};Oa?Oa(Fa,Ua,Qa):Qa()}else Pn(Fa,pa,Sa)},ba=(da,pa,Sa,Aa=!1,Ra=!1)=>{const{type:Fa,props:za,ref:Wa,children:Ya,dynamicChildren:ja,shapeFlag:qa,patchFlag:Xa,dirs:Oa}=da;if(Wa!=null&&setRef(Wa,null,Sa,da,!0),qa&256){pa.ctx.deactivate(da);return}const Ma=qa&1&&Oa,Ua=!isAsyncWrapper(da);let Qa;if(Ua&&(Qa=za&&za.onVnodeBeforeUnmount)&&invokeVNodeHook(Qa,pa,da),qa&6)xa(da.component,Sa,Aa);else{if(qa&128){da.suspense.unmount(Sa,Aa);return}Ma&&invokeDirectiveHook(da,null,pa,"beforeUnmount"),qa&64?da.type.remove(da,pa,Sa,Ra,$a,Aa):ja&&(Fa!==Fragment||Xa>0&&Xa&64)?Ta(ja,pa,Sa,!1,!0):(Fa===Fragment&&Xa&384||!Ra&&qa&16)&&Ta(Ya,pa,Sa),Aa&&Ia(da)}(Ua&&(Qa=za&&za.onVnodeUnmounted)||Ma)&&queuePostRenderEffect(()=>{Qa&&invokeVNodeHook(Qa,pa,da),Ma&&invokeDirectiveHook(da,null,pa,"unmounted")},Sa)},Ia=da=>{const{type:pa,el:Sa,anchor:Aa,transition:Ra}=da;if(pa===Fragment){Ea(Sa,Aa);return}if(pa===Static){Jo(da);return}const Fa=()=>{In(Sa),Ra&&!Ra.persisted&&Ra.afterLeave&&Ra.afterLeave()};if(da.shapeFlag&1&&Ra&&!Ra.persisted){const{leave:za,delayLeave:Wa}=Ra,Ya=()=>za(Sa,Fa);Wa?Wa(da.el,Fa,Ya):Ya()}else Fa()},Ea=(da,pa)=>{let Sa;for(;da!==pa;)Sa=zn(da),In(da),da=Sa;In(pa)},xa=(da,pa,Sa)=>{const{bum:Aa,scope:Ra,update:Fa,subTree:za,um:Wa}=da;Aa&&invokeArrayFns(Aa),Ra.stop(),Fa&&(Fa.active=!1,ba(za,da,pa,Sa)),Wa&&queuePostRenderEffect(Wa,pa),queuePostRenderEffect(()=>{da.isUnmounted=!0},pa),pa&&pa.pendingBranch&&!pa.isUnmounted&&da.asyncDep&&!da.asyncResolved&&da.suspenseId===pa.pendingId&&(pa.deps--,pa.deps===0&&pa.resolve())},Ta=(da,pa,Sa,Aa=!1,Ra=!1,Fa=0)=>{for(let za=Fa;zada.shapeFlag&6?wa(da.component.subTree):da.shapeFlag&128?da.suspense.next():zn(da.anchor||da.el);let La=!1;const Na=(da,pa,Sa)=>{da==null?pa._vnode&&ba(pa._vnode,null,null,!0):Gn(pa._vnode||null,da,pa,null,null,null,Sa),La||(La=!0,flushPreFlushCbs(),flushPostFlushCbs(),La=!1),pa._vnode=da},$a={p:Gn,um:ba,m:ya,r:Ia,mt:ga,mc:ta,pc:ia,pbc:ra,n:wa,o:$n};let ka,Ha;return Cn&&([ka,Ha]=Cn($a)),{render:Na,hydrate:ka,createApp:createAppAPI(Na,ka)}}function resolveChildrenNamespace({type:$n,props:Cn},_n){return _n==="svg"&&$n==="foreignObject"||_n==="mathml"&&$n==="annotation-xml"&&Cn&&Cn.encoding&&Cn.encoding.includes("html")?void 0:_n}function toggleRecurse({effect:$n,update:Cn},_n){$n.allowRecurse=Cn.allowRecurse=_n}function needTransition($n,Cn){return(!$n||$n&&!$n.pendingBranch)&&Cn&&!Cn.persisted}function traverseStaticChildren($n,Cn,_n=!1){const Pn=$n.children,In=Cn.children;if(isArray$4(Pn)&&isArray$4(In))for(let Nn=0;Nn>1,$n[_n[Dn]]0&&(Cn[Pn]=_n[Nn-1]),_n[Nn]=Pn)}}for(Nn=_n.length,Rn=_n[Nn-1];Nn-- >0;)_n[Nn]=Rn,Rn=Cn[Rn];return _n}function locateNonHydratedAsyncRoot($n){const Cn=$n.subTree.component;if(Cn)return Cn.asyncDep&&!Cn.asyncResolved?Cn:locateNonHydratedAsyncRoot(Cn)}const isTeleport=$n=>$n.__isTeleport,isTeleportDisabled=$n=>$n&&($n.disabled||$n.disabled===""),isTargetSVG=$n=>typeof SVGElement<"u"&&$n instanceof SVGElement,isTargetMathML=$n=>typeof MathMLElement=="function"&&$n instanceof MathMLElement,resolveTarget=($n,Cn)=>{const _n=$n&&$n.to;return isString$4(_n)?Cn?Cn(_n):null:_n},TeleportImpl={name:"Teleport",__isTeleport:!0,process($n,Cn,_n,Pn,In,Nn,Rn,Dn,Ln,Fn){const{mc:Bn,pc:Hn,pbc:zn,o:{insert:Wn,querySelector:Yn,createText:Gn,createComment:Go}}=Fn,Xn=isTeleportDisabled(Cn.props);let{shapeFlag:Yo,children:qo,dynamicChildren:Jo}=Cn;if($n==null){const Zo=Cn.el=Gn(""),rr=Cn.anchor=Gn("");Wn(Zo,_n,Pn),Wn(rr,_n,Pn);const nr=Cn.target=resolveTarget(Cn.props,Yn),ta=Cn.targetAnchor=Gn("");nr&&(Wn(ta,nr),Rn==="svg"||isTargetSVG(nr)?Rn="svg":(Rn==="mathml"||isTargetMathML(nr))&&(Rn="mathml"));const oa=(ra,ea)=>{Yo&16&&Bn(qo,ra,ea,In,Nn,Rn,Dn,Ln)};Xn?oa(_n,rr):nr&&oa(nr,ta)}else{Cn.el=$n.el;const Zo=Cn.anchor=$n.anchor,rr=Cn.target=$n.target,nr=Cn.targetAnchor=$n.targetAnchor,ta=isTeleportDisabled($n.props),oa=ta?_n:rr,ra=ta?Zo:nr;if(Rn==="svg"||isTargetSVG(rr)?Rn="svg":(Rn==="mathml"||isTargetMathML(rr))&&(Rn="mathml"),Jo?(zn($n.dynamicChildren,Jo,oa,In,Nn,Rn,Dn),traverseStaticChildren($n,Cn,!0)):Ln||Hn($n,Cn,oa,ra,In,Nn,Rn,Dn,!1),Xn)ta?Cn.props&&$n.props&&Cn.props.to!==$n.props.to&&(Cn.props.to=$n.props.to):moveTeleport(Cn,_n,Zo,Fn,1);else if((Cn.props&&Cn.props.to)!==($n.props&&$n.props.to)){const ea=Cn.target=resolveTarget(Cn.props,Yn);ea&&moveTeleport(Cn,ea,null,Fn,0)}else ta&&moveTeleport(Cn,rr,nr,Fn,1)}updateCssVars(Cn)},remove($n,Cn,_n,Pn,{um:In,o:{remove:Nn}},Rn){const{shapeFlag:Dn,children:Ln,anchor:Fn,targetAnchor:Bn,target:Hn,props:zn}=$n;if(Hn&&Nn(Bn),Rn&&Nn(Fn),Dn&16){const Wn=Rn||!isTeleportDisabled(zn);for(let Yn=0;Yn0?currentBlock||EMPTY_ARR:null,closeBlock(),isBlockTreeEnabled>0&¤tBlock&¤tBlock.push($n),$n}function createElementBlock($n,Cn,_n,Pn,In,Nn){return setupBlock(createBaseVNode($n,Cn,_n,Pn,In,Nn,!0))}function createBlock($n,Cn,_n,Pn,In){return setupBlock(createVNode($n,Cn,_n,Pn,In,!0))}function isVNode$1($n){return $n?$n.__v_isVNode===!0:!1}function isSameVNodeType($n,Cn){return $n.type===Cn.type&&$n.key===Cn.key}const InternalObjectKey="__vInternal",normalizeKey=({key:$n})=>$n??null,normalizeRef=({ref:$n,ref_key:Cn,ref_for:_n})=>(typeof $n=="number"&&($n=""+$n),$n!=null?isString$4($n)||isRef($n)||isFunction$3($n)?{i:currentRenderingInstance,r:$n,k:Cn,f:!!_n}:$n:null);function createBaseVNode($n,Cn=null,_n=null,Pn=0,In=null,Nn=$n===Fragment?0:1,Rn=!1,Dn=!1){const Ln={__v_isVNode:!0,__v_skip:!0,type:$n,props:Cn,key:Cn&&normalizeKey(Cn),ref:Cn&&normalizeRef(Cn),scopeId:currentScopeId,slotScopeIds:null,children:_n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:Nn,patchFlag:Pn,dynamicProps:In,dynamicChildren:null,appContext:null,ctx:currentRenderingInstance};return Dn?(normalizeChildren(Ln,_n),Nn&128&&$n.normalize(Ln)):_n&&(Ln.shapeFlag|=isString$4(_n)?8:16),isBlockTreeEnabled>0&&!Rn&¤tBlock&&(Ln.patchFlag>0||Nn&6)&&Ln.patchFlag!==32&¤tBlock.push(Ln),Ln}const createVNode=_createVNode;function _createVNode($n,Cn=null,_n=null,Pn=0,In=null,Nn=!1){if((!$n||$n===NULL_DYNAMIC_COMPONENT)&&($n=Comment$1),isVNode$1($n)){const Dn=cloneVNode($n,Cn,!0);return _n&&normalizeChildren(Dn,_n),isBlockTreeEnabled>0&&!Nn&¤tBlock&&(Dn.shapeFlag&6?currentBlock[currentBlock.indexOf($n)]=Dn:currentBlock.push(Dn)),Dn.patchFlag|=-2,Dn}if(isClassComponent($n)&&($n=$n.__vccOpts),Cn){Cn=guardReactiveProps(Cn);let{class:Dn,style:Ln}=Cn;Dn&&!isString$4(Dn)&&(Cn.class=normalizeClass(Dn)),isObject$7(Ln)&&(isProxy(Ln)&&!isArray$4(Ln)&&(Ln=extend({},Ln)),Cn.style=normalizeStyle$1(Ln))}const Rn=isString$4($n)?1:isSuspense($n)?128:isTeleport($n)?64:isObject$7($n)?4:isFunction$3($n)?2:0;return createBaseVNode($n,Cn,_n,Pn,In,Rn,Nn,!0)}function guardReactiveProps($n){return $n?isProxy($n)||InternalObjectKey in $n?extend({},$n):$n:null}function cloneVNode($n,Cn,_n=!1){const{props:Pn,ref:In,patchFlag:Nn,children:Rn}=$n,Dn=Cn?mergeProps(Pn||{},Cn):Pn;return{__v_isVNode:!0,__v_skip:!0,type:$n.type,props:Dn,key:Dn&&normalizeKey(Dn),ref:Cn&&Cn.ref?_n&&In?isArray$4(In)?In.concat(normalizeRef(Cn)):[In,normalizeRef(Cn)]:normalizeRef(Cn):In,scopeId:$n.scopeId,slotScopeIds:$n.slotScopeIds,children:Rn,target:$n.target,targetAnchor:$n.targetAnchor,staticCount:$n.staticCount,shapeFlag:$n.shapeFlag,patchFlag:Cn&&$n.type!==Fragment?Nn===-1?16:Nn|16:Nn,dynamicProps:$n.dynamicProps,dynamicChildren:$n.dynamicChildren,appContext:$n.appContext,dirs:$n.dirs,transition:$n.transition,component:$n.component,suspense:$n.suspense,ssContent:$n.ssContent&&cloneVNode($n.ssContent),ssFallback:$n.ssFallback&&cloneVNode($n.ssFallback),el:$n.el,anchor:$n.anchor,ctx:$n.ctx,ce:$n.ce}}function createTextVNode($n=" ",Cn=0){return createVNode(Text$2,null,$n,Cn)}function createCommentVNode($n="",Cn=!1){return Cn?(openBlock(),createBlock(Comment$1,null,$n)):createVNode(Comment$1,null,$n)}function normalizeVNode($n){return $n==null||typeof $n=="boolean"?createVNode(Comment$1):isArray$4($n)?createVNode(Fragment,null,$n.slice()):typeof $n=="object"?cloneIfMounted($n):createVNode(Text$2,null,String($n))}function cloneIfMounted($n){return $n.el===null&&$n.patchFlag!==-1||$n.memo?$n:cloneVNode($n)}function normalizeChildren($n,Cn){let _n=0;const{shapeFlag:Pn}=$n;if(Cn==null)Cn=null;else if(isArray$4(Cn))_n=16;else if(typeof Cn=="object")if(Pn&65){const In=Cn.default;In&&(In._c&&(In._d=!1),normalizeChildren($n,In()),In._c&&(In._d=!0));return}else{_n=32;const In=Cn._;!In&&!(InternalObjectKey in Cn)?Cn._ctx=currentRenderingInstance:In===3&¤tRenderingInstance&&(currentRenderingInstance.slots._===1?Cn._=1:(Cn._=2,$n.patchFlag|=1024))}else isFunction$3(Cn)?(Cn={default:Cn,_ctx:currentRenderingInstance},_n=32):(Cn=String(Cn),Pn&64?(_n=16,Cn=[createTextVNode(Cn)]):_n=8);$n.children=Cn,$n.shapeFlag|=_n}function mergeProps(...$n){const Cn={};for(let _n=0;_n<$n.length;_n++){const Pn=$n[_n];for(const In in Pn)if(In==="class")Cn.class!==Pn.class&&(Cn.class=normalizeClass([Cn.class,Pn.class]));else if(In==="style")Cn.style=normalizeStyle$1([Cn.style,Pn.style]);else if(isOn$1(In)){const Nn=Cn[In],Rn=Pn[In];Rn&&Nn!==Rn&&!(isArray$4(Nn)&&Nn.includes(Rn))&&(Cn[In]=Nn?[].concat(Nn,Rn):Rn)}else In!==""&&(Cn[In]=Pn[In])}return Cn}function invokeVNodeHook($n,Cn,_n,Pn=null){callWithAsyncErrorHandling($n,Cn,7,[_n,Pn])}const emptyAppContext=createAppContext();let uid$2=0;function createComponentInstance($n,Cn,_n){const Pn=$n.type,In=(Cn?Cn.appContext:$n.appContext)||emptyAppContext,Nn={uid:uid$2++,vnode:$n,type:Pn,parent:Cn,appContext:In,root:null,next:null,subTree:null,effect:null,update:null,scope:new EffectScope(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:Cn?Cn.provides:Object.create(In.provides),accessCache:null,renderCache:[],components:null,directives:null,propsOptions:normalizePropsOptions(Pn,In),emitsOptions:normalizeEmitsOptions(Pn,In),emit:null,emitted:null,propsDefaults:EMPTY_OBJ,inheritAttrs:Pn.inheritAttrs,ctx:EMPTY_OBJ,data:EMPTY_OBJ,props:EMPTY_OBJ,attrs:EMPTY_OBJ,slots:EMPTY_OBJ,refs:EMPTY_OBJ,setupState:EMPTY_OBJ,setupContext:null,attrsProxy:null,slotsProxy:null,suspense:_n,suspenseId:_n?_n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return Nn.ctx={_:Nn},Nn.root=Cn?Cn.root:Nn,Nn.emit=emit.bind(null,Nn),$n.ce&&$n.ce(Nn),Nn}let currentInstance=null;const getCurrentInstance=()=>currentInstance||currentRenderingInstance;let internalSetCurrentInstance,setInSSRSetupState;{const $n=getGlobalThis$1(),Cn=(_n,Pn)=>{let In;return(In=$n[_n])||(In=$n[_n]=[]),In.push(Pn),Nn=>{In.length>1?In.forEach(Rn=>Rn(Nn)):In[0](Nn)}};internalSetCurrentInstance=Cn("__VUE_INSTANCE_SETTERS__",_n=>currentInstance=_n),setInSSRSetupState=Cn("__VUE_SSR_SETTERS__",_n=>isInSSRComponentSetup=_n)}const setCurrentInstance=$n=>{const Cn=currentInstance;return internalSetCurrentInstance($n),$n.scope.on(),()=>{$n.scope.off(),internalSetCurrentInstance(Cn)}},unsetCurrentInstance=()=>{currentInstance&¤tInstance.scope.off(),internalSetCurrentInstance(null)};function isStatefulComponent($n){return $n.vnode.shapeFlag&4}let isInSSRComponentSetup=!1;function setupComponent($n,Cn=!1){Cn&&setInSSRSetupState(Cn);const{props:_n,children:Pn}=$n.vnode,In=isStatefulComponent($n);initProps($n,_n,In,Cn),initSlots($n,Pn);const Nn=In?setupStatefulComponent($n,Cn):void 0;return Cn&&setInSSRSetupState(!1),Nn}function setupStatefulComponent($n,Cn){const _n=$n.type;$n.accessCache=Object.create(null),$n.proxy=markRaw(new Proxy($n.ctx,PublicInstanceProxyHandlers));const{setup:Pn}=_n;if(Pn){const In=$n.setupContext=Pn.length>1?createSetupContext($n):null,Nn=setCurrentInstance($n);pauseTracking();const Rn=callWithErrorHandling(Pn,$n,0,[$n.props,In]);if(resetTracking(),Nn(),isPromise$1(Rn)){if(Rn.then(unsetCurrentInstance,unsetCurrentInstance),Cn)return Rn.then(Dn=>{handleSetupResult($n,Dn,Cn)}).catch(Dn=>{handleError(Dn,$n,0)});$n.asyncDep=Rn}else handleSetupResult($n,Rn,Cn)}else finishComponentSetup($n,Cn)}function handleSetupResult($n,Cn,_n){isFunction$3(Cn)?$n.type.__ssrInlineRender?$n.ssrRender=Cn:$n.render=Cn:isObject$7(Cn)&&($n.setupState=proxyRefs(Cn)),finishComponentSetup($n,_n)}let compile$2;function finishComponentSetup($n,Cn,_n){const Pn=$n.type;if(!$n.render){if(!Cn&&compile$2&&!Pn.render){const In=Pn.template||resolveMergedOptions($n).template;if(In){const{isCustomElement:Nn,compilerOptions:Rn}=$n.appContext.config,{delimiters:Dn,compilerOptions:Ln}=Pn,Fn=extend(extend({isCustomElement:Nn,delimiters:Dn},Rn),Ln);Pn.render=compile$2(In,Fn)}}$n.render=Pn.render||NOOP}{const In=setCurrentInstance($n);pauseTracking();try{applyOptions($n)}finally{resetTracking(),In()}}}function getAttrsProxy($n){return $n.attrsProxy||($n.attrsProxy=new Proxy($n.attrs,{get(Cn,_n){return track($n,"get","$attrs"),Cn[_n]}}))}function createSetupContext($n){const Cn=_n=>{$n.exposed=_n||{}};return{get attrs(){return getAttrsProxy($n)},slots:$n.slots,emit:$n.emit,expose:Cn}}function getExposeProxy($n){if($n.exposed)return $n.exposeProxy||($n.exposeProxy=new Proxy(proxyRefs(markRaw($n.exposed)),{get(Cn,_n){if(_n in Cn)return Cn[_n];if(_n in publicPropertiesMap)return publicPropertiesMap[_n]($n)},has(Cn,_n){return _n in Cn||_n in publicPropertiesMap}}))}const classifyRE=/(?:^|[-_])(\w)/g,classify=$n=>$n.replace(classifyRE,Cn=>Cn.toUpperCase()).replace(/[-_]/g,"");function getComponentName($n,Cn=!0){return isFunction$3($n)?$n.displayName||$n.name:$n.name||Cn&&$n.__name}function formatComponentName($n,Cn,_n=!1){let Pn=getComponentName(Cn);if(!Pn&&Cn.__file){const In=Cn.__file.match(/([^/\\]+)\.\w+$/);In&&(Pn=In[1])}if(!Pn&&$n&&$n.parent){const In=Nn=>{for(const Rn in Nn)if(Nn[Rn]===Cn)return Rn};Pn=In($n.components||$n.parent.type.components)||In($n.appContext.components)}return Pn?classify(Pn):_n?"App":"Anonymous"}function isClassComponent($n){return isFunction$3($n)&&"__vccOpts"in $n}const computed=($n,Cn)=>computed$1($n,Cn,isInSSRComponentSetup);function h$3($n,Cn,_n){const Pn=arguments.length;return Pn===2?isObject$7(Cn)&&!isArray$4(Cn)?isVNode$1(Cn)?createVNode($n,null,[Cn]):createVNode($n,Cn):createVNode($n,null,Cn):(Pn>3?_n=Array.prototype.slice.call(arguments,2):Pn===3&&isVNode$1(_n)&&(_n=[_n]),createVNode($n,Cn,_n))}const version$1="3.4.15";/** -* @vue/runtime-dom v3.4.15 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/const svgNS="http://www.w3.org/2000/svg",mathmlNS="http://www.w3.org/1998/Math/MathML",doc=typeof document<"u"?document:null,templateContainer=doc&&doc.createElement("template"),nodeOps={insert:($n,Cn,_n)=>{Cn.insertBefore($n,_n||null)},remove:$n=>{const Cn=$n.parentNode;Cn&&Cn.removeChild($n)},createElement:($n,Cn,_n,Pn)=>{const In=Cn==="svg"?doc.createElementNS(svgNS,$n):Cn==="mathml"?doc.createElementNS(mathmlNS,$n):doc.createElement($n,_n?{is:_n}:void 0);return $n==="select"&&Pn&&Pn.multiple!=null&&In.setAttribute("multiple",Pn.multiple),In},createText:$n=>doc.createTextNode($n),createComment:$n=>doc.createComment($n),setText:($n,Cn)=>{$n.nodeValue=Cn},setElementText:($n,Cn)=>{$n.textContent=Cn},parentNode:$n=>$n.parentNode,nextSibling:$n=>$n.nextSibling,querySelector:$n=>doc.querySelector($n),setScopeId($n,Cn){$n.setAttribute(Cn,"")},insertStaticContent($n,Cn,_n,Pn,In,Nn){const Rn=_n?_n.previousSibling:Cn.lastChild;if(In&&(In===Nn||In.nextSibling))for(;Cn.insertBefore(In.cloneNode(!0),_n),!(In===Nn||!(In=In.nextSibling)););else{templateContainer.innerHTML=Pn==="svg"?`${$n}`:Pn==="mathml"?`${$n}`:$n;const Dn=templateContainer.content;if(Pn==="svg"||Pn==="mathml"){const Ln=Dn.firstChild;for(;Ln.firstChild;)Dn.appendChild(Ln.firstChild);Dn.removeChild(Ln)}Cn.insertBefore(Dn,_n)}return[Rn?Rn.nextSibling:Cn.firstChild,_n?_n.previousSibling:Cn.lastChild]}},TRANSITION="transition",ANIMATION="animation",vtcKey=Symbol("_vtc"),Transition=($n,{slots:Cn})=>h$3(BaseTransition,resolveTransitionProps($n),Cn);Transition.displayName="Transition";const DOMTransitionPropsValidators={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},TransitionPropsValidators=Transition.props=extend({},BaseTransitionPropsValidators,DOMTransitionPropsValidators),callHook=($n,Cn=[])=>{isArray$4($n)?$n.forEach(_n=>_n(...Cn)):$n&&$n(...Cn)},hasExplicitCallback=$n=>$n?isArray$4($n)?$n.some(Cn=>Cn.length>1):$n.length>1:!1;function resolveTransitionProps($n){const Cn={};for(const la in $n)la in DOMTransitionPropsValidators||(Cn[la]=$n[la]);if($n.css===!1)return Cn;const{name:_n="v",type:Pn,duration:In,enterFromClass:Nn=`${_n}-enter-from`,enterActiveClass:Rn=`${_n}-enter-active`,enterToClass:Dn=`${_n}-enter-to`,appearFromClass:Ln=Nn,appearActiveClass:Fn=Rn,appearToClass:Bn=Dn,leaveFromClass:Hn=`${_n}-leave-from`,leaveActiveClass:zn=`${_n}-leave-active`,leaveToClass:Wn=`${_n}-leave-to`}=$n,Yn=normalizeDuration(In),Gn=Yn&&Yn[0],Go=Yn&&Yn[1],{onBeforeEnter:Xn,onEnter:Yo,onEnterCancelled:qo,onLeave:Jo,onLeaveCancelled:Zo,onBeforeAppear:rr=Xn,onAppear:nr=Yo,onAppearCancelled:ta=qo}=Cn,oa=(la,ua,ga)=>{removeTransitionClass(la,ua?Bn:Dn),removeTransitionClass(la,ua?Fn:Rn),ga&&ga()},ra=(la,ua)=>{la._isLeaving=!1,removeTransitionClass(la,Hn),removeTransitionClass(la,Wn),removeTransitionClass(la,zn),ua&&ua()},ea=la=>(ua,ga)=>{const aa=la?nr:Yo,ca=()=>oa(ua,la,ga);callHook(aa,[ua,ca]),nextFrame(()=>{removeTransitionClass(ua,la?Ln:Nn),addTransitionClass(ua,la?Bn:Dn),hasExplicitCallback(aa)||whenTransitionEnds(ua,Pn,Gn,ca)})};return extend(Cn,{onBeforeEnter(la){callHook(Xn,[la]),addTransitionClass(la,Nn),addTransitionClass(la,Rn)},onBeforeAppear(la){callHook(rr,[la]),addTransitionClass(la,Ln),addTransitionClass(la,Fn)},onEnter:ea(!1),onAppear:ea(!0),onLeave(la,ua){la._isLeaving=!0;const ga=()=>ra(la,ua);addTransitionClass(la,Hn),forceReflow(),addTransitionClass(la,zn),nextFrame(()=>{la._isLeaving&&(removeTransitionClass(la,Hn),addTransitionClass(la,Wn),hasExplicitCallback(Jo)||whenTransitionEnds(la,Pn,Go,ga))}),callHook(Jo,[la,ga])},onEnterCancelled(la){oa(la,!1),callHook(qo,[la])},onAppearCancelled(la){oa(la,!0),callHook(ta,[la])},onLeaveCancelled(la){ra(la),callHook(Zo,[la])}})}function normalizeDuration($n){if($n==null)return null;if(isObject$7($n))return[NumberOf($n.enter),NumberOf($n.leave)];{const Cn=NumberOf($n);return[Cn,Cn]}}function NumberOf($n){return toNumber$1($n)}function addTransitionClass($n,Cn){Cn.split(/\s+/).forEach(_n=>_n&&$n.classList.add(_n)),($n[vtcKey]||($n[vtcKey]=new Set)).add(Cn)}function removeTransitionClass($n,Cn){Cn.split(/\s+/).forEach(Pn=>Pn&&$n.classList.remove(Pn));const _n=$n[vtcKey];_n&&(_n.delete(Cn),_n.size||($n[vtcKey]=void 0))}function nextFrame($n){requestAnimationFrame(()=>{requestAnimationFrame($n)})}let endId=0;function whenTransitionEnds($n,Cn,_n,Pn){const In=$n._endId=++endId,Nn=()=>{In===$n._endId&&Pn()};if(_n)return setTimeout(Nn,_n);const{type:Rn,timeout:Dn,propCount:Ln}=getTransitionInfo($n,Cn);if(!Rn)return Pn();const Fn=Rn+"end";let Bn=0;const Hn=()=>{$n.removeEventListener(Fn,zn),Nn()},zn=Wn=>{Wn.target===$n&&++Bn>=Ln&&Hn()};setTimeout(()=>{Bn(_n[Yn]||"").split(", "),In=Pn(`${TRANSITION}Delay`),Nn=Pn(`${TRANSITION}Duration`),Rn=getTimeout(In,Nn),Dn=Pn(`${ANIMATION}Delay`),Ln=Pn(`${ANIMATION}Duration`),Fn=getTimeout(Dn,Ln);let Bn=null,Hn=0,zn=0;Cn===TRANSITION?Rn>0&&(Bn=TRANSITION,Hn=Rn,zn=Nn.length):Cn===ANIMATION?Fn>0&&(Bn=ANIMATION,Hn=Fn,zn=Ln.length):(Hn=Math.max(Rn,Fn),Bn=Hn>0?Rn>Fn?TRANSITION:ANIMATION:null,zn=Bn?Bn===TRANSITION?Nn.length:Ln.length:0);const Wn=Bn===TRANSITION&&/\b(transform|all)(,|$)/.test(Pn(`${TRANSITION}Property`).toString());return{type:Bn,timeout:Hn,propCount:zn,hasTransform:Wn}}function getTimeout($n,Cn){for(;$n.lengthtoMs(_n)+toMs($n[Pn])))}function toMs($n){return $n==="auto"?0:Number($n.slice(0,-1).replace(",","."))*1e3}function forceReflow(){return document.body.offsetHeight}function patchClass($n,Cn,_n){const Pn=$n[vtcKey];Pn&&(Cn=(Cn?[Cn,...Pn]:[...Pn]).join(" ")),Cn==null?$n.removeAttribute("class"):_n?$n.setAttribute("class",Cn):$n.className=Cn}const vShowOldKey=Symbol("_vod"),vShow={beforeMount($n,{value:Cn},{transition:_n}){$n[vShowOldKey]=$n.style.display==="none"?"":$n.style.display,_n&&Cn?_n.beforeEnter($n):setDisplay($n,Cn)},mounted($n,{value:Cn},{transition:_n}){_n&&Cn&&_n.enter($n)},updated($n,{value:Cn,oldValue:_n},{transition:Pn}){!Cn!=!_n&&(Pn?Cn?(Pn.beforeEnter($n),setDisplay($n,!0),Pn.enter($n)):Pn.leave($n,()=>{setDisplay($n,!1)}):setDisplay($n,Cn))},beforeUnmount($n,{value:Cn}){setDisplay($n,Cn)}};function setDisplay($n,Cn){$n.style.display=Cn?$n[vShowOldKey]:"none"}const CSS_VAR_TEXT=Symbol("");function useCssVars($n){const Cn=getCurrentInstance();if(!Cn)return;const _n=Cn.ut=(In=$n(Cn.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${Cn.uid}"]`)).forEach(Nn=>setVarsOnNode(Nn,In))},Pn=()=>{const In=$n(Cn.proxy);setVarsOnVNode(Cn.subTree,In),_n(In)};watchPostEffect(Pn),onMounted(()=>{const In=new MutationObserver(Pn);In.observe(Cn.subTree.el.parentNode,{childList:!0}),onUnmounted(()=>In.disconnect())})}function setVarsOnVNode($n,Cn){if($n.shapeFlag&128){const _n=$n.suspense;$n=_n.activeBranch,_n.pendingBranch&&!_n.isHydrating&&_n.effects.push(()=>{setVarsOnVNode(_n.activeBranch,Cn)})}for(;$n.component;)$n=$n.component.subTree;if($n.shapeFlag&1&&$n.el)setVarsOnNode($n.el,Cn);else if($n.type===Fragment)$n.children.forEach(_n=>setVarsOnVNode(_n,Cn));else if($n.type===Static){let{el:_n,anchor:Pn}=$n;for(;_n&&(setVarsOnNode(_n,Cn),_n!==Pn);)_n=_n.nextSibling}}function setVarsOnNode($n,Cn){if($n.nodeType===1){const _n=$n.style;let Pn="";for(const In in Cn)_n.setProperty(`--${In}`,Cn[In]),Pn+=`--${In}: ${Cn[In]};`;_n[CSS_VAR_TEXT]=Pn}}function patchStyle($n,Cn,_n){const Pn=$n.style,In=Pn.display,Nn=isString$4(_n);if(_n&&!Nn){if(Cn&&!isString$4(Cn))for(const Rn in Cn)_n[Rn]==null&&setStyle(Pn,Rn,"");for(const Rn in _n)setStyle(Pn,Rn,_n[Rn])}else if(Nn){if(Cn!==_n){const Rn=Pn[CSS_VAR_TEXT];Rn&&(_n+=";"+Rn),Pn.cssText=_n}}else Cn&&$n.removeAttribute("style");vShowOldKey in $n&&(Pn.display=In)}const importantRE=/\s*!important$/;function setStyle($n,Cn,_n){if(isArray$4(_n))_n.forEach(Pn=>setStyle($n,Cn,Pn));else if(_n==null&&(_n=""),Cn.startsWith("--"))$n.setProperty(Cn,_n);else{const Pn=autoPrefix($n,Cn);importantRE.test(_n)?$n.setProperty(hyphenate$1(Pn),_n.replace(importantRE,""),"important"):$n[Pn]=_n}}const prefixes=["Webkit","Moz","ms"],prefixCache={};function autoPrefix($n,Cn){const _n=prefixCache[Cn];if(_n)return _n;let Pn=camelize$1(Cn);if(Pn!=="filter"&&Pn in $n)return prefixCache[Cn]=Pn;Pn=capitalize$2(Pn);for(let In=0;IncachedNow||(p$2.then(()=>cachedNow=0),cachedNow=Date.now());function createInvoker($n,Cn){const _n=Pn=>{if(!Pn._vts)Pn._vts=Date.now();else if(Pn._vts<=_n.attached)return;callWithAsyncErrorHandling(patchStopImmediatePropagation(Pn,_n.value),Cn,5,[Pn])};return _n.value=$n,_n.attached=getNow(),_n}function patchStopImmediatePropagation($n,Cn){if(isArray$4(Cn)){const _n=$n.stopImmediatePropagation;return $n.stopImmediatePropagation=()=>{_n.call($n),$n._stopped=!0},Cn.map(Pn=>In=>!In._stopped&&Pn&&Pn(In))}else return Cn}const isNativeOn=$n=>$n.charCodeAt(0)===111&&$n.charCodeAt(1)===110&&$n.charCodeAt(2)>96&&$n.charCodeAt(2)<123,patchProp=($n,Cn,_n,Pn,In,Nn,Rn,Dn,Ln)=>{const Fn=In==="svg";Cn==="class"?patchClass($n,Pn,Fn):Cn==="style"?patchStyle($n,_n,Pn):isOn$1(Cn)?isModelListener(Cn)||patchEvent($n,Cn,_n,Pn,Rn):(Cn[0]==="."?(Cn=Cn.slice(1),!0):Cn[0]==="^"?(Cn=Cn.slice(1),!1):shouldSetAsProp($n,Cn,Pn,Fn))?patchDOMProp($n,Cn,Pn,Nn,Rn,Dn,Ln):(Cn==="true-value"?$n._trueValue=Pn:Cn==="false-value"&&($n._falseValue=Pn),patchAttr($n,Cn,Pn,Fn))};function shouldSetAsProp($n,Cn,_n,Pn){if(Pn)return!!(Cn==="innerHTML"||Cn==="textContent"||Cn in $n&&isNativeOn(Cn)&&isFunction$3(_n));if(Cn==="spellcheck"||Cn==="draggable"||Cn==="translate"||Cn==="form"||Cn==="list"&&$n.tagName==="INPUT"||Cn==="type"&&$n.tagName==="TEXTAREA")return!1;if(Cn==="width"||Cn==="height"){const In=$n.tagName;if(In==="IMG"||In==="VIDEO"||In==="CANVAS"||In==="SOURCE")return!1}return isNativeOn(Cn)&&isString$4(_n)?!1:Cn in $n}const positionMap=new WeakMap,newPositionMap=new WeakMap,moveCbKey=Symbol("_moveCb"),enterCbKey=Symbol("_enterCb"),TransitionGroupImpl={name:"TransitionGroup",props:extend({},TransitionPropsValidators,{tag:String,moveClass:String}),setup($n,{slots:Cn}){const _n=getCurrentInstance(),Pn=useTransitionState();let In,Nn;return onUpdated(()=>{if(!In.length)return;const Rn=$n.moveClass||`${$n.name||"v"}-move`;if(!hasCSSTransform(In[0].el,_n.vnode.el,Rn))return;In.forEach(callPendingCbs),In.forEach(recordPosition);const Dn=In.filter(applyTranslation);forceReflow(),Dn.forEach(Ln=>{const Fn=Ln.el,Bn=Fn.style;addTransitionClass(Fn,Rn),Bn.transform=Bn.webkitTransform=Bn.transitionDuration="";const Hn=Fn[moveCbKey]=zn=>{zn&&zn.target!==Fn||(!zn||/transform$/.test(zn.propertyName))&&(Fn.removeEventListener("transitionend",Hn),Fn[moveCbKey]=null,removeTransitionClass(Fn,Rn))};Fn.addEventListener("transitionend",Hn)})}),()=>{const Rn=toRaw($n),Dn=resolveTransitionProps(Rn);let Ln=Rn.tag||Fragment;In=Nn,Nn=Cn.default?getTransitionRawChildren(Cn.default()):[];for(let Fn=0;Fndelete $n.mode;TransitionGroupImpl.props;const TransitionGroup=TransitionGroupImpl;function callPendingCbs($n){const Cn=$n.el;Cn[moveCbKey]&&Cn[moveCbKey](),Cn[enterCbKey]&&Cn[enterCbKey]()}function recordPosition($n){newPositionMap.set($n,$n.el.getBoundingClientRect())}function applyTranslation($n){const Cn=positionMap.get($n),_n=newPositionMap.get($n),Pn=Cn.left-_n.left,In=Cn.top-_n.top;if(Pn||In){const Nn=$n.el.style;return Nn.transform=Nn.webkitTransform=`translate(${Pn}px,${In}px)`,Nn.transitionDuration="0s",$n}}function hasCSSTransform($n,Cn,_n){const Pn=$n.cloneNode(),In=$n[vtcKey];In&&In.forEach(Dn=>{Dn.split(/\s+/).forEach(Ln=>Ln&&Pn.classList.remove(Ln))}),_n.split(/\s+/).forEach(Dn=>Dn&&Pn.classList.add(Dn)),Pn.style.display="none";const Nn=Cn.nodeType===1?Cn:Cn.parentNode;Nn.appendChild(Pn);const{hasTransform:Rn}=getTransitionInfo(Pn);return Nn.removeChild(Pn),Rn}const systemModifiers=["ctrl","shift","alt","meta"],modifierGuards={stop:$n=>$n.stopPropagation(),prevent:$n=>$n.preventDefault(),self:$n=>$n.target!==$n.currentTarget,ctrl:$n=>!$n.ctrlKey,shift:$n=>!$n.shiftKey,alt:$n=>!$n.altKey,meta:$n=>!$n.metaKey,left:$n=>"button"in $n&&$n.button!==0,middle:$n=>"button"in $n&&$n.button!==1,right:$n=>"button"in $n&&$n.button!==2,exact:($n,Cn)=>systemModifiers.some(_n=>$n[`${_n}Key`]&&!Cn.includes(_n))},withModifiers=($n,Cn)=>{const _n=$n._withMods||($n._withMods={}),Pn=Cn.join(".");return _n[Pn]||(_n[Pn]=(In,...Nn)=>{for(let Rn=0;Rn{const _n=$n._withKeys||($n._withKeys={}),Pn=Cn.join(".");return _n[Pn]||(_n[Pn]=In=>{if(!("key"in In))return;const Nn=hyphenate$1(In.key);if(Cn.some(Rn=>Rn===Nn||keyNames[Rn]===Nn))return $n(In)})},rendererOptions=extend({patchProp},nodeOps);let renderer;function ensureRenderer(){return renderer||(renderer=createRenderer(rendererOptions))}const render$1=(...$n)=>{ensureRenderer().render(...$n)},createApp=(...$n)=>{const Cn=ensureRenderer().createApp(...$n),{mount:_n}=Cn;return Cn.mount=Pn=>{const In=normalizeContainer(Pn);if(!In)return;const Nn=Cn._component;!isFunction$3(Nn)&&!Nn.render&&!Nn.template&&(Nn.template=In.innerHTML),In.innerHTML="";const Rn=_n(In,!1,resolveRootNamespace(In));return In instanceof Element&&(In.removeAttribute("v-cloak"),In.setAttribute("data-v-app","")),Rn},Cn};function resolveRootNamespace($n){if($n instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&$n instanceof MathMLElement)return"mathml"}function normalizeContainer($n){return isString$4($n)?document.querySelector($n):$n}function _typeof$2($n){"@babel/helpers - typeof";return _typeof$2=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(Cn){return typeof Cn}:function(Cn){return Cn&&typeof Symbol=="function"&&Cn.constructor===Symbol&&Cn!==Symbol.prototype?"symbol":typeof Cn},_typeof$2($n)}function toPrimitive($n,Cn){if(_typeof$2($n)!="object"||!$n)return $n;var _n=$n[Symbol.toPrimitive];if(_n!==void 0){var Pn=_n.call($n,Cn||"default");if(_typeof$2(Pn)!="object")return Pn;throw new TypeError("@@toPrimitive must return a primitive value.")}return(Cn==="string"?String:Number)($n)}function toPropertyKey($n){var Cn=toPrimitive($n,"string");return _typeof$2(Cn)=="symbol"?Cn:String(Cn)}function _defineProperty$Y($n,Cn,_n){return Cn=toPropertyKey(Cn),Cn in $n?Object.defineProperty($n,Cn,{value:_n,enumerable:!0,configurable:!0,writable:!0}):$n[Cn]=_n,$n}function ownKeys$1($n,Cn){var _n=Object.keys($n);if(Object.getOwnPropertySymbols){var Pn=Object.getOwnPropertySymbols($n);Cn&&(Pn=Pn.filter(function(In){return Object.getOwnPropertyDescriptor($n,In).enumerable})),_n.push.apply(_n,Pn)}return _n}function _objectSpread2$1($n){for(var Cn=1;Cntypeof $n=="function",isArray$3=Array.isArray,isString$3=$n=>typeof $n=="string",isObject$6=$n=>$n!==null&&typeof $n=="object",onRE=/^on[^a-z]/,isOn=$n=>onRE.test($n),cacheStringFunction=$n=>{const Cn=Object.create(null);return _n=>Cn[_n]||(Cn[_n]=$n(_n))},camelizeRE=/-(\w)/g,camelize=cacheStringFunction($n=>$n.replace(camelizeRE,(Cn,_n)=>_n?_n.toUpperCase():"")),hyphenateRE=/\B([A-Z])/g,hyphenate=cacheStringFunction($n=>$n.replace(hyphenateRE,"-$1").toLowerCase()),capitalize$1=cacheStringFunction($n=>$n.charAt(0).toUpperCase()+$n.slice(1)),hasOwnProperty$f=Object.prototype.hasOwnProperty,hasOwn$1=($n,Cn)=>hasOwnProperty$f.call($n,Cn);function resolvePropValue($n,Cn,_n,Pn){const In=$n[_n];if(In!=null){const Nn=hasOwn$1(In,"default");if(Nn&&Pn===void 0){const Rn=In.default;Pn=In.type!==Function&&isFunction$2(Rn)?Rn():Rn}In.type===Boolean&&(!hasOwn$1(Cn,_n)&&!Nn?Pn=!1:Pn===""&&(Pn=!0))}return Pn}function getDataAndAriaProps($n){return Object.keys($n).reduce((Cn,_n)=>((_n.startsWith("data-")||_n.startsWith("aria-"))&&(Cn[_n]=$n[_n]),Cn),{})}function toPx($n){return typeof $n=="number"?`${$n}px`:$n}function renderHelper($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=arguments.length>2?arguments[2]:void 0;return typeof $n=="function"?$n(Cn):$n??_n}function wrapPromiseFn($n){let Cn;const _n=new Promise(In=>{Cn=$n(()=>{In(!0)})}),Pn=()=>{Cn==null||Cn()};return Pn.then=(In,Nn)=>_n.then(In,Nn),Pn.promise=_n,Pn}function classNames(){const $n=[];for(let Cn=0;Cn0},$n.prototype.connect_=function(){!isBrowser$1||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),mutationObserverSupported?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},$n.prototype.disconnect_=function(){!isBrowser$1||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},$n.prototype.onTransitionEnd_=function(Cn){var _n=Cn.propertyName,Pn=_n===void 0?"":_n,In=transitionKeys.some(function(Nn){return!!~Pn.indexOf(Nn)});In&&this.refresh()},$n.getInstance=function(){return this.instance_||(this.instance_=new $n),this.instance_},$n.instance_=null,$n}(),defineConfigurable=function($n,Cn){for(var _n=0,Pn=Object.keys(Cn);_n"u"||!(Element instanceof Object))){if(!(Cn instanceof getWindowOf(Cn).Element))throw new TypeError('parameter 1 is not of type "Element".');var _n=this.observations_;_n.has(Cn)||(_n.set(Cn,new ResizeObservation(Cn)),this.controller_.addObserver(this),this.controller_.refresh())}},$n.prototype.unobserve=function(Cn){if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");if(!(typeof Element>"u"||!(Element instanceof Object))){if(!(Cn instanceof getWindowOf(Cn).Element))throw new TypeError('parameter 1 is not of type "Element".');var _n=this.observations_;_n.has(Cn)&&(_n.delete(Cn),_n.size||this.controller_.removeObserver(this))}},$n.prototype.disconnect=function(){this.clearActive(),this.observations_.clear(),this.controller_.removeObserver(this)},$n.prototype.gatherActive=function(){var Cn=this;this.clearActive(),this.observations_.forEach(function(_n){_n.isActive()&&Cn.activeObservations_.push(_n)})},$n.prototype.broadcastActive=function(){if(this.hasActive()){var Cn=this.callbackCtx_,_n=this.activeObservations_.map(function(Pn){return new ResizeObserverEntry(Pn.target,Pn.broadcastRect())});this.callback_.call(Cn,_n,Cn),this.clearActive()}},$n.prototype.clearActive=function(){this.activeObservations_.splice(0)},$n.prototype.hasActive=function(){return this.activeObservations_.length>0},$n}(),observers=typeof WeakMap<"u"?new WeakMap:new MapShim,ResizeObserver$2=function(){function $n(Cn){if(!(this instanceof $n))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var _n=ResizeObserverController.getInstance(),Pn=new ResizeObserverSPI(Cn,_n,this);observers.set(this,Pn)}return $n}();["observe","unobserve","disconnect"].forEach(function($n){ResizeObserver$2.prototype[$n]=function(){var Cn;return(Cn=observers.get(this))[$n].apply(Cn,arguments)}});var index$t=function(){return typeof global$1.ResizeObserver<"u"?global$1.ResizeObserver:ResizeObserver$2}();const ResizeObserver$3=index$t,isValid$2=$n=>$n!=null&&$n!=="",initDefaultProps=($n,Cn)=>{const _n=_extends$1({},$n);return Object.keys(Cn).forEach(Pn=>{const In=_n[Pn];if(In)In.type||In.default?In.default=Cn[Pn]:In.def?In.def(Cn[Pn]):_n[Pn]={type:In,default:Cn[Pn]};else throw new Error(`not have ${Pn} prop`)}),_n},splitAttrs=$n=>{const Cn=Object.keys($n),_n={},Pn={},In={};for(let Nn=0,Rn=Cn.length;Nn0&&arguments[0]!==void 0?arguments[0]:"",Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const _n={},Pn=/;(?![^(]*\))/g,In=/:(.+)/;return typeof $n=="object"?$n:($n.split(Pn).forEach(function(Nn){if(Nn){const Rn=Nn.split(In);if(Rn.length>1){const Dn=Cn?camelize(Rn[0].trim()):Rn[0].trim();_n[Dn]=Rn[1].trim()}}}),_n)},hasProp=($n,Cn)=>$n[Cn]!==void 0,skipFlattenKey=Symbol("skipFlatten"),flattenChildren=function(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;const _n=Array.isArray($n)?$n:[$n],Pn=[];return _n.forEach(In=>{Array.isArray(In)?Pn.push(...flattenChildren(In,Cn)):In&&In.type===Fragment?In.key===skipFlattenKey?Pn.push(In):Pn.push(...flattenChildren(In.children,Cn)):In&&isVNode$1(In)?Cn&&!isEmptyElement(In)?Pn.push(In):Cn||Pn.push(In):isValid$2(In)&&Pn.push(In)}),Pn},getSlot=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"default",_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(isVNode$1($n))return $n.type===Fragment?Cn==="default"?flattenChildren($n.children):[]:$n.children&&$n.children[Cn]?flattenChildren($n.children[Cn](_n)):[];{const Pn=$n.$slots[Cn]&&$n.$slots[Cn](_n);return flattenChildren(Pn)}},findDOMNode=$n=>{var Cn;let _n=((Cn=$n==null?void 0:$n.vnode)===null||Cn===void 0?void 0:Cn.el)||$n&&($n.$el||$n);for(;_n&&!_n.tagName;)_n=_n.nextSibling;return _n},getOptionProps=$n=>{const Cn={};if($n.$&&$n.$.vnode){const _n=$n.$.vnode.props||{};Object.keys($n.$props).forEach(Pn=>{const In=$n.$props[Pn],Nn=hyphenate(Pn);(In!==void 0||Nn in _n)&&(Cn[Pn]=In)})}else if(isVNode$1($n)&&typeof $n.type=="object"){const _n=$n.props||{},Pn={};Object.keys(_n).forEach(Nn=>{Pn[camelize(Nn)]=_n[Nn]});const In=$n.type.props||{};Object.keys(In).forEach(Nn=>{const Rn=resolvePropValue(In,Pn,Nn,Pn[Nn]);(Rn!==void 0||Nn in Pn)&&(Cn[Nn]=Rn)})}return Cn},getComponent=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"default",_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:$n,Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,In;if($n.$){const Nn=$n[Cn];if(Nn!==void 0)return typeof Nn=="function"&&Pn?Nn(_n):Nn;In=$n.$slots[Cn],In=Pn&&In?In(_n):In}else if(isVNode$1($n)){const Nn=$n.props&&$n.props[Cn];if(Nn!==void 0&&$n.props!==null)return typeof Nn=="function"&&Pn?Nn(_n):Nn;$n.type===Fragment?In=$n.children:$n.children&&$n.children[Cn]&&(In=$n.children[Cn],In=Pn&&In?In(_n):In)}return Array.isArray(In)&&(In=flattenChildren(In),In=In.length===1?In[0]:In,In=In.length===0?void 0:In),In};function getEvents(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,_n={};return $n.$?_n=_extends$1(_extends$1({},_n),$n.$attrs):_n=_extends$1(_extends$1({},_n),$n.props),splitAttrs(_n)[Cn?"onEvents":"events"]}function getClass($n){const _n=((isVNode$1($n)?$n.props:$n.$attrs)||{}).class||{};let Pn={};return typeof _n=="string"?_n.split(" ").forEach(In=>{Pn[In.trim()]=!0}):Array.isArray(_n)?classNames(_n).split(" ").forEach(In=>{Pn[In.trim()]=!0}):Pn=_extends$1(_extends$1({},Pn),_n),Pn}function getStyle$3($n,Cn){let Pn=((isVNode$1($n)?$n.props:$n.$attrs)||{}).style||{};if(typeof Pn=="string")Pn=parseStyleText(Pn,Cn);else if(Cn&&Pn){const In={};return Object.keys(Pn).forEach(Nn=>In[camelize(Nn)]=Pn[Nn]),In}return Pn}function isFragment($n){return $n.length===1&&$n[0].type===Fragment}function isEmptyContent($n){return $n==null||$n===""||Array.isArray($n)&&$n.length===0}function isEmptyElement($n){return $n&&($n.type===Comment$1||$n.type===Fragment&&$n.children.length===0||$n.type===Text$2&&$n.children.trim()==="")}function isStringElement($n){return $n&&$n.type===Text$2}function filterEmpty(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];const Cn=[];return $n.forEach(_n=>{Array.isArray(_n)?Cn.push(..._n):(_n==null?void 0:_n.type)===Fragment?Cn.push(...filterEmpty(_n.children)):Cn.push(_n)}),Cn.filter(_n=>!isEmptyElement(_n))}function filterEmptyWithUndefined($n){if($n){const Cn=filterEmpty($n);return Cn.length?Cn:void 0}else return $n}function isValidElement($n){return Array.isArray($n)&&$n.length===1&&($n=$n[0]),$n&&$n.__v_isVNode&&typeof $n.type!="symbol"}function getPropsSlot($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"default";var Pn,In;return(Pn=Cn[_n])!==null&&Pn!==void 0?Pn:(In=$n[_n])===null||In===void 0?void 0:In.call($n)}const ResizeObserver$1=defineComponent({compatConfig:{MODE:3},name:"ResizeObserver",props:{disabled:Boolean,onResize:Function},emits:["resize"],setup($n,Cn){let{slots:_n}=Cn;const Pn=reactive({width:0,height:0,offsetHeight:0,offsetWidth:0});let In=null,Nn=null;const Rn=()=>{Nn&&(Nn.disconnect(),Nn=null)},Dn=Bn=>{const{onResize:Hn}=$n,zn=Bn[0].target,{width:Wn,height:Yn}=zn.getBoundingClientRect(),{offsetWidth:Gn,offsetHeight:Go}=zn,Xn=Math.floor(Wn),Yo=Math.floor(Yn);if(Pn.width!==Xn||Pn.height!==Yo||Pn.offsetWidth!==Gn||Pn.offsetHeight!==Go){const qo={width:Xn,height:Yo,offsetWidth:Gn,offsetHeight:Go};_extends$1(Pn,qo),Hn&&Promise.resolve().then(()=>{Hn(_extends$1(_extends$1({},qo),{offsetWidth:Gn,offsetHeight:Go}),zn)})}},Ln=getCurrentInstance(),Fn=()=>{const{disabled:Bn}=$n;if(Bn){Rn();return}const Hn=findDOMNode(Ln);Hn!==In&&(Rn(),In=Hn),!Nn&&Hn&&(Nn=new ResizeObserver$3(Dn),Nn.observe(Hn))};return onMounted(()=>{Fn()}),onUpdated(()=>{Fn()}),onUnmounted(()=>{Rn()}),watch(()=>$n.disabled,()=>{Fn()},{flush:"post"}),()=>{var Bn;return(Bn=_n.default)===null||Bn===void 0?void 0:Bn.call(_n)[0]}}});let raf=$n=>setTimeout($n,16),caf=$n=>clearTimeout($n);typeof window<"u"&&"requestAnimationFrame"in window&&(raf=$n=>window.requestAnimationFrame($n),caf=$n=>window.cancelAnimationFrame($n));let rafUUID=0;const rafIds=new Map;function cleanup($n){rafIds.delete($n)}function wrapperRaf($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1;rafUUID+=1;const _n=rafUUID;function Pn(In){if(In===0)cleanup(_n),$n();else{const Nn=raf(()=>{Pn(In-1)});rafIds.set(_n,Nn)}}return Pn(Cn),_n}wrapperRaf.cancel=$n=>{const Cn=rafIds.get($n);return cleanup(Cn),caf(Cn)};function throttleByAnimationFrame($n){let Cn;const _n=In=>()=>{Cn=null,$n(...In)},Pn=function(){if(Cn==null){for(var In=arguments.length,Nn=new Array(In),Rn=0;Rn{wrapperRaf.cancel(Cn),Cn=null},Pn}const tuple$1=function(){for(var $n=arguments.length,Cn=new Array($n),_n=0;_n<$n;_n++)Cn[_n]=arguments[_n];return Cn},tupleNum=function(){for(var $n=arguments.length,Cn=new Array($n),_n=0;_n<$n;_n++)Cn[_n]=arguments[_n];return Cn},withInstall=$n=>{const Cn=$n;return Cn.install=function(_n){_n.component(Cn.displayName||Cn.name,$n)},$n};function eventType(){return{type:[Function,Array]}}function objectType($n){return{type:Object,default:$n}}function booleanType($n){return{type:Boolean,default:$n}}function functionType($n){return{type:Function,default:$n}}function anyType($n,Cn){const _n={validator:()=>!0,default:$n};return _n}function vNodeType(){return{validator:()=>!0}}function arrayType($n){return{type:Array,default:$n}}function stringType($n){return{type:String,default:$n}}function someType($n,Cn){return $n?{type:$n,default:Cn}:anyType(Cn)}let supportsPassive=!1;try{const $n=Object.defineProperty({},"passive",{get(){supportsPassive=!0}});window.addEventListener("testPassive",null,$n),window.removeEventListener("testPassive",null,$n)}catch{}const supportsPassive$1=supportsPassive;function addEventListenerWrap($n,Cn,_n,Pn){if($n&&$n.addEventListener){let In=Pn;In===void 0&&supportsPassive$1&&(Cn==="touchstart"||Cn==="touchmove"||Cn==="wheel")&&(In={passive:!1}),$n.addEventListener(Cn,_n,In)}return{remove:()=>{$n&&$n.removeEventListener&&$n.removeEventListener(Cn,_n)}}}function getTargetRect($n){return $n!==window?$n.getBoundingClientRect():{top:0,bottom:window.innerHeight}}function getFixedTop($n,Cn,_n){if(_n!==void 0&&Cn.top>$n.top-_n)return`${_n+Cn.top}px`}function getFixedBottom($n,Cn,_n){if(_n!==void 0&&Cn.bottom<$n.bottom+_n){const Pn=window.innerHeight-Cn.bottom;return`${_n+Pn}px`}}const TRIGGER_EVENTS=["resize","scroll","touchstart","touchmove","touchend","pageshow","load"];let observerEntities=[];function addObserveTarget($n,Cn){if(!$n)return;let _n=observerEntities.find(Pn=>Pn.target===$n);_n?_n.affixList.push(Cn):(_n={target:$n,affixList:[Cn],eventHandlers:{}},observerEntities.push(_n),TRIGGER_EVENTS.forEach(Pn=>{_n.eventHandlers[Pn]=addEventListenerWrap($n,Pn,()=>{_n.affixList.forEach(In=>{const{lazyUpdatePosition:Nn}=In.exposed;Nn()},(Pn==="touchstart"||Pn==="touchmove")&&supportsPassive$1?{passive:!0}:!1)})}))}function removeObserveTarget($n){const Cn=observerEntities.find(_n=>{const Pn=_n.affixList.some(In=>In===$n);return Pn&&(_n.affixList=_n.affixList.filter(In=>In!==$n)),Pn});Cn&&Cn.affixList.length===0&&(observerEntities=observerEntities.filter(_n=>_n!==Cn),TRIGGER_EVENTS.forEach(_n=>{const Pn=Cn.eventHandlers[_n];Pn&&Pn.remove&&Pn.remove()}))}const defaultIconPrefixCls="anticon",GlobalFormContextKey=Symbol("GlobalFormContextKey"),useProvideGlobalForm=$n=>{provide(GlobalFormContextKey,$n)},useInjectGlobalForm=()=>inject(GlobalFormContextKey,{validateMessages:computed(()=>{})}),configProviderProps=()=>({iconPrefixCls:String,getTargetContainer:{type:Function},getPopupContainer:{type:Function},prefixCls:String,getPrefixCls:{type:Function},renderEmpty:{type:Function},transformCellText:{type:Function},csp:objectType(),input:objectType(),autoInsertSpaceInButton:{type:Boolean,default:void 0},locale:objectType(),pageHeader:objectType(),componentSize:{type:String},componentDisabled:{type:Boolean,default:void 0},direction:{type:String,default:"ltr"},space:objectType(),virtual:{type:Boolean,default:void 0},dropdownMatchSelectWidth:{type:[Number,Boolean],default:!0},form:objectType(),pagination:objectType(),theme:objectType(),select:objectType(),wave:objectType()}),configProviderKey=Symbol("configProvider"),defaultConfigProvider={getPrefixCls:($n,Cn)=>Cn||($n?`ant-${$n}`:"ant"),iconPrefixCls:computed(()=>defaultIconPrefixCls),getPopupContainer:computed(()=>()=>document.body),direction:computed(()=>"ltr")},useConfigContextInject=()=>inject(configProviderKey,defaultConfigProvider),useConfigContextProvider=$n=>provide(configProviderKey,$n),DisabledContextKey=Symbol("DisabledContextKey"),useInjectDisabled=()=>inject(DisabledContextKey,ref(void 0)),useProviderDisabled=$n=>{const Cn=useInjectDisabled();return provide(DisabledContextKey,computed(()=>{var _n;return(_n=$n.value)!==null&&_n!==void 0?_n:Cn.value})),$n},enUS$1={items_per_page:"/ page",jump_to:"Go to",jump_to_confirm:"confirm",page:"",prev_page:"Previous Page",next_page:"Next Page",prev_5:"Previous 5 Pages",next_5:"Next 5 Pages",prev_3:"Previous 3 Pages",next_3:"Next 3 Pages"},locale$6={locale:"en_US",today:"Today",now:"Now",backToToday:"Back to today",ok:"Ok",clear:"Clear",month:"Month",year:"Year",timeSelect:"select time",dateSelect:"select date",weekSelect:"Choose a week",monthSelect:"Choose a month",yearSelect:"Choose a year",decadeSelect:"Choose a decade",yearFormat:"YYYY",dateFormat:"M/D/YYYY",dayFormat:"D",dateTimeFormat:"M/D/YYYY HH:mm:ss",monthBeforeYear:!0,previousMonth:"Previous month (PageUp)",nextMonth:"Next month (PageDown)",previousYear:"Last year (Control + left)",nextYear:"Next year (Control + right)",previousDecade:"Last decade",nextDecade:"Next decade",previousCentury:"Last century",nextCentury:"Next century"},CalendarLocale$1=locale$6,locale$5={placeholder:"Select time",rangePlaceholder:["Start time","End time"]},TimePicker$4=locale$5,locale$4={lang:_extends$1({placeholder:"Select date",yearPlaceholder:"Select year",quarterPlaceholder:"Select quarter",monthPlaceholder:"Select month",weekPlaceholder:"Select week",rangePlaceholder:["Start date","End date"],rangeYearPlaceholder:["Start year","End year"],rangeQuarterPlaceholder:["Start quarter","End quarter"],rangeMonthPlaceholder:["Start month","End month"],rangeWeekPlaceholder:["Start week","End week"]},CalendarLocale$1),timePickerLocale:_extends$1({},TimePicker$4)},enUS=locale$4,typeTemplate$2="${label} is not a valid ${type}",localeValues$1={locale:"en",Pagination:enUS$1,DatePicker:enUS,TimePicker:TimePicker$4,Calendar:enUS,global:{placeholder:"Please select"},Table:{filterTitle:"Filter menu",filterConfirm:"OK",filterReset:"Reset",filterEmptyText:"No filters",filterCheckall:"Select all items",filterSearchPlaceholder:"Search in filters",emptyText:"No data",selectAll:"Select current page",selectInvert:"Invert current page",selectNone:"Clear all data",selectionAll:"Select all data",sortTitle:"Sort",expand:"Expand row",collapse:"Collapse row",triggerDesc:"Click to sort descending",triggerAsc:"Click to sort ascending",cancelSort:"Click to cancel sorting"},Tour:{Next:"Next",Previous:"Previous",Finish:"Finish"},Modal:{okText:"OK",cancelText:"Cancel",justOkText:"OK"},Popconfirm:{okText:"OK",cancelText:"Cancel"},Transfer:{titles:["",""],searchPlaceholder:"Search here",itemUnit:"item",itemsUnit:"items",remove:"Remove",selectCurrent:"Select current page",removeCurrent:"Remove current page",selectAll:"Select all data",removeAll:"Remove all data",selectInvert:"Invert current page"},Upload:{uploading:"Uploading...",removeFile:"Remove file",uploadError:"Upload error",previewFile:"Preview file",downloadFile:"Download file"},Empty:{description:"No data"},Icon:{icon:"icon"},Text:{edit:"Edit",copy:"Copy",copied:"Copied",expand:"Expand"},PageHeader:{back:"Back"},Form:{optional:"(optional)",defaultValidateMessages:{default:"Field validation error for ${label}",required:"Please enter ${label}",enum:"${label} must be one of [${enum}]",whitespace:"${label} cannot be a blank character",date:{format:"${label} date format is invalid",parse:"${label} cannot be converted to a date",invalid:"${label} is an invalid date"},types:{string:typeTemplate$2,method:typeTemplate$2,array:typeTemplate$2,object:typeTemplate$2,number:typeTemplate$2,date:typeTemplate$2,boolean:typeTemplate$2,integer:typeTemplate$2,float:typeTemplate$2,regexp:typeTemplate$2,email:typeTemplate$2,url:typeTemplate$2,hex:typeTemplate$2},string:{len:"${label} must be ${len} characters",min:"${label} must be at least ${min} characters",max:"${label} must be up to ${max} characters",range:"${label} must be between ${min}-${max} characters"},number:{len:"${label} must be equal to ${len}",min:"${label} must be minimum ${min}",max:"${label} must be maximum ${max}",range:"${label} must be between ${min}-${max}"},array:{len:"Must be ${len} ${label}",min:"At least ${min} ${label}",max:"At most ${max} ${label}",range:"The amount of ${label} must be between ${min}-${max}"},pattern:{mismatch:"${label} does not match the pattern ${pattern}"}}},Image:{preview:"Preview"},QRCode:{expired:"QR code expired",refresh:"Refresh",scanned:"Scanned"}},LocaleReceiver=defineComponent({compatConfig:{MODE:3},name:"LocaleReceiver",props:{componentName:String,defaultLocale:{type:[Object,Function]},children:{type:Function}},setup($n,Cn){let{slots:_n}=Cn;const Pn=inject("localeData",{}),In=computed(()=>{const{componentName:Rn="global",defaultLocale:Dn}=$n,Ln=Dn||localeValues$1[Rn||"global"],{antLocale:Fn}=Pn,Bn=Rn&&Fn?Fn[Rn]:{};return _extends$1(_extends$1({},typeof Ln=="function"?Ln():Ln),Bn||{})}),Nn=computed(()=>{const{antLocale:Rn}=Pn,Dn=Rn&&Rn.locale;return Rn&&Rn.exist&&!Dn?localeValues$1.locale:Dn});return()=>{const Rn=$n.children||_n.default,{antLocale:Dn}=Pn;return Rn==null?void 0:Rn(In.value,Nn.value,Dn)}}});function useLocaleReceiver($n,Cn,_n){const Pn=inject("localeData",{});return[computed(()=>{const{antLocale:Nn}=Pn,Rn=unref(Cn)||localeValues$1[$n||"global"],Dn=$n&&Nn?Nn[$n]:{};return _extends$1(_extends$1(_extends$1({},typeof Rn=="function"?Rn():Rn),Dn||{}),unref(_n)||{})})]}function murmur2($n){for(var Cn=0,_n,Pn=0,In=$n.length;In>=4;++Pn,In-=4)_n=$n.charCodeAt(Pn)&255|($n.charCodeAt(++Pn)&255)<<8|($n.charCodeAt(++Pn)&255)<<16|($n.charCodeAt(++Pn)&255)<<24,_n=(_n&65535)*1540483477+((_n>>>16)*59797<<16),_n^=_n>>>24,Cn=(_n&65535)*1540483477+((_n>>>16)*59797<<16)^(Cn&65535)*1540483477+((Cn>>>16)*59797<<16);switch(In){case 3:Cn^=($n.charCodeAt(Pn+2)&255)<<16;case 2:Cn^=($n.charCodeAt(Pn+1)&255)<<8;case 1:Cn^=$n.charCodeAt(Pn)&255,Cn=(Cn&65535)*1540483477+((Cn>>>16)*59797<<16)}return Cn^=Cn>>>13,Cn=(Cn&65535)*1540483477+((Cn>>>16)*59797<<16),((Cn^Cn>>>15)>>>0).toString(36)}const SPLIT="%";class Entity{constructor(Cn){this.cache=new Map,this.instanceId=Cn}get(Cn){return this.cache.get(Array.isArray(Cn)?Cn.join(SPLIT):Cn)||null}update(Cn,_n){const Pn=Array.isArray(Cn)?Cn.join(SPLIT):Cn,In=this.cache.get(Pn),Nn=_n(In);Nn===null?this.cache.delete(Pn):this.cache.set(Pn,Nn)}}const CacheEntity=Entity,ATTR_TOKEN="data-token-hash",ATTR_MARK="data-css-hash",CSS_IN_JS_INSTANCE="__cssinjs_instance__";function createCache(){const $n=Math.random().toString(12).slice(2);if(typeof document<"u"&&document.head&&document.body){const Cn=document.body.querySelectorAll(`style[${ATTR_MARK}]`)||[],{firstChild:_n}=document.head;Array.from(Cn).forEach(In=>{In[CSS_IN_JS_INSTANCE]=In[CSS_IN_JS_INSTANCE]||$n,In[CSS_IN_JS_INSTANCE]===$n&&document.head.insertBefore(In,_n)});const Pn={};Array.from(document.querySelectorAll(`style[${ATTR_MARK}]`)).forEach(In=>{var Nn;const Rn=In.getAttribute(ATTR_MARK);Pn[Rn]?In[CSS_IN_JS_INSTANCE]===$n&&((Nn=In.parentNode)===null||Nn===void 0||Nn.removeChild(In)):Pn[Rn]=!0})}return new CacheEntity($n)}const StyleContextKey=Symbol("StyleContextKey"),getCache=()=>{var $n,Cn,_n;const Pn=getCurrentInstance();let In;if(Pn&&Pn.appContext){const Nn=(_n=(Cn=($n=Pn.appContext)===null||$n===void 0?void 0:$n.config)===null||Cn===void 0?void 0:Cn.globalProperties)===null||_n===void 0?void 0:_n.__ANTDV_CSSINJS_CACHE__;Nn?In=Nn:(In=createCache(),Pn.appContext.config.globalProperties&&(Pn.appContext.config.globalProperties.__ANTDV_CSSINJS_CACHE__=In))}else In=createCache();return In},defaultStyleContext={cache:createCache(),defaultCache:!0,hashPriority:"low"},useStyleInject=()=>{const $n=getCache();return inject(StyleContextKey,shallowRef(_extends$1(_extends$1({},defaultStyleContext),{cache:$n})))},useStyleProvider=$n=>{const Cn=useStyleInject(),_n=shallowRef(_extends$1(_extends$1({},defaultStyleContext),{cache:createCache()}));return watch([()=>unref($n),Cn],()=>{const Pn=_extends$1({},Cn.value),In=unref($n);Object.keys(In).forEach(Rn=>{const Dn=In[Rn];In[Rn]!==void 0&&(Pn[Rn]=Dn)});const{cache:Nn}=In;Pn.cache=Pn.cache||createCache(),Pn.defaultCache=!Nn&&Cn.value.defaultCache,_n.value=Pn},{immediate:!0}),provide(StyleContextKey,_n),_n},styleProviderProps=()=>({autoClear:booleanType(),mock:stringType(),cache:objectType(),defaultCache:booleanType(),hashPriority:stringType(),container:someType(),ssrInline:booleanType(),transformers:arrayType(),linters:arrayType()}),StyleProvider=withInstall(defineComponent({name:"AStyleProvider",inheritAttrs:!1,props:styleProviderProps(),setup($n,Cn){let{slots:_n}=Cn;return useStyleProvider($n),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}));function useClientCache($n,Cn,_n,Pn){const In=useStyleInject(),Nn=shallowRef(""),Rn=shallowRef();watchEffect(()=>{Nn.value=[$n,...Cn.value].join("%")});const Dn=Ln=>{In.value.cache.update(Ln,Fn=>{const[Bn=0,Hn]=Fn||[];return Bn-1===0?(Pn==null||Pn(Hn,!1),null):[Bn-1,Hn]})};return watch(Nn,(Ln,Fn)=>{Fn&&Dn(Fn),In.value.cache.update(Ln,Bn=>{const[Hn=0,zn]=Bn||[],Yn=zn||_n();return[Hn+1,Yn]}),Rn.value=In.value.cache.get(Nn.value)[1]},{immediate:!0}),onBeforeUnmount(()=>{Dn(Nn.value)}),Rn}function canUseDom$1(){return!!(typeof window<"u"&&window.document&&window.document.createElement)}function contains$2($n,Cn){return $n&&$n.contains?$n.contains(Cn):!1}const APPEND_ORDER$1="data-vc-order",MARK_KEY$1="vc-util-key",containerCache$1=new Map;function getMark$1(){let{mark:$n}=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return $n?$n.startsWith("data-")?$n:`data-${$n}`:MARK_KEY$1}function getContainer$2($n){return $n.attachTo?$n.attachTo:document.querySelector("head")||document.body}function getOrder$1($n){return $n==="queue"?"prependQueue":$n?"prepend":"append"}function findStyles$1($n){return Array.from((containerCache$1.get($n)||$n).children).filter(Cn=>Cn.tagName==="STYLE")}function injectCSS$1($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!canUseDom$1())return null;const{csp:_n,prepend:Pn}=Cn,In=document.createElement("style");In.setAttribute(APPEND_ORDER$1,getOrder$1(Pn)),_n!=null&&_n.nonce&&(In.nonce=_n==null?void 0:_n.nonce),In.innerHTML=$n;const Nn=getContainer$2(Cn),{firstChild:Rn}=Nn;if(Pn){if(Pn==="queue"){const Dn=findStyles$1(Nn).filter(Ln=>["prepend","prependQueue"].includes(Ln.getAttribute(APPEND_ORDER$1)));if(Dn.length)return Nn.insertBefore(In,Dn[Dn.length-1].nextSibling),In}Nn.insertBefore(In,Rn)}else Nn.appendChild(In);return In}function findExistNode$1($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const _n=getContainer$2(Cn);return findStyles$1(_n).find(Pn=>Pn.getAttribute(getMark$1(Cn))===$n)}function removeCSS($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const _n=findExistNode$1($n,Cn);_n&&getContainer$2(Cn).removeChild(_n)}function syncRealContainer$1($n,Cn){const _n=containerCache$1.get($n);if(!_n||!contains$2(document,_n)){const Pn=injectCSS$1("",Cn),{parentNode:In}=Pn;containerCache$1.set($n,In),$n.removeChild(Pn)}}function updateCSS$1($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};var Pn,In,Nn;const Rn=getContainer$2(_n);syncRealContainer$1(Rn,_n);const Dn=findExistNode$1(Cn,_n);if(Dn)return!((Pn=_n.csp)===null||Pn===void 0)&&Pn.nonce&&Dn.nonce!==((In=_n.csp)===null||In===void 0?void 0:In.nonce)&&(Dn.nonce=(Nn=_n.csp)===null||Nn===void 0?void 0:Nn.nonce),Dn.innerHTML!==$n&&(Dn.innerHTML=$n),Dn;const Ln=injectCSS$1($n,_n);return Ln.setAttribute(getMark$1(_n),Cn),Ln}function sameDerivativeOption($n,Cn){if($n.length!==Cn.length)return!1;for(let _n=0;_n<$n.length;_n++)if($n[_n]!==Cn[_n])return!1;return!0}class ThemeCache{constructor(){this.cache=new Map,this.keys=[],this.cacheCallTimes=0}size(){return this.keys.length}internalGet(Cn){let _n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,Pn={map:this.cache};return Cn.forEach(In=>{var Nn;Pn?Pn=(Nn=Pn==null?void 0:Pn.map)===null||Nn===void 0?void 0:Nn.get(In):Pn=void 0}),Pn!=null&&Pn.value&&_n&&(Pn.value[1]=this.cacheCallTimes++),Pn==null?void 0:Pn.value}get(Cn){var _n;return(_n=this.internalGet(Cn,!0))===null||_n===void 0?void 0:_n[0]}has(Cn){return!!this.internalGet(Cn)}set(Cn,_n){if(!this.has(Cn)){if(this.size()+1>ThemeCache.MAX_CACHE_SIZE+ThemeCache.MAX_CACHE_OFFSET){const[In]=this.keys.reduce((Nn,Rn)=>{const[,Dn]=Nn;return this.internalGet(Rn)[1]{if(Nn===Cn.length-1)Pn.set(In,{value:[_n,this.cacheCallTimes++]});else{const Rn=Pn.get(In);Rn?Rn.map||(Rn.map=new Map):Pn.set(In,{map:new Map}),Pn=Pn.get(In).map}})}deleteByPath(Cn,_n){var Pn;const In=Cn.get(_n[0]);if(_n.length===1)return In.map?Cn.set(_n[0],{map:In.map}):Cn.delete(_n[0]),(Pn=In.value)===null||Pn===void 0?void 0:Pn[0];const Nn=this.deleteByPath(In.map,_n.slice(1));return(!In.map||In.map.size===0)&&!In.value&&Cn.delete(_n[0]),Nn}delete(Cn){if(this.has(Cn))return this.keys=this.keys.filter(_n=>!sameDerivativeOption(_n,Cn)),this.deleteByPath(this.cache,Cn)}}ThemeCache.MAX_CACHE_SIZE=20;ThemeCache.MAX_CACHE_OFFSET=5;let warned={};function warning$4($n,Cn){}function note($n,Cn){}function call($n,Cn,_n){!Cn&&!warned[_n]&&($n(!1,_n),warned[_n]=!0)}function warningOnce($n,Cn){call(warning$4,$n,Cn)}function noteOnce($n,Cn){call(note,$n,Cn)}function noop$g(){}let warning$2=noop$g;const warning$3=warning$2;let uuid$7=0;class Theme{constructor(Cn){this.derivatives=Array.isArray(Cn)?Cn:[Cn],this.id=uuid$7,Cn.length===0&&warning$3(Cn.length>0),uuid$7+=1}getDerivativeToken(Cn){return this.derivatives.reduce((_n,Pn)=>Pn(Cn,_n),void 0)}}const cacheThemes=new ThemeCache;function createTheme($n){const Cn=Array.isArray($n)?$n:[$n];return cacheThemes.has(Cn)||cacheThemes.set(Cn,new Theme(Cn)),cacheThemes.get(Cn)}const flattenTokenCache=new WeakMap;function flattenToken($n){let Cn=flattenTokenCache.get($n)||"";return Cn||(Object.keys($n).forEach(_n=>{const Pn=$n[_n];Cn+=_n,Pn instanceof Theme?Cn+=Pn.id:Pn&&typeof Pn=="object"?Cn+=flattenToken(Pn):Cn+=Pn}),flattenTokenCache.set($n,Cn)),Cn}function token2key($n,Cn){return murmur2(`${Cn}_${flattenToken($n)}`)}const randomSelectorKey=`random-${Date.now()}-${Math.random()}`.replace(/\./g,""),checkContent="_bAmBoO_";function supportSelector($n,Cn,_n){var Pn,In;if(canUseDom$1()){updateCSS$1($n,randomSelectorKey);const Nn=document.createElement("div");Nn.style.position="fixed",Nn.style.left="0",Nn.style.top="0",Cn==null||Cn(Nn),document.body.appendChild(Nn);const Rn=_n?_n(Nn):(Pn=getComputedStyle(Nn).content)===null||Pn===void 0?void 0:Pn.includes(checkContent);return(In=Nn.parentNode)===null||In===void 0||In.removeChild(Nn),removeCSS(randomSelectorKey),Rn}return!1}let canLayer;function supportLayer(){return canLayer===void 0&&(canLayer=supportSelector(`@layer ${randomSelectorKey} { .${randomSelectorKey} { content: "${checkContent}"!important; } }`,$n=>{$n.className=randomSelectorKey})),canLayer}const EMPTY_OVERRIDE={},isProduction=!0,isPrerender=!1,hashPrefix=!isProduction&&!isPrerender?"css-dev-only-do-not-override":"css",tokenKeys=new Map;function recordCleanToken($n){tokenKeys.set($n,(tokenKeys.get($n)||0)+1)}function removeStyleTags($n,Cn){typeof document<"u"&&document.querySelectorAll(`style[${ATTR_TOKEN}="${$n}"]`).forEach(Pn=>{var In;Pn[CSS_IN_JS_INSTANCE]===Cn&&((In=Pn.parentNode)===null||In===void 0||In.removeChild(Pn))})}const TOKEN_THRESHOLD=0;function cleanTokenStyle($n,Cn){tokenKeys.set($n,(tokenKeys.get($n)||0)-1);const _n=Array.from(tokenKeys.keys()),Pn=_n.filter(In=>(tokenKeys.get(In)||0)<=0);_n.length-Pn.length>TOKEN_THRESHOLD&&Pn.forEach(In=>{removeStyleTags(In,Cn),tokenKeys.delete(In)})}const getComputedToken=($n,Cn,_n,Pn)=>{const In=_n.getDerivativeToken($n);let Nn=_extends$1(_extends$1({},In),Cn);return Pn&&(Nn=Pn(Nn)),Nn};function useCacheToken($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:ref({});const Pn=useStyleInject(),In=computed(()=>_extends$1({},...Cn.value)),Nn=computed(()=>flattenToken(In.value)),Rn=computed(()=>flattenToken(_n.value.override||EMPTY_OVERRIDE));return useClientCache("token",computed(()=>[_n.value.salt||"",$n.value.id,Nn.value,Rn.value]),()=>{const{salt:Ln="",override:Fn=EMPTY_OVERRIDE,formatToken:Bn,getComputedToken:Hn}=_n.value,zn=Hn?Hn(In.value,Fn,$n.value):getComputedToken(In.value,Fn,$n.value,Bn),Wn=token2key(zn,Ln);zn._tokenKey=Wn,recordCleanToken(Wn);const Yn=`${hashPrefix}-${murmur2(Wn)}`;return zn._hashId=Yn,[zn,Yn]},Ln=>{var Fn;cleanTokenStyle(Ln[0]._tokenKey,(Fn=Pn.value)===null||Fn===void 0?void 0:Fn.cache.instanceId)})}var unitlessKeys={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},COMMENT="comm",RULESET="rule",DECLARATION="decl",IMPORT="@import",KEYFRAMES="@keyframes",LAYER="@layer",abs=Math.abs,from=String.fromCharCode;function trim($n){return $n.trim()}function replace($n,Cn,_n){return $n.replace(Cn,_n)}function indexof($n,Cn,_n){return $n.indexOf(Cn,_n)}function charat($n,Cn){return $n.charCodeAt(Cn)|0}function substr($n,Cn,_n){return $n.slice(Cn,_n)}function strlen($n){return $n.length}function sizeof($n){return $n.length}function append($n,Cn){return Cn.push($n),$n}var line=1,column=1,length=0,position=0,character=0,characters="";function node($n,Cn,_n,Pn,In,Nn,Rn,Dn){return{value:$n,root:Cn,parent:_n,type:Pn,props:In,children:Nn,line,column,length:Rn,return:"",siblings:Dn}}function char(){return character}function prev(){return character=position>0?charat(characters,--position):0,column--,character===10&&(column=1,line--),character}function next(){return character=position2||token(character)>3?"":" "}function escaping($n,Cn){for(;--Cn&&next()&&!(character<48||character>102||character>57&&character<65||character>70&&character<97););return slice($n,caret()+(Cn<6&&peek()==32&&next()==32))}function delimiter($n){for(;next();)switch(character){case $n:return position;case 34:case 39:$n!==34&&$n!==39&&delimiter(character);break;case 40:$n===41&&delimiter($n);break;case 92:next();break}return position}function commenter($n,Cn){for(;next()&&$n+character!==57;)if($n+character===84&&peek()===47)break;return"/*"+slice(Cn,position-1)+"*"+from($n===47?$n:next())}function identifier($n){for(;!token(peek());)next();return slice($n,position)}function compile$1($n){return dealloc(parse$2("",null,null,null,[""],$n=alloc($n),0,[0],$n))}function parse$2($n,Cn,_n,Pn,In,Nn,Rn,Dn,Ln){for(var Fn=0,Bn=0,Hn=Rn,zn=0,Wn=0,Yn=0,Gn=1,Go=1,Xn=1,Yo=0,qo="",Jo=In,Zo=Nn,rr=Pn,nr=qo;Go;)switch(Yn=Yo,Yo=next()){case 40:if(Yn!=108&&charat(nr,Hn-1)==58){indexof(nr+=replace(delimit(Yo),"&","&\f"),"&\f",abs(Fn?Dn[Fn-1]:0))!=-1&&(Xn=-1);break}case 34:case 39:case 91:nr+=delimit(Yo);break;case 9:case 10:case 13:case 32:nr+=whitespace$1(Yn);break;case 92:nr+=escaping(caret()-1,7);continue;case 47:switch(peek()){case 42:case 47:append(comment(commenter(next(),caret()),Cn,_n,Ln),Ln);break;default:nr+="/"}break;case 123*Gn:Dn[Fn++]=strlen(nr)*Xn;case 125*Gn:case 59:case 0:switch(Yo){case 0:case 125:Go=0;case 59+Bn:Xn==-1&&(nr=replace(nr,/\f/g,"")),Wn>0&&strlen(nr)-Hn&&append(Wn>32?declaration(nr+";",Pn,_n,Hn-1,Ln):declaration(replace(nr," ","")+";",Pn,_n,Hn-2,Ln),Ln);break;case 59:nr+=";";default:if(append(rr=ruleset(nr,Cn,_n,Fn,Bn,In,Dn,qo,Jo=[],Zo=[],Hn,Nn),Nn),Yo===123)if(Bn===0)parse$2(nr,Cn,rr,rr,Jo,Nn,Hn,Dn,Zo);else switch(zn===99&&charat(nr,3)===110?100:zn){case 100:case 108:case 109:case 115:parse$2($n,rr,rr,Pn&&append(ruleset($n,rr,rr,0,0,In,Dn,qo,In,Jo=[],Hn,Zo),Zo),In,Zo,Hn,Dn,Pn?Jo:Zo);break;default:parse$2(nr,rr,rr,rr,[""],Zo,0,Dn,Zo)}}Fn=Bn=Wn=0,Gn=Xn=1,qo=nr="",Hn=Rn;break;case 58:Hn=1+strlen(nr),Wn=Yn;default:if(Gn<1){if(Yo==123)--Gn;else if(Yo==125&&Gn++==0&&prev()==125)continue}switch(nr+=from(Yo),Yo*Gn){case 38:Xn=Bn>0?1:(nr+="\f",-1);break;case 44:Dn[Fn++]=(strlen(nr)-1)*Xn,Xn=1;break;case 64:peek()===45&&(nr+=delimit(next())),zn=peek(),Bn=Hn=strlen(qo=nr+=identifier(caret())),Yo++;break;case 45:Yn===45&&strlen(nr)==2&&(Gn=0)}}return Nn}function ruleset($n,Cn,_n,Pn,In,Nn,Rn,Dn,Ln,Fn,Bn,Hn){for(var zn=In-1,Wn=In===0?Nn:[""],Yn=sizeof(Wn),Gn=0,Go=0,Xn=0;Gn0?Wn[Yo]+" "+qo:replace(qo,/&\f/g,Wn[Yo])))&&(Ln[Xn++]=Jo);return node($n,Cn,_n,In===0?RULESET:Dn,Ln,Fn,Bn,Hn)}function comment($n,Cn,_n,Pn){return node($n,Cn,_n,COMMENT,from(char()),substr($n,2,-2),0,Pn)}function declaration($n,Cn,_n,Pn,In){return node($n,Cn,_n,DECLARATION,substr($n,0,Pn),substr($n,Pn+1,-1),Pn,In)}function serialize$1($n,Cn){for(var _n="",Pn=0;Pn<$n.length;Pn++)_n+=Cn($n[Pn],Pn,$n,Cn)||"";return _n}function stringify$1($n,Cn,_n,Pn){switch($n.type){case LAYER:if($n.children.length)break;case IMPORT:case DECLARATION:return $n.return=$n.return||$n.value;case COMMENT:return"";case KEYFRAMES:return $n.return=$n.value+"{"+serialize$1($n.children,Pn)+"}";case RULESET:if(!strlen($n.value=$n.props.join(",")))return""}return strlen(_n=serialize$1($n.children,Pn))?$n.return=$n.value+"{"+_n+"}":""}function lintWarning($n,Cn){const{path:_n,parentSelectors:Pn}=Cn;warningOnce(!1,`[Ant Design Vue CSS-in-JS] ${_n?`Error in '${_n}': `:""}${$n}${Pn.length?` Selector info: ${Pn.join(" -> ")}`:""}`)}function isConcatSelector($n){var Cn;return(((Cn=$n.match(/:not\(([^)]*)\)/))===null||Cn===void 0?void 0:Cn[1])||"").split(/(\[[^[]*])|(?=[.#])/).filter(In=>In).length>1}function parsePath($n){return $n.parentSelectors.reduce((Cn,_n)=>Cn?_n.includes("&")?_n.replace(/&/g,Cn):`${Cn} ${_n}`:_n,"")}const linter$2=($n,Cn,_n)=>{const In=parsePath(_n).match(/:not\([^)]*\)/g)||[];In.length>0&&In.some(isConcatSelector)&&lintWarning("Concat ':not' selector not support in legacy browsers.",_n)},legacyNotSelectorLinter=linter$2,linter$1=($n,Cn,_n)=>{switch($n){case"marginLeft":case"marginRight":case"paddingLeft":case"paddingRight":case"left":case"right":case"borderLeft":case"borderLeftWidth":case"borderLeftStyle":case"borderLeftColor":case"borderRight":case"borderRightWidth":case"borderRightStyle":case"borderRightColor":case"borderTopLeftRadius":case"borderTopRightRadius":case"borderBottomLeftRadius":case"borderBottomRightRadius":lintWarning(`You seem to be using non-logical property '${$n}' which is not compatible with RTL mode. Please use logical properties and values instead. For more information: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties.`,_n);return;case"margin":case"padding":case"borderWidth":case"borderStyle":if(typeof Cn=="string"){const Pn=Cn.split(" ").map(In=>In.trim());Pn.length===4&&Pn[1]!==Pn[3]&&lintWarning(`You seem to be using '${$n}' property with different left ${$n} and right ${$n}, which is not compatible with RTL mode. Please use logical properties and values instead. For more information: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties.`,_n)}return;case"clear":case"textAlign":(Cn==="left"||Cn==="right")&&lintWarning(`You seem to be using non-logical value '${Cn}' of ${$n}, which is not compatible with RTL mode. Please use logical properties and values instead. For more information: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties.`,_n);return;case"borderRadius":typeof Cn=="string"&&Cn.split("/").map(Nn=>Nn.trim()).reduce((Nn,Rn)=>{if(Nn)return Nn;const Dn=Rn.split(" ").map(Ln=>Ln.trim());return Dn.length>=2&&Dn[0]!==Dn[1]||Dn.length===3&&Dn[1]!==Dn[2]||Dn.length===4&&Dn[2]!==Dn[3]?!0:Nn},!1)&&lintWarning(`You seem to be using non-logical value '${Cn}' of ${$n}, which is not compatible with RTL mode. Please use logical properties and values instead. For more information: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties.`,_n);return}},logicalPropertiesLinter=linter$1,linter=($n,Cn,_n)=>{_n.parentSelectors.some(Pn=>Pn.split(",").some(Nn=>Nn.split("&").length>2))&&lintWarning("Should not use more than one `&` in a selector.",_n)},parentSelectorLinter=linter,ATTR_CACHE_MAP="data-ant-cssinjs-cache-path",CSS_FILE_STYLE="_FILE_STYLE__";function serialize($n){return Object.keys($n).map(Cn=>{const _n=$n[Cn];return`${Cn}:${_n}`}).join(";")}let cachePathMap,fromCSSFile=!0;function prepare$1(){var $n;if(!cachePathMap&&(cachePathMap={},canUseDom$1())){const Cn=document.createElement("div");Cn.className=ATTR_CACHE_MAP,Cn.style.position="fixed",Cn.style.visibility="hidden",Cn.style.top="-9999px",document.body.appendChild(Cn);let _n=getComputedStyle(Cn).content||"";_n=_n.replace(/^"/,"").replace(/"$/,""),_n.split(";").forEach(In=>{const[Nn,Rn]=In.split(":");cachePathMap[Nn]=Rn});const Pn=document.querySelector(`style[${ATTR_CACHE_MAP}]`);Pn&&(fromCSSFile=!1,($n=Pn.parentNode)===null||$n===void 0||$n.removeChild(Pn)),document.body.removeChild(Cn)}}function existPath($n){return prepare$1(),!!cachePathMap[$n]}function getStyleAndHash($n){const Cn=cachePathMap[$n];let _n=null;if(Cn&&canUseDom$1())if(fromCSSFile)_n=CSS_FILE_STYLE;else{const Pn=document.querySelector(`style[${ATTR_MARK}="${cachePathMap[$n]}"]`);Pn?_n=Pn.innerHTML:delete cachePathMap[$n]}return[_n,Cn]}const isClientSide=canUseDom$1(),SKIP_CHECK="_skip_check_",MULTI_VALUE="_multi_value_";function normalizeStyle($n){return serialize$1(compile$1($n),stringify$1).replace(/\{%%%\:[^;];}/g,";")}function isCompoundCSSProperty($n){return typeof $n=="object"&&$n&&(SKIP_CHECK in $n||MULTI_VALUE in $n)}function injectSelectorHash($n,Cn,_n){if(!Cn)return $n;const Pn=`.${Cn}`,In=_n==="low"?`:where(${Pn})`:Pn;return $n.split(",").map(Rn=>{var Dn;const Ln=Rn.trim().split(/\s+/);let Fn=Ln[0]||"";const Bn=((Dn=Fn.match(/^\w+/))===null||Dn===void 0?void 0:Dn[0])||"";return Fn=`${Bn}${In}${Fn.slice(Bn.length)}`,[Fn,...Ln.slice(1)].join(" ")}).join(",")}const globalEffectStyleKeys=new Set,parseStyle=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},{root:_n,injectHash:Pn,parentSelectors:In}=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{root:!0,parentSelectors:[]};const{hashId:Nn,layer:Rn,path:Dn,hashPriority:Ln,transformers:Fn=[],linters:Bn=[]}=Cn;let Hn="",zn={};function Wn(Go){const Xn=Go.getName(Nn);if(!zn[Xn]){const[Yo]=parseStyle(Go.style,Cn,{root:!1,parentSelectors:In});zn[Xn]=`@keyframes ${Go.getName(Nn)}${Yo}`}}function Yn(Go){let Xn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[];return Go.forEach(Yo=>{Array.isArray(Yo)?Yn(Yo,Xn):Yo&&Xn.push(Yo)}),Xn}if(Yn(Array.isArray($n)?$n:[$n]).forEach(Go=>{const Xn=typeof Go=="string"&&!_n?{}:Go;if(typeof Xn=="string")Hn+=`${Xn} -`;else if(Xn._keyframe)Wn(Xn);else{const Yo=Fn.reduce((qo,Jo)=>{var Zo;return((Zo=Jo==null?void 0:Jo.visit)===null||Zo===void 0?void 0:Zo.call(Jo,qo))||qo},Xn);Object.keys(Yo).forEach(qo=>{var Jo;const Zo=Yo[qo];if(typeof Zo=="object"&&Zo&&(qo!=="animationName"||!Zo._keyframe)&&!isCompoundCSSProperty(Zo)){let rr=!1,nr=qo.trim(),ta=!1;(_n||Pn)&&Nn?nr.startsWith("@")?rr=!0:nr=injectSelectorHash(qo,Nn,Ln):_n&&!Nn&&(nr==="&"||nr==="")&&(nr="",ta=!0);const[oa,ra]=parseStyle(Zo,Cn,{root:ta,injectHash:rr,parentSelectors:[...In,nr]});zn=_extends$1(_extends$1({},zn),ra),Hn+=`${nr}${oa}`}else{let rr=function(ta,oa){const ra=ta.replace(/[A-Z]/g,la=>`-${la.toLowerCase()}`);let ea=oa;!unitlessKeys[ta]&&typeof ea=="number"&&ea!==0&&(ea=`${ea}px`),ta==="animationName"&&(oa!=null&&oa._keyframe)&&(Wn(oa),ea=oa.getName(Nn)),Hn+=`${ra}:${ea};`};const nr=(Jo=Zo==null?void 0:Zo.value)!==null&&Jo!==void 0?Jo:Zo;typeof Zo=="object"&&(Zo!=null&&Zo[MULTI_VALUE])&&Array.isArray(nr)?nr.forEach(ta=>{rr(qo,ta)}):rr(qo,nr)}})}}),!_n)Hn=`{${Hn}}`;else if(Rn&&supportLayer()){const Go=Rn.split(",");Hn=`@layer ${Go[Go.length-1].trim()} {${Hn}}`,Go.length>1&&(Hn=`@layer ${Rn}{%%%:%}${Hn}`)}return[Hn,zn]};function uniqueHash($n,Cn){return murmur2(`${$n.join("%")}${Cn}`)}function useStyleRegister($n,Cn){const _n=useStyleInject(),Pn=computed(()=>$n.value.token._tokenKey),In=computed(()=>[Pn.value,...$n.value.path]);let Nn=isClientSide;return useClientCache("style",In,()=>{const{path:Rn,hashId:Dn,layer:Ln,nonce:Fn,clientOnly:Bn,order:Hn=0}=$n.value,zn=In.value.join("|");if(existPath(zn)){const[nr,ta]=getStyleAndHash(zn);if(nr)return[nr,Pn.value,ta,{},Bn,Hn]}const Wn=Cn(),{hashPriority:Yn,container:Gn,transformers:Go,linters:Xn,cache:Yo}=_n.value,[qo,Jo]=parseStyle(Wn,{hashId:Dn,hashPriority:Yn,layer:Ln,path:Rn.join("-"),transformers:Go,linters:Xn}),Zo=normalizeStyle(qo),rr=uniqueHash(In.value,Zo);if(Nn){const nr={mark:ATTR_MARK,prepend:"queue",attachTo:Gn,priority:Hn},ta=typeof Fn=="function"?Fn():Fn;ta&&(nr.csp={nonce:ta});const oa=updateCSS$1(Zo,rr,nr);oa[CSS_IN_JS_INSTANCE]=Yo.instanceId,oa.setAttribute(ATTR_TOKEN,Pn.value),Object.keys(Jo).forEach(ra=>{globalEffectStyleKeys.has(ra)||(globalEffectStyleKeys.add(ra),updateCSS$1(normalizeStyle(Jo[ra]),`_effect-${ra}`,{mark:ATTR_MARK,prepend:"queue",attachTo:Gn}))})}return[Zo,Pn.value,rr,Jo,Bn,Hn]},(Rn,Dn)=>{let[,,Ln]=Rn;(Dn||_n.value.autoClear)&&isClientSide&&removeCSS(Ln,{mark:ATTR_MARK})}),Rn=>Rn}function extractStyle($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const _n="style%",Pn=Array.from($n.cache.keys()).filter(Fn=>Fn.startsWith(_n)),In={},Nn={};let Rn="";function Dn(Fn,Bn,Hn){let zn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};const Wn=_extends$1(_extends$1({},zn),{[ATTR_TOKEN]:Bn,[ATTR_MARK]:Hn}),Yn=Object.keys(Wn).map(Gn=>{const Go=Wn[Gn];return Go?`${Gn}="${Go}"`:null}).filter(Gn=>Gn).join(" ");return Cn?Fn:``}return Pn.map(Fn=>{const Bn=Fn.slice(_n.length).replace(/%/g,"|"),[Hn,zn,Wn,Yn,Gn,Go]=$n.cache.get(Fn)[1];if(Gn)return null;const Xn={"data-vc-order":"prependQueue","data-vc-priority":`${Go}`};let Yo=Dn(Hn,zn,Wn,Xn);return Nn[Bn]=Wn,Yn&&Object.keys(Yn).forEach(Jo=>{In[Jo]||(In[Jo]=!0,Yo+=Dn(normalizeStyle(Yn[Jo]),zn,`_effect-${Jo}`,Xn))}),[Go,Yo]}).filter(Fn=>Fn).sort((Fn,Bn)=>Fn[0]-Bn[0]).forEach(Fn=>{let[,Bn]=Fn;Rn+=Bn}),Rn+=Dn(`.${ATTR_CACHE_MAP}{content:"${serialize(Nn)}";}`,void 0,void 0,{[ATTR_CACHE_MAP]:ATTR_CACHE_MAP}),Rn}class Keyframe{constructor(Cn,_n){this._keyframe=!0,this.name=Cn,this.style=_n}getName(){let Cn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"";return Cn?`${Cn}-${this.name}`:this.name}}const Keyframes=Keyframe;function splitValues($n){if(typeof $n=="number")return[$n];const Cn=String($n).split(/\s+/);let _n="",Pn=0;return Cn.reduce((In,Nn)=>(Nn.includes("(")?(_n+=Nn,Pn+=Nn.split("(").length-1):Nn.includes(")")?(_n+=` ${Nn}`,Pn-=Nn.split(")").length-1,Pn===0&&(In.push(_n),_n="")):Pn>0?_n+=` ${Nn}`:In.push(Nn),In),[])}function noSplit($n){return $n.notSplit=!0,$n}const keyMap={inset:["top","right","bottom","left"],insetBlock:["top","bottom"],insetBlockStart:["top"],insetBlockEnd:["bottom"],insetInline:["left","right"],insetInlineStart:["left"],insetInlineEnd:["right"],marginBlock:["marginTop","marginBottom"],marginBlockStart:["marginTop"],marginBlockEnd:["marginBottom"],marginInline:["marginLeft","marginRight"],marginInlineStart:["marginLeft"],marginInlineEnd:["marginRight"],paddingBlock:["paddingTop","paddingBottom"],paddingBlockStart:["paddingTop"],paddingBlockEnd:["paddingBottom"],paddingInline:["paddingLeft","paddingRight"],paddingInlineStart:["paddingLeft"],paddingInlineEnd:["paddingRight"],borderBlock:noSplit(["borderTop","borderBottom"]),borderBlockStart:noSplit(["borderTop"]),borderBlockEnd:noSplit(["borderBottom"]),borderInline:noSplit(["borderLeft","borderRight"]),borderInlineStart:noSplit(["borderLeft"]),borderInlineEnd:noSplit(["borderRight"]),borderBlockWidth:["borderTopWidth","borderBottomWidth"],borderBlockStartWidth:["borderTopWidth"],borderBlockEndWidth:["borderBottomWidth"],borderInlineWidth:["borderLeftWidth","borderRightWidth"],borderInlineStartWidth:["borderLeftWidth"],borderInlineEndWidth:["borderRightWidth"],borderBlockStyle:["borderTopStyle","borderBottomStyle"],borderBlockStartStyle:["borderTopStyle"],borderBlockEndStyle:["borderBottomStyle"],borderInlineStyle:["borderLeftStyle","borderRightStyle"],borderInlineStartStyle:["borderLeftStyle"],borderInlineEndStyle:["borderRightStyle"],borderBlockColor:["borderTopColor","borderBottomColor"],borderBlockStartColor:["borderTopColor"],borderBlockEndColor:["borderBottomColor"],borderInlineColor:["borderLeftColor","borderRightColor"],borderInlineStartColor:["borderLeftColor"],borderInlineEndColor:["borderRightColor"],borderStartStartRadius:["borderTopLeftRadius"],borderStartEndRadius:["borderTopRightRadius"],borderEndStartRadius:["borderBottomLeftRadius"],borderEndEndRadius:["borderBottomRightRadius"]};function skipCheck($n){return{_skip_check_:!0,value:$n}}const transform$2={visit:$n=>{const Cn={};return Object.keys($n).forEach(_n=>{const Pn=$n[_n],In=keyMap[_n];if(In&&(typeof Pn=="number"||typeof Pn=="string")){const Nn=splitValues(Pn);In.length&&In.notSplit?In.forEach(Rn=>{Cn[Rn]=skipCheck(Pn)}):In.length===1?Cn[In[0]]=skipCheck(Pn):In.length===2?In.forEach((Rn,Dn)=>{var Ln;Cn[Rn]=skipCheck((Ln=Nn[Dn])!==null&&Ln!==void 0?Ln:Nn[0])}):In.length===4?In.forEach((Rn,Dn)=>{var Ln,Fn;Cn[Rn]=skipCheck((Fn=(Ln=Nn[Dn])!==null&&Ln!==void 0?Ln:Nn[Dn-2])!==null&&Fn!==void 0?Fn:Nn[0])}):Cn[_n]=Pn}else Cn[_n]=Pn}),Cn}},legacyLogicalPropertiesTransformer=transform$2,pxRegex=/url\([^)]+\)|var\([^)]+\)|(\d*\.?\d+)px/g;function toFixed$1($n,Cn){const _n=Math.pow(10,Cn+1),Pn=Math.floor($n*_n);return Math.round(Pn/10)*10/_n}const transform$1=function(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};const{rootValue:Cn=16,precision:_n=5,mediaQuery:Pn=!1}=$n,In=(Rn,Dn)=>{if(!Dn)return Rn;const Ln=parseFloat(Dn);return Ln<=1?Rn:`${toFixed$1(Ln/Cn,_n)}rem`};return{visit:Rn=>{const Dn=_extends$1({},Rn);return Object.entries(Rn).forEach(Ln=>{let[Fn,Bn]=Ln;if(typeof Bn=="string"&&Bn.includes("px")){const zn=Bn.replace(pxRegex,In);Dn[Fn]=zn}!unitlessKeys[Fn]&&typeof Bn=="number"&&Bn!==0&&(Dn[Fn]=`${Bn}px`.replace(pxRegex,In));const Hn=Fn.trim();if(Hn.startsWith("@")&&Hn.includes("px")&&Pn){const zn=Fn.replace(pxRegex,In);Dn[zn]=Dn[Fn],delete Dn[Fn]}}),Dn}}},px2remTransformer=transform$1,cssinjs={Theme,createTheme,useStyleRegister,useCacheToken,createCache,useStyleInject,useStyleProvider,Keyframes,extractStyle,legacyLogicalPropertiesTransformer,px2remTransformer,logicalPropertiesLinter,legacyNotSelectorLinter,parentSelectorLinter,StyleProvider},cssinjs$1=cssinjs,version="4.1.2",PresetColors=["blue","purple","cyan","green","magenta","pink","red","orange","yellow","volcano","geekblue","lime","gold"];function bound01$1($n,Cn){isOnePointZero$1($n)&&($n="100%");var _n=isPercentage$1($n);return $n=Cn===360?$n:Math.min(Cn,Math.max(0,parseFloat($n))),_n&&($n=parseInt(String($n*Cn),10)/100),Math.abs($n-Cn)<1e-6?1:(Cn===360?$n=($n<0?$n%Cn+Cn:$n%Cn)/parseFloat(String(Cn)):$n=$n%Cn/parseFloat(String(Cn)),$n)}function clamp01$1($n){return Math.min(1,Math.max(0,$n))}function isOnePointZero$1($n){return typeof $n=="string"&&$n.indexOf(".")!==-1&&parseFloat($n)===1}function isPercentage$1($n){return typeof $n=="string"&&$n.indexOf("%")!==-1}function boundAlpha$1($n){return $n=parseFloat($n),(isNaN($n)||$n<0||$n>1)&&($n=1),$n}function convertToPercentage$1($n){return $n<=1?"".concat(Number($n)*100,"%"):$n}function pad2$1($n){return $n.length===1?"0"+$n:String($n)}function rgbToRgb$1($n,Cn,_n){return{r:bound01$1($n,255)*255,g:bound01$1(Cn,255)*255,b:bound01$1(_n,255)*255}}function rgbToHsl$1($n,Cn,_n){$n=bound01$1($n,255),Cn=bound01$1(Cn,255),_n=bound01$1(_n,255);var Pn=Math.max($n,Cn,_n),In=Math.min($n,Cn,_n),Nn=0,Rn=0,Dn=(Pn+In)/2;if(Pn===In)Rn=0,Nn=0;else{var Ln=Pn-In;switch(Rn=Dn>.5?Ln/(2-Pn-In):Ln/(Pn+In),Pn){case $n:Nn=(Cn-_n)/Ln+(Cn<_n?6:0);break;case Cn:Nn=(_n-$n)/Ln+2;break;case _n:Nn=($n-Cn)/Ln+4;break}Nn/=6}return{h:Nn,s:Rn,l:Dn}}function hue2rgb($n,Cn,_n){return _n<0&&(_n+=1),_n>1&&(_n-=1),_n<1/6?$n+(Cn-$n)*(6*_n):_n<1/2?Cn:_n<2/3?$n+(Cn-$n)*(2/3-_n)*6:$n}function hslToRgb$1($n,Cn,_n){var Pn,In,Nn;if($n=bound01$1($n,360),Cn=bound01$1(Cn,100),_n=bound01$1(_n,100),Cn===0)In=_n,Nn=_n,Pn=_n;else{var Rn=_n<.5?_n*(1+Cn):_n+Cn-_n*Cn,Dn=2*_n-Rn;Pn=hue2rgb(Dn,Rn,$n+1/3),In=hue2rgb(Dn,Rn,$n),Nn=hue2rgb(Dn,Rn,$n-1/3)}return{r:Pn*255,g:In*255,b:Nn*255}}function rgbToHsv$1($n,Cn,_n){$n=bound01$1($n,255),Cn=bound01$1(Cn,255),_n=bound01$1(_n,255);var Pn=Math.max($n,Cn,_n),In=Math.min($n,Cn,_n),Nn=0,Rn=Pn,Dn=Pn-In,Ln=Pn===0?0:Dn/Pn;if(Pn===In)Nn=0;else{switch(Pn){case $n:Nn=(Cn-_n)/Dn+(Cn<_n?6:0);break;case Cn:Nn=(_n-$n)/Dn+2;break;case _n:Nn=($n-Cn)/Dn+4;break}Nn/=6}return{h:Nn,s:Ln,v:Rn}}function hsvToRgb$1($n,Cn,_n){$n=bound01$1($n,360)*6,Cn=bound01$1(Cn,100),_n=bound01$1(_n,100);var Pn=Math.floor($n),In=$n-Pn,Nn=_n*(1-Cn),Rn=_n*(1-In*Cn),Dn=_n*(1-(1-In)*Cn),Ln=Pn%6,Fn=[_n,Rn,Nn,Nn,Dn,_n][Ln],Bn=[Dn,_n,_n,Rn,Nn,Nn][Ln],Hn=[Nn,Nn,Dn,_n,_n,Rn][Ln];return{r:Fn*255,g:Bn*255,b:Hn*255}}function rgbToHex$1($n,Cn,_n,Pn){var In=[pad2$1(Math.round($n).toString(16)),pad2$1(Math.round(Cn).toString(16)),pad2$1(Math.round(_n).toString(16))];return Pn&&In[0].startsWith(In[0].charAt(1))&&In[1].startsWith(In[1].charAt(1))&&In[2].startsWith(In[2].charAt(1))?In[0].charAt(0)+In[1].charAt(0)+In[2].charAt(0):In.join("")}function rgbaToHex$1($n,Cn,_n,Pn,In){var Nn=[pad2$1(Math.round($n).toString(16)),pad2$1(Math.round(Cn).toString(16)),pad2$1(Math.round(_n).toString(16)),pad2$1(convertDecimalToHex$1(Pn))];return In&&Nn[0].startsWith(Nn[0].charAt(1))&&Nn[1].startsWith(Nn[1].charAt(1))&&Nn[2].startsWith(Nn[2].charAt(1))&&Nn[3].startsWith(Nn[3].charAt(1))?Nn[0].charAt(0)+Nn[1].charAt(0)+Nn[2].charAt(0)+Nn[3].charAt(0):Nn.join("")}function convertDecimalToHex$1($n){return Math.round(parseFloat($n)*255).toString(16)}function convertHexToDecimal$1($n){return parseIntFromHex$1($n)/255}function parseIntFromHex$1($n){return parseInt($n,16)}function numberInputToObject($n){return{r:$n>>16,g:($n&65280)>>8,b:$n&255}}var names$1={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",goldenrod:"#daa520",gold:"#ffd700",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavenderblush:"#fff0f5",lavender:"#e6e6fa",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};function inputToRGB$1($n){var Cn={r:0,g:0,b:0},_n=1,Pn=null,In=null,Nn=null,Rn=!1,Dn=!1;return typeof $n=="string"&&($n=stringInputToObject$1($n)),typeof $n=="object"&&(isValidCSSUnit$1($n.r)&&isValidCSSUnit$1($n.g)&&isValidCSSUnit$1($n.b)?(Cn=rgbToRgb$1($n.r,$n.g,$n.b),Rn=!0,Dn=String($n.r).substr(-1)==="%"?"prgb":"rgb"):isValidCSSUnit$1($n.h)&&isValidCSSUnit$1($n.s)&&isValidCSSUnit$1($n.v)?(Pn=convertToPercentage$1($n.s),In=convertToPercentage$1($n.v),Cn=hsvToRgb$1($n.h,Pn,In),Rn=!0,Dn="hsv"):isValidCSSUnit$1($n.h)&&isValidCSSUnit$1($n.s)&&isValidCSSUnit$1($n.l)&&(Pn=convertToPercentage$1($n.s),Nn=convertToPercentage$1($n.l),Cn=hslToRgb$1($n.h,Pn,Nn),Rn=!0,Dn="hsl"),Object.prototype.hasOwnProperty.call($n,"a")&&(_n=$n.a)),_n=boundAlpha$1(_n),{ok:Rn,format:$n.format||Dn,r:Math.min(255,Math.max(Cn.r,0)),g:Math.min(255,Math.max(Cn.g,0)),b:Math.min(255,Math.max(Cn.b,0)),a:_n}}var CSS_INTEGER="[-\\+]?\\d+%?",CSS_NUMBER="[-\\+]?\\d*\\.\\d+%?",CSS_UNIT="(?:".concat(CSS_NUMBER,")|(?:").concat(CSS_INTEGER,")"),PERMISSIVE_MATCH3="[\\s|\\(]+(".concat(CSS_UNIT,")[,|\\s]+(").concat(CSS_UNIT,")[,|\\s]+(").concat(CSS_UNIT,")\\s*\\)?"),PERMISSIVE_MATCH4="[\\s|\\(]+(".concat(CSS_UNIT,")[,|\\s]+(").concat(CSS_UNIT,")[,|\\s]+(").concat(CSS_UNIT,")[,|\\s]+(").concat(CSS_UNIT,")\\s*\\)?"),matchers$1={CSS_UNIT:new RegExp(CSS_UNIT),rgb:new RegExp("rgb"+PERMISSIVE_MATCH3),rgba:new RegExp("rgba"+PERMISSIVE_MATCH4),hsl:new RegExp("hsl"+PERMISSIVE_MATCH3),hsla:new RegExp("hsla"+PERMISSIVE_MATCH4),hsv:new RegExp("hsv"+PERMISSIVE_MATCH3),hsva:new RegExp("hsva"+PERMISSIVE_MATCH4),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/};function stringInputToObject$1($n){if($n=$n.trim().toLowerCase(),$n.length===0)return!1;var Cn=!1;if(names$1[$n])$n=names$1[$n],Cn=!0;else if($n==="transparent")return{r:0,g:0,b:0,a:0,format:"name"};var _n=matchers$1.rgb.exec($n);return _n?{r:_n[1],g:_n[2],b:_n[3]}:(_n=matchers$1.rgba.exec($n),_n?{r:_n[1],g:_n[2],b:_n[3],a:_n[4]}:(_n=matchers$1.hsl.exec($n),_n?{h:_n[1],s:_n[2],l:_n[3]}:(_n=matchers$1.hsla.exec($n),_n?{h:_n[1],s:_n[2],l:_n[3],a:_n[4]}:(_n=matchers$1.hsv.exec($n),_n?{h:_n[1],s:_n[2],v:_n[3]}:(_n=matchers$1.hsva.exec($n),_n?{h:_n[1],s:_n[2],v:_n[3],a:_n[4]}:(_n=matchers$1.hex8.exec($n),_n?{r:parseIntFromHex$1(_n[1]),g:parseIntFromHex$1(_n[2]),b:parseIntFromHex$1(_n[3]),a:convertHexToDecimal$1(_n[4]),format:Cn?"name":"hex8"}:(_n=matchers$1.hex6.exec($n),_n?{r:parseIntFromHex$1(_n[1]),g:parseIntFromHex$1(_n[2]),b:parseIntFromHex$1(_n[3]),format:Cn?"name":"hex"}:(_n=matchers$1.hex4.exec($n),_n?{r:parseIntFromHex$1(_n[1]+_n[1]),g:parseIntFromHex$1(_n[2]+_n[2]),b:parseIntFromHex$1(_n[3]+_n[3]),a:convertHexToDecimal$1(_n[4]+_n[4]),format:Cn?"name":"hex8"}:(_n=matchers$1.hex3.exec($n),_n?{r:parseIntFromHex$1(_n[1]+_n[1]),g:parseIntFromHex$1(_n[2]+_n[2]),b:parseIntFromHex$1(_n[3]+_n[3]),format:Cn?"name":"hex"}:!1)))))))))}function isValidCSSUnit$1($n){return!!matchers$1.CSS_UNIT.exec(String($n))}var TinyColor=function(){function $n(Cn,_n){Cn===void 0&&(Cn=""),_n===void 0&&(_n={});var Pn;if(Cn instanceof $n)return Cn;typeof Cn=="number"&&(Cn=numberInputToObject(Cn)),this.originalInput=Cn;var In=inputToRGB$1(Cn);this.originalInput=Cn,this.r=In.r,this.g=In.g,this.b=In.b,this.a=In.a,this.roundA=Math.round(100*this.a)/100,this.format=(Pn=_n.format)!==null&&Pn!==void 0?Pn:In.format,this.gradientType=_n.gradientType,this.r<1&&(this.r=Math.round(this.r)),this.g<1&&(this.g=Math.round(this.g)),this.b<1&&(this.b=Math.round(this.b)),this.isValid=In.ok}return $n.prototype.isDark=function(){return this.getBrightness()<128},$n.prototype.isLight=function(){return!this.isDark()},$n.prototype.getBrightness=function(){var Cn=this.toRgb();return(Cn.r*299+Cn.g*587+Cn.b*114)/1e3},$n.prototype.getLuminance=function(){var Cn=this.toRgb(),_n,Pn,In,Nn=Cn.r/255,Rn=Cn.g/255,Dn=Cn.b/255;return Nn<=.03928?_n=Nn/12.92:_n=Math.pow((Nn+.055)/1.055,2.4),Rn<=.03928?Pn=Rn/12.92:Pn=Math.pow((Rn+.055)/1.055,2.4),Dn<=.03928?In=Dn/12.92:In=Math.pow((Dn+.055)/1.055,2.4),.2126*_n+.7152*Pn+.0722*In},$n.prototype.getAlpha=function(){return this.a},$n.prototype.setAlpha=function(Cn){return this.a=boundAlpha$1(Cn),this.roundA=Math.round(100*this.a)/100,this},$n.prototype.isMonochrome=function(){var Cn=this.toHsl().s;return Cn===0},$n.prototype.toHsv=function(){var Cn=rgbToHsv$1(this.r,this.g,this.b);return{h:Cn.h*360,s:Cn.s,v:Cn.v,a:this.a}},$n.prototype.toHsvString=function(){var Cn=rgbToHsv$1(this.r,this.g,this.b),_n=Math.round(Cn.h*360),Pn=Math.round(Cn.s*100),In=Math.round(Cn.v*100);return this.a===1?"hsv(".concat(_n,", ").concat(Pn,"%, ").concat(In,"%)"):"hsva(".concat(_n,", ").concat(Pn,"%, ").concat(In,"%, ").concat(this.roundA,")")},$n.prototype.toHsl=function(){var Cn=rgbToHsl$1(this.r,this.g,this.b);return{h:Cn.h*360,s:Cn.s,l:Cn.l,a:this.a}},$n.prototype.toHslString=function(){var Cn=rgbToHsl$1(this.r,this.g,this.b),_n=Math.round(Cn.h*360),Pn=Math.round(Cn.s*100),In=Math.round(Cn.l*100);return this.a===1?"hsl(".concat(_n,", ").concat(Pn,"%, ").concat(In,"%)"):"hsla(".concat(_n,", ").concat(Pn,"%, ").concat(In,"%, ").concat(this.roundA,")")},$n.prototype.toHex=function(Cn){return Cn===void 0&&(Cn=!1),rgbToHex$1(this.r,this.g,this.b,Cn)},$n.prototype.toHexString=function(Cn){return Cn===void 0&&(Cn=!1),"#"+this.toHex(Cn)},$n.prototype.toHex8=function(Cn){return Cn===void 0&&(Cn=!1),rgbaToHex$1(this.r,this.g,this.b,this.a,Cn)},$n.prototype.toHex8String=function(Cn){return Cn===void 0&&(Cn=!1),"#"+this.toHex8(Cn)},$n.prototype.toHexShortString=function(Cn){return Cn===void 0&&(Cn=!1),this.a===1?this.toHexString(Cn):this.toHex8String(Cn)},$n.prototype.toRgb=function(){return{r:Math.round(this.r),g:Math.round(this.g),b:Math.round(this.b),a:this.a}},$n.prototype.toRgbString=function(){var Cn=Math.round(this.r),_n=Math.round(this.g),Pn=Math.round(this.b);return this.a===1?"rgb(".concat(Cn,", ").concat(_n,", ").concat(Pn,")"):"rgba(".concat(Cn,", ").concat(_n,", ").concat(Pn,", ").concat(this.roundA,")")},$n.prototype.toPercentageRgb=function(){var Cn=function(_n){return"".concat(Math.round(bound01$1(_n,255)*100),"%")};return{r:Cn(this.r),g:Cn(this.g),b:Cn(this.b),a:this.a}},$n.prototype.toPercentageRgbString=function(){var Cn=function(_n){return Math.round(bound01$1(_n,255)*100)};return this.a===1?"rgb(".concat(Cn(this.r),"%, ").concat(Cn(this.g),"%, ").concat(Cn(this.b),"%)"):"rgba(".concat(Cn(this.r),"%, ").concat(Cn(this.g),"%, ").concat(Cn(this.b),"%, ").concat(this.roundA,")")},$n.prototype.toName=function(){if(this.a===0)return"transparent";if(this.a<1)return!1;for(var Cn="#"+rgbToHex$1(this.r,this.g,this.b,!1),_n=0,Pn=Object.entries(names$1);_n=0,Nn=!_n&&In&&(Cn.startsWith("hex")||Cn==="name");return Nn?Cn==="name"&&this.a===0?this.toName():this.toRgbString():(Cn==="rgb"&&(Pn=this.toRgbString()),Cn==="prgb"&&(Pn=this.toPercentageRgbString()),(Cn==="hex"||Cn==="hex6")&&(Pn=this.toHexString()),Cn==="hex3"&&(Pn=this.toHexString(!0)),Cn==="hex4"&&(Pn=this.toHex8String(!0)),Cn==="hex8"&&(Pn=this.toHex8String()),Cn==="name"&&(Pn=this.toName()),Cn==="hsl"&&(Pn=this.toHslString()),Cn==="hsv"&&(Pn=this.toHsvString()),Pn||this.toHexString())},$n.prototype.toNumber=function(){return(Math.round(this.r)<<16)+(Math.round(this.g)<<8)+Math.round(this.b)},$n.prototype.clone=function(){return new $n(this.toString())},$n.prototype.lighten=function(Cn){Cn===void 0&&(Cn=10);var _n=this.toHsl();return _n.l+=Cn/100,_n.l=clamp01$1(_n.l),new $n(_n)},$n.prototype.brighten=function(Cn){Cn===void 0&&(Cn=10);var _n=this.toRgb();return _n.r=Math.max(0,Math.min(255,_n.r-Math.round(255*-(Cn/100)))),_n.g=Math.max(0,Math.min(255,_n.g-Math.round(255*-(Cn/100)))),_n.b=Math.max(0,Math.min(255,_n.b-Math.round(255*-(Cn/100)))),new $n(_n)},$n.prototype.darken=function(Cn){Cn===void 0&&(Cn=10);var _n=this.toHsl();return _n.l-=Cn/100,_n.l=clamp01$1(_n.l),new $n(_n)},$n.prototype.tint=function(Cn){return Cn===void 0&&(Cn=10),this.mix("white",Cn)},$n.prototype.shade=function(Cn){return Cn===void 0&&(Cn=10),this.mix("black",Cn)},$n.prototype.desaturate=function(Cn){Cn===void 0&&(Cn=10);var _n=this.toHsl();return _n.s-=Cn/100,_n.s=clamp01$1(_n.s),new $n(_n)},$n.prototype.saturate=function(Cn){Cn===void 0&&(Cn=10);var _n=this.toHsl();return _n.s+=Cn/100,_n.s=clamp01$1(_n.s),new $n(_n)},$n.prototype.greyscale=function(){return this.desaturate(100)},$n.prototype.spin=function(Cn){var _n=this.toHsl(),Pn=(_n.h+Cn)%360;return _n.h=Pn<0?360+Pn:Pn,new $n(_n)},$n.prototype.mix=function(Cn,_n){_n===void 0&&(_n=50);var Pn=this.toRgb(),In=new $n(Cn).toRgb(),Nn=_n/100,Rn={r:(In.r-Pn.r)*Nn+Pn.r,g:(In.g-Pn.g)*Nn+Pn.g,b:(In.b-Pn.b)*Nn+Pn.b,a:(In.a-Pn.a)*Nn+Pn.a};return new $n(Rn)},$n.prototype.analogous=function(Cn,_n){Cn===void 0&&(Cn=6),_n===void 0&&(_n=30);var Pn=this.toHsl(),In=360/_n,Nn=[this];for(Pn.h=(Pn.h-(In*Cn>>1)+720)%360;--Cn;)Pn.h=(Pn.h+In)%360,Nn.push(new $n(Pn));return Nn},$n.prototype.complement=function(){var Cn=this.toHsl();return Cn.h=(Cn.h+180)%360,new $n(Cn)},$n.prototype.monochromatic=function(Cn){Cn===void 0&&(Cn=6);for(var _n=this.toHsv(),Pn=_n.h,In=_n.s,Nn=_n.v,Rn=[],Dn=1/Cn;Cn--;)Rn.push(new $n({h:Pn,s:In,v:Nn})),Nn=(Nn+Dn)%1;return Rn},$n.prototype.splitcomplement=function(){var Cn=this.toHsl(),_n=Cn.h;return[this,new $n({h:(_n+72)%360,s:Cn.s,l:Cn.l}),new $n({h:(_n+216)%360,s:Cn.s,l:Cn.l})]},$n.prototype.onBackground=function(Cn){var _n=this.toRgb(),Pn=new $n(Cn).toRgb(),In=_n.a+Pn.a*(1-_n.a);return new $n({r:(_n.r*_n.a+Pn.r*Pn.a*(1-_n.a))/In,g:(_n.g*_n.a+Pn.g*Pn.a*(1-_n.a))/In,b:(_n.b*_n.a+Pn.b*Pn.a*(1-_n.a))/In,a:In})},$n.prototype.triad=function(){return this.polyad(3)},$n.prototype.tetrad=function(){return this.polyad(4)},$n.prototype.polyad=function(Cn){for(var _n=this.toHsl(),Pn=_n.h,In=[this],Nn=360/Cn,Rn=1;Rn=60&&Math.round($n.h)<=240?Pn=_n?Math.round($n.h)-hueStep*Cn:Math.round($n.h)+hueStep*Cn:Pn=_n?Math.round($n.h)+hueStep*Cn:Math.round($n.h)-hueStep*Cn,Pn<0?Pn+=360:Pn>=360&&(Pn-=360),Pn}function getSaturation($n,Cn,_n){if($n.h===0&&$n.s===0)return $n.s;var Pn;return _n?Pn=$n.s-saturationStep*Cn:Cn===darkColorCount?Pn=$n.s+saturationStep:Pn=$n.s+saturationStep2*Cn,Pn>1&&(Pn=1),_n&&Cn===lightColorCount&&Pn>.1&&(Pn=.1),Pn<.06&&(Pn=.06),Number(Pn.toFixed(2))}function getValue$4($n,Cn,_n){var Pn;return _n?Pn=$n.v+brightnessStep1*Cn:Pn=$n.v-brightnessStep2*Cn,Pn>1&&(Pn=1),Number(Pn.toFixed(2))}function generate$2($n){for(var Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=[],Pn=inputToRGB$1($n),In=lightColorCount;In>0;In-=1){var Nn=toHsv(Pn),Rn=toHex(inputToRGB$1({h:getHue(Nn,In,!0),s:getSaturation(Nn,In,!0),v:getValue$4(Nn,In,!0)}));_n.push(Rn)}_n.push(toHex(Pn));for(var Dn=1;Dn<=darkColorCount;Dn+=1){var Ln=toHsv(Pn),Fn=toHex(inputToRGB$1({h:getHue(Ln,Dn),s:getSaturation(Ln,Dn),v:getValue$4(Ln,Dn)}));_n.push(Fn)}return Cn.theme==="dark"?darkColorMap.map(function(Bn){var Hn=Bn.index,zn=Bn.opacity,Wn=toHex(mix$1(inputToRGB$1(Cn.backgroundColor||"#141414"),inputToRGB$1(_n[Hn]),zn*100));return Wn}):_n}var presetPrimaryColors={red:"#F5222D",volcano:"#FA541C",orange:"#FA8C16",gold:"#FAAD14",yellow:"#FADB14",lime:"#A0D911",green:"#52C41A",cyan:"#13C2C2",blue:"#1890FF",geekblue:"#2F54EB",purple:"#722ED1",magenta:"#EB2F96",grey:"#666666"},presetPalettes={},presetDarkPalettes={};Object.keys(presetPrimaryColors).forEach(function($n){presetPalettes[$n]=generate$2(presetPrimaryColors[$n]),presetPalettes[$n].primary=presetPalettes[$n][5],presetDarkPalettes[$n]=generate$2(presetPrimaryColors[$n],{theme:"dark",backgroundColor:"#141414"}),presetDarkPalettes[$n].primary=presetDarkPalettes[$n][5]});var gold=presetPalettes.gold,blue=presetPalettes.blue;const genControlHeight=$n=>{const{controlHeight:Cn}=$n;return{controlHeightSM:Cn*.75,controlHeightXS:Cn*.5,controlHeightLG:Cn*1.25}};function genSizeMapToken($n){const{sizeUnit:Cn,sizeStep:_n}=$n;return{sizeXXL:Cn*(_n+8),sizeXL:Cn*(_n+4),sizeLG:Cn*(_n+2),sizeMD:Cn*(_n+1),sizeMS:Cn*_n,size:Cn*_n,sizeSM:Cn*(_n-1),sizeXS:Cn*(_n-2),sizeXXS:Cn*(_n-3)}}const defaultPresetColors={blue:"#1677ff",purple:"#722ED1",cyan:"#13C2C2",green:"#52C41A",magenta:"#EB2F96",pink:"#eb2f96",red:"#F5222D",orange:"#FA8C16",yellow:"#FADB14",volcano:"#FA541C",geekblue:"#2F54EB",gold:"#FAAD14",lime:"#A0D911"},seedToken=_extends$1(_extends$1({},defaultPresetColors),{colorPrimary:"#1677ff",colorSuccess:"#52c41a",colorWarning:"#faad14",colorError:"#ff4d4f",colorInfo:"#1677ff",colorTextBase:"",colorBgBase:"",fontFamily:`-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, -'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', -'Noto Color Emoji'`,fontSize:14,lineWidth:1,lineType:"solid",motionUnit:.1,motionBase:0,motionEaseOutCirc:"cubic-bezier(0.08, 0.82, 0.17, 1)",motionEaseInOutCirc:"cubic-bezier(0.78, 0.14, 0.15, 0.86)",motionEaseOut:"cubic-bezier(0.215, 0.61, 0.355, 1)",motionEaseInOut:"cubic-bezier(0.645, 0.045, 0.355, 1)",motionEaseOutBack:"cubic-bezier(0.12, 0.4, 0.29, 1.46)",motionEaseInBack:"cubic-bezier(0.71, -0.46, 0.88, 0.6)",motionEaseInQuint:"cubic-bezier(0.755, 0.05, 0.855, 0.06)",motionEaseOutQuint:"cubic-bezier(0.23, 1, 0.32, 1)",borderRadius:6,sizeUnit:4,sizeStep:4,sizePopupArrow:16,controlHeight:32,zIndexBase:0,zIndexPopupBase:1e3,opacityImage:1,wireframe:!1}),defaultSeedToken=seedToken;function genColorMapToken($n,Cn){let{generateColorPalettes:_n,generateNeutralColorPalettes:Pn}=Cn;const{colorSuccess:In,colorWarning:Nn,colorError:Rn,colorInfo:Dn,colorPrimary:Ln,colorBgBase:Fn,colorTextBase:Bn}=$n,Hn=_n(Ln),zn=_n(In),Wn=_n(Nn),Yn=_n(Rn),Gn=_n(Dn),Go=Pn(Fn,Bn);return _extends$1(_extends$1({},Go),{colorPrimaryBg:Hn[1],colorPrimaryBgHover:Hn[2],colorPrimaryBorder:Hn[3],colorPrimaryBorderHover:Hn[4],colorPrimaryHover:Hn[5],colorPrimary:Hn[6],colorPrimaryActive:Hn[7],colorPrimaryTextHover:Hn[8],colorPrimaryText:Hn[9],colorPrimaryTextActive:Hn[10],colorSuccessBg:zn[1],colorSuccessBgHover:zn[2],colorSuccessBorder:zn[3],colorSuccessBorderHover:zn[4],colorSuccessHover:zn[4],colorSuccess:zn[6],colorSuccessActive:zn[7],colorSuccessTextHover:zn[8],colorSuccessText:zn[9],colorSuccessTextActive:zn[10],colorErrorBg:Yn[1],colorErrorBgHover:Yn[2],colorErrorBorder:Yn[3],colorErrorBorderHover:Yn[4],colorErrorHover:Yn[5],colorError:Yn[6],colorErrorActive:Yn[7],colorErrorTextHover:Yn[8],colorErrorText:Yn[9],colorErrorTextActive:Yn[10],colorWarningBg:Wn[1],colorWarningBgHover:Wn[2],colorWarningBorder:Wn[3],colorWarningBorderHover:Wn[4],colorWarningHover:Wn[4],colorWarning:Wn[6],colorWarningActive:Wn[7],colorWarningTextHover:Wn[8],colorWarningText:Wn[9],colorWarningTextActive:Wn[10],colorInfoBg:Gn[1],colorInfoBgHover:Gn[2],colorInfoBorder:Gn[3],colorInfoBorderHover:Gn[4],colorInfoHover:Gn[4],colorInfo:Gn[6],colorInfoActive:Gn[7],colorInfoTextHover:Gn[8],colorInfoText:Gn[9],colorInfoTextActive:Gn[10],colorBgMask:new TinyColor("#000").setAlpha(.45).toRgbString(),colorWhite:"#fff"})}const genRadius=$n=>{let Cn=$n,_n=$n,Pn=$n,In=$n;return $n<6&&$n>=5?Cn=$n+1:$n<16&&$n>=6?Cn=$n+2:$n>=16&&(Cn=16),$n<7&&$n>=5?_n=4:$n<8&&$n>=7?_n=5:$n<14&&$n>=8?_n=6:$n<16&&$n>=14?_n=7:$n>=16&&(_n=8),$n<6&&$n>=2?Pn=1:$n>=6&&(Pn=2),$n>4&&$n<8?In=4:$n>=8&&(In=6),{borderRadius:$n>16?16:$n,borderRadiusXS:Pn,borderRadiusSM:_n,borderRadiusLG:Cn,borderRadiusOuter:In}};function genCommonMapToken($n){const{motionUnit:Cn,motionBase:_n,borderRadius:Pn,lineWidth:In}=$n;return _extends$1({motionDurationFast:`${(_n+Cn).toFixed(1)}s`,motionDurationMid:`${(_n+Cn*2).toFixed(1)}s`,motionDurationSlow:`${(_n+Cn*3).toFixed(1)}s`,lineWidthBold:In+1},genRadius(Pn))}const getAlphaColor$1=($n,Cn)=>new TinyColor($n).setAlpha(Cn).toRgbString(),getSolidColor=($n,Cn)=>new TinyColor($n).darken(Cn).toHexString(),generateColorPalettes=$n=>{const Cn=generate$2($n);return{1:Cn[0],2:Cn[1],3:Cn[2],4:Cn[3],5:Cn[4],6:Cn[5],7:Cn[6],8:Cn[4],9:Cn[5],10:Cn[6]}},generateNeutralColorPalettes=($n,Cn)=>{const _n=$n||"#fff",Pn=Cn||"#000";return{colorBgBase:_n,colorTextBase:Pn,colorText:getAlphaColor$1(Pn,.88),colorTextSecondary:getAlphaColor$1(Pn,.65),colorTextTertiary:getAlphaColor$1(Pn,.45),colorTextQuaternary:getAlphaColor$1(Pn,.25),colorFill:getAlphaColor$1(Pn,.15),colorFillSecondary:getAlphaColor$1(Pn,.06),colorFillTertiary:getAlphaColor$1(Pn,.04),colorFillQuaternary:getAlphaColor$1(Pn,.02),colorBgLayout:getSolidColor(_n,4),colorBgContainer:getSolidColor(_n,0),colorBgElevated:getSolidColor(_n,0),colorBgSpotlight:getAlphaColor$1(Pn,.85),colorBorder:getSolidColor(_n,15),colorBorderSecondary:getSolidColor(_n,6)}};function getFontSizes($n){const Cn=new Array(10).fill(null).map((_n,Pn)=>{const In=Pn-1,Nn=$n*Math.pow(2.71828,In/5),Rn=Pn>1?Math.floor(Nn):Math.ceil(Nn);return Math.floor(Rn/2)*2});return Cn[1]=$n,Cn.map(_n=>{const Pn=_n+8;return{size:_n,lineHeight:Pn/_n}})}const genFontMapToken=$n=>{const Cn=getFontSizes($n),_n=Cn.map(In=>In.size),Pn=Cn.map(In=>In.lineHeight);return{fontSizeSM:_n[0],fontSize:_n[1],fontSizeLG:_n[2],fontSizeXL:_n[3],fontSizeHeading1:_n[6],fontSizeHeading2:_n[5],fontSizeHeading3:_n[4],fontSizeHeading4:_n[3],fontSizeHeading5:_n[2],lineHeight:Pn[1],lineHeightLG:Pn[2],lineHeightSM:Pn[0],lineHeightHeading1:Pn[6],lineHeightHeading2:Pn[5],lineHeightHeading3:Pn[4],lineHeightHeading4:Pn[3],lineHeightHeading5:Pn[2]}};function derivative($n){const Cn=Object.keys(defaultPresetColors).map(_n=>{const Pn=generate$2($n[_n]);return new Array(10).fill(1).reduce((In,Nn,Rn)=>(In[`${_n}-${Rn+1}`]=Pn[Rn],In),{})}).reduce((_n,Pn)=>(_n=_extends$1(_extends$1({},_n),Pn),_n),{});return _extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},$n),Cn),genColorMapToken($n,{generateColorPalettes,generateNeutralColorPalettes})),genFontMapToken($n.fontSize)),genSizeMapToken($n)),genControlHeight($n)),genCommonMapToken($n))}function isStableColor($n){return $n>=0&&$n<=255}function getAlphaColor($n,Cn){const{r:_n,g:Pn,b:In,a:Nn}=new TinyColor($n).toRgb();if(Nn<1)return $n;const{r:Rn,g:Dn,b:Ln}=new TinyColor(Cn).toRgb();for(let Fn=.01;Fn<=1;Fn+=.01){const Bn=Math.round((_n-Rn*(1-Fn))/Fn),Hn=Math.round((Pn-Dn*(1-Fn))/Fn),zn=Math.round((In-Ln*(1-Fn))/Fn);if(isStableColor(Bn)&&isStableColor(Hn)&&isStableColor(zn))return new TinyColor({r:Bn,g:Hn,b:zn,a:Math.round(Fn*100)/100}).toRgbString()}return new TinyColor({r:_n,g:Pn,b:In,a:1}).toRgbString()}var __rest$1f=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{delete Pn[Wn]});const In=_extends$1(_extends$1({},_n),Pn),Nn=480,Rn=576,Dn=768,Ln=992,Fn=1200,Bn=1600,Hn=2e3;return _extends$1(_extends$1(_extends$1({},In),{colorLink:In.colorInfoText,colorLinkHover:In.colorInfoHover,colorLinkActive:In.colorInfoActive,colorFillContent:In.colorFillSecondary,colorFillContentHover:In.colorFill,colorFillAlter:In.colorFillQuaternary,colorBgContainerDisabled:In.colorFillTertiary,colorBorderBg:In.colorBgContainer,colorSplit:getAlphaColor(In.colorBorderSecondary,In.colorBgContainer),colorTextPlaceholder:In.colorTextQuaternary,colorTextDisabled:In.colorTextQuaternary,colorTextHeading:In.colorText,colorTextLabel:In.colorTextSecondary,colorTextDescription:In.colorTextTertiary,colorTextLightSolid:In.colorWhite,colorHighlight:In.colorError,colorBgTextHover:In.colorFillSecondary,colorBgTextActive:In.colorFill,colorIcon:In.colorTextTertiary,colorIconHover:In.colorText,colorErrorOutline:getAlphaColor(In.colorErrorBg,In.colorBgContainer),colorWarningOutline:getAlphaColor(In.colorWarningBg,In.colorBgContainer),fontSizeIcon:In.fontSizeSM,lineWidth:In.lineWidth,controlOutlineWidth:In.lineWidth*2,controlInteractiveSize:In.controlHeight/2,controlItemBgHover:In.colorFillTertiary,controlItemBgActive:In.colorPrimaryBg,controlItemBgActiveHover:In.colorPrimaryBgHover,controlItemBgActiveDisabled:In.colorFill,controlTmpOutline:In.colorFillQuaternary,controlOutline:getAlphaColor(In.colorPrimaryBg,In.colorBgContainer),lineType:In.lineType,borderRadius:In.borderRadius,borderRadiusXS:In.borderRadiusXS,borderRadiusSM:In.borderRadiusSM,borderRadiusLG:In.borderRadiusLG,fontWeightStrong:600,opacityLoading:.65,linkDecoration:"none",linkHoverDecoration:"none",linkFocusDecoration:"none",controlPaddingHorizontal:12,controlPaddingHorizontalSM:8,paddingXXS:In.sizeXXS,paddingXS:In.sizeXS,paddingSM:In.sizeSM,padding:In.size,paddingMD:In.sizeMD,paddingLG:In.sizeLG,paddingXL:In.sizeXL,paddingContentHorizontalLG:In.sizeLG,paddingContentVerticalLG:In.sizeMS,paddingContentHorizontal:In.sizeMS,paddingContentVertical:In.sizeSM,paddingContentHorizontalSM:In.size,paddingContentVerticalSM:In.sizeXS,marginXXS:In.sizeXXS,marginXS:In.sizeXS,marginSM:In.sizeSM,margin:In.size,marginMD:In.sizeMD,marginLG:In.sizeLG,marginXL:In.sizeXL,marginXXL:In.sizeXXL,boxShadow:` - 0 1px 2px 0 rgba(0, 0, 0, 0.03), - 0 1px 6px -1px rgba(0, 0, 0, 0.02), - 0 2px 4px 0 rgba(0, 0, 0, 0.02) - `,boxShadowSecondary:` - 0 6px 16px 0 rgba(0, 0, 0, 0.08), - 0 3px 6px -4px rgba(0, 0, 0, 0.12), - 0 9px 28px 8px rgba(0, 0, 0, 0.05) - `,boxShadowTertiary:` - 0 1px 2px 0 rgba(0, 0, 0, 0.03), - 0 1px 6px -1px rgba(0, 0, 0, 0.02), - 0 2px 4px 0 rgba(0, 0, 0, 0.02) - `,screenXS:Nn,screenXSMin:Nn,screenXSMax:Rn-1,screenSM:Rn,screenSMMin:Rn,screenSMMax:Dn-1,screenMD:Dn,screenMDMin:Dn,screenMDMax:Ln-1,screenLG:Ln,screenLGMin:Ln,screenLGMax:Fn-1,screenXL:Fn,screenXLMin:Fn,screenXLMax:Bn-1,screenXXL:Bn,screenXXLMin:Bn,screenXXLMax:Hn-1,screenXXXL:Hn,screenXXXLMin:Hn,boxShadowPopoverArrow:"3px 3px 7px rgba(0, 0, 0, 0.1)",boxShadowCard:` - 0 1px 2px -2px ${new TinyColor("rgba(0, 0, 0, 0.16)").toRgbString()}, - 0 3px 6px 0 ${new TinyColor("rgba(0, 0, 0, 0.12)").toRgbString()}, - 0 5px 12px 4px ${new TinyColor("rgba(0, 0, 0, 0.09)").toRgbString()} - `,boxShadowDrawerRight:` - -6px 0 16px 0 rgba(0, 0, 0, 0.08), - -3px 0 6px -4px rgba(0, 0, 0, 0.12), - -9px 0 28px 8px rgba(0, 0, 0, 0.05) - `,boxShadowDrawerLeft:` - 6px 0 16px 0 rgba(0, 0, 0, 0.08), - 3px 0 6px -4px rgba(0, 0, 0, 0.12), - 9px 0 28px 8px rgba(0, 0, 0, 0.05) - `,boxShadowDrawerUp:` - 0 6px 16px 0 rgba(0, 0, 0, 0.08), - 0 3px 6px -4px rgba(0, 0, 0, 0.12), - 0 9px 28px 8px rgba(0, 0, 0, 0.05) - `,boxShadowDrawerDown:` - 0 -6px 16px 0 rgba(0, 0, 0, 0.08), - 0 -3px 6px -4px rgba(0, 0, 0, 0.12), - 0 -9px 28px 8px rgba(0, 0, 0, 0.05) - `,boxShadowTabsOverflowLeft:"inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowRight:"inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowTop:"inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowBottom:"inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)"}),Pn)}const operationUnit=$n=>({color:$n.colorLink,textDecoration:"none",outline:"none",cursor:"pointer",transition:`color ${$n.motionDurationSlow}`,"&:focus, &:hover":{color:$n.colorLinkHover},"&:active":{color:$n.colorLinkActive}}),roundedArrow=($n,Cn,_n,Pn,In)=>{const Nn=$n/2,Rn=0,Dn=Nn,Ln=_n*1/Math.sqrt(2),Fn=Nn-_n*(1-1/Math.sqrt(2)),Bn=Nn-Cn*(1/Math.sqrt(2)),Hn=_n*(Math.sqrt(2)-1)+Cn*(1/Math.sqrt(2)),zn=2*Nn-Bn,Wn=Hn,Yn=2*Nn-Ln,Gn=Fn,Go=2*Nn-Rn,Xn=Dn,Yo=Nn*Math.sqrt(2)+_n*(Math.sqrt(2)-2),qo=_n*(Math.sqrt(2)-1);return{pointerEvents:"none",width:$n,height:$n,overflow:"hidden","&::after":{content:'""',position:"absolute",width:Yo,height:Yo,bottom:0,insetInline:0,margin:"auto",borderRadius:{_skip_check_:!0,value:`0 0 ${Cn}px 0`},transform:"translateY(50%) rotate(-135deg)",boxShadow:In,zIndex:0,background:"transparent"},"&::before":{position:"absolute",bottom:0,insetInlineStart:0,width:$n,height:$n/2,background:Pn,clipPath:{_multi_value_:!0,value:[`polygon(${qo}px 100%, 50% ${qo}px, ${2*Nn-qo}px 100%, ${qo}px 100%)`,`path('M ${Rn} ${Dn} A ${_n} ${_n} 0 0 0 ${Ln} ${Fn} L ${Bn} ${Hn} A ${Cn} ${Cn} 0 0 1 ${zn} ${Wn} L ${Yn} ${Gn} A ${_n} ${_n} 0 0 0 ${Go} ${Xn} Z')`]},content:'""'}}};function genPresetColor($n,Cn){return PresetColors.reduce((_n,Pn)=>{const In=$n[`${Pn}-1`],Nn=$n[`${Pn}-3`],Rn=$n[`${Pn}-6`],Dn=$n[`${Pn}-7`];return _extends$1(_extends$1({},_n),Cn(Pn,{lightColor:In,lightBorderColor:Nn,darkColor:Rn,textColor:Dn}))},{})}const textEllipsis={overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"},resetComponent=$n=>({boxSizing:"border-box",margin:0,padding:0,color:$n.colorText,fontSize:$n.fontSize,lineHeight:$n.lineHeight,listStyle:"none",fontFamily:$n.fontFamily}),resetIcon=()=>({display:"inline-flex",alignItems:"center",color:"inherit",fontStyle:"normal",lineHeight:0,textAlign:"center",textTransform:"none",verticalAlign:"-0.125em",textRendering:"optimizeLegibility","-webkit-font-smoothing":"antialiased","-moz-osx-font-smoothing":"grayscale","> *":{lineHeight:1},svg:{display:"inline-block"}}),clearFix=()=>({"&::before":{display:"table",content:'""'},"&::after":{display:"table",clear:"both",content:'""'}}),genLinkStyle=$n=>({a:{color:$n.colorLink,textDecoration:$n.linkDecoration,backgroundColor:"transparent",outline:"none",cursor:"pointer",transition:`color ${$n.motionDurationSlow}`,"-webkit-text-decoration-skip":"objects","&:hover":{color:$n.colorLinkHover},"&:active":{color:$n.colorLinkActive},"&:active,\n &:hover":{textDecoration:$n.linkHoverDecoration,outline:0},"&:focus":{textDecoration:$n.linkFocusDecoration,outline:0},"&[disabled]":{color:$n.colorTextDisabled,cursor:"not-allowed"}}}),genCommonStyle=($n,Cn)=>{const{fontFamily:_n,fontSize:Pn}=$n,In=`[class^="${Cn}"], [class*=" ${Cn}"]`;return{[In]:{fontFamily:_n,fontSize:Pn,boxSizing:"border-box","&::before, &::after":{boxSizing:"border-box"},[In]:{boxSizing:"border-box","&::before, &::after":{boxSizing:"border-box"}}}}},genFocusOutline=$n=>({outline:`${$n.lineWidthBold}px solid ${$n.colorPrimaryBorder}`,outlineOffset:1,transition:"outline-offset 0s, outline 0s"}),genFocusStyle=$n=>({"&:focus-visible":_extends$1({},genFocusOutline($n))});function genComponentStyleHook($n,Cn,_n){return Pn=>{const In=computed(()=>Pn==null?void 0:Pn.value),[Nn,Rn,Dn]=useToken(),{getPrefixCls:Ln,iconPrefixCls:Fn}=useConfigContextInject(),Bn=computed(()=>Ln()),Hn=computed(()=>({theme:Nn.value,token:Rn.value,hashId:Dn.value,path:["Shared",Bn.value]}));useStyleRegister(Hn,()=>[{"&":genLinkStyle(Rn.value)}]);const zn=computed(()=>({theme:Nn.value,token:Rn.value,hashId:Dn.value,path:[$n,In.value,Fn.value]}));return[useStyleRegister(zn,()=>{const{token:Wn,flush:Yn}=statisticToken(Rn.value),Gn=typeof _n=="function"?_n(Wn):_n,Go=_extends$1(_extends$1({},Gn),Rn.value[$n]),Xn=`.${In.value}`,Yo=merge$1(Wn,{componentCls:Xn,prefixCls:In.value,iconCls:`.${Fn.value}`,antCls:`.${Bn.value}`},Go),qo=Cn(Yo,{hashId:Dn.value,prefixCls:In.value,rootPrefixCls:Bn.value,iconPrefixCls:Fn.value,overrideComponentToken:Rn.value[$n]});return Yn($n,Go),[genCommonStyle(Rn.value,In.value),qo]}),Dn]}}const enableStatistic=typeof CSSINJS_STATISTIC<"u";let recording=!0;function merge$1(){for(var $n=arguments.length,Cn=new Array($n),_n=0;_n<$n;_n++)Cn[_n]=arguments[_n];if(!enableStatistic)return _extends$1({},...Cn);recording=!1;const Pn={};return Cn.forEach(In=>{Object.keys(In).forEach(Rn=>{Object.defineProperty(Pn,Rn,{configurable:!0,enumerable:!0,get:()=>In[Rn]})})}),recording=!0,Pn}function noop$f(){}function statisticToken($n){let Cn,_n=$n,Pn=noop$f;return enableStatistic&&(Cn=new Set,_n=new Proxy($n,{get(In,Nn){return recording&&Cn.add(Nn),In[Nn]}}),Pn=(In,Nn)=>{Array.from(Cn)}),{token:_n,keys:Cn,flush:Pn}}const defaultTheme=createTheme(derivative),defaultConfig$1={token:defaultSeedToken,hashed:!0},DesignTokenContextKey=Symbol("DesignTokenContext"),globalDesignTokenApi=shallowRef(),useDesignTokenProvider=$n=>{provide(DesignTokenContextKey,$n),watch($n,()=>{globalDesignTokenApi.value=unref($n),triggerRef(globalDesignTokenApi)},{immediate:!0,deep:!0})},DesignTokenProvider=defineComponent({props:{value:objectType()},setup($n,Cn){let{slots:_n}=Cn;return useDesignTokenProvider(computed(()=>$n.value)),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}});function useToken(){const $n=inject(DesignTokenContextKey,computed(()=>globalDesignTokenApi.value||defaultConfig$1)),Cn=computed(()=>`${version}-${$n.value.hashed||""}`),_n=computed(()=>$n.value.theme||defaultTheme),Pn=useCacheToken(_n,computed(()=>[defaultSeedToken,$n.value.token]),computed(()=>({salt:Cn.value,override:_extends$1({override:$n.value.token},$n.value.components),formatToken})));return[_n,computed(()=>Pn.value[0]),computed(()=>$n.value.hashed?Pn.value[1]:"")]}const Empty$2=defineComponent({compatConfig:{MODE:3},setup(){const[,$n]=useToken(),Cn=computed(()=>new TinyColor($n.value.colorBgBase).toHsl().l<.5?{opacity:.65}:{});return()=>createVNode("svg",{style:Cn.value,width:"184",height:"152",viewBox:"0 0 184 152",xmlns:"http://www.w3.org/2000/svg"},[createVNode("g",{fill:"none","fill-rule":"evenodd"},[createVNode("g",{transform:"translate(24 31.67)"},[createVNode("ellipse",{"fill-opacity":".8",fill:"#F5F5F7",cx:"67.797",cy:"106.89",rx:"67.797",ry:"12.668"},null),createVNode("path",{d:"M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z",fill:"#AEB8C2"},null),createVNode("path",{d:"M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z",fill:"url(#linearGradient-1)",transform:"translate(13.56)"},null),createVNode("path",{d:"M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z",fill:"#F5F5F7"},null),createVNode("path",{d:"M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z",fill:"#DCE0E6"},null)]),createVNode("path",{d:"M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z",fill:"#DCE0E6"},null),createVNode("g",{transform:"translate(149.65 15.383)",fill:"#FFF"},[createVNode("ellipse",{cx:"20.654",cy:"3.167",rx:"2.849",ry:"2.815"},null),createVNode("path",{d:"M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z"},null)])])])}});Empty$2.PRESENTED_IMAGE_DEFAULT=!0;const DefaultEmptyImg=Empty$2,Simple=defineComponent({compatConfig:{MODE:3},setup(){const[,$n]=useToken(),Cn=computed(()=>{const{colorFill:_n,colorFillTertiary:Pn,colorFillQuaternary:In,colorBgContainer:Nn}=$n.value;return{borderColor:new TinyColor(_n).onBackground(Nn).toHexString(),shadowColor:new TinyColor(Pn).onBackground(Nn).toHexString(),contentColor:new TinyColor(In).onBackground(Nn).toHexString()}});return()=>createVNode("svg",{width:"64",height:"41",viewBox:"0 0 64 41",xmlns:"http://www.w3.org/2000/svg"},[createVNode("g",{transform:"translate(0 1)",fill:"none","fill-rule":"evenodd"},[createVNode("ellipse",{fill:Cn.value.shadowColor,cx:"32",cy:"33",rx:"32",ry:"7"},null),createVNode("g",{"fill-rule":"nonzero",stroke:Cn.value.borderColor},[createVNode("path",{d:"M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"},null),createVNode("path",{d:"M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z",fill:Cn.value.contentColor},null)])])])}});Simple.PRESENTED_IMAGE_SIMPLE=!0;const SimpleEmptyImg=Simple,genSharedEmptyStyle=$n=>{const{componentCls:Cn,margin:_n,marginXS:Pn,marginXL:In,fontSize:Nn,lineHeight:Rn}=$n;return{[Cn]:{marginInline:Pn,fontSize:Nn,lineHeight:Rn,textAlign:"center",[`${Cn}-image`]:{height:$n.emptyImgHeight,marginBottom:Pn,opacity:$n.opacityImage,img:{height:"100%"},svg:{height:"100%",margin:"auto"}},[`${Cn}-footer`]:{marginTop:_n},"&-normal":{marginBlock:In,color:$n.colorTextDisabled,[`${Cn}-image`]:{height:$n.emptyImgHeightMD}},"&-small":{marginBlock:Pn,color:$n.colorTextDisabled,[`${Cn}-image`]:{height:$n.emptyImgHeightSM}}}}},useStyle$Z=genComponentStyleHook("Empty",$n=>{const{componentCls:Cn,controlHeightLG:_n}=$n,Pn=merge$1($n,{emptyImgCls:`${Cn}-img`,emptyImgHeight:_n*2.5,emptyImgHeightMD:_n,emptyImgHeightSM:_n*.875});return[genSharedEmptyStyle(Pn)]});var __rest$1e=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,imageStyle:objectType(),image:anyType(),description:anyType()}),Empty=defineComponent({name:"AEmpty",compatConfig:{MODE:3},inheritAttrs:!1,props:emptyProps(),setup($n,Cn){let{slots:_n={},attrs:Pn}=Cn;const{direction:In,prefixCls:Nn}=useConfigInject("empty",$n),[Rn,Dn]=useStyle$Z(Nn);return()=>{var Ln,Fn;const Bn=Nn.value,Hn=_extends$1(_extends$1({},$n),Pn),{image:zn=((Ln=_n.image)===null||Ln===void 0?void 0:Ln.call(_n))||defaultEmptyImg,description:Wn=((Fn=_n.description)===null||Fn===void 0?void 0:Fn.call(_n))||void 0,imageStyle:Yn,class:Gn=""}=Hn,Go=__rest$1e(Hn,["image","description","imageStyle","class"]);return Rn(createVNode(LocaleReceiver,{componentName:"Empty",children:Xn=>{const Yo=typeof Wn<"u"?Wn:Xn.description,qo=typeof Yo=="string"?Yo:"empty";let Jo=null;return typeof zn=="string"?Jo=createVNode("img",{alt:qo,src:zn},null):Jo=zn,createVNode("div",_objectSpread2$1({class:classNames(Bn,Gn,Dn.value,{[`${Bn}-normal`]:zn===simpleEmptyImg,[`${Bn}-rtl`]:In.value==="rtl"})},Go),[createVNode("div",{class:`${Bn}-image`,style:Yn},[Jo]),Yo&&createVNode("p",{class:`${Bn}-description`},[Yo]),_n.default&&createVNode("div",{class:`${Bn}-footer`},[filterEmpty(_n.default())])])}},null))}}});Empty.PRESENTED_IMAGE_DEFAULT=defaultEmptyImg;Empty.PRESENTED_IMAGE_SIMPLE=simpleEmptyImg;const Empty$1=withInstall(Empty),DefaultRenderEmpty=$n=>{const{prefixCls:Cn}=useConfigInject("empty",$n);return(Pn=>{switch(Pn){case"Table":case"List":return createVNode(Empty$1,{image:Empty$1.PRESENTED_IMAGE_SIMPLE},null);case"Select":case"TreeSelect":case"Cascader":case"Transfer":case"Mentions":return createVNode(Empty$1,{image:Empty$1.PRESENTED_IMAGE_SIMPLE,class:`${Cn.value}-small`},null);default:return createVNode(Empty$1,null,null)}})($n.componentName)};function renderEmpty($n){return createVNode(DefaultRenderEmpty,{componentName:$n},null)}const SizeContextKey=Symbol("SizeContextKey"),useInjectSize=()=>inject(SizeContextKey,ref(void 0)),useProviderSize=$n=>{const Cn=useInjectSize();return provide(SizeContextKey,computed(()=>$n.value||Cn.value)),$n},useConfigInject=($n,Cn)=>{const _n=useInjectSize(),Pn=useInjectDisabled(),In=inject(configProviderKey,_extends$1(_extends$1({},defaultConfigProvider),{renderEmpty:nr=>h$3(DefaultRenderEmpty,{componentName:nr})})),Nn=computed(()=>In.getPrefixCls($n,Cn.prefixCls)),Rn=computed(()=>{var nr,ta;return(nr=Cn.direction)!==null&&nr!==void 0?nr:(ta=In.direction)===null||ta===void 0?void 0:ta.value}),Dn=computed(()=>{var nr;return(nr=Cn.iconPrefixCls)!==null&&nr!==void 0?nr:In.iconPrefixCls.value}),Ln=computed(()=>In.getPrefixCls()),Fn=computed(()=>{var nr;return(nr=In.autoInsertSpaceInButton)===null||nr===void 0?void 0:nr.value}),Bn=In.renderEmpty,Hn=In.space,zn=In.pageHeader,Wn=In.form,Yn=computed(()=>{var nr,ta;return(nr=Cn.getTargetContainer)!==null&&nr!==void 0?nr:(ta=In.getTargetContainer)===null||ta===void 0?void 0:ta.value}),Gn=computed(()=>{var nr,ta,oa;return(ta=(nr=Cn.getContainer)!==null&&nr!==void 0?nr:Cn.getPopupContainer)!==null&&ta!==void 0?ta:(oa=In.getPopupContainer)===null||oa===void 0?void 0:oa.value}),Go=computed(()=>{var nr,ta;return(nr=Cn.dropdownMatchSelectWidth)!==null&&nr!==void 0?nr:(ta=In.dropdownMatchSelectWidth)===null||ta===void 0?void 0:ta.value}),Xn=computed(()=>{var nr;return(Cn.virtual===void 0?((nr=In.virtual)===null||nr===void 0?void 0:nr.value)!==!1:Cn.virtual!==!1)&&Go.value!==!1}),Yo=computed(()=>Cn.size||_n.value),qo=computed(()=>{var nr,ta,oa;return(nr=Cn.autocomplete)!==null&&nr!==void 0?nr:(oa=(ta=In.input)===null||ta===void 0?void 0:ta.value)===null||oa===void 0?void 0:oa.autocomplete}),Jo=computed(()=>{var nr;return(nr=Cn.disabled)!==null&&nr!==void 0?nr:Pn.value}),Zo=computed(()=>{var nr;return(nr=Cn.csp)!==null&&nr!==void 0?nr:In.csp}),rr=computed(()=>{var nr,ta;return(nr=Cn.wave)!==null&&nr!==void 0?nr:(ta=In.wave)===null||ta===void 0?void 0:ta.value});return{configProvider:In,prefixCls:Nn,direction:Rn,size:Yo,getTargetContainer:Yn,getPopupContainer:Gn,space:Hn,pageHeader:zn,form:Wn,autoInsertSpaceInButton:Fn,renderEmpty:Bn,virtual:Xn,dropdownMatchSelectWidth:Go,rootPrefixCls:Ln,getPrefixCls:In.getPrefixCls,autocomplete:qo,csp:Zo,iconPrefixCls:Dn,disabled:Jo,select:In.select,wave:rr}};function omit$1($n,Cn){const _n=_extends$1({},$n);for(let Pn=0;Pn{const{componentCls:Cn}=$n;return{[Cn]:{position:"fixed",zIndex:$n.zIndexPopup}}},useStyle$Y=genComponentStyleHook("Affix",$n=>{const Cn=merge$1($n,{zIndexPopup:$n.zIndexBase+10});return[genSharedAffixStyle(Cn)]});function getDefaultTarget(){return typeof window<"u"?window:null}var AffixStatus;(function($n){$n[$n.None=0]="None",$n[$n.Prepare=1]="Prepare"})(AffixStatus||(AffixStatus={}));const affixProps=()=>({offsetTop:Number,offsetBottom:Number,target:{type:Function,default:getDefaultTarget},prefixCls:String,onChange:Function,onTestUpdatePosition:Function}),Affix=defineComponent({compatConfig:{MODE:3},name:"AAffix",inheritAttrs:!1,props:affixProps(),setup($n,Cn){let{slots:_n,emit:Pn,expose:In,attrs:Nn}=Cn;const Rn=shallowRef(),Dn=shallowRef(),Ln=reactive({affixStyle:void 0,placeholderStyle:void 0,status:AffixStatus.None,lastAffix:!1,prevTarget:null,timeout:null}),Fn=getCurrentInstance(),Bn=computed(()=>$n.offsetBottom===void 0&&$n.offsetTop===void 0?0:$n.offsetTop),Hn=computed(()=>$n.offsetBottom),zn=()=>{const{status:qo,lastAffix:Jo}=Ln,{target:Zo}=$n;if(qo!==AffixStatus.Prepare||!Dn.value||!Rn.value||!Zo)return;const rr=Zo();if(!rr)return;const nr={status:AffixStatus.None},ta=getTargetRect(Rn.value);if(ta.top===0&&ta.left===0&&ta.width===0&&ta.height===0)return;const oa=getTargetRect(rr),ra=getFixedTop(ta,oa,Bn.value),ea=getFixedBottom(ta,oa,Hn.value);if(!(ta.top===0&&ta.left===0&&ta.width===0&&ta.height===0)){if(ra!==void 0){const la=`${ta.width}px`,ua=`${ta.height}px`;nr.affixStyle={position:"fixed",top:ra,width:la,height:ua},nr.placeholderStyle={width:la,height:ua}}else if(ea!==void 0){const la=`${ta.width}px`,ua=`${ta.height}px`;nr.affixStyle={position:"fixed",bottom:ea,width:la,height:ua},nr.placeholderStyle={width:la,height:ua}}nr.lastAffix=!!nr.affixStyle,Jo!==nr.lastAffix&&Pn("change",nr.lastAffix),_extends$1(Ln,nr)}},Wn=()=>{_extends$1(Ln,{status:AffixStatus.Prepare,affixStyle:void 0,placeholderStyle:void 0})},Yn=throttleByAnimationFrame(()=>{Wn()}),Gn=throttleByAnimationFrame(()=>{const{target:qo}=$n,{affixStyle:Jo}=Ln;if(qo&&Jo){const Zo=qo();if(Zo&&Rn.value){const rr=getTargetRect(Zo),nr=getTargetRect(Rn.value),ta=getFixedTop(nr,rr,Bn.value),oa=getFixedBottom(nr,rr,Hn.value);if(ta!==void 0&&Jo.top===ta||oa!==void 0&&Jo.bottom===oa)return}}Wn()});In({updatePosition:Yn,lazyUpdatePosition:Gn}),watch(()=>$n.target,qo=>{const Jo=(qo==null?void 0:qo())||null;Ln.prevTarget!==Jo&&(removeObserveTarget(Fn),Jo&&(addObserveTarget(Jo,Fn),Yn()),Ln.prevTarget=Jo)}),watch(()=>[$n.offsetTop,$n.offsetBottom],Yn),onMounted(()=>{const{target:qo}=$n;qo&&(Ln.timeout=setTimeout(()=>{addObserveTarget(qo(),Fn),Yn()}))}),onUpdated(()=>{zn()}),onUnmounted(()=>{clearTimeout(Ln.timeout),removeObserveTarget(Fn),Yn.cancel(),Gn.cancel()});const{prefixCls:Go}=useConfigInject("affix",$n),[Xn,Yo]=useStyle$Y(Go);return()=>{var qo;const{affixStyle:Jo,placeholderStyle:Zo,status:rr}=Ln,nr=classNames({[Go.value]:Jo,[Yo.value]:!0}),ta=omit$1($n,["prefixCls","offsetTop","offsetBottom","target","onChange","onTestUpdatePosition"]);return Xn(createVNode(ResizeObserver$1,{onResize:Yn},{default:()=>[createVNode("div",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},ta),Nn),{},{ref:Rn,"data-measure-status":rr}),[Jo&&createVNode("div",{style:Zo,"aria-hidden":"true"},null),createVNode("div",{class:nr,ref:Dn,style:Jo},[(qo=_n.default)===null||qo===void 0?void 0:qo.call(_n)])])]}))}}}),Affix$1=withInstall(Affix);function t$3($n){return typeof $n=="object"&&$n!=null&&$n.nodeType===1}function e$2($n,Cn){return(!Cn||$n!=="hidden")&&$n!=="visible"&&$n!=="clip"}function n$3($n,Cn){if($n.clientHeight<$n.scrollHeight||$n.clientWidth<$n.scrollWidth){var _n=getComputedStyle($n,null);return e$2(_n.overflowY,Cn)||e$2(_n.overflowX,Cn)||function(Pn){var In=function(Nn){if(!Nn.ownerDocument||!Nn.ownerDocument.defaultView)return null;try{return Nn.ownerDocument.defaultView.frameElement}catch{return null}}(Pn);return!!In&&(In.clientHeightCn||Nn>$n&&Rn=Cn&&Dn>=_n?Nn-$n-Pn:Rn>Cn&&Dn<_n||Nn<$n&&Dn>_n?Rn-Cn+In:0}var i$3=function($n,Cn){var _n=window,Pn=Cn.scrollMode,In=Cn.block,Nn=Cn.inline,Rn=Cn.boundary,Dn=Cn.skipOverflowHiddenElements,Ln=typeof Rn=="function"?Rn:function(pa){return pa!==Rn};if(!t$3($n))throw new TypeError("Invalid target");for(var Fn,Bn,Hn=document.scrollingElement||document.documentElement,zn=[],Wn=$n;t$3(Wn)&&Ln(Wn);){if((Wn=(Bn=(Fn=Wn).parentElement)==null?Fn.getRootNode().host||null:Bn)===Hn){zn.push(Wn);break}Wn!=null&&Wn===document.body&&n$3(Wn)&&!n$3(document.documentElement)||Wn!=null&&n$3(Wn,Dn)&&zn.push(Wn)}for(var Yn=_n.visualViewport?_n.visualViewport.width:innerWidth,Gn=_n.visualViewport?_n.visualViewport.height:innerHeight,Go=window.scrollX||pageXOffset,Xn=window.scrollY||pageYOffset,Yo=$n.getBoundingClientRect(),qo=Yo.height,Jo=Yo.width,Zo=Yo.top,rr=Yo.right,nr=Yo.bottom,ta=Yo.left,oa=In==="start"||In==="nearest"?Zo:In==="end"?nr:Zo+qo/2,ra=Nn==="center"?ta+Jo/2:Nn==="end"?rr:ta,ea=[],la=0;la=0&&ta>=0&&nr<=Gn&&rr<=Yn&&Zo>=sa&&nr<=fa&&ta>=ma&&rr<=ia)return ea;var ya=getComputedStyle(ua),ba=parseInt(ya.borderLeftWidth,10),Ia=parseInt(ya.borderTopWidth,10),Ea=parseInt(ya.borderRightWidth,10),xa=parseInt(ya.borderBottomWidth,10),Ta=0,wa=0,La="offsetWidth"in ua?ua.offsetWidth-ua.clientWidth-ba-Ea:0,Na="offsetHeight"in ua?ua.offsetHeight-ua.clientHeight-Ia-xa:0,$a="offsetWidth"in ua?ua.offsetWidth===0?0:ca/ua.offsetWidth:0,ka="offsetHeight"in ua?ua.offsetHeight===0?0:aa/ua.offsetHeight:0;if(Hn===ua)Ta=In==="start"?oa:In==="end"?oa-Gn:In==="nearest"?r$3(Xn,Xn+Gn,Gn,Ia,xa,Xn+oa,Xn+oa+qo,qo):oa-Gn/2,wa=Nn==="start"?ra:Nn==="center"?ra-Yn/2:Nn==="end"?ra-Yn:r$3(Go,Go+Yn,Yn,ba,Ea,Go+ra,Go+ra+Jo,Jo),Ta=Math.max(0,Ta+Xn),wa=Math.max(0,wa+Go);else{Ta=In==="start"?oa-sa-Ia:In==="end"?oa-fa+xa+Na:In==="nearest"?r$3(sa,fa,aa,Ia,xa+Na,oa,oa+qo,qo):oa-(sa+aa/2)+Na/2,wa=Nn==="start"?ra-ma-ba:Nn==="center"?ra-(ma+ca/2)+La/2:Nn==="end"?ra-ia+Ea+La:r$3(ma,ia,ca,ba,Ea+La,ra,ra+Jo,Jo);var Ha=ua.scrollLeft,da=ua.scrollTop;oa+=da-(Ta=Math.max(0,Math.min(da+Ta/ka,ua.scrollHeight-aa/ka+Na))),ra+=Ha-(wa=Math.max(0,Math.min(Ha+wa/$a,ua.scrollWidth-ca/$a+La)))}ea.push({el:ua,top:Ta,left:wa})}return ea};function isOptionsObject($n){return $n===Object($n)&&Object.keys($n).length!==0}function defaultBehavior($n,Cn){Cn===void 0&&(Cn="auto");var _n="scrollBehavior"in document.body.style;$n.forEach(function(Pn){var In=Pn.el,Nn=Pn.top,Rn=Pn.left;In.scroll&&_n?In.scroll({top:Nn,left:Rn,behavior:Cn}):(In.scrollTop=Nn,In.scrollLeft=Rn)})}function getOptions($n){return $n===!1?{block:"end",inline:"nearest"}:isOptionsObject($n)?$n:{block:"start",inline:"nearest"}}function scrollIntoView($n,Cn){var _n=$n.isConnected||$n.ownerDocument.documentElement.contains($n);if(isOptionsObject(Cn)&&typeof Cn.behavior=="function")return Cn.behavior(_n?i$3($n,Cn):[]);if(_n){var Pn=getOptions(Cn);return defaultBehavior(i$3($n,Pn),Pn.behavior)}}function easeInOutCubic($n,Cn,_n,Pn){const In=_n-Cn;return $n/=Pn/2,$n<1?In/2*$n*$n*$n+Cn:In/2*(($n-=2)*$n*$n+2)+Cn}function isWindow$1($n){return $n!=null&&$n===$n.window}function getScroll$3($n,Cn){var _n,Pn;if(typeof window>"u")return 0;const In=Cn?"scrollTop":"scrollLeft";let Nn=0;return isWindow$1($n)?Nn=$n[Cn?"pageYOffset":"pageXOffset"]:$n instanceof Document?Nn=$n.documentElement[In]:($n instanceof HTMLElement||$n)&&(Nn=$n[In]),$n&&!isWindow$1($n)&&typeof Nn!="number"&&(Nn=(Pn=((_n=$n.ownerDocument)!==null&&_n!==void 0?_n:$n).documentElement)===null||Pn===void 0?void 0:Pn[In]),Nn}function scrollTo$1($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const{getContainer:_n=()=>window,callback:Pn,duration:In=450}=Cn,Nn=_n(),Rn=getScroll$3(Nn,!0),Dn=Date.now(),Ln=()=>{const Bn=Date.now()-Dn,Hn=easeInOutCubic(Bn>In?In:Bn,Rn,$n,In);isWindow$1(Nn)?Nn.scrollTo(window.pageXOffset,Hn):Nn instanceof Document||Nn.constructor.name==="HTMLDocument"?Nn.documentElement.scrollTop=Hn:Nn.scrollTop=Hn,Bn{provide(AnchorContextKey,$n)},useInjectAnchor=()=>inject(AnchorContextKey,{registerLink:noop$e,unregisterLink:noop$e,scrollTo:noop$e,activeLink:computed(()=>""),handleClick:noop$e,direction:computed(()=>"vertical")}),genSharedAnchorStyle=$n=>{const{componentCls:Cn,holderOffsetBlock:_n,motionDurationSlow:Pn,lineWidthBold:In,colorPrimary:Nn,lineType:Rn,colorSplit:Dn}=$n;return{[`${Cn}-wrapper`]:{marginBlockStart:-_n,paddingBlockStart:_n,backgroundColor:"transparent",[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",paddingInlineStart:In,[`${Cn}-link`]:{paddingBlock:$n.anchorPaddingBlock,paddingInline:`${$n.anchorPaddingInline}px 0`,"&-title":_extends$1(_extends$1({},textEllipsis),{position:"relative",display:"block",marginBlockEnd:$n.anchorTitleBlock,color:$n.colorText,transition:`all ${$n.motionDurationSlow}`,"&:only-child":{marginBlockEnd:0}}),[`&-active > ${Cn}-link-title`]:{color:$n.colorPrimary},[`${Cn}-link`]:{paddingBlock:$n.anchorPaddingBlockSecondary}}}),[`&:not(${Cn}-wrapper-horizontal)`]:{[Cn]:{"&::before":{position:"absolute",left:{_skip_check_:!0,value:0},top:0,height:"100%",borderInlineStart:`${In}px ${Rn} ${Dn}`,content:'" "'},[`${Cn}-ink`]:{position:"absolute",left:{_skip_check_:!0,value:0},display:"none",transform:"translateY(-50%)",transition:`top ${Pn} ease-in-out`,width:In,backgroundColor:Nn,[`&${Cn}-ink-visible`]:{display:"inline-block"}}}},[`${Cn}-fixed ${Cn}-ink ${Cn}-ink`]:{display:"none"}}}},genSharedAnchorHorizontalStyle=$n=>{const{componentCls:Cn,motionDurationSlow:_n,lineWidthBold:Pn,colorPrimary:In}=$n;return{[`${Cn}-wrapper-horizontal`]:{position:"relative","&::before":{position:"absolute",left:{_skip_check_:!0,value:0},right:{_skip_check_:!0,value:0},bottom:0,borderBottom:`1px ${$n.lineType} ${$n.colorSplit}`,content:'" "'},[Cn]:{overflowX:"scroll",position:"relative",display:"flex",scrollbarWidth:"none","&::-webkit-scrollbar":{display:"none"},[`${Cn}-link:first-of-type`]:{paddingInline:0},[`${Cn}-ink`]:{position:"absolute",bottom:0,transition:`left ${_n} ease-in-out, width ${_n} ease-in-out`,height:Pn,backgroundColor:In}}}}},useStyle$X=genComponentStyleHook("Anchor",$n=>{const{fontSize:Cn,fontSizeLG:_n,padding:Pn,paddingXXS:In}=$n,Nn=merge$1($n,{holderOffsetBlock:In,anchorPaddingBlock:In,anchorPaddingBlockSecondary:In/2,anchorPaddingInline:Pn,anchorTitleBlock:Cn/14*3,anchorBallSize:_n/2});return[genSharedAnchorStyle(Nn),genSharedAnchorHorizontalStyle(Nn)]}),anchorLinkProps=()=>({prefixCls:String,href:String,title:anyType(),target:String,customTitleProps:objectType()}),AnchorLink=defineComponent({compatConfig:{MODE:3},name:"AAnchorLink",inheritAttrs:!1,props:initDefaultProps(anchorLinkProps(),{href:"#"}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn,In=null;const{handleClick:Nn,scrollTo:Rn,unregisterLink:Dn,registerLink:Ln,activeLink:Fn}=useInjectAnchor(),{prefixCls:Bn}=useConfigInject("anchor",$n),Hn=zn=>{const{href:Wn}=$n;Nn(zn,{title:In,href:Wn}),Rn(Wn)};return watch(()=>$n.href,(zn,Wn)=>{nextTick(()=>{Dn(Wn),Ln(zn)})}),onMounted(()=>{Ln($n.href)}),onBeforeUnmount(()=>{Dn($n.href)}),()=>{var zn;const{href:Wn,target:Yn,title:Gn=_n.title,customTitleProps:Go={}}=$n,Xn=Bn.value;In=typeof Gn=="function"?Gn(Go):Gn;const Yo=Fn.value===Wn,qo=classNames(`${Xn}-link`,{[`${Xn}-link-active`]:Yo},Pn.class),Jo=classNames(`${Xn}-link-title`,{[`${Xn}-link-title-active`]:Yo});return createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:qo}),[createVNode("a",{class:Jo,href:Wn,title:typeof In=="string"?In:"",target:Yn,onClick:Hn},[_n.customTitle?_n.customTitle(Go):In]),(zn=_n.default)===null||zn===void 0?void 0:zn.call(_n)])}}});function e$1($n,Cn){for(var _n=0;_n=0||(In[_n]=$n[_n]);return In}function o$2($n){return((Cn=$n)!=null&&typeof Cn=="object"&&Array.isArray(Cn)===!1)==1&&Object.prototype.toString.call($n)==="[object Object]";var Cn}var u$2=Object.prototype,a$2=u$2.toString,f$2=u$2.hasOwnProperty,c$2=/^\s*function (\w+)/;function l$2($n){var Cn,_n=(Cn=$n==null?void 0:$n.type)!==null&&Cn!==void 0?Cn:$n;if(_n){var Pn=_n.toString().match(c$2);return Pn?Pn[1]:""}return""}var s$2=function($n){var Cn,_n;return o$2($n)!==!1&&typeof(Cn=$n.constructor)=="function"&&o$2(_n=Cn.prototype)!==!1&&_n.hasOwnProperty("isPrototypeOf")!==!1},v$2=function($n){return $n},y$2=v$2,d$2=function($n,Cn){return f$2.call($n,Cn)},h$2=Number.isInteger||function($n){return typeof $n=="number"&&isFinite($n)&&Math.floor($n)===$n},b$2=Array.isArray||function($n){return a$2.call($n)==="[object Array]"},O$2=function($n){return a$2.call($n)==="[object Function]"},g$2=function($n){return s$2($n)&&d$2($n,"_vueTypes_name")},m$2=function($n){return s$2($n)&&(d$2($n,"type")||["_vueTypes_name","validator","default","required"].some(function(Cn){return d$2($n,Cn)}))};function j$2($n,Cn){return Object.defineProperty($n.bind(Cn),"__original",{value:$n})}function _$3($n,Cn,_n){var Pn;_n===void 0&&(_n=!1);var In=!0,Nn="";Pn=s$2($n)?$n:{type:$n};var Rn=g$2(Pn)?Pn._vueTypes_name+" - ":"";if(m$2(Pn)&&Pn.type!==null){if(Pn.type===void 0||Pn.type===!0||!Pn.required&&Cn===void 0)return In;b$2(Pn.type)?(In=Pn.type.some(function(Hn){return _$3(Hn,Cn,!0)===!0}),Nn=Pn.type.map(function(Hn){return l$2(Hn)}).join(" or ")):In=(Nn=l$2(Pn))==="Array"?b$2(Cn):Nn==="Object"?s$2(Cn):Nn==="String"||Nn==="Number"||Nn==="Boolean"||Nn==="Function"?function(Hn){if(Hn==null)return"";var zn=Hn.constructor.toString().match(c$2);return zn?zn[1]:""}(Cn)===Nn:Cn instanceof Pn.type}if(!In){var Dn=Rn+'value "'+Cn+'" should be of type "'+Nn+'"';return _n===!1?(y$2(Dn),!1):Dn}if(d$2(Pn,"validator")&&O$2(Pn.validator)){var Ln=y$2,Fn=[];if(y$2=function(Hn){Fn.push(Hn)},In=Pn.validator(Cn),y$2=Ln,!In){var Bn=(Fn.length>1?"* ":"")+Fn.join(` -* `);return Fn.length=0,_n===!1?(y$2(Bn),In):Bn}}return In}function T$2($n,Cn){var _n=Object.defineProperties(Cn,{_vueTypes_name:{value:$n,writable:!0},isRequired:{get:function(){return this.required=!0,this}},def:{value:function(In){return In!==void 0||this.default?O$2(In)||_$3(this,In,!0)===!0?(this.default=b$2(In)?function(){return[].concat(In)}:s$2(In)?function(){return Object.assign({},In)}:In,this):(y$2(this._vueTypes_name+' - invalid default value: "'+In+'"'),this):this}}}),Pn=_n.validator;return O$2(Pn)&&(_n.validator=j$2(Pn,_n)),_n}function w$2($n,Cn){var _n=T$2($n,Cn);return Object.defineProperty(_n,"validate",{value:function(Pn){return O$2(this.validator)&&y$2(this._vueTypes_name+` - calling .validate() will overwrite the current custom validator function. Validator info: -`+JSON.stringify(this)),this.validator=j$2(Pn,this),this}})}function k$1($n,Cn,_n){var Pn,In,Nn=(Pn=Cn,In={},Object.getOwnPropertyNames(Pn).forEach(function(Hn){In[Hn]=Object.getOwnPropertyDescriptor(Pn,Hn)}),Object.defineProperties({},In));if(Nn._vueTypes_name=$n,!s$2(_n))return Nn;var Rn,Dn,Ln=_n.validator,Fn=i$2(_n,["validator"]);if(O$2(Ln)){var Bn=Nn.validator;Bn&&(Bn=(Dn=(Rn=Bn).__original)!==null&&Dn!==void 0?Dn:Rn),Nn.validator=j$2(Bn?function(Hn){return Bn.call(this,Hn)&&Ln.call(this,Hn)}:Ln,Nn)}return Object.assign(Nn,Fn)}function P$2($n){return $n.replace(/^(?!\s*$)/gm," ")}var x$2=function(){return w$2("any",{})},A$2=function(){return w$2("function",{type:Function})},E$2=function(){return w$2("boolean",{type:Boolean})},N$2=function(){return w$2("string",{type:String})},q$2=function(){return w$2("number",{type:Number})},S$2=function(){return w$2("array",{type:Array})},V$3=function(){return w$2("object",{type:Object})},F$2=function(){return T$2("integer",{type:Number,validator:function($n){return h$2($n)}})},D$2=function(){return T$2("symbol",{validator:function($n){return typeof $n=="symbol"}})};function L$3($n,Cn){if(Cn===void 0&&(Cn="custom validation failed"),typeof $n!="function")throw new TypeError("[VueTypes error]: You must provide a function as argument");return T$2($n.name||"<>",{validator:function(_n){var Pn=$n(_n);return Pn||y$2(this._vueTypes_name+" - "+Cn),Pn}})}function Y$2($n){if(!b$2($n))throw new TypeError("[VueTypes error]: You must provide an array as argument.");var Cn='oneOf - value should be one of "'+$n.join('", "')+'".',_n=$n.reduce(function(Pn,In){if(In!=null){var Nn=In.constructor;Pn.indexOf(Nn)===-1&&Pn.push(Nn)}return Pn},[]);return T$2("oneOf",{type:_n.length>0?_n:void 0,validator:function(Pn){var In=$n.indexOf(Pn)!==-1;return In||y$2(Cn),In}})}function B$3($n){if(!b$2($n))throw new TypeError("[VueTypes error]: You must provide an array as argument");for(var Cn=!1,_n=[],Pn=0;Pn<$n.length;Pn+=1){var In=$n[Pn];if(m$2(In)){if(g$2(In)&&In._vueTypes_name==="oneOf"){_n=_n.concat(In.type);continue}if(O$2(In.validator)&&(Cn=!0),In.type!==!0&&In.type){_n=_n.concat(In.type);continue}}_n.push(In)}return _n=_n.filter(function(Nn,Rn){return _n.indexOf(Nn)===Rn}),T$2("oneOfType",Cn?{type:_n,validator:function(Nn){var Rn=[],Dn=$n.some(function(Ln){var Fn=_$3(g$2(Ln)&&Ln._vueTypes_name==="oneOf"?Ln.type||null:Ln,Nn,!0);return typeof Fn=="string"&&Rn.push(Fn),Fn===!0});return Dn||y$2("oneOfType - provided value does not match any of the "+Rn.length+` passed-in validators: -`+P$2(Rn.join(` -`))),Dn}}:{type:_n})}function I$2($n){return T$2("arrayOf",{type:Array,validator:function(Cn){var _n,Pn=Cn.every(function(In){return(_n=_$3($n,In,!0))===!0});return Pn||y$2(`arrayOf - value validation error: -`+P$2(_n)),Pn}})}function J$2($n){return T$2("instanceOf",{type:$n})}function M$2($n){return T$2("objectOf",{type:Object,validator:function(Cn){var _n,Pn=Object.keys(Cn).every(function(In){return(_n=_$3($n,Cn[In],!0))===!0});return Pn||y$2(`objectOf - value validation error: -`+P$2(_n)),Pn}})}function R$2($n){var Cn=Object.keys($n),_n=Cn.filter(function(In){var Nn;return!!(!((Nn=$n[In])===null||Nn===void 0)&&Nn.required)}),Pn=T$2("shape",{type:Object,validator:function(In){var Nn=this;if(!s$2(In))return!1;var Rn=Object.keys(In);if(_n.length>0&&_n.some(function(Ln){return Rn.indexOf(Ln)===-1})){var Dn=_n.filter(function(Ln){return Rn.indexOf(Ln)===-1});return y$2(Dn.length===1?'shape - required property "'+Dn[0]+'" is not defined.':'shape - required properties "'+Dn.join('", "')+'" are not defined.'),!1}return Rn.every(function(Ln){if(Cn.indexOf(Ln)===-1)return Nn._vueTypes_isLoose===!0||(y$2('shape - shape definition does not include a "'+Ln+'" property. Allowed keys: "'+Cn.join('", "')+'".'),!1);var Fn=_$3($n[Ln],In[Ln],!0);return typeof Fn=="string"&&y$2('shape - "'+Ln+`" property validation error: - `+P$2(Fn)),Fn===!0})}});return Object.defineProperty(Pn,"_vueTypes_isLoose",{writable:!0,value:!1}),Object.defineProperty(Pn,"loose",{get:function(){return this._vueTypes_isLoose=!0,this}}),Pn}var $$2=function(){function $n(){}return $n.extend=function(Cn){var _n=this;if(b$2(Cn))return Cn.forEach(function(Hn){return _n.extend(Hn)}),this;var Pn=Cn.name,In=Cn.validate,Nn=In!==void 0&&In,Rn=Cn.getter,Dn=Rn!==void 0&&Rn,Ln=i$2(Cn,["name","validate","getter"]);if(d$2(this,Pn))throw new TypeError('[VueTypes error]: Type "'+Pn+'" already defined');var Fn,Bn=Ln.type;return g$2(Bn)?(delete Ln.type,Object.defineProperty(this,Pn,Dn?{get:function(){return k$1(Pn,Bn,Ln)}}:{value:function(){var Hn,zn=k$1(Pn,Bn,Ln);return zn.validator&&(zn.validator=(Hn=zn.validator).bind.apply(Hn,[zn].concat([].slice.call(arguments)))),zn}})):(Fn=Dn?{get:function(){var Hn=Object.assign({},Ln);return Nn?w$2(Pn,Hn):T$2(Pn,Hn)},enumerable:!0}:{value:function(){var Hn,zn,Wn=Object.assign({},Ln);return Hn=Nn?w$2(Pn,Wn):T$2(Pn,Wn),Wn.validator&&(Hn.validator=(zn=Wn.validator).bind.apply(zn,[Hn].concat([].slice.call(arguments)))),Hn},enumerable:!0},Object.defineProperty(this,Pn,Fn))},t$2($n,null,[{key:"any",get:function(){return x$2()}},{key:"func",get:function(){return A$2().def(this.defaults.func)}},{key:"bool",get:function(){return E$2().def(this.defaults.bool)}},{key:"string",get:function(){return N$2().def(this.defaults.string)}},{key:"number",get:function(){return q$2().def(this.defaults.number)}},{key:"array",get:function(){return S$2().def(this.defaults.array)}},{key:"object",get:function(){return V$3().def(this.defaults.object)}},{key:"integer",get:function(){return F$2().def(this.defaults.integer)}},{key:"symbol",get:function(){return D$2()}}]),$n}();function z$2($n){var Cn;return $n===void 0&&($n={func:function(){},bool:!0,string:"",number:0,array:function(){return[]},object:function(){return{}},integer:0}),(Cn=function(_n){function Pn(){return _n.apply(this,arguments)||this}return r$2(Pn,_n),t$2(Pn,null,[{key:"sensibleDefaults",get:function(){return n$2({},this.defaults)},set:function(In){this.defaults=In!==!1?n$2({},In!==!0?In:$n):{}}}]),Pn}($$2)).defaults=n$2({},$n),Cn}$$2.defaults={},$$2.custom=L$3,$$2.oneOf=Y$2,$$2.instanceOf=J$2,$$2.oneOfType=B$3,$$2.arrayOf=I$2,$$2.objectOf=M$2,$$2.shape=R$2,$$2.utils={validate:function($n,Cn){return _$3(Cn,$n,!0)===!0},toType:function($n,Cn,_n){return _n===void 0&&(_n=!1),_n?w$2($n,Cn):T$2($n,Cn)}};(function($n){function Cn(){return $n.apply(this,arguments)||this}return r$2(Cn,$n),Cn})(z$2());const PropTypes=z$2({func:void 0,bool:void 0,string:void 0,number:void 0,array:void 0,object:void 0,integer:void 0});PropTypes.extend([{name:"looseBool",getter:!0,type:Boolean,default:void 0},{name:"style",getter:!0,type:[String,Object],default:void 0},{name:"VueNode",getter:!0,type:null}]);function withUndefined($n){return $n.default=void 0,$n}const devWarning=($n,Cn,_n)=>{warningOnce($n,`[ant-design-vue: ${Cn}] ${_n}`)};function getDefaultContainer(){return window}function getOffsetTop($n,Cn){if(!$n.getClientRects().length)return 0;const _n=$n.getBoundingClientRect();return _n.width||_n.height?Cn===window?(Cn=$n.ownerDocument.documentElement,_n.top-Cn.clientTop):_n.top-Cn.getBoundingClientRect().top:_n.top}const sharpMatcherRegx=/#([\S ]+)$/,anchorProps=()=>({prefixCls:String,offsetTop:Number,bounds:Number,affix:{type:Boolean,default:!0},showInkInFixed:{type:Boolean,default:!1},getContainer:Function,wrapperClass:String,wrapperStyle:{type:Object,default:void 0},getCurrentAnchor:Function,targetOffset:Number,items:arrayType(),direction:PropTypes.oneOf(["vertical","horizontal"]).def("vertical"),onChange:Function,onClick:Function}),Anchor=defineComponent({compatConfig:{MODE:3},name:"AAnchor",inheritAttrs:!1,props:anchorProps(),setup($n,Cn){let{emit:_n,attrs:Pn,slots:In,expose:Nn}=Cn;const{prefixCls:Rn,getTargetContainer:Dn,direction:Ln}=useConfigInject("anchor",$n),Fn=computed(()=>{var nr;return(nr=$n.direction)!==null&&nr!==void 0?nr:"vertical"}),Bn=ref(null),Hn=ref(),zn=reactive({links:[],scrollContainer:null,scrollEvent:null,animating:!1}),Wn=ref(null),Yn=computed(()=>{const{getContainer:nr}=$n;return nr||(Dn==null?void 0:Dn.value)||getDefaultContainer}),Gn=function(){let nr=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,ta=arguments.length>1&&arguments[1]!==void 0?arguments[1]:5;const oa=[],ra=Yn.value();return zn.links.forEach(ea=>{const la=sharpMatcherRegx.exec(ea.toString());if(!la)return;const ua=document.getElementById(la[1]);if(ua){const ga=getOffsetTop(ua,ra);gaua.top>la.top?ua:la).link:""},Go=nr=>{const{getCurrentAnchor:ta}=$n;Wn.value!==nr&&(Wn.value=typeof ta=="function"?ta(nr):nr,_n("change",nr))},Xn=nr=>{const{offsetTop:ta,targetOffset:oa}=$n;Go(nr);const ra=sharpMatcherRegx.exec(nr);if(!ra)return;const ea=document.getElementById(ra[1]);if(!ea)return;const la=Yn.value(),ua=getScroll$3(la,!0),ga=getOffsetTop(ea,la);let aa=ua+ga;aa-=oa!==void 0?oa:ta||0,zn.animating=!0,scrollTo$1(aa,{callback:()=>{zn.animating=!1},getContainer:Yn.value})};Nn({scrollTo:Xn});const Yo=()=>{if(zn.animating)return;const{offsetTop:nr,bounds:ta,targetOffset:oa}=$n,ra=Gn(oa!==void 0?oa:nr||0,ta);Go(ra)},qo=()=>{const nr=Hn.value.querySelector(`.${Rn.value}-link-title-active`);if(nr&&Bn.value){const ta=Fn.value==="horizontal";Bn.value.style.top=ta?"":`${nr.offsetTop+nr.clientHeight/2}px`,Bn.value.style.height=ta?"":`${nr.clientHeight}px`,Bn.value.style.left=ta?`${nr.offsetLeft}px`:"",Bn.value.style.width=ta?`${nr.clientWidth}px`:"",ta&&scrollIntoView(nr,{scrollMode:"if-needed",block:"nearest"})}};useProvideAnchor({registerLink:nr=>{zn.links.includes(nr)||zn.links.push(nr)},unregisterLink:nr=>{const ta=zn.links.indexOf(nr);ta!==-1&&zn.links.splice(ta,1)},activeLink:Wn,scrollTo:Xn,handleClick:(nr,ta)=>{_n("click",nr,ta)},direction:Fn}),onMounted(()=>{nextTick(()=>{const nr=Yn.value();zn.scrollContainer=nr,zn.scrollEvent=addEventListenerWrap(zn.scrollContainer,"scroll",Yo),Yo()})}),onBeforeUnmount(()=>{zn.scrollEvent&&zn.scrollEvent.remove()}),onUpdated(()=>{if(zn.scrollEvent){const nr=Yn.value();zn.scrollContainer!==nr&&(zn.scrollContainer=nr,zn.scrollEvent.remove(),zn.scrollEvent=addEventListenerWrap(zn.scrollContainer,"scroll",Yo),Yo())}qo()});const Jo=nr=>Array.isArray(nr)?nr.map(ta=>{const{children:oa,key:ra,href:ea,target:la,class:ua,style:ga,title:aa}=ta;return createVNode(AnchorLink,{key:ra,href:ea,target:la,class:ua,style:ga,title:aa,customTitleProps:ta},{default:()=>[Fn.value==="vertical"?Jo(oa):null],customTitle:In.customTitle})}):null,[Zo,rr]=useStyle$X(Rn);return()=>{var nr;const{offsetTop:ta,affix:oa,showInkInFixed:ra}=$n,ea=Rn.value,la=classNames(`${ea}-ink`,{[`${ea}-ink-visible`]:Wn.value}),ua=classNames(rr.value,$n.wrapperClass,`${ea}-wrapper`,{[`${ea}-wrapper-horizontal`]:Fn.value==="horizontal",[`${ea}-rtl`]:Ln.value==="rtl"}),ga=classNames(ea,{[`${ea}-fixed`]:!oa&&!ra}),aa=_extends$1({maxHeight:ta?`calc(100vh - ${ta}px)`:"100vh"},$n.wrapperStyle),ca=createVNode("div",{class:ua,style:aa,ref:Hn},[createVNode("div",{class:ga},[createVNode("span",{class:la,ref:Bn},null),Array.isArray($n.items)?Jo($n.items):(nr=In.default)===null||nr===void 0?void 0:nr.call(In)])]);return Zo(oa?createVNode(Affix$1,_objectSpread2$1(_objectSpread2$1({},Pn),{},{offsetTop:ta,target:Yn.value}),{default:()=>[ca]}):ca)}}});Anchor.Link=AnchorLink;Anchor.install=function($n){return $n.component(Anchor.name,Anchor),$n.component(Anchor.Link.name,Anchor.Link),$n};function getKey$2($n,Cn){const{key:_n}=$n;let Pn;return"value"in $n&&({value:Pn}=$n),_n??(Pn!==void 0?Pn:`rc-index-key-${Cn}`)}function fillFieldNames$3($n,Cn){const{label:_n,value:Pn,options:In}=$n||{};return{label:_n||(Cn?"children":"label"),value:Pn||"value",options:In||"options"}}function flattenOptions($n){let{fieldNames:Cn,childrenAsData:_n}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const Pn=[],{label:In,value:Nn,options:Rn}=fillFieldNames$3(Cn,!1);function Dn(Ln,Fn){Ln.forEach(Bn=>{const Hn=Bn[In];if(Fn||!(Rn in Bn)){const zn=Bn[Nn];Pn.push({key:getKey$2(Bn,Pn.length),groupOption:Fn,data:Bn,label:Hn,value:zn})}else{let zn=Hn;zn===void 0&&_n&&(zn=Bn.label),Pn.push({key:getKey$2(Bn,Pn.length),group:!0,data:Bn,label:zn}),Dn(Bn[Rn],!0)}})}return Dn($n,!1),Pn}function injectPropsWithOption($n){const Cn=_extends$1({},$n);return"props"in Cn||Object.defineProperty(Cn,"props",{get(){return Cn}}),Cn}function getSeparatedContent($n,Cn){if(!Cn||!Cn.length)return null;let _n=!1;function Pn(Nn,Rn){let[Dn,...Ln]=Rn;if(!Dn)return[Nn];const Fn=Nn.split(Dn);return _n=_n||Fn.length>1,Fn.reduce((Bn,Hn)=>[...Bn,...Pn(Hn,Ln)],[]).filter(Bn=>Bn)}const In=Pn($n,Cn);return _n?In:null}function returnEmptyString(){return""}function returnDocument($n){return $n?$n.ownerDocument:window.document}function noop$d(){}const triggerProps=()=>({action:PropTypes.oneOfType([PropTypes.string,PropTypes.arrayOf(PropTypes.string)]).def([]),showAction:PropTypes.any.def([]),hideAction:PropTypes.any.def([]),getPopupClassNameFromAlign:PropTypes.any.def(returnEmptyString),onPopupVisibleChange:Function,afterPopupVisibleChange:PropTypes.func.def(noop$d),popup:PropTypes.any,popupStyle:{type:Object,default:void 0},prefixCls:PropTypes.string.def("rc-trigger-popup"),popupClassName:PropTypes.string.def(""),popupPlacement:String,builtinPlacements:PropTypes.object,popupTransitionName:String,popupAnimation:PropTypes.any,mouseEnterDelay:PropTypes.number.def(0),mouseLeaveDelay:PropTypes.number.def(.1),zIndex:Number,focusDelay:PropTypes.number.def(0),blurDelay:PropTypes.number.def(.15),getPopupContainer:Function,getDocument:PropTypes.func.def(returnDocument),forceRender:{type:Boolean,default:void 0},destroyPopupOnHide:{type:Boolean,default:!1},mask:{type:Boolean,default:!1},maskClosable:{type:Boolean,default:!0},popupAlign:PropTypes.object.def(()=>({})),popupVisible:{type:Boolean,default:void 0},defaultPopupVisible:{type:Boolean,default:!1},maskTransitionName:String,maskAnimation:String,stretch:String,alignPoint:{type:Boolean,default:void 0},autoDestroy:{type:Boolean,default:!1},mobile:Object,getTriggerDOMNode:Function}),innerProps={visible:Boolean,prefixCls:String,zIndex:Number,destroyPopupOnHide:Boolean,forceRender:Boolean,animation:[String,Object],transitionName:String,stretch:{type:String},align:{type:Object},point:{type:Object},getRootDomNode:{type:Function},getClassNameFromAlign:{type:Function},onAlign:{type:Function},onMouseenter:{type:Function},onMouseleave:{type:Function},onMousedown:{type:Function},onTouchstart:{type:Function}},mobileProps=_extends$1(_extends$1({},innerProps),{mobile:{type:Object}}),popupProps=_extends$1(_extends$1({},innerProps),{mask:Boolean,mobile:{type:Object},maskAnimation:String,maskTransitionName:String});function getMotion$1($n){let{prefixCls:Cn,animation:_n,transitionName:Pn}=$n;return _n?{name:`${Cn}-${_n}`}:Pn?{name:Pn}:{}}function Mask$3($n){const{prefixCls:Cn,visible:_n,zIndex:Pn,mask:In,maskAnimation:Nn,maskTransitionName:Rn}=$n;if(!In)return null;let Dn={};return(Rn||Nn)&&(Dn=getMotion$1({prefixCls:Cn,transitionName:Rn,animation:Nn})),createVNode(Transition,_objectSpread2$1({appear:!0},Dn),{default:()=>[withDirectives(createVNode("div",{style:{zIndex:Pn},class:`${Cn}-mask`},null),[[resolveDirective("if"),_n]])]})}Mask$3.displayName="Mask";const MobilePopupInner=defineComponent({compatConfig:{MODE:3},name:"MobilePopupInner",inheritAttrs:!1,props:mobileProps,emits:["mouseenter","mouseleave","mousedown","touchstart","align"],setup($n,Cn){let{expose:_n,slots:Pn}=Cn;const In=ref();return _n({forceAlign:()=>{},getElement:()=>In.value}),()=>{var Nn;const{zIndex:Rn,visible:Dn,prefixCls:Ln,mobile:{popupClassName:Fn,popupStyle:Bn,popupMotion:Hn={},popupRender:zn}={}}=$n,Wn=_extends$1({zIndex:Rn},Bn);let Yn=flattenChildren((Nn=Pn.default)===null||Nn===void 0?void 0:Nn.call(Pn));Yn.length>1&&(Yn=createVNode("div",{class:`${Ln}-content`},[Yn])),zn&&(Yn=zn(Yn));const Gn=classNames(Ln,Fn);return createVNode(Transition,_objectSpread2$1({ref:In},Hn),{default:()=>[Dn?createVNode("div",{class:Gn,style:Wn},[Yn]):null]})}}});var __awaiter$3=function($n,Cn,_n,Pn){function In(Nn){return Nn instanceof _n?Nn:new _n(function(Rn){Rn(Nn)})}return new(_n||(_n=Promise))(function(Nn,Rn){function Dn(Bn){try{Fn(Pn.next(Bn))}catch(Hn){Rn(Hn)}}function Ln(Bn){try{Fn(Pn.throw(Bn))}catch(Hn){Rn(Hn)}}function Fn(Bn){Bn.done?Nn(Bn.value):In(Bn.value).then(Dn,Ln)}Fn((Pn=Pn.apply($n,Cn||[])).next())})};const StatusQueue=["measure","align",null,"motion"],useVisibleStatus=($n,Cn)=>{const _n=shallowRef(null),Pn=shallowRef(),In=shallowRef(!1);function Nn(Ln){In.value||(_n.value=Ln)}function Rn(){wrapperRaf.cancel(Pn.value)}function Dn(Ln){Rn(),Pn.value=wrapperRaf(()=>{let Fn=_n.value;switch(_n.value){case"align":Fn="motion";break;case"motion":Fn="stable";break}Nn(Fn),Ln==null||Ln()})}return watch($n,()=>{Nn("measure")},{immediate:!0,flush:"post"}),onMounted(()=>{watch(_n,()=>{switch(_n.value){case"measure":Cn();break}_n.value&&(Pn.value=wrapperRaf(()=>__awaiter$3(void 0,void 0,void 0,function*(){const Ln=StatusQueue.indexOf(_n.value),Fn=StatusQueue[Ln+1];Fn&&Ln!==-1&&Nn(Fn)})))},{immediate:!0,flush:"post"})}),onBeforeUnmount(()=>{In.value=!0,Rn()}),[_n,Dn]},useStretchStyle=$n=>{const Cn=shallowRef({width:0,height:0});function _n(In){Cn.value={width:In.offsetWidth,height:In.offsetHeight}}return[computed(()=>{const In={};if($n.value){const{width:Nn,height:Rn}=Cn.value;$n.value.indexOf("height")!==-1&&Rn?In.height=`${Rn}px`:$n.value.indexOf("minHeight")!==-1&&Rn&&(In.minHeight=`${Rn}px`),$n.value.indexOf("width")!==-1&&Nn?In.width=`${Nn}px`:$n.value.indexOf("minWidth")!==-1&&Nn&&(In.minWidth=`${Nn}px`)}return In}),_n]};function ownKeys($n,Cn){var _n=Object.keys($n);if(Object.getOwnPropertySymbols){var Pn=Object.getOwnPropertySymbols($n);Cn&&(Pn=Pn.filter(function(In){return Object.getOwnPropertyDescriptor($n,In).enumerable})),_n.push.apply(_n,Pn)}return _n}function _objectSpread2($n){for(var Cn=1;Cn=0&&_n.left>=0&&_n.bottom>_n.top&&_n.right>_n.left?_n:null}function adjustForViewport($n,Cn,_n,Pn){var In=utils.clone($n),Nn={width:Cn.width,height:Cn.height};return Pn.adjustX&&In.left<_n.left&&(In.left=_n.left),Pn.resizeWidth&&In.left>=_n.left&&In.left+Nn.width>_n.right&&(Nn.width-=In.left+Nn.width-_n.right),Pn.adjustX&&In.left+Nn.width>_n.right&&(In.left=Math.max(_n.right-Nn.width,_n.left)),Pn.adjustY&&In.top<_n.top&&(In.top=_n.top),Pn.resizeHeight&&In.top>=_n.top&&In.top+Nn.height>_n.bottom&&(Nn.height-=In.top+Nn.height-_n.bottom),Pn.adjustY&&In.top+Nn.height>_n.bottom&&(In.top=Math.max(_n.bottom-Nn.height,_n.top)),utils.mix(In,Nn)}function getRegion($n){var Cn,_n,Pn;if(!utils.isWindow($n)&&$n.nodeType!==9)Cn=utils.offset($n),_n=utils.outerWidth($n),Pn=utils.outerHeight($n);else{var In=utils.getWindow($n);Cn={left:utils.getWindowScrollLeft(In),top:utils.getWindowScrollTop(In)},_n=utils.viewportWidth(In),Pn=utils.viewportHeight(In)}return Cn.width=_n,Cn.height=Pn,Cn}function getAlignOffset($n,Cn){var _n=Cn.charAt(0),Pn=Cn.charAt(1),In=$n.width,Nn=$n.height,Rn=$n.left,Dn=$n.top;return _n==="c"?Dn+=Nn/2:_n==="b"&&(Dn+=Nn),Pn==="c"?Rn+=In/2:Pn==="r"&&(Rn+=In),{left:Rn,top:Dn}}function getElFuturePos($n,Cn,_n,Pn,In){var Nn=getAlignOffset(Cn,_n[1]),Rn=getAlignOffset($n,_n[0]),Dn=[Rn.left-Nn.left,Rn.top-Nn.top];return{left:Math.round($n.left-Dn[0]+Pn[0]-In[0]),top:Math.round($n.top-Dn[1]+Pn[1]-In[1])}}function isFailX($n,Cn,_n){return $n.left<_n.left||$n.left+Cn.width>_n.right}function isFailY($n,Cn,_n){return $n.top<_n.top||$n.top+Cn.height>_n.bottom}function isCompleteFailX($n,Cn,_n){return $n.left>_n.right||$n.left+Cn.width<_n.left}function isCompleteFailY($n,Cn,_n){return $n.top>_n.bottom||$n.top+Cn.height<_n.top}function flip$3($n,Cn,_n){var Pn=[];return utils.each($n,function(In){Pn.push(In.replace(Cn,function(Nn){return _n[Nn]}))}),Pn}function flipOffset($n,Cn){return $n[Cn]=-$n[Cn],$n}function convertOffset($n,Cn){var _n;return/%$/.test($n)?_n=parseInt($n.substring(0,$n.length-1),10)/100*Cn:_n=parseInt($n,10),_n||0}function normalizeOffset($n,Cn){$n[0]=convertOffset($n[0],Cn.width),$n[1]=convertOffset($n[1],Cn.height)}function doAlign($n,Cn,_n,Pn){var In=_n.points,Nn=_n.offset||[0,0],Rn=_n.targetOffset||[0,0],Dn=_n.overflow,Ln=_n.source||$n;Nn=[].concat(Nn),Rn=[].concat(Rn),Dn=Dn||{};var Fn={},Bn=0,Hn=!!(Dn&&Dn.alwaysByViewport),zn=getVisibleRectForElement(Ln,Hn),Wn=getRegion(Ln);normalizeOffset(Nn,Wn),normalizeOffset(Rn,Cn);var Yn=getElFuturePos(Wn,Cn,In,Nn,Rn),Gn=utils.merge(Wn,Yn);if(zn&&(Dn.adjustX||Dn.adjustY)&&Pn){if(Dn.adjustX&&isFailX(Yn,Wn,zn)){var Go=flip$3(In,/[lr]/gi,{l:"r",r:"l"}),Xn=flipOffset(Nn,0),Yo=flipOffset(Rn,0),qo=getElFuturePos(Wn,Cn,Go,Xn,Yo);isCompleteFailX(qo,Wn,zn)||(Bn=1,In=Go,Nn=Xn,Rn=Yo)}if(Dn.adjustY&&isFailY(Yn,Wn,zn)){var Jo=flip$3(In,/[tb]/gi,{t:"b",b:"t"}),Zo=flipOffset(Nn,1),rr=flipOffset(Rn,1),nr=getElFuturePos(Wn,Cn,Jo,Zo,rr);isCompleteFailY(nr,Wn,zn)||(Bn=1,In=Jo,Nn=Zo,Rn=rr)}Bn&&(Yn=getElFuturePos(Wn,Cn,In,Nn,Rn),utils.mix(Gn,Yn));var ta=isFailX(Yn,Wn,zn),oa=isFailY(Yn,Wn,zn);if(ta||oa){var ra=In;ta&&(ra=flip$3(In,/[lr]/gi,{l:"r",r:"l"})),oa&&(ra=flip$3(In,/[tb]/gi,{t:"b",b:"t"})),In=ra,Nn=_n.offset||[0,0],Rn=_n.targetOffset||[0,0]}Fn.adjustX=Dn.adjustX&&ta,Fn.adjustY=Dn.adjustY&&oa,(Fn.adjustX||Fn.adjustY)&&(Gn=adjustForViewport(Yn,Wn,zn,Fn))}return Gn.width!==Wn.width&&utils.css(Ln,"width",utils.width(Ln)+Gn.width-Wn.width),Gn.height!==Wn.height&&utils.css(Ln,"height",utils.height(Ln)+Gn.height-Wn.height),utils.offset(Ln,{left:Gn.left,top:Gn.top},{useCssRight:_n.useCssRight,useCssBottom:_n.useCssBottom,useCssTransform:_n.useCssTransform,ignoreShake:_n.ignoreShake}),{points:In,offset:Nn,targetOffset:Rn,overflow:Fn}}function isOutOfVisibleRect($n,Cn){var _n=getVisibleRectForElement($n,Cn),Pn=getRegion($n);return!_n||Pn.left+Pn.width<=_n.left||Pn.top+Pn.height<=_n.top||Pn.left>=_n.right||Pn.top>=_n.bottom}function alignElement($n,Cn,_n){var Pn=_n.target||Cn,In=getRegion(Pn),Nn=!isOutOfVisibleRect(Pn,_n.overflow&&_n.overflow.alwaysByViewport);return doAlign($n,In,_n,Nn)}alignElement.__getOffsetParent=getOffsetParent$1;alignElement.__getVisibleRectForElement=getVisibleRectForElement;function alignPoint($n,Cn,_n){var Pn,In,Nn=utils.getDocument($n),Rn=Nn.defaultView||Nn.parentWindow,Dn=utils.getWindowScrollLeft(Rn),Ln=utils.getWindowScrollTop(Rn),Fn=utils.viewportWidth(Rn),Bn=utils.viewportHeight(Rn);"pageX"in Cn?Pn=Cn.pageX:Pn=Dn+Cn.clientX,"pageY"in Cn?In=Cn.pageY:In=Ln+Cn.clientY;var Hn={left:Pn,top:In,width:0,height:0},zn=Pn>=0&&Pn<=Dn+Fn&&In>=0&&In<=Ln+Bn,Wn=[_n.points[0],"cc"];return doAlign($n,Hn,_objectSpread2(_objectSpread2({},_n),{},{points:Wn}),zn)}function cloneElement($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,In=$n;if(Array.isArray($n)&&(In=filterEmpty($n)[0]),!In)return null;const Nn=cloneVNode(In,Cn,Pn);return Nn.props=_n?_extends$1(_extends$1({},Nn.props),Cn):Nn.props,warning$3(typeof Nn.props.class!="object"),Nn}function cloneVNodes($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return $n.map(Pn=>cloneElement(Pn,Cn,_n))}function deepCloneElement($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(Array.isArray($n))return $n.map(In=>deepCloneElement(In,Cn,_n,Pn));{if(!isVNode$1($n))return $n;const In=cloneElement($n,Cn,_n,Pn);return Array.isArray(In.children)&&(In.children=deepCloneElement(In.children)),In}}function triggerVNodeUpdate($n,Cn,_n){render$1(cloneVNode($n,_extends$1({},Cn)),_n)}const ensureValidVNode=$n=>($n||[]).some(Cn=>isVNode$1(Cn)?!(Cn.type===Comment$1||Cn.type===Fragment&&!ensureValidVNode(Cn.children)):!0)?$n:null;function customRenderSlot($n,Cn,_n,Pn){var In;const Nn=(In=$n[Cn])===null||In===void 0?void 0:In.call($n,_n);return ensureValidVNode(Nn)?Nn:Pn==null?void 0:Pn()}const isVisible=$n=>{if(!$n)return!1;if($n.offsetParent)return!0;if($n.getBBox){const Cn=$n.getBBox();if(Cn.width||Cn.height)return!0}if($n.getBoundingClientRect){const Cn=$n.getBoundingClientRect();if(Cn.width||Cn.height)return!0}return!1};function isSamePoint($n,Cn){return $n===Cn?!0:!$n||!Cn?!1:"pageX"in Cn&&"pageY"in Cn?$n.pageX===Cn.pageX&&$n.pageY===Cn.pageY:"clientX"in Cn&&"clientY"in Cn?$n.clientX===Cn.clientX&&$n.clientY===Cn.clientY:!1}function restoreFocus($n,Cn){$n!==document.activeElement&&contains$2(Cn,$n)&&typeof $n.focus=="function"&&$n.focus()}function monitorResize($n,Cn){let _n=null,Pn=null;function In(Rn){let[{target:Dn}]=Rn;if(!document.documentElement.contains(Dn))return;const{width:Ln,height:Fn}=Dn.getBoundingClientRect(),Bn=Math.floor(Ln),Hn=Math.floor(Fn);(_n!==Bn||Pn!==Hn)&&Promise.resolve().then(()=>{Cn({width:Bn,height:Hn})}),_n=Bn,Pn=Hn}const Nn=new ResizeObserver$3(In);return $n&&Nn.observe($n),()=>{Nn.disconnect()}}const useBuffer=($n,Cn)=>{let _n=!1,Pn=null;function In(){clearTimeout(Pn)}function Nn(Rn){if(!_n||Rn===!0){if($n()===!1)return;_n=!0,In(),Pn=setTimeout(()=>{_n=!1},Cn.value)}else In(),Pn=setTimeout(()=>{_n=!1,Nn()},Cn.value)}return[Nn,()=>{_n=!1,In()}]};function listCacheClear(){this.__data__=[],this.size=0}function eq($n,Cn){return $n===Cn||$n!==$n&&Cn!==Cn}function assocIndexOf($n,Cn){for(var _n=$n.length;_n--;)if(eq($n[_n][0],Cn))return _n;return-1}var arrayProto=Array.prototype,splice=arrayProto.splice;function listCacheDelete($n){var Cn=this.__data__,_n=assocIndexOf(Cn,$n);if(_n<0)return!1;var Pn=Cn.length-1;return _n==Pn?Cn.pop():splice.call(Cn,_n,1),--this.size,!0}function listCacheGet($n){var Cn=this.__data__,_n=assocIndexOf(Cn,$n);return _n<0?void 0:Cn[_n][1]}function listCacheHas($n){return assocIndexOf(this.__data__,$n)>-1}function listCacheSet($n,Cn){var _n=this.__data__,Pn=assocIndexOf(_n,$n);return Pn<0?(++this.size,_n.push([$n,Cn])):_n[Pn][1]=Cn,this}function ListCache($n){var Cn=-1,_n=$n==null?0:$n.length;for(this.clear();++Cn<_n;){var Pn=$n[Cn];this.set(Pn[0],Pn[1])}}ListCache.prototype.clear=listCacheClear;ListCache.prototype.delete=listCacheDelete;ListCache.prototype.get=listCacheGet;ListCache.prototype.has=listCacheHas;ListCache.prototype.set=listCacheSet;function stackClear(){this.__data__=new ListCache,this.size=0}function stackDelete($n){var Cn=this.__data__,_n=Cn.delete($n);return this.size=Cn.size,_n}function stackGet($n){return this.__data__.get($n)}function stackHas($n){return this.__data__.has($n)}var freeGlobal=typeof global=="object"&&global&&global.Object===Object&&global,freeSelf=typeof self=="object"&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol$1=root.Symbol,objectProto$g=Object.prototype,hasOwnProperty$e=objectProto$g.hasOwnProperty,nativeObjectToString$1=objectProto$g.toString,symToStringTag$1=Symbol$1?Symbol$1.toStringTag:void 0;function getRawTag($n){var Cn=hasOwnProperty$e.call($n,symToStringTag$1),_n=$n[symToStringTag$1];try{$n[symToStringTag$1]=void 0;var Pn=!0}catch{}var In=nativeObjectToString$1.call($n);return Pn&&(Cn?$n[symToStringTag$1]=_n:delete $n[symToStringTag$1]),In}var objectProto$f=Object.prototype,nativeObjectToString=objectProto$f.toString;function objectToString$1($n){return nativeObjectToString.call($n)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag=Symbol$1?Symbol$1.toStringTag:void 0;function baseGetTag($n){return $n==null?$n===void 0?undefinedTag:nullTag:symToStringTag&&symToStringTag in Object($n)?getRawTag($n):objectToString$1($n)}function isObject$5($n){var Cn=typeof $n;return $n!=null&&(Cn=="object"||Cn=="function")}var asyncTag="[object AsyncFunction]",funcTag$2="[object Function]",genTag$1="[object GeneratorFunction]",proxyTag="[object Proxy]";function isFunction$1($n){if(!isObject$5($n))return!1;var Cn=baseGetTag($n);return Cn==funcTag$2||Cn==genTag$1||Cn==asyncTag||Cn==proxyTag}var coreJsData=root["__core-js_shared__"],maskSrcKey=function(){var $n=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||"");return $n?"Symbol(src)_1."+$n:""}();function isMasked($n){return!!maskSrcKey&&maskSrcKey in $n}var funcProto$2=Function.prototype,funcToString$2=funcProto$2.toString;function toSource($n){if($n!=null){try{return funcToString$2.call($n)}catch{}try{return $n+""}catch{}}return""}var reRegExpChar=/[\\^$.*+?()[\]{}|]/g,reIsHostCtor=/^\[object .+?Constructor\]$/,funcProto$1=Function.prototype,objectProto$e=Object.prototype,funcToString$1=funcProto$1.toString,hasOwnProperty$d=objectProto$e.hasOwnProperty,reIsNative=RegExp("^"+funcToString$1.call(hasOwnProperty$d).replace(reRegExpChar,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function baseIsNative($n){if(!isObject$5($n)||isMasked($n))return!1;var Cn=isFunction$1($n)?reIsNative:reIsHostCtor;return Cn.test(toSource($n))}function getValue$3($n,Cn){return $n==null?void 0:$n[Cn]}function getNative($n,Cn){var _n=getValue$3($n,Cn);return baseIsNative(_n)?_n:void 0}var Map$1=getNative(root,"Map"),nativeCreate=getNative(Object,"create");function hashClear(){this.__data__=nativeCreate?nativeCreate(null):{},this.size=0}function hashDelete($n){var Cn=this.has($n)&&delete this.__data__[$n];return this.size-=Cn?1:0,Cn}var HASH_UNDEFINED$2="__lodash_hash_undefined__",objectProto$d=Object.prototype,hasOwnProperty$c=objectProto$d.hasOwnProperty;function hashGet($n){var Cn=this.__data__;if(nativeCreate){var _n=Cn[$n];return _n===HASH_UNDEFINED$2?void 0:_n}return hasOwnProperty$c.call(Cn,$n)?Cn[$n]:void 0}var objectProto$c=Object.prototype,hasOwnProperty$b=objectProto$c.hasOwnProperty;function hashHas($n){var Cn=this.__data__;return nativeCreate?Cn[$n]!==void 0:hasOwnProperty$b.call(Cn,$n)}var HASH_UNDEFINED$1="__lodash_hash_undefined__";function hashSet($n,Cn){var _n=this.__data__;return this.size+=this.has($n)?0:1,_n[$n]=nativeCreate&&Cn===void 0?HASH_UNDEFINED$1:Cn,this}function Hash($n){var Cn=-1,_n=$n==null?0:$n.length;for(this.clear();++Cn<_n;){var Pn=$n[Cn];this.set(Pn[0],Pn[1])}}Hash.prototype.clear=hashClear;Hash.prototype.delete=hashDelete;Hash.prototype.get=hashGet;Hash.prototype.has=hashHas;Hash.prototype.set=hashSet;function mapCacheClear(){this.size=0,this.__data__={hash:new Hash,map:new(Map$1||ListCache),string:new Hash}}function isKeyable($n){var Cn=typeof $n;return Cn=="string"||Cn=="number"||Cn=="symbol"||Cn=="boolean"?$n!=="__proto__":$n===null}function getMapData($n,Cn){var _n=$n.__data__;return isKeyable(Cn)?_n[typeof Cn=="string"?"string":"hash"]:_n.map}function mapCacheDelete($n){var Cn=getMapData(this,$n).delete($n);return this.size-=Cn?1:0,Cn}function mapCacheGet($n){return getMapData(this,$n).get($n)}function mapCacheHas($n){return getMapData(this,$n).has($n)}function mapCacheSet($n,Cn){var _n=getMapData(this,$n),Pn=_n.size;return _n.set($n,Cn),this.size+=_n.size==Pn?0:1,this}function MapCache($n){var Cn=-1,_n=$n==null?0:$n.length;for(this.clear();++Cn<_n;){var Pn=$n[Cn];this.set(Pn[0],Pn[1])}}MapCache.prototype.clear=mapCacheClear;MapCache.prototype.delete=mapCacheDelete;MapCache.prototype.get=mapCacheGet;MapCache.prototype.has=mapCacheHas;MapCache.prototype.set=mapCacheSet;var LARGE_ARRAY_SIZE$1=200;function stackSet($n,Cn){var _n=this.__data__;if(_n instanceof ListCache){var Pn=_n.__data__;if(!Map$1||Pn.lengthDn))return!1;var Fn=Nn.get($n),Bn=Nn.get(Cn);if(Fn&&Bn)return Fn==Cn&&Bn==$n;var Hn=-1,zn=!0,Wn=_n&COMPARE_UNORDERED_FLAG$3?new SetCache:void 0;for(Nn.set($n,Cn),Nn.set(Cn,$n);++Hn-1&&$n%1==0&&$n-1&&$n%1==0&&$n<=MAX_SAFE_INTEGER}var argsTag$2="[object Arguments]",arrayTag$2="[object Array]",boolTag$2="[object Boolean]",dateTag$2="[object Date]",errorTag$1="[object Error]",funcTag$1="[object Function]",mapTag$5="[object Map]",numberTag$3="[object Number]",objectTag$4="[object Object]",regexpTag$2="[object RegExp]",setTag$5="[object Set]",stringTag$2="[object String]",weakMapTag$2="[object WeakMap]",arrayBufferTag$2="[object ArrayBuffer]",dataViewTag$3="[object DataView]",float32Tag$2="[object Float32Array]",float64Tag$2="[object Float64Array]",int8Tag$2="[object Int8Array]",int16Tag$2="[object Int16Array]",int32Tag$2="[object Int32Array]",uint8Tag$2="[object Uint8Array]",uint8ClampedTag$2="[object Uint8ClampedArray]",uint16Tag$2="[object Uint16Array]",uint32Tag$2="[object Uint32Array]",typedArrayTags={};typedArrayTags[float32Tag$2]=typedArrayTags[float64Tag$2]=typedArrayTags[int8Tag$2]=typedArrayTags[int16Tag$2]=typedArrayTags[int32Tag$2]=typedArrayTags[uint8Tag$2]=typedArrayTags[uint8ClampedTag$2]=typedArrayTags[uint16Tag$2]=typedArrayTags[uint32Tag$2]=!0;typedArrayTags[argsTag$2]=typedArrayTags[arrayTag$2]=typedArrayTags[arrayBufferTag$2]=typedArrayTags[boolTag$2]=typedArrayTags[dataViewTag$3]=typedArrayTags[dateTag$2]=typedArrayTags[errorTag$1]=typedArrayTags[funcTag$1]=typedArrayTags[mapTag$5]=typedArrayTags[numberTag$3]=typedArrayTags[objectTag$4]=typedArrayTags[regexpTag$2]=typedArrayTags[setTag$5]=typedArrayTags[stringTag$2]=typedArrayTags[weakMapTag$2]=!1;function baseIsTypedArray($n){return isObjectLike($n)&&isLength($n.length)&&!!typedArrayTags[baseGetTag($n)]}function baseUnary($n){return function(Cn){return $n(Cn)}}var freeExports$1=typeof exports=="object"&&exports&&!exports.nodeType&&exports,freeModule$1=freeExports$1&&typeof module=="object"&&module&&!module.nodeType&&module,moduleExports$1=freeModule$1&&freeModule$1.exports===freeExports$1,freeProcess=moduleExports$1&&freeGlobal.process,nodeUtil=function(){try{var $n=freeModule$1&&freeModule$1.require&&freeModule$1.require("util").types;return $n||freeProcess&&freeProcess.binding&&freeProcess.binding("util")}catch{}}(),nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray,isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;const isTypedArray$1=isTypedArray;var objectProto$9=Object.prototype,hasOwnProperty$9=objectProto$9.hasOwnProperty;function arrayLikeKeys($n,Cn){var _n=isArray$2($n),Pn=!_n&&isArguments($n),In=!_n&&!Pn&&isBuffer($n),Nn=!_n&&!Pn&&!In&&isTypedArray$1($n),Rn=_n||Pn||In||Nn,Dn=Rn?baseTimes($n.length,String):[],Ln=Dn.length;for(var Fn in $n)(Cn||hasOwnProperty$9.call($n,Fn))&&!(Rn&&(Fn=="length"||In&&(Fn=="offset"||Fn=="parent")||Nn&&(Fn=="buffer"||Fn=="byteLength"||Fn=="byteOffset")||isIndex(Fn,Ln)))&&Dn.push(Fn);return Dn}var objectProto$8=Object.prototype;function isPrototype($n){var Cn=$n&&$n.constructor,_n=typeof Cn=="function"&&Cn.prototype||objectProto$8;return $n===_n}function overArg($n,Cn){return function(_n){return $n(Cn(_n))}}var nativeKeys=overArg(Object.keys,Object),objectProto$7=Object.prototype,hasOwnProperty$8=objectProto$7.hasOwnProperty;function baseKeys($n){if(!isPrototype($n))return nativeKeys($n);var Cn=[];for(var _n in Object($n))hasOwnProperty$8.call($n,_n)&&_n!="constructor"&&Cn.push(_n);return Cn}function isArrayLike($n){return $n!=null&&isLength($n.length)&&!isFunction$1($n)}function keys($n){return isArrayLike($n)?arrayLikeKeys($n):baseKeys($n)}function getAllKeys$1($n){return baseGetAllKeys($n,keys,getSymbols)}var COMPARE_PARTIAL_FLAG$3=1,objectProto$6=Object.prototype,hasOwnProperty$7=objectProto$6.hasOwnProperty;function equalObjects($n,Cn,_n,Pn,In,Nn){var Rn=_n&COMPARE_PARTIAL_FLAG$3,Dn=getAllKeys$1($n),Ln=Dn.length,Fn=getAllKeys$1(Cn),Bn=Fn.length;if(Ln!=Bn&&!Rn)return!1;for(var Hn=Ln;Hn--;){var zn=Dn[Hn];if(!(Rn?zn in Cn:hasOwnProperty$7.call(Cn,zn)))return!1}var Wn=Nn.get($n),Yn=Nn.get(Cn);if(Wn&&Yn)return Wn==Cn&&Yn==$n;var Gn=!0;Nn.set($n,Cn),Nn.set(Cn,$n);for(var Go=Rn;++Hn{const{disabled:zn,target:Wn,align:Yn,onAlign:Gn}=$n;if(!zn&&Wn&&Nn.value){const Go=Nn.value;let Xn;const Yo=getElement(Wn),qo=getPoint(Wn);In.value.element=Yo,In.value.point=qo,In.value.align=Yn;const{activeElement:Jo}=document;return Yo&&isVisible(Yo)?Xn=alignElement(Go,Yo,Yn):qo&&(Xn=alignPoint(Go,qo,Yn)),restoreFocus(Jo,Go),Gn&&Xn&&Gn(Go,Xn),!0}return!1},computed(()=>$n.monitorBufferTime)),Ln=ref({cancel:()=>{}}),Fn=ref({cancel:()=>{}}),Bn=()=>{const zn=$n.target,Wn=getElement(zn),Yn=getPoint(zn);Nn.value!==Fn.value.element&&(Fn.value.cancel(),Fn.value.element=Nn.value,Fn.value.cancel=monitorResize(Nn.value,Rn)),(In.value.element!==Wn||!isSamePoint(In.value.point,Yn)||!isEqual$2(In.value.align,$n.align))&&(Rn(),Ln.value.element!==Wn&&(Ln.value.cancel(),Ln.value.element=Wn,Ln.value.cancel=monitorResize(Wn,Rn)))};onMounted(()=>{nextTick(()=>{Bn()})}),onUpdated(()=>{nextTick(()=>{Bn()})}),watch(()=>$n.disabled,zn=>{zn?Dn():Rn()},{immediate:!0,flush:"post"});const Hn=ref(null);return watch(()=>$n.monitorWindowResize,zn=>{zn?Hn.value||(Hn.value=addEventListenerWrap(window,"resize",Rn)):Hn.value&&(Hn.value.remove(),Hn.value=null)},{flush:"post"}),onUnmounted(()=>{Ln.value.cancel(),Fn.value.cancel(),Hn.value&&Hn.value.remove(),Dn()}),_n({forceAlign:()=>Rn(!0)}),()=>{const zn=Pn==null?void 0:Pn.default();return zn?cloneElement(zn[0],{ref:Nn},!0,!0):null}}});tuple$1("bottomLeft","bottomRight","topLeft","topRight");const getTransitionDirection=$n=>$n!==void 0&&($n==="topLeft"||$n==="topRight")?"slide-down":"slide-up",getTransitionProps=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return _extends$1($n?{name:$n,appear:!0,enterFromClass:`${$n}-enter ${$n}-enter-prepare ${$n}-enter-start`,enterActiveClass:`${$n}-enter ${$n}-enter-prepare`,enterToClass:`${$n}-enter ${$n}-enter-active`,leaveFromClass:` ${$n}-leave`,leaveActiveClass:`${$n}-leave ${$n}-leave-active`,leaveToClass:`${$n}-leave ${$n}-leave-active`}:{css:!1},Cn)},getTransitionGroupProps=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return _extends$1($n?{name:$n,appear:!0,appearActiveClass:`${$n}`,appearToClass:`${$n}-appear ${$n}-appear-active`,enterFromClass:`${$n}-appear ${$n}-enter ${$n}-appear-prepare ${$n}-enter-prepare`,enterActiveClass:`${$n}`,enterToClass:`${$n}-enter ${$n}-appear ${$n}-appear-active ${$n}-enter-active`,leaveActiveClass:`${$n} ${$n}-leave`,leaveToClass:`${$n}-leave-active`}:{css:!1},Cn)},getTransitionName$1=($n,Cn,_n)=>_n!==void 0?_n:`${$n}-${Cn}`,PopupInner=defineComponent({compatConfig:{MODE:3},name:"PopupInner",inheritAttrs:!1,props:innerProps,emits:["mouseenter","mouseleave","mousedown","touchstart","align"],setup($n,Cn){let{expose:_n,attrs:Pn,slots:In}=Cn;const Nn=shallowRef(),Rn=shallowRef(),Dn=shallowRef(),[Ln,Fn]=useStretchStyle(toRef($n,"stretch")),Bn=()=>{$n.stretch&&Fn($n.getRootDomNode())},Hn=shallowRef(!1);let zn;watch(()=>$n.visible,rr=>{clearTimeout(zn),rr?zn=setTimeout(()=>{Hn.value=$n.visible}):Hn.value=!1},{immediate:!0});const[Wn,Yn]=useVisibleStatus(Hn,Bn),Gn=shallowRef(),Go=()=>$n.point?$n.point:$n.getRootDomNode,Xn=()=>{var rr;(rr=Nn.value)===null||rr===void 0||rr.forceAlign()},Yo=(rr,nr)=>{var ta;const oa=$n.getClassNameFromAlign(nr),ra=Dn.value;Dn.value!==oa&&(Dn.value=oa),Wn.value==="align"&&(ra!==oa?Promise.resolve().then(()=>{Xn()}):Yn(()=>{var ea;(ea=Gn.value)===null||ea===void 0||ea.call(Gn)}),(ta=$n.onAlign)===null||ta===void 0||ta.call($n,rr,nr))},qo=computed(()=>{const rr=typeof $n.animation=="object"?$n.animation:getMotion$1($n);return["onAfterEnter","onAfterLeave"].forEach(nr=>{const ta=rr[nr];rr[nr]=oa=>{Yn(),Wn.value="stable",ta==null||ta(oa)}}),rr}),Jo=()=>new Promise(rr=>{Gn.value=rr});watch([qo,Wn],()=>{!qo.value&&Wn.value==="motion"&&Yn()},{immediate:!0}),_n({forceAlign:Xn,getElement:()=>Rn.value.$el||Rn.value});const Zo=computed(()=>{var rr;return!(!((rr=$n.align)===null||rr===void 0)&&rr.points&&(Wn.value==="align"||Wn.value==="stable"))});return()=>{var rr;const{zIndex:nr,align:ta,prefixCls:oa,destroyPopupOnHide:ra,onMouseenter:ea,onMouseleave:la,onTouchstart:ua=()=>{},onMousedown:ga}=$n,aa=Wn.value,ca=[_extends$1(_extends$1({},Ln.value),{zIndex:nr,opacity:aa==="motion"||aa==="stable"||!Hn.value?null:0,pointerEvents:!Hn.value&&aa!=="stable"?"none":null}),Pn.style];let sa=flattenChildren((rr=In.default)===null||rr===void 0?void 0:rr.call(In,{visible:$n.visible}));sa.length>1&&(sa=createVNode("div",{class:`${oa}-content`},[sa]));const ia=classNames(oa,Pn.class,Dn.value),ma=Hn.value||!$n.visible?getTransitionProps(qo.value.name,qo.value):{};return createVNode(Transition,_objectSpread2$1(_objectSpread2$1({ref:Rn},ma),{},{onBeforeEnter:Jo}),{default:()=>!ra||$n.visible?withDirectives(createVNode(Align,{target:Go(),key:"popup",ref:Nn,monitorWindowResize:!0,disabled:Zo.value,align:ta,onAlign:Yo},{default:()=>createVNode("div",{class:ia,onMouseenter:ea,onMouseleave:la,onMousedown:withModifiers(ga,["capture"]),[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]:withModifiers(ua,["capture"]),style:ca},[sa])}),[[vShow,Hn.value]]):null})}}}),Popup=defineComponent({compatConfig:{MODE:3},name:"Popup",inheritAttrs:!1,props:popupProps,setup($n,Cn){let{attrs:_n,slots:Pn,expose:In}=Cn;const Nn=shallowRef(!1),Rn=shallowRef(!1),Dn=shallowRef(),Ln=shallowRef();return watch([()=>$n.visible,()=>$n.mobile],()=>{Nn.value=$n.visible,$n.visible&&$n.mobile&&(Rn.value=!0)},{immediate:!0,flush:"post"}),In({forceAlign:()=>{var Fn;(Fn=Dn.value)===null||Fn===void 0||Fn.forceAlign()},getElement:()=>{var Fn;return(Fn=Dn.value)===null||Fn===void 0?void 0:Fn.getElement()}}),()=>{const Fn=_extends$1(_extends$1(_extends$1({},$n),_n),{visible:Nn.value}),Bn=Rn.value?createVNode(MobilePopupInner,_objectSpread2$1(_objectSpread2$1({},Fn),{},{mobile:$n.mobile,ref:Dn}),{default:Pn.default}):createVNode(PopupInner,_objectSpread2$1(_objectSpread2$1({},Fn),{},{ref:Dn}),{default:Pn.default});return createVNode("div",{ref:Ln},[createVNode(Mask$3,Fn,null),Bn])}}});function isPointsEq($n,Cn,_n){return _n?$n[0]===Cn[0]:$n[0]===Cn[0]&&$n[1]===Cn[1]}function getAlignFromPlacement($n,Cn,_n){const Pn=$n[Cn]||{};return _extends$1(_extends$1({},Pn),_n)}function getAlignPopupClassName($n,Cn,_n,Pn){const{points:In}=_n,Nn=Object.keys($n);for(let Rn=0;Rn0&&arguments[0]!==void 0?arguments[0]:{},Cn=arguments.length>1?arguments[1]:void 0,_n=typeof $n=="function"?$n(this.$data,this.$props):$n;if(this.getDerivedStateFromProps){const Pn=this.getDerivedStateFromProps(getOptionProps(this),_extends$1(_extends$1({},this.$data),_n));if(Pn===null)return;_n=_extends$1(_extends$1({},_n),Pn||{})}_extends$1(this.$data,_n),this._.isMounted&&this.$forceUpdate(),nextTick(()=>{Cn&&Cn()})},__emit(){const $n=[].slice.call(arguments,0);let Cn=$n[0];Cn=`on${Cn[0].toUpperCase()}${Cn.substring(1)}`;const _n=this.$props[Cn]||this.$attrs[Cn];if($n.length&&_n)if(Array.isArray(_n))for(let Pn=0,In=_n.length;Pn1&&arguments[1]!==void 0?arguments[1]:{inTriggerContext:!0};provide(PortalContextKey,{inTriggerContext:Cn.inTriggerContext,shouldRender:computed(()=>{const{sPopupVisible:_n,popupRef:Pn,forceRender:In,autoDestroy:Nn}=$n||{};let Rn=!1;return(_n||Pn||In)&&(Rn=!0),!_n&&Nn&&(Rn=!1),Rn})})},useInjectPortal=()=>{useProvidePortal({},{inTriggerContext:!1});const $n=inject(PortalContextKey,{shouldRender:computed(()=>!1),inTriggerContext:!1});return{shouldRender:computed(()=>$n.shouldRender.value||$n.inTriggerContext===!1)}},Portal$1=defineComponent({compatConfig:{MODE:3},name:"Portal",inheritAttrs:!1,props:{getContainer:PropTypes.func.isRequired,didUpdate:Function},setup($n,Cn){let{slots:_n}=Cn,Pn=!0,In;const{shouldRender:Nn}=useInjectPortal();function Rn(){Nn.value&&(In=$n.getContainer())}onBeforeMount(()=>{Pn=!1,Rn()}),onMounted(()=>{In||Rn()});const Dn=watch(Nn,()=>{Nn.value&&!In&&(In=$n.getContainer()),In&&Dn()});return onUpdated(()=>{nextTick(()=>{var Ln;Nn.value&&((Ln=$n.didUpdate)===null||Ln===void 0||Ln.call($n,$n))})}),()=>{var Ln;return Nn.value?Pn?(Ln=_n.default)===null||Ln===void 0?void 0:Ln.call(_n):In?createVNode(Teleport,{to:In},_n):null:null}}});let cached;function getScrollBarSize($n){if(typeof document>"u")return 0;if($n||cached===void 0){const Cn=document.createElement("div");Cn.style.width="100%",Cn.style.height="200px";const _n=document.createElement("div"),Pn=_n.style;Pn.position="absolute",Pn.top="0",Pn.left="0",Pn.pointerEvents="none",Pn.visibility="hidden",Pn.width="200px",Pn.height="150px",Pn.overflow="hidden",_n.appendChild(Cn),document.body.appendChild(_n);const In=Cn.offsetWidth;_n.style.overflow="scroll";let Nn=Cn.offsetWidth;In===Nn&&(Nn=_n.clientWidth),document.body.removeChild(_n),cached=In-Nn}return cached}function ensureSize($n){const Cn=$n.match(/^(.*)px$/),_n=Number(Cn==null?void 0:Cn[1]);return Number.isNaN(_n)?getScrollBarSize():_n}function getTargetScrollBarSize($n){if(typeof document>"u"||!$n||!($n instanceof Element))return{width:0,height:0};const{width:Cn,height:_n}=getComputedStyle($n,"::-webkit-scrollbar");return{width:ensureSize(Cn),height:ensureSize(_n)}}const UNIQUE_ID=`vc-util-locker-${Date.now()}`;let uuid$6=0;function isBodyOverflowing(){return document.body.scrollHeight>(window.innerHeight||document.documentElement.clientHeight)&&window.innerWidth>document.body.offsetWidth}function useScrollLocker($n){const Cn=computed(()=>!!$n&&!!$n.value);uuid$6+=1;const _n=`${UNIQUE_ID}_${uuid$6}`;watchEffect(Pn=>{if(canUseDom$1()){if(Cn.value){const In=getScrollBarSize(),Nn=isBodyOverflowing();updateCSS$1(` -html body { - overflow-y: hidden; - ${Nn?`width: calc(100% - ${In}px);`:""} -}`,_n)}else removeCSS(_n);Pn(()=>{removeCSS(_n)})}},{flush:"post"})}let openCount=0;const supportDom=canUseDom$1(),getParent=$n=>{if(!supportDom)return null;if($n){if(typeof $n=="string")return document.querySelectorAll($n)[0];if(typeof $n=="function")return $n();if(typeof $n=="object"&&$n instanceof window.HTMLElement)return $n}return document.body},Portal=defineComponent({compatConfig:{MODE:3},name:"PortalWrapper",inheritAttrs:!1,props:{wrapperClassName:String,forceRender:{type:Boolean,default:void 0},getContainer:PropTypes.any,visible:{type:Boolean,default:void 0},autoLock:booleanType(),didUpdate:Function},setup($n,Cn){let{slots:_n}=Cn;const Pn=shallowRef(),In=shallowRef(),Nn=shallowRef(),Rn=shallowRef(1),Dn=canUseDom$1()&&document.createElement("div"),Ln=()=>{var Wn,Yn;Pn.value===Dn&&((Yn=(Wn=Pn.value)===null||Wn===void 0?void 0:Wn.parentNode)===null||Yn===void 0||Yn.removeChild(Pn.value)),Pn.value=null};let Fn=null;const Bn=function(){return(arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1)||Pn.value&&!Pn.value.parentNode?(Fn=getParent($n.getContainer),Fn?(Fn.appendChild(Pn.value),!0):!1):!0},Hn=()=>supportDom?(Pn.value||(Pn.value=Dn,Bn(!0)),zn(),Pn.value):null,zn=()=>{const{wrapperClassName:Wn}=$n;Pn.value&&Wn&&Wn!==Pn.value.className&&(Pn.value.className=Wn)};return onUpdated(()=>{zn(),Bn()}),useScrollLocker(computed(()=>$n.autoLock&&$n.visible&&canUseDom$1()&&(Pn.value===document.body||Pn.value===Dn))),onMounted(()=>{let Wn=!1;watch([()=>$n.visible,()=>$n.getContainer],(Yn,Gn)=>{let[Go,Xn]=Yn,[Yo,qo]=Gn;supportDom&&(Fn=getParent($n.getContainer),Fn===document.body&&(Go&&!Yo?openCount+=1:Wn&&(openCount-=1))),Wn&&(typeof Xn=="function"&&typeof qo=="function"?Xn.toString()!==qo.toString():Xn!==qo)&&Ln(),Wn=!0},{immediate:!0,flush:"post"}),nextTick(()=>{Bn()||(Nn.value=wrapperRaf(()=>{Rn.value+=1}))})}),onBeforeUnmount(()=>{const{visible:Wn}=$n;supportDom&&Fn===document.body&&(openCount=Wn&&openCount?openCount-1:openCount),Ln(),wrapperRaf.cancel(Nn.value)}),()=>{const{forceRender:Wn,visible:Yn}=$n;let Gn=null;const Go={getOpenCount:()=>openCount,getContainer:Hn};return Rn.value&&(Wn||Yn||In.value)&&(Gn=createVNode(Portal$1,{getContainer:Hn,ref:In,didUpdate:$n.didUpdate},{default:()=>{var Xn;return(Xn=_n.default)===null||Xn===void 0?void 0:Xn.call(_n,Go)}})),Gn}}}),ALL_HANDLERS=["onClick","onMousedown","onTouchstart","onMouseenter","onMouseleave","onFocus","onBlur","onContextmenu"],Trigger=defineComponent({compatConfig:{MODE:3},name:"Trigger",mixins:[BaseMixin],inheritAttrs:!1,props:triggerProps(),setup($n){const Cn=computed(()=>{const{popupPlacement:In,popupAlign:Nn,builtinPlacements:Rn}=$n;return In&&Rn?getAlignFromPlacement(Rn,In,Nn):Nn}),_n=shallowRef(null),Pn=In=>{_n.value=In};return{vcTriggerContext:inject("vcTriggerContext",{}),popupRef:_n,setPopupRef:Pn,triggerRef:shallowRef(null),align:Cn,focusTime:null,clickOutsideHandler:null,contextmenuOutsideHandler1:null,contextmenuOutsideHandler2:null,touchOutsideHandler:null,attachId:null,delayTimer:null,hasPopupMouseDown:!1,preClickTime:null,preTouchTime:null,mouseDownTimeout:null,childOriginEvents:{}}},data(){const $n=this.$props;let Cn;return this.popupVisible!==void 0?Cn=!!$n.popupVisible:Cn=!!$n.defaultPopupVisible,ALL_HANDLERS.forEach(_n=>{this[`fire${_n}`]=Pn=>{this.fireEvents(_n,Pn)}}),{prevPopupVisible:Cn,sPopupVisible:Cn,point:null}},watch:{popupVisible($n){$n!==void 0&&(this.prevPopupVisible=this.sPopupVisible,this.sPopupVisible=$n)}},created(){provide("vcTriggerContext",{onPopupMouseDown:this.onPopupMouseDown,onPopupMouseenter:this.onPopupMouseenter,onPopupMouseleave:this.onPopupMouseleave}),useProvidePortal(this)},deactivated(){this.setPopupVisible(!1)},mounted(){this.$nextTick(()=>{this.updatedCal()})},updated(){this.$nextTick(()=>{this.updatedCal()})},beforeUnmount(){this.clearDelayTimer(),this.clearOutsideHandler(),clearTimeout(this.mouseDownTimeout),wrapperRaf.cancel(this.attachId)},methods:{updatedCal(){const $n=this.$props;if(this.$data.sPopupVisible){let _n;!this.clickOutsideHandler&&(this.isClickToHide()||this.isContextmenuToShow())&&(_n=$n.getDocument(this.getRootDomNode()),this.clickOutsideHandler=addEventListenerWrap(_n,"mousedown",this.onDocumentClick)),this.touchOutsideHandler||(_n=_n||$n.getDocument(this.getRootDomNode()),this.touchOutsideHandler=addEventListenerWrap(_n,"touchstart",this.onDocumentClick,supportsPassive$1?{passive:!1}:!1)),!this.contextmenuOutsideHandler1&&this.isContextmenuToShow()&&(_n=_n||$n.getDocument(this.getRootDomNode()),this.contextmenuOutsideHandler1=addEventListenerWrap(_n,"scroll",this.onContextmenuClose)),!this.contextmenuOutsideHandler2&&this.isContextmenuToShow()&&(this.contextmenuOutsideHandler2=addEventListenerWrap(window,"blur",this.onContextmenuClose))}else this.clearOutsideHandler()},onMouseenter($n){const{mouseEnterDelay:Cn}=this.$props;this.fireEvents("onMouseenter",$n),this.delaySetPopupVisible(!0,Cn,Cn?null:$n)},onMouseMove($n){this.fireEvents("onMousemove",$n),this.setPoint($n)},onMouseleave($n){this.fireEvents("onMouseleave",$n),this.delaySetPopupVisible(!1,this.$props.mouseLeaveDelay)},onPopupMouseenter(){const{vcTriggerContext:$n={}}=this;$n.onPopupMouseenter&&$n.onPopupMouseenter(),this.clearDelayTimer()},onPopupMouseleave($n){var Cn;if($n&&$n.relatedTarget&&!$n.relatedTarget.setTimeout&&contains$2((Cn=this.popupRef)===null||Cn===void 0?void 0:Cn.getElement(),$n.relatedTarget))return;this.isMouseLeaveToHide()&&this.delaySetPopupVisible(!1,this.$props.mouseLeaveDelay);const{vcTriggerContext:_n={}}=this;_n.onPopupMouseleave&&_n.onPopupMouseleave($n)},onFocus($n){this.fireEvents("onFocus",$n),this.clearDelayTimer(),this.isFocusToShow()&&(this.focusTime=Date.now(),this.delaySetPopupVisible(!0,this.$props.focusDelay))},onMousedown($n){this.fireEvents("onMousedown",$n),this.preClickTime=Date.now()},onTouchstart($n){this.fireEvents("onTouchstart",$n),this.preTouchTime=Date.now()},onBlur($n){contains$2($n.target,$n.relatedTarget||document.activeElement)||(this.fireEvents("onBlur",$n),this.clearDelayTimer(),this.isBlurToHide()&&this.delaySetPopupVisible(!1,this.$props.blurDelay))},onContextmenu($n){$n.preventDefault(),this.fireEvents("onContextmenu",$n),this.setPopupVisible(!0,$n)},onContextmenuClose(){this.isContextmenuToShow()&&this.close()},onClick($n){if(this.fireEvents("onClick",$n),this.focusTime){let _n;if(this.preClickTime&&this.preTouchTime?_n=Math.min(this.preClickTime,this.preTouchTime):this.preClickTime?_n=this.preClickTime:this.preTouchTime&&(_n=this.preTouchTime),Math.abs(_n-this.focusTime)<20)return;this.focusTime=0}this.preClickTime=0,this.preTouchTime=0,this.isClickToShow()&&(this.isClickToHide()||this.isBlurToHide())&&$n&&$n.preventDefault&&$n.preventDefault(),$n&&$n.domEvent&&$n.domEvent.preventDefault();const Cn=!this.$data.sPopupVisible;(this.isClickToHide()&&!Cn||Cn&&this.isClickToShow())&&this.setPopupVisible(!this.$data.sPopupVisible,$n)},onPopupMouseDown(){const{vcTriggerContext:$n={}}=this;this.hasPopupMouseDown=!0,clearTimeout(this.mouseDownTimeout),this.mouseDownTimeout=setTimeout(()=>{this.hasPopupMouseDown=!1},0),$n.onPopupMouseDown&&$n.onPopupMouseDown(...arguments)},onDocumentClick($n){if(this.$props.mask&&!this.$props.maskClosable)return;const Cn=$n.target,_n=this.getRootDomNode(),Pn=this.getPopupDomNode();(!contains$2(_n,Cn)||this.isContextMenuOnly())&&!contains$2(Pn,Cn)&&!this.hasPopupMouseDown&&this.delaySetPopupVisible(!1,.1)},getPopupDomNode(){var $n;return(($n=this.popupRef)===null||$n===void 0?void 0:$n.getElement())||null},getRootDomNode(){var $n,Cn,_n,Pn;const{getTriggerDOMNode:In}=this.$props;if(In){const Nn=((Cn=($n=this.triggerRef)===null||$n===void 0?void 0:$n.$el)===null||Cn===void 0?void 0:Cn.nodeName)==="#comment"?null:findDOMNode(this.triggerRef);return findDOMNode(In(Nn))}try{const Nn=((Pn=(_n=this.triggerRef)===null||_n===void 0?void 0:_n.$el)===null||Pn===void 0?void 0:Pn.nodeName)==="#comment"?null:findDOMNode(this.triggerRef);if(Nn)return Nn}catch{}return findDOMNode(this)},handleGetPopupClassFromAlign($n){const Cn=[],_n=this.$props,{popupPlacement:Pn,builtinPlacements:In,prefixCls:Nn,alignPoint:Rn,getPopupClassNameFromAlign:Dn}=_n;return Pn&&In&&Cn.push(getAlignPopupClassName(In,Nn,$n,Rn)),Dn&&Cn.push(Dn($n)),Cn.join(" ")},getPopupAlign(){const $n=this.$props,{popupPlacement:Cn,popupAlign:_n,builtinPlacements:Pn}=$n;return Cn&&Pn?getAlignFromPlacement(Pn,Cn,_n):_n},getComponent(){const $n={};this.isMouseEnterToShow()&&($n.onMouseenter=this.onPopupMouseenter),this.isMouseLeaveToHide()&&($n.onMouseleave=this.onPopupMouseleave),$n.onMousedown=this.onPopupMouseDown,$n[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]=this.onPopupMouseDown;const{handleGetPopupClassFromAlign:Cn,getRootDomNode:_n,$attrs:Pn}=this,{prefixCls:In,destroyPopupOnHide:Nn,popupClassName:Rn,popupAnimation:Dn,popupTransitionName:Ln,popupStyle:Fn,mask:Bn,maskAnimation:Hn,maskTransitionName:zn,zIndex:Wn,stretch:Yn,alignPoint:Gn,mobile:Go,forceRender:Xn}=this.$props,{sPopupVisible:Yo,point:qo}=this.$data,Jo=_extends$1(_extends$1({prefixCls:In,destroyPopupOnHide:Nn,visible:Yo,point:Gn?qo:null,align:this.align,animation:Dn,getClassNameFromAlign:Cn,stretch:Yn,getRootDomNode:_n,mask:Bn,zIndex:Wn,transitionName:Ln,maskAnimation:Hn,maskTransitionName:zn,class:Rn,style:Fn,onAlign:Pn.onPopupAlign||noop$d},$n),{ref:this.setPopupRef,mobile:Go,forceRender:Xn});return createVNode(Popup,Jo,{default:this.$slots.popup||(()=>getComponent(this,"popup"))})},attachParent($n){wrapperRaf.cancel(this.attachId);const{getPopupContainer:Cn,getDocument:_n}=this.$props,Pn=this.getRootDomNode();let In;Cn?(Pn||Cn.length===0)&&(In=Cn(Pn)):In=_n(this.getRootDomNode()).body,In?In.appendChild($n):this.attachId=wrapperRaf(()=>{this.attachParent($n)})},getContainer(){const{$props:$n}=this,{getDocument:Cn}=$n,_n=Cn(this.getRootDomNode()).createElement("div");return _n.style.position="absolute",_n.style.top="0",_n.style.left="0",_n.style.width="100%",this.attachParent(_n),_n},setPopupVisible($n,Cn){const{alignPoint:_n,sPopupVisible:Pn,onPopupVisibleChange:In}=this;this.clearDelayTimer(),Pn!==$n&&(hasProp(this,"popupVisible")||this.setState({sPopupVisible:$n,prevPopupVisible:Pn}),In&&In($n)),_n&&Cn&&$n&&this.setPoint(Cn)},setPoint($n){const{alignPoint:Cn}=this.$props;!Cn||!$n||this.setState({point:{pageX:$n.pageX,pageY:$n.pageY}})},handlePortalUpdate(){this.prevPopupVisible!==this.sPopupVisible&&this.afterPopupVisibleChange(this.sPopupVisible)},delaySetPopupVisible($n,Cn,_n){const Pn=Cn*1e3;if(this.clearDelayTimer(),Pn){const In=_n?{pageX:_n.pageX,pageY:_n.pageY}:null;this.delayTimer=setTimeout(()=>{this.setPopupVisible($n,In),this.clearDelayTimer()},Pn)}else this.setPopupVisible($n,_n)},clearDelayTimer(){this.delayTimer&&(clearTimeout(this.delayTimer),this.delayTimer=null)},clearOutsideHandler(){this.clickOutsideHandler&&(this.clickOutsideHandler.remove(),this.clickOutsideHandler=null),this.contextmenuOutsideHandler1&&(this.contextmenuOutsideHandler1.remove(),this.contextmenuOutsideHandler1=null),this.contextmenuOutsideHandler2&&(this.contextmenuOutsideHandler2.remove(),this.contextmenuOutsideHandler2=null),this.touchOutsideHandler&&(this.touchOutsideHandler.remove(),this.touchOutsideHandler=null)},createTwoChains($n){let Cn=()=>{};const _n=getEvents(this);return this.childOriginEvents[$n]&&_n[$n]?this[`fire${$n}`]:(Cn=this.childOriginEvents[$n]||_n[$n]||Cn,Cn)},isClickToShow(){const{action:$n,showAction:Cn}=this.$props;return $n.indexOf("click")!==-1||Cn.indexOf("click")!==-1},isContextMenuOnly(){const{action:$n}=this.$props;return $n==="contextmenu"||$n.length===1&&$n[0]==="contextmenu"},isContextmenuToShow(){const{action:$n,showAction:Cn}=this.$props;return $n.indexOf("contextmenu")!==-1||Cn.indexOf("contextmenu")!==-1},isClickToHide(){const{action:$n,hideAction:Cn}=this.$props;return $n.indexOf("click")!==-1||Cn.indexOf("click")!==-1},isMouseEnterToShow(){const{action:$n,showAction:Cn}=this.$props;return $n.indexOf("hover")!==-1||Cn.indexOf("mouseenter")!==-1},isMouseLeaveToHide(){const{action:$n,hideAction:Cn}=this.$props;return $n.indexOf("hover")!==-1||Cn.indexOf("mouseleave")!==-1},isFocusToShow(){const{action:$n,showAction:Cn}=this.$props;return $n.indexOf("focus")!==-1||Cn.indexOf("focus")!==-1},isBlurToHide(){const{action:$n,hideAction:Cn}=this.$props;return $n.indexOf("focus")!==-1||Cn.indexOf("blur")!==-1},forcePopupAlign(){var $n;this.$data.sPopupVisible&&(($n=this.popupRef)===null||$n===void 0||$n.forceAlign())},fireEvents($n,Cn){this.childOriginEvents[$n]&&this.childOriginEvents[$n](Cn);const _n=this.$props[$n]||this.$attrs[$n];_n&&_n(Cn)},close(){this.setPopupVisible(!1)}},render(){const{$attrs:$n}=this,Cn=filterEmpty(getSlot(this)),{alignPoint:_n,getPopupContainer:Pn}=this.$props,In=Cn[0];this.childOriginEvents=getEvents(In);const Nn={key:"trigger"};this.isContextmenuToShow()?Nn.onContextmenu=this.onContextmenu:Nn.onContextmenu=this.createTwoChains("onContextmenu"),this.isClickToHide()||this.isClickToShow()?(Nn.onClick=this.onClick,Nn.onMousedown=this.onMousedown,Nn[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]=this.onTouchstart):(Nn.onClick=this.createTwoChains("onClick"),Nn.onMousedown=this.createTwoChains("onMousedown"),Nn[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]=this.createTwoChains("onTouchstart")),this.isMouseEnterToShow()?(Nn.onMouseenter=this.onMouseenter,_n&&(Nn.onMousemove=this.onMouseMove)):Nn.onMouseenter=this.createTwoChains("onMouseenter"),this.isMouseLeaveToHide()?Nn.onMouseleave=this.onMouseleave:Nn.onMouseleave=this.createTwoChains("onMouseleave"),this.isFocusToShow()||this.isBlurToHide()?(Nn.onFocus=this.onFocus,Nn.onBlur=this.onBlur):(Nn.onFocus=this.createTwoChains("onFocus"),Nn.onBlur=Fn=>{Fn&&(!Fn.relatedTarget||!contains$2(Fn.target,Fn.relatedTarget))&&this.createTwoChains("onBlur")(Fn)});const Rn=classNames(In&&In.props&&In.props.class,$n.class);Rn&&(Nn.class=Rn);const Dn=cloneElement(In,_extends$1(_extends$1({},Nn),{ref:"triggerRef"}),!0,!0),Ln=createVNode(Portal,{key:"portal",getContainer:Pn&&(()=>Pn(this.getRootDomNode())),didUpdate:this.handlePortalUpdate,visible:this.$data.sPopupVisible},{default:this.getComponent});return createVNode(Fragment,null,[Dn,Ln])}});var __rest$1d=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const Cn=$n===!0?0:1;return{bottomLeft:{points:["tl","bl"],offset:[0,4],overflow:{adjustX:Cn,adjustY:1}},bottomRight:{points:["tr","br"],offset:[0,4],overflow:{adjustX:Cn,adjustY:1}},topLeft:{points:["bl","tl"],offset:[0,-4],overflow:{adjustX:Cn,adjustY:1}},topRight:{points:["br","tr"],offset:[0,-4],overflow:{adjustX:Cn,adjustY:1}}}},SelectTrigger=defineComponent({name:"SelectTrigger",inheritAttrs:!1,props:{dropdownAlign:Object,visible:{type:Boolean,default:void 0},disabled:{type:Boolean,default:void 0},dropdownClassName:String,dropdownStyle:PropTypes.object,placement:String,empty:{type:Boolean,default:void 0},prefixCls:String,popupClassName:String,animation:String,transitionName:String,getPopupContainer:Function,dropdownRender:Function,containerWidth:Number,dropdownMatchSelectWidth:PropTypes.oneOfType([Number,Boolean]).def(!0),popupElement:PropTypes.any,direction:String,getTriggerDOMNode:Function,onPopupVisibleChange:Function,onPopupMouseEnter:Function,onPopupFocusin:Function,onPopupFocusout:Function},setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;const Nn=computed(()=>{const{dropdownMatchSelectWidth:Dn}=$n;return getBuiltInPlacements(Dn)}),Rn=ref();return In({getPopupElement:()=>Rn.value}),()=>{const Dn=_extends$1(_extends$1({},$n),Pn),{empty:Ln=!1}=Dn,Fn=__rest$1d(Dn,["empty"]),{visible:Bn,dropdownAlign:Hn,prefixCls:zn,popupElement:Wn,dropdownClassName:Yn,dropdownStyle:Gn,direction:Go="ltr",placement:Xn,dropdownMatchSelectWidth:Yo,containerWidth:qo,dropdownRender:Jo,animation:Zo,transitionName:rr,getPopupContainer:nr,getTriggerDOMNode:ta,onPopupVisibleChange:oa,onPopupMouseEnter:ra,onPopupFocusin:ea,onPopupFocusout:la}=Fn,ua=`${zn}-dropdown`;let ga=Wn;Jo&&(ga=Jo({menuNode:Wn,props:$n}));const aa=Zo?`${ua}-${Zo}`:rr,ca=_extends$1({minWidth:`${qo}px`},Gn);return typeof Yo=="number"?ca.width=`${Yo}px`:Yo&&(ca.width=`${qo}px`),createVNode(Trigger,_objectSpread2$1(_objectSpread2$1({},$n),{},{showAction:oa?["click"]:[],hideAction:oa?["click"]:[],popupPlacement:Xn||(Go==="rtl"?"bottomRight":"bottomLeft"),builtinPlacements:Nn.value,prefixCls:ua,popupTransitionName:aa,popupAlign:Hn,popupVisible:Bn,getPopupContainer:nr,popupClassName:classNames(Yn,{[`${ua}-empty`]:Ln}),popupStyle:ca,getTriggerDOMNode:ta,onPopupVisibleChange:oa}),{default:_n.default,popup:()=>createVNode("div",{ref:Rn,onMouseenter:ra,onFocusin:ea,onFocusout:la},[ga])})}}}),SelectTrigger$1=SelectTrigger,KeyCode={MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(Cn){const{keyCode:_n}=Cn;if(Cn.altKey&&!Cn.ctrlKey||Cn.metaKey||_n>=KeyCode.F1&&_n<=KeyCode.F12)return!1;switch(_n){case KeyCode.ALT:case KeyCode.CAPS_LOCK:case KeyCode.CONTEXT_MENU:case KeyCode.CTRL:case KeyCode.DOWN:case KeyCode.END:case KeyCode.ESC:case KeyCode.HOME:case KeyCode.INSERT:case KeyCode.LEFT:case KeyCode.MAC_FF_META:case KeyCode.META:case KeyCode.NUMLOCK:case KeyCode.NUM_CENTER:case KeyCode.PAGE_DOWN:case KeyCode.PAGE_UP:case KeyCode.PAUSE:case KeyCode.PRINT_SCREEN:case KeyCode.RIGHT:case KeyCode.SHIFT:case KeyCode.UP:case KeyCode.WIN_KEY:case KeyCode.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(Cn){if(Cn>=KeyCode.ZERO&&Cn<=KeyCode.NINE||Cn>=KeyCode.NUM_ZERO&&Cn<=KeyCode.NUM_MULTIPLY||Cn>=KeyCode.A&&Cn<=KeyCode.Z||window.navigator.userAgent.indexOf("WebKit")!==-1&&Cn===0)return!0;switch(Cn){case KeyCode.SPACE:case KeyCode.QUESTION_MARK:case KeyCode.NUM_PLUS:case KeyCode.NUM_MINUS:case KeyCode.NUM_PERIOD:case KeyCode.NUM_DIVISION:case KeyCode.SEMICOLON:case KeyCode.DASH:case KeyCode.EQUALS:case KeyCode.COMMA:case KeyCode.PERIOD:case KeyCode.SLASH:case KeyCode.APOSTROPHE:case KeyCode.SINGLE_QUOTE:case KeyCode.OPEN_SQUARE_BRACKET:case KeyCode.BACKSLASH:case KeyCode.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}},KeyCode$1=KeyCode,TransBtn=($n,Cn)=>{let{slots:_n}=Cn;var Pn;const{class:In,customizeIcon:Nn,customizeIconProps:Rn,onMousedown:Dn,onClick:Ln}=$n;let Fn;return typeof Nn=="function"?Fn=Nn(Rn):Fn=Nn,createVNode("span",{class:In,onMousedown:Bn=>{Bn.preventDefault(),Dn&&Dn(Bn)},style:{userSelect:"none",WebkitUserSelect:"none"},unselectable:"on",onClick:Ln,"aria-hidden":!0},[Fn!==void 0?Fn:createVNode("span",{class:In.split(/\s+/).map(Bn=>`${Bn}-icon`)},[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)])])};TransBtn.inheritAttrs=!1;TransBtn.displayName="TransBtn";TransBtn.props={class:String,customizeIcon:PropTypes.any,customizeIconProps:PropTypes.any,onMousedown:Function,onClick:Function};const TransBtn$1=TransBtn;function onCompositionStart($n){$n.target.composing=!0}function onCompositionEnd($n){$n.target.composing&&($n.target.composing=!1,trigger($n.target,"input"))}function trigger($n,Cn){const _n=document.createEvent("HTMLEvents");_n.initEvent(Cn,!0,!0),$n.dispatchEvent(_n)}function addEventListener($n,Cn,_n,Pn){$n.addEventListener(Cn,_n,Pn)}const antInput={created($n,Cn){(!Cn.modifiers||!Cn.modifiers.lazy)&&(addEventListener($n,"compositionstart",onCompositionStart),addEventListener($n,"compositionend",onCompositionEnd),addEventListener($n,"change",onCompositionEnd))}},antInputDirective=antInput,inputProps$2={inputRef:PropTypes.any,prefixCls:String,id:String,inputElement:PropTypes.VueNode,disabled:{type:Boolean,default:void 0},autofocus:{type:Boolean,default:void 0},autocomplete:String,editable:{type:Boolean,default:void 0},activeDescendantId:String,value:String,open:{type:Boolean,default:void 0},tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),attrs:PropTypes.object,onKeydown:{type:Function},onMousedown:{type:Function},onChange:{type:Function},onPaste:{type:Function},onCompositionstart:{type:Function},onCompositionend:{type:Function},onFocus:{type:Function},onBlur:{type:Function}},Input$1=defineComponent({compatConfig:{MODE:3},name:"SelectInput",inheritAttrs:!1,props:inputProps$2,setup($n){let Cn=null;const _n=inject("VCSelectContainerEvent");return()=>{var Pn;const{prefixCls:In,id:Nn,inputElement:Rn,disabled:Dn,tabindex:Ln,autofocus:Fn,autocomplete:Bn,editable:Hn,activeDescendantId:zn,value:Wn,onKeydown:Yn,onMousedown:Gn,onChange:Go,onPaste:Xn,onCompositionstart:Yo,onCompositionend:qo,onFocus:Jo,onBlur:Zo,open:rr,inputRef:nr,attrs:ta}=$n;let oa=Rn||withDirectives(createVNode("input",null,null),[[antInputDirective]]);const ra=oa.props||{},{onKeydown:ea,onInput:la,onFocus:ua,onBlur:ga,onMousedown:aa,onCompositionstart:ca,onCompositionend:sa,style:ia}=ra;return oa=cloneElement(oa,_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({type:"search"},ra),{id:Nn,ref:nr,disabled:Dn,tabindex:Ln,autocomplete:Bn||"off",autofocus:Fn,class:classNames(`${In}-selection-search-input`,(Pn=oa==null?void 0:oa.props)===null||Pn===void 0?void 0:Pn.class),role:"combobox","aria-expanded":rr,"aria-haspopup":"listbox","aria-owns":`${Nn}_list`,"aria-autocomplete":"list","aria-controls":`${Nn}_list`,"aria-activedescendant":zn}),ta),{value:Hn?Wn:"",readonly:!Hn,unselectable:Hn?null:"on",style:_extends$1(_extends$1({},ia),{opacity:Hn?null:0}),onKeydown:fa=>{Yn(fa),ea&&ea(fa)},onMousedown:fa=>{Gn(fa),aa&&aa(fa)},onInput:fa=>{Go(fa),la&&la(fa)},onCompositionstart(fa){Yo(fa),ca&&ca(fa)},onCompositionend(fa){qo(fa),sa&&sa(fa)},onPaste:Xn,onFocus:function(){clearTimeout(Cn),ua&&ua(arguments.length<=0?void 0:arguments[0]),Jo&&Jo(arguments.length<=0?void 0:arguments[0]),_n==null||_n.focus(arguments.length<=0?void 0:arguments[0])},onBlur:function(){for(var fa=arguments.length,ma=new Array(fa),ya=0;ya{ga&&ga(ma[0]),Zo&&Zo(ma[0]),_n==null||_n.blur(ma[0])},100)}}),oa.type==="textarea"?{}:{type:"search"}),!0,!0),oa}}}),Input$2=Input$1,attributes=`accept acceptcharset accesskey action allowfullscreen allowtransparency -alt async autocomplete autofocus autoplay capture cellpadding cellspacing challenge -charset checked classid classname colspan cols content contenteditable contextmenu -controls coords crossorigin data datetime default defer dir disabled download draggable -enctype form formaction formenctype formmethod formnovalidate formtarget frameborder -headers height hidden high href hreflang htmlfor for httpequiv icon id inputmode integrity -is keyparams keytype kind label lang list loop low manifest marginheight marginwidth max maxlength media -mediagroup method min minlength multiple muted name novalidate nonce open -optimum pattern placeholder poster preload radiogroup readonly rel required -reversed role rowspan rows sandbox scope scoped scrolling seamless selected -shape size sizes span spellcheck src srcdoc srclang srcset start step style -summary tabindex target title type usemap value width wmode wrap`,eventsName=`onCopy onCut onPaste onCompositionend onCompositionstart onCompositionupdate onKeydown - onKeypress onKeyup onFocus onBlur onChange onInput onSubmit onClick onContextmenu onDoubleclick onDblclick - onDrag onDragend onDragenter onDragexit onDragleave onDragover onDragstart onDrop onMousedown - onMouseenter onMouseleave onMousemove onMouseout onMouseover onMouseup onSelect onTouchcancel - onTouchend onTouchmove onTouchstart onTouchstartPassive onTouchmovePassive onScroll onWheel onAbort onCanplay onCanplaythrough - onDurationchange onEmptied onEncrypted onEnded onError onLoadeddata onLoadedmetadata - onLoadstart onPause onPlay onPlaying onProgress onRatechange onSeeked onSeeking onStalled onSuspend onTimeupdate onVolumechange onWaiting onLoad onError`,propList=`${attributes} ${eventsName}`.split(/[\s\n]+/),ariaPrefix="aria-",dataPrefix="data-";function match($n,Cn){return $n.indexOf(Cn)===0}function pickAttrs($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,_n;Cn===!1?_n={aria:!0,data:!0,attr:!0}:Cn===!0?_n={aria:!0}:_n=_extends$1({},Cn);const Pn={};return Object.keys($n).forEach(In=>{(_n.aria&&(In==="role"||match(In,ariaPrefix))||_n.data&&match(In,dataPrefix)||_n.attr&&(propList.includes(In)||propList.includes(In.toLowerCase())))&&(Pn[In]=$n[In])}),Pn}const OverflowContextProviderKey=Symbol("OverflowContextProviderKey"),OverflowContextProvider=defineComponent({compatConfig:{MODE:3},name:"OverflowContextProvider",inheritAttrs:!1,props:{value:{type:Object}},setup($n,Cn){let{slots:_n}=Cn;return provide(OverflowContextProviderKey,computed(()=>$n.value)),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),useInjectOverflowContext=()=>inject(OverflowContextProviderKey,computed(()=>null));var __rest$1c=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.responsive&&!$n.display),Nn=ref();Pn({itemNodeRef:Nn});function Rn(Dn){$n.registerSize($n.itemKey,Dn)}return onUnmounted(()=>{Rn(null)}),()=>{var Dn;const{prefixCls:Ln,invalidate:Fn,item:Bn,renderItem:Hn,responsive:zn,registerSize:Wn,itemKey:Yn,display:Gn,order:Go,component:Xn="div"}=$n,Yo=__rest$1c($n,["prefixCls","invalidate","item","renderItem","responsive","registerSize","itemKey","display","order","component"]),qo=(Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n),Jo=Hn&&Bn!==UNDEFINED?Hn(Bn):qo;let Zo;Fn||(Zo={opacity:In.value?0:1,height:In.value?0:UNDEFINED,overflowY:In.value?"hidden":UNDEFINED,order:zn?Go:UNDEFINED,pointerEvents:In.value?"none":UNDEFINED,position:In.value?"absolute":UNDEFINED});const rr={};return In.value&&(rr["aria-hidden"]=!0),createVNode(ResizeObserver$1,{disabled:!zn,onResize:nr=>{let{offsetWidth:ta}=nr;Rn(ta)}},{default:()=>createVNode(Xn,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({class:classNames(!Fn&&Ln),style:Zo},rr),Yo),{},{ref:Nn}),{default:()=>[Jo]})})}}});var __rest$1b=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{var Nn;if(!In.value){const{component:Hn="div"}=$n,zn=__rest$1b($n,["component"]);return createVNode(Hn,_objectSpread2$1(_objectSpread2$1({},zn),Pn),{default:()=>[(Nn=_n.default)===null||Nn===void 0?void 0:Nn.call(_n)]})}const Rn=In.value,{className:Dn}=Rn,Ln=__rest$1b(Rn,["className"]),{class:Fn}=Pn,Bn=__rest$1b(Pn,["class"]);return createVNode(OverflowContextProvider,{value:null},{default:()=>[createVNode(Item$3,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({class:classNames(Dn,Fn)},Ln),Bn),$n),_n)]})}}});var __rest$1a=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({id:String,prefixCls:String,data:Array,itemKey:[String,Number,Function],itemWidth:{type:Number,default:10},renderItem:Function,renderRawItem:Function,maxCount:[Number,String],renderRest:Function,renderRawRest:Function,suffix:PropTypes.any,component:String,itemComponent:PropTypes.any,onVisibleChange:Function,ssr:String,onMousedown:Function}),Overflow=defineComponent({name:"Overflow",inheritAttrs:!1,props:overflowProps(),emits:["visibleChange"],setup($n,Cn){let{attrs:_n,emit:Pn,slots:In}=Cn;const Nn=computed(()=>$n.ssr==="full"),Rn=shallowRef(null),Dn=computed(()=>Rn.value||0),Ln=shallowRef(new Map),Fn=shallowRef(0),Bn=shallowRef(0),Hn=shallowRef(0),zn=shallowRef(null),Wn=shallowRef(null),Yn=computed(()=>Wn.value===null&&Nn.value?Number.MAX_SAFE_INTEGER:Wn.value||0),Gn=shallowRef(!1),Go=computed(()=>`${$n.prefixCls}-item`),Xn=computed(()=>Math.max(Fn.value,Bn.value)),Yo=computed(()=>!!($n.data.length&&$n.maxCount===RESPONSIVE)),qo=computed(()=>$n.maxCount===INVALIDATE),Jo=computed(()=>Yo.value||typeof $n.maxCount=="number"&&$n.data.length>$n.maxCount),Zo=computed(()=>{let aa=$n.data;return Yo.value?Rn.value===null&&Nn.value?aa=$n.data:aa=$n.data.slice(0,Math.min($n.data.length,Dn.value/$n.itemWidth)):typeof $n.maxCount=="number"&&(aa=$n.data.slice(0,$n.maxCount)),aa}),rr=computed(()=>Yo.value?$n.data.slice(Yn.value+1):$n.data.slice(Zo.value.length)),nr=(aa,ca)=>{var sa;return typeof $n.itemKey=="function"?$n.itemKey(aa):(sa=$n.itemKey&&(aa==null?void 0:aa[$n.itemKey]))!==null&&sa!==void 0?sa:ca},ta=computed(()=>$n.renderItem||(aa=>aa)),oa=(aa,ca)=>{Wn.value=aa,ca||(Gn.value=aa<$n.data.length-1,Pn("visibleChange",aa))},ra=(aa,ca)=>{Rn.value=ca.clientWidth},ea=(aa,ca)=>{const sa=new Map(Ln.value);ca===null?sa.delete(aa):sa.set(aa,ca),Ln.value=sa},la=(aa,ca)=>{Fn.value=Bn.value,Bn.value=ca},ua=(aa,ca)=>{Hn.value=ca},ga=aa=>Ln.value.get(nr(Zo.value[aa],aa));return watch([Dn,Ln,Bn,Hn,()=>$n.itemKey,Zo],()=>{if(Dn.value&&Xn.value&&Zo.value){let aa=Hn.value;const ca=Zo.value.length,sa=ca-1;if(!ca){oa(0),zn.value=null;return}for(let ia=0;iaDn.value){oa(ia-1),zn.value=aa-fa-Hn.value+Bn.value;break}}$n.suffix&&ga(0)+Hn.value>Dn.value&&(zn.value=null)}}),()=>{const aa=Gn.value&&!!rr.value.length,{itemComponent:ca,renderRawItem:sa,renderRawRest:ia,renderRest:fa,prefixCls:ma="rc-overflow",suffix:ya,component:ba="div",id:Ia,onMousedown:Ea}=$n,{class:xa,style:Ta}=_n,wa=__rest$1a(_n,["class","style"]);let La={};zn.value!==null&&Yo.value&&(La={position:"absolute",left:`${zn.value}px`,top:0});const Na={prefixCls:Go.value,responsive:Yo.value,component:ca,invalidate:qo.value},$a=sa?(pa,Sa)=>{const Aa=nr(pa,Sa);return createVNode(OverflowContextProvider,{key:Aa,value:_extends$1(_extends$1({},Na),{order:Sa,item:pa,itemKey:Aa,registerSize:ea,display:Sa<=Yn.value})},{default:()=>[sa(pa,Sa)]})}:(pa,Sa)=>{const Aa=nr(pa,Sa);return createVNode(Item$3,_objectSpread2$1(_objectSpread2$1({},Na),{},{order:Sa,key:Aa,item:pa,renderItem:ta.value,itemKey:Aa,registerSize:ea,display:Sa<=Yn.value}),null)};let ka=()=>null;const Ha={order:aa?Yn.value:Number.MAX_SAFE_INTEGER,className:`${Go.value} ${Go.value}-rest`,registerSize:la,display:aa};if(ia)ia&&(ka=()=>createVNode(OverflowContextProvider,{value:_extends$1(_extends$1({},Na),Ha)},{default:()=>[ia(rr.value)]}));else{const pa=fa||defaultRenderRest;ka=()=>createVNode(Item$3,_objectSpread2$1(_objectSpread2$1({},Na),Ha),{default:()=>typeof pa=="function"?pa(rr.value):pa})}const da=()=>{var pa;return createVNode(ba,_objectSpread2$1({id:Ia,class:classNames(!qo.value&&ma,xa),style:Ta,onMousedown:Ea},wa),{default:()=>[Zo.value.map($a),Jo.value?ka():null,ya&&createVNode(Item$3,_objectSpread2$1(_objectSpread2$1({},Na),{},{order:Yn.value,class:`${Go.value}-suffix`,registerSize:ua,display:!0,style:La}),{default:()=>ya}),(pa=In.default)===null||pa===void 0?void 0:pa.call(In)]})};return createVNode(ResizeObserver$1,{disabled:!Yo.value,onResize:ra},{default:da})}}});Overflow.Item=RawItem;Overflow.RESPONSIVE=RESPONSIVE;Overflow.INVALIDATE=INVALIDATE;const Overflow$1=Overflow,TreeSelectLegacyContextPropsKey=Symbol("TreeSelectLegacyContextPropsKey");function useProvideLegacySelectContext($n){return provide(TreeSelectLegacyContextPropsKey,$n)}function useInjectLegacySelectContext(){return inject(TreeSelectLegacyContextPropsKey,{})}const props$2={id:String,prefixCls:String,values:PropTypes.array,open:{type:Boolean,default:void 0},searchValue:String,inputRef:PropTypes.any,placeholder:PropTypes.any,disabled:{type:Boolean,default:void 0},mode:String,showSearch:{type:Boolean,default:void 0},autofocus:{type:Boolean,default:void 0},autocomplete:String,activeDescendantId:String,tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),removeIcon:PropTypes.any,choiceTransitionName:String,maxTagCount:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),maxTagTextLength:Number,maxTagPlaceholder:PropTypes.any.def(()=>$n=>`+ ${$n.length} ...`),tagRender:Function,onToggleOpen:{type:Function},onRemove:Function,onInputChange:Function,onInputPaste:Function,onInputKeyDown:Function,onInputMouseDown:Function,onInputCompositionStart:Function,onInputCompositionEnd:Function},onPreventMouseDown=$n=>{$n.preventDefault(),$n.stopPropagation()},SelectSelector=defineComponent({name:"MultipleSelectSelector",inheritAttrs:!1,props:props$2,setup($n){const Cn=shallowRef(),_n=shallowRef(0),Pn=shallowRef(!1),In=useInjectLegacySelectContext(),Nn=computed(()=>`${$n.prefixCls}-selection`),Rn=computed(()=>$n.open||$n.mode==="tags"?$n.searchValue:""),Dn=computed(()=>$n.mode==="tags"||$n.showSearch&&($n.open||Pn.value));onMounted(()=>{watch(Rn,()=>{_n.value=Cn.value.scrollWidth},{flush:"post",immediate:!0})});function Ln(zn,Wn,Yn,Gn,Go){return createVNode("span",{class:classNames(`${Nn.value}-item`,{[`${Nn.value}-item-disabled`]:Yn}),title:typeof zn=="string"||typeof zn=="number"?zn.toString():void 0},[createVNode("span",{class:`${Nn.value}-item-content`},[Wn]),Gn&&createVNode(TransBtn$1,{class:`${Nn.value}-item-remove`,onMousedown:onPreventMouseDown,onClick:Go,customizeIcon:$n.removeIcon},{default:()=>[createTextVNode("×")]})])}function Fn(zn,Wn,Yn,Gn,Go,Xn){var Yo;const qo=Zo=>{onPreventMouseDown(Zo),$n.onToggleOpen(!open)};let Jo=Xn;return In.keyEntities&&(Jo=((Yo=In.keyEntities[zn])===null||Yo===void 0?void 0:Yo.node)||{}),createVNode("span",{key:zn,onMousedown:qo},[$n.tagRender({label:Wn,value:zn,disabled:Yn,closable:Gn,onClose:Go,option:Jo})])}function Bn(zn){const{disabled:Wn,label:Yn,value:Gn,option:Go}=zn,Xn=!$n.disabled&&!Wn;let Yo=Yn;if(typeof $n.maxTagTextLength=="number"&&(typeof Yn=="string"||typeof Yn=="number")){const Jo=String(Yo);Jo.length>$n.maxTagTextLength&&(Yo=`${Jo.slice(0,$n.maxTagTextLength)}...`)}const qo=Jo=>{var Zo;Jo&&Jo.stopPropagation(),(Zo=$n.onRemove)===null||Zo===void 0||Zo.call($n,zn)};return typeof $n.tagRender=="function"?Fn(Gn,Yo,Wn,Xn,qo,Go):Ln(Yn,Yo,Wn,Xn,qo)}function Hn(zn){const{maxTagPlaceholder:Wn=Gn=>`+ ${Gn.length} ...`}=$n,Yn=typeof Wn=="function"?Wn(zn):Wn;return Ln(Yn,Yn,!1)}return()=>{const{id:zn,prefixCls:Wn,values:Yn,open:Gn,inputRef:Go,placeholder:Xn,disabled:Yo,autofocus:qo,autocomplete:Jo,activeDescendantId:Zo,tabindex:rr,onInputChange:nr,onInputPaste:ta,onInputKeyDown:oa,onInputMouseDown:ra,onInputCompositionStart:ea,onInputCompositionEnd:la}=$n,ua=createVNode("div",{class:`${Nn.value}-search`,style:{width:_n.value+"px"},key:"input"},[createVNode(Input$2,{inputRef:Go,open:Gn,prefixCls:Wn,id:zn,inputElement:null,disabled:Yo,autofocus:qo,autocomplete:Jo,editable:Dn.value,activeDescendantId:Zo,value:Rn.value,onKeydown:oa,onMousedown:ra,onChange:nr,onPaste:ta,onCompositionstart:ea,onCompositionend:la,tabindex:rr,attrs:pickAttrs($n,!0),onFocus:()=>Pn.value=!0,onBlur:()=>Pn.value=!1},null),createVNode("span",{ref:Cn,class:`${Nn.value}-search-mirror`,"aria-hidden":!0},[Rn.value,createTextVNode(" ")])]),ga=createVNode(Overflow$1,{prefixCls:`${Nn.value}-overflow`,data:Yn,renderItem:Bn,renderRest:Hn,suffix:ua,itemKey:"key",maxCount:$n.maxTagCount,key:"overflow"},null);return createVNode(Fragment,null,[ga,!Yn.length&&!Rn.value&&createVNode("span",{class:`${Nn.value}-placeholder`},[Xn])])}}}),MultipleSelector=SelectSelector,props$1={inputElement:PropTypes.any,id:String,prefixCls:String,values:PropTypes.array,open:{type:Boolean,default:void 0},searchValue:String,inputRef:PropTypes.any,placeholder:PropTypes.any,disabled:{type:Boolean,default:void 0},mode:String,showSearch:{type:Boolean,default:void 0},autofocus:{type:Boolean,default:void 0},autocomplete:String,activeDescendantId:String,tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),activeValue:String,backfill:{type:Boolean,default:void 0},optionLabelRender:Function,onInputChange:Function,onInputPaste:Function,onInputKeyDown:Function,onInputMouseDown:Function,onInputCompositionStart:Function,onInputCompositionEnd:Function},SingleSelector=defineComponent({name:"SingleSelector",setup($n){const Cn=shallowRef(!1),_n=computed(()=>$n.mode==="combobox"),Pn=computed(()=>_n.value||$n.showSearch),In=computed(()=>{let Fn=$n.searchValue||"";return _n.value&&$n.activeValue&&!Cn.value&&(Fn=$n.activeValue),Fn}),Nn=useInjectLegacySelectContext();watch([_n,()=>$n.activeValue],()=>{_n.value&&(Cn.value=!1)},{immediate:!0});const Rn=computed(()=>$n.mode!=="combobox"&&!$n.open&&!$n.showSearch?!1:!!In.value),Dn=computed(()=>{const Fn=$n.values[0];return Fn&&(typeof Fn.label=="string"||typeof Fn.label=="number")?Fn.label.toString():void 0}),Ln=()=>{if($n.values[0])return null;const Fn=Rn.value?{visibility:"hidden"}:void 0;return createVNode("span",{class:`${$n.prefixCls}-selection-placeholder`,style:Fn},[$n.placeholder])};return()=>{var Fn,Bn,Hn,zn;const{inputElement:Wn,prefixCls:Yn,id:Gn,values:Go,inputRef:Xn,disabled:Yo,autofocus:qo,autocomplete:Jo,activeDescendantId:Zo,open:rr,tabindex:nr,optionLabelRender:ta,onInputKeyDown:oa,onInputMouseDown:ra,onInputChange:ea,onInputPaste:la,onInputCompositionStart:ua,onInputCompositionEnd:ga}=$n,aa=Go[0];let ca=null;if(aa&&Nn.customSlots){const sa=(Fn=aa.key)!==null&&Fn!==void 0?Fn:aa.value,ia=((Bn=Nn.keyEntities[sa])===null||Bn===void 0?void 0:Bn.node)||{};ca=Nn.customSlots[(Hn=ia.slots)===null||Hn===void 0?void 0:Hn.title]||Nn.customSlots.title||aa.label,typeof ca=="function"&&(ca=ca(ia))}else ca=ta&&aa?ta(aa.option):aa==null?void 0:aa.label;return createVNode(Fragment,null,[createVNode("span",{class:`${Yn}-selection-search`},[createVNode(Input$2,{inputRef:Xn,prefixCls:Yn,id:Gn,open:rr,inputElement:Wn,disabled:Yo,autofocus:qo,autocomplete:Jo,editable:Pn.value,activeDescendantId:Zo,value:In.value,onKeydown:oa,onMousedown:ra,onChange:sa=>{Cn.value=!0,ea(sa)},onPaste:la,onCompositionstart:ua,onCompositionend:ga,tabindex:nr,attrs:pickAttrs($n,!0)},null)]),!_n.value&&aa&&!Rn.value&&createVNode("span",{class:`${Yn}-selection-item`,title:Dn.value},[createVNode(Fragment,{key:(zn=aa.key)!==null&&zn!==void 0?zn:aa.value},[ca])]),Ln()])}}});SingleSelector.props=props$1;SingleSelector.inheritAttrs=!1;const SingleSelector$1=SingleSelector;function isValidateOpenKey($n){return![KeyCode$1.ESC,KeyCode$1.SHIFT,KeyCode$1.BACKSPACE,KeyCode$1.TAB,KeyCode$1.WIN_KEY,KeyCode$1.ALT,KeyCode$1.META,KeyCode$1.WIN_KEY_RIGHT,KeyCode$1.CTRL,KeyCode$1.SEMICOLON,KeyCode$1.EQUALS,KeyCode$1.CAPS_LOCK,KeyCode$1.CONTEXT_MENU,KeyCode$1.F1,KeyCode$1.F2,KeyCode$1.F3,KeyCode$1.F4,KeyCode$1.F5,KeyCode$1.F6,KeyCode$1.F7,KeyCode$1.F8,KeyCode$1.F9,KeyCode$1.F10,KeyCode$1.F11,KeyCode$1.F12].includes($n)}function useLock(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:250,Cn=null,_n;onBeforeUnmount(()=>{clearTimeout(_n)});function Pn(In){(In||Cn===null)&&(Cn=In),clearTimeout(_n),_n=setTimeout(()=>{Cn=null},$n)}return[()=>Cn,Pn]}function createRef(){const $n=Cn=>{$n.current=Cn};return $n}const Selector=defineComponent({name:"Selector",inheritAttrs:!1,props:{id:String,prefixCls:String,showSearch:{type:Boolean,default:void 0},open:{type:Boolean,default:void 0},values:PropTypes.array,multiple:{type:Boolean,default:void 0},mode:String,searchValue:String,activeValue:String,inputElement:PropTypes.any,autofocus:{type:Boolean,default:void 0},activeDescendantId:String,tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),disabled:{type:Boolean,default:void 0},placeholder:PropTypes.any,removeIcon:PropTypes.any,maxTagCount:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),maxTagTextLength:Number,maxTagPlaceholder:PropTypes.any,tagRender:Function,optionLabelRender:Function,tokenWithEnter:{type:Boolean,default:void 0},choiceTransitionName:String,onToggleOpen:{type:Function},onSearch:Function,onSearchSubmit:Function,onRemove:Function,onInputKeyDown:{type:Function},domRef:Function},setup($n,Cn){let{expose:_n}=Cn;const Pn=createRef();let In=!1;const[Nn,Rn]=useLock(0),Dn=Xn=>{const{which:Yo}=Xn;(Yo===KeyCode$1.UP||Yo===KeyCode$1.DOWN)&&Xn.preventDefault(),$n.onInputKeyDown&&$n.onInputKeyDown(Xn),Yo===KeyCode$1.ENTER&&$n.mode==="tags"&&!In&&!$n.open&&$n.onSearchSubmit(Xn.target.value),isValidateOpenKey(Yo)&&$n.onToggleOpen(!0)},Ln=()=>{Rn(!0)};let Fn=null;const Bn=Xn=>{$n.onSearch(Xn,!0,In)!==!1&&$n.onToggleOpen(!0)},Hn=()=>{In=!0},zn=Xn=>{In=!1,$n.mode!=="combobox"&&Bn(Xn.target.value)},Wn=Xn=>{let{target:{value:Yo}}=Xn;if($n.tokenWithEnter&&Fn&&/[\r\n]/.test(Fn)){const qo=Fn.replace(/[\r\n]+$/,"").replace(/\r\n/g," ").replace(/[\r\n]/g," ");Yo=Yo.replace(qo,Fn)}Fn=null,Bn(Yo)},Yn=Xn=>{const{clipboardData:Yo}=Xn;Fn=Yo.getData("text")},Gn=Xn=>{let{target:Yo}=Xn;Yo!==Pn.current&&(document.body.style.msTouchAction!==void 0?setTimeout(()=>{Pn.current.focus()}):Pn.current.focus())},Go=Xn=>{const Yo=Nn();Xn.target!==Pn.current&&!Yo&&Xn.preventDefault(),($n.mode!=="combobox"&&(!$n.showSearch||!Yo)||!$n.open)&&($n.open&&$n.onSearch("",!0,!1),$n.onToggleOpen())};return _n({focus:()=>{Pn.current.focus()},blur:()=>{Pn.current.blur()}}),()=>{const{prefixCls:Xn,domRef:Yo,mode:qo}=$n,Jo={inputRef:Pn,onInputKeyDown:Dn,onInputMouseDown:Ln,onInputChange:Wn,onInputPaste:Yn,onInputCompositionStart:Hn,onInputCompositionEnd:zn},Zo=qo==="multiple"||qo==="tags"?createVNode(MultipleSelector,_objectSpread2$1(_objectSpread2$1({},$n),Jo),null):createVNode(SingleSelector$1,_objectSpread2$1(_objectSpread2$1({},$n),Jo),null);return createVNode("div",{ref:Yo,class:`${Xn}-selector`,onClick:Gn,onMousedown:Go},[Zo])}}}),Selector$1=Selector;function useSelectTriggerControl($n,Cn,_n){function Pn(In){var Nn,Rn,Dn;let Ln=In.target;Ln.shadowRoot&&In.composed&&(Ln=In.composedPath()[0]||Ln);const Fn=[(Nn=$n[0])===null||Nn===void 0?void 0:Nn.value,(Dn=(Rn=$n[1])===null||Rn===void 0?void 0:Rn.value)===null||Dn===void 0?void 0:Dn.getPopupElement()];Cn.value&&Fn.every(Bn=>Bn&&!Bn.contains(Ln)&&Bn!==Ln)&&_n(!1)}onMounted(()=>{window.addEventListener("mousedown",Pn)}),onBeforeUnmount(()=>{window.removeEventListener("mousedown",Pn)})}function useDelayReset(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:10;const Cn=shallowRef(!1);let _n;const Pn=()=>{clearTimeout(_n)};return onMounted(()=>{Pn()}),[Cn,(Nn,Rn)=>{Pn(),_n=setTimeout(()=>{Cn.value=Nn,Rn&&Rn()},$n)},Pn]}const BaseSelectContextKey=Symbol("BaseSelectContextKey");function useProvideBaseSelectProps($n){return provide(BaseSelectContextKey,$n)}function useBaseProps(){return inject(BaseSelectContextKey,{})}const isMobile=()=>{if(typeof navigator>"u"||typeof window>"u")return!1;const $n=navigator.userAgent||navigator.vendor||window.opera;return/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test($n)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test($n==null?void 0:$n.substr(0,4))};function toReactive($n){if(!isRef($n))return reactive($n);const Cn=new Proxy({},{get(_n,Pn,In){return Reflect.get($n.value,Pn,In)},set(_n,Pn,In){return $n.value[Pn]=In,!0},deleteProperty(_n,Pn){return Reflect.deleteProperty($n.value,Pn)},has(_n,Pn){return Reflect.has($n.value,Pn)},ownKeys(){return Object.keys($n.value)},getOwnPropertyDescriptor(){return{enumerable:!0,configurable:!0}}});return reactive(Cn)}var __rest$19=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,id:String,omitDomProps:Array,displayValues:Array,onDisplayValuesChange:Function,activeValue:String,activeDescendantId:String,onActiveValueChange:Function,searchValue:String,onSearch:Function,onSearchSplit:Function,maxLength:Number,OptionList:PropTypes.any,emptyOptions:Boolean}),baseSelectPropsWithoutPrivate=()=>({showSearch:{type:Boolean,default:void 0},tagRender:{type:Function},optionLabelRender:{type:Function},direction:{type:String},tabindex:Number,autofocus:Boolean,notFoundContent:PropTypes.any,placeholder:PropTypes.any,onClear:Function,choiceTransitionName:String,mode:String,disabled:{type:Boolean,default:void 0},loading:{type:Boolean,default:void 0},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:void 0},onDropdownVisibleChange:{type:Function},getInputElement:{type:Function},getRawInputElement:{type:Function},maxTagTextLength:Number,maxTagCount:{type:[String,Number]},maxTagPlaceholder:PropTypes.any,tokenSeparators:{type:Array},allowClear:{type:Boolean,default:void 0},showArrow:{type:Boolean,default:void 0},inputIcon:PropTypes.any,clearIcon:PropTypes.any,removeIcon:PropTypes.any,animation:String,transitionName:String,dropdownStyle:{type:Object},dropdownClassName:String,dropdownMatchSelectWidth:{type:[Boolean,Number],default:void 0},dropdownRender:{type:Function},dropdownAlign:Object,placement:{type:String},getPopupContainer:{type:Function},showAction:{type:Array},onBlur:{type:Function},onFocus:{type:Function},onKeyup:Function,onKeydown:Function,onMousedown:Function,onPopupScroll:Function,onInputKeyDown:Function,onMouseenter:Function,onMouseleave:Function,onClick:Function}),baseSelectProps=()=>_extends$1(_extends$1({},baseSelectPrivateProps()),baseSelectPropsWithoutPrivate());function isMultiple($n){return $n==="tags"||$n==="multiple"}const BaseSelect=defineComponent({compatConfig:{MODE:3},name:"BaseSelect",inheritAttrs:!1,props:initDefaultProps(baseSelectProps(),{showAction:[],notFoundContent:"Not Found"}),setup($n,Cn){let{attrs:_n,expose:Pn,slots:In}=Cn;const Nn=computed(()=>isMultiple($n.mode)),Rn=computed(()=>$n.showSearch!==void 0?$n.showSearch:Nn.value||$n.mode==="combobox"),Dn=shallowRef(!1);onMounted(()=>{Dn.value=isMobile()});const Ln=useInjectLegacySelectContext(),Fn=shallowRef(null),Bn=createRef(),Hn=shallowRef(null),zn=shallowRef(null),Wn=shallowRef(null),Yn=ref(!1),[Gn,Go,Xn]=useDelayReset();Pn({focus:()=>{var $a;($a=zn.value)===null||$a===void 0||$a.focus()},blur:()=>{var $a;($a=zn.value)===null||$a===void 0||$a.blur()},scrollTo:$a=>{var ka;return(ka=Wn.value)===null||ka===void 0?void 0:ka.scrollTo($a)}});const Jo=computed(()=>{var $a;if($n.mode!=="combobox")return $n.searchValue;const ka=($a=$n.displayValues[0])===null||$a===void 0?void 0:$a.value;return typeof ka=="string"||typeof ka=="number"?String(ka):""}),Zo=$n.open!==void 0?$n.open:$n.defaultOpen,rr=shallowRef(Zo),nr=shallowRef(Zo),ta=$a=>{rr.value=$n.open!==void 0?$n.open:$a,nr.value=rr.value};watch(()=>$n.open,()=>{ta($n.open)});const oa=computed(()=>!$n.notFoundContent&&$n.emptyOptions);watchEffect(()=>{nr.value=rr.value,($n.disabled||oa.value&&nr.value&&$n.mode==="combobox")&&(nr.value=!1)});const ra=computed(()=>oa.value?!1:nr.value),ea=$a=>{const ka=$a!==void 0?$a:!nr.value;nr.value!==ka&&!$n.disabled&&(ta(ka),$n.onDropdownVisibleChange&&$n.onDropdownVisibleChange(ka))},la=computed(()=>($n.tokenSeparators||[]).some($a=>[` -`,`\r -`].includes($a))),ua=($a,ka,Ha)=>{var da,pa;let Sa=!0,Aa=$a;(da=$n.onActiveValueChange)===null||da===void 0||da.call($n,null);const Ra=Ha?null:getSeparatedContent($a,$n.tokenSeparators);return $n.mode!=="combobox"&&Ra&&(Aa="",(pa=$n.onSearchSplit)===null||pa===void 0||pa.call($n,Ra),ea(!1),Sa=!1),$n.onSearch&&Jo.value!==Aa&&$n.onSearch(Aa,{source:ka?"typing":"effect"}),Sa},ga=$a=>{var ka;!$a||!$a.trim()||(ka=$n.onSearch)===null||ka===void 0||ka.call($n,$a,{source:"submit"})};watch(nr,()=>{!nr.value&&!Nn.value&&$n.mode!=="combobox"&&ua("",!1,!1)},{immediate:!0,flush:"post"}),watch(()=>$n.disabled,()=>{rr.value&&$n.disabled&&ta(!1),$n.disabled&&!Yn.value&&Go(!1)},{immediate:!0});const[aa,ca]=useLock(),sa=function($a){var ka;const Ha=aa(),{which:da}=$a;if(da===KeyCode$1.ENTER&&($n.mode!=="combobox"&&$a.preventDefault(),nr.value||ea(!0)),ca(!!Jo.value),da===KeyCode$1.BACKSPACE&&!Ha&&Nn.value&&!Jo.value&&$n.displayValues.length){const Ra=[...$n.displayValues];let Fa=null;for(let za=Ra.length-1;za>=0;za-=1){const Wa=Ra[za];if(!Wa.disabled){Ra.splice(za,1),Fa=Wa;break}}Fa&&$n.onDisplayValuesChange(Ra,{type:"remove",values:[Fa]})}for(var pa=arguments.length,Sa=new Array(pa>1?pa-1:0),Aa=1;Aa1?ka-1:0),da=1;da{const ka=$n.displayValues.filter(Ha=>Ha!==$a);$n.onDisplayValuesChange(ka,{type:"remove",values:[$a]})},ma=shallowRef(!1),ya=function(){Go(!0),$n.disabled||($n.onFocus&&!ma.value&&$n.onFocus(...arguments),$n.showAction&&$n.showAction.includes("focus")&&ea(!0)),ma.value=!0},ba=ref(!1),Ia=function(){if(ba.value||(Yn.value=!0,Go(!1,()=>{ma.value=!1,Yn.value=!1,ea(!1)}),$n.disabled))return;const $a=Jo.value;$a&&($n.mode==="tags"?$n.onSearch($a,{source:"submit"}):$n.mode==="multiple"&&$n.onSearch("",{source:"blur"})),$n.onBlur&&$n.onBlur(...arguments)},Ea=()=>{ba.value=!0},xa=()=>{ba.value=!1};provide("VCSelectContainerEvent",{focus:ya,blur:Ia});const Ta=[];onMounted(()=>{Ta.forEach($a=>clearTimeout($a)),Ta.splice(0,Ta.length)}),onBeforeUnmount(()=>{Ta.forEach($a=>clearTimeout($a)),Ta.splice(0,Ta.length)});const wa=function($a){var ka,Ha;const{target:da}=$a,pa=(ka=Hn.value)===null||ka===void 0?void 0:ka.getPopupElement();if(pa&&pa.contains(da)){const Fa=setTimeout(()=>{var za;const Wa=Ta.indexOf(Fa);Wa!==-1&&Ta.splice(Wa,1),Xn(),!Dn.value&&!pa.contains(document.activeElement)&&((za=zn.value)===null||za===void 0||za.focus())});Ta.push(Fa)}for(var Sa=arguments.length,Aa=new Array(Sa>1?Sa-1:0),Ra=1;Ra{};return onMounted(()=>{watch(ra,()=>{var $a;if(ra.value){const ka=Math.ceil(($a=Fn.value)===null||$a===void 0?void 0:$a.offsetWidth);La.value!==ka&&!Number.isNaN(ka)&&(La.value=ka)}},{immediate:!0,flush:"post"})}),useSelectTriggerControl([Fn,Hn],ra,ea),useProvideBaseSelectProps(toReactive(_extends$1(_extends$1({},toRefs($n)),{open:nr,triggerOpen:ra,showSearch:Rn,multiple:Nn,toggleOpen:ea}))),()=>{const $a=_extends$1(_extends$1({},$n),_n),{prefixCls:ka,id:Ha,open:da,defaultOpen:pa,mode:Sa,showSearch:Aa,searchValue:Ra,onSearch:Fa,allowClear:za,clearIcon:Wa,showArrow:Ya,inputIcon:ja,disabled:qa,loading:Xa,getInputElement:Oa,getPopupContainer:Ma,placement:Ua,animation:Qa,transitionName:ri,dropdownStyle:fi,dropdownClassName:ei,dropdownMatchSelectWidth:ti,dropdownRender:ni,dropdownAlign:ui,showAction:mi,direction:di,tokenSeparators:gi,tagRender:wi,optionLabelRender:Ti,onPopupScroll:Ei,onDropdownVisibleChange:Ni,onFocus:Ri,onBlur:Zi,onKeyup:Qi,onKeydown:Ji,onMousedown:Yi,onClear:rl,omitDomProps:yi,getRawInputElement:il,displayValues:Tl,onDisplayValuesChange:ul,emptyOptions:ts,activeDescendantId:ci,activeValue:Ci,OptionList:bi}=$a,Bi=__rest$19($a,["prefixCls","id","open","defaultOpen","mode","showSearch","searchValue","onSearch","allowClear","clearIcon","showArrow","inputIcon","disabled","loading","getInputElement","getPopupContainer","placement","animation","transitionName","dropdownStyle","dropdownClassName","dropdownMatchSelectWidth","dropdownRender","dropdownAlign","showAction","direction","tokenSeparators","tagRender","optionLabelRender","onPopupScroll","onDropdownVisibleChange","onFocus","onBlur","onKeyup","onKeydown","onMousedown","onClear","omitDomProps","getRawInputElement","displayValues","onDisplayValuesChange","emptyOptions","activeDescendantId","activeValue","OptionList"]),nl=Sa==="combobox"&&Oa&&Oa()||null,el=typeof il=="function"&&il(),gl=_extends$1({},Bi);let ll;el&&(ll=vl=>{ea(vl)}),DEFAULT_OMIT_PROPS.forEach(vl=>{delete gl[vl]}),yi==null||yi.forEach(vl=>{delete gl[vl]});const Rl=Ya!==void 0?Ya:Xa||!Nn.value&&Sa!=="combobox";let ml;Rl&&(ml=createVNode(TransBtn$1,{class:classNames(`${ka}-arrow`,{[`${ka}-arrow-loading`]:Xa}),customizeIcon:ja,customizeIconProps:{loading:Xa,searchValue:Jo.value,open:nr.value,focused:Gn.value,showSearch:Rn.value}},null));let hl;const zi=()=>{rl==null||rl(),ul([],{type:"clear",values:Tl}),ua("",!1,!1)};!qa&&za&&(Tl.length||Jo.value)&&(hl=createVNode(TransBtn$1,{class:`${ka}-clear`,onMousedown:zi,customizeIcon:Wa},{default:()=>[createTextVNode("×")]}));const Pl=createVNode(bi,{ref:Wn},_extends$1(_extends$1({},Ln.customSlots),{option:In.option})),Cl=classNames(ka,_n.class,{[`${ka}-focused`]:Gn.value,[`${ka}-multiple`]:Nn.value,[`${ka}-single`]:!Nn.value,[`${ka}-allow-clear`]:za,[`${ka}-show-arrow`]:Rl,[`${ka}-disabled`]:qa,[`${ka}-loading`]:Xa,[`${ka}-open`]:nr.value,[`${ka}-customize-input`]:nl,[`${ka}-show-search`]:Rn.value}),Fl=createVNode(SelectTrigger$1,{ref:Hn,disabled:qa,prefixCls:ka,visible:ra.value,popupElement:Pl,containerWidth:La.value,animation:Qa,transitionName:ri,dropdownStyle:fi,dropdownClassName:ei,direction:di,dropdownMatchSelectWidth:ti,dropdownRender:ni,dropdownAlign:ui,placement:Ua,getPopupContainer:Ma,empty:ts,getTriggerDOMNode:()=>Bn.current,onPopupVisibleChange:ll,onPopupMouseEnter:Na,onPopupFocusin:Ea,onPopupFocusout:xa},{default:()=>el?isValidElement(el)&&cloneElement(el,{ref:Bn},!1,!0):createVNode(Selector$1,_objectSpread2$1(_objectSpread2$1({},$n),{},{domRef:Bn,prefixCls:ka,inputElement:nl,ref:zn,id:Ha,showSearch:Rn.value,mode:Sa,activeDescendantId:ci,tagRender:wi,optionLabelRender:Ti,values:Tl,open:nr.value,onToggleOpen:ea,activeValue:Ci,searchValue:Jo.value,onSearch:ua,onSearchSubmit:ga,onRemove:fa,tokenWithEnter:la.value}),null)});let Bl;return el?Bl=Fl:Bl=createVNode("div",_objectSpread2$1(_objectSpread2$1({},gl),{},{class:Cl,ref:Fn,onMousedown:wa,onKeydown:sa,onKeyup:ia}),[Gn.value&&!nr.value&&createVNode("span",{style:{width:0,height:0,position:"absolute",overflow:"hidden",opacity:0},"aria-live":"polite"},[`${Tl.map(vl=>{let{label:ns,value:yl}=vl;return["number","string"].includes(typeof ns)?ns:yl}).join(", ")}`]),Fl,ml,hl]),Bl}}}),Filter=($n,Cn)=>{let{height:_n,offset:Pn,prefixCls:In,onInnerResize:Nn}=$n,{slots:Rn}=Cn;var Dn;let Ln={},Fn={display:"flex",flexDirection:"column"};return Pn!==void 0&&(Ln={height:`${_n}px`,position:"relative",overflow:"hidden"},Fn=_extends$1(_extends$1({},Fn),{transform:`translateY(${Pn}px)`,position:"absolute",left:0,right:0,top:0})),createVNode("div",{style:Ln},[createVNode(ResizeObserver$1,{onResize:Bn=>{let{offsetHeight:Hn}=Bn;Hn&&Nn&&Nn()}},{default:()=>[createVNode("div",{style:Fn,class:classNames({[`${In}-holder-inner`]:In})},[(Dn=Rn.default)===null||Dn===void 0?void 0:Dn.call(Rn)])]})])};Filter.displayName="Filter";Filter.inheritAttrs=!1;Filter.props={prefixCls:String,height:Number,offset:Number,onInnerResize:Function};const Filler=Filter,Item$1=($n,Cn)=>{let{setRef:_n}=$n,{slots:Pn}=Cn;var In;const Nn=flattenChildren((In=Pn.default)===null||In===void 0?void 0:In.call(Pn));return Nn&&Nn.length?cloneVNode(Nn[0],{ref:_n}):Nn};Item$1.props={setRef:{type:Function,default:()=>{}}};const Item$2=Item$1,MIN_SIZE=20;function getPageY($n){return"touches"in $n?$n.touches[0].pageY:$n.pageY}const ScrollBar=defineComponent({compatConfig:{MODE:3},name:"ScrollBar",inheritAttrs:!1,props:{prefixCls:String,scrollTop:Number,scrollHeight:Number,height:Number,count:Number,onScroll:{type:Function},onStartMove:{type:Function},onStopMove:{type:Function}},setup(){return{moveRaf:null,scrollbarRef:createRef(),thumbRef:createRef(),visibleTimeout:null,state:reactive({dragging:!1,pageY:null,startTop:null,visible:!1})}},watch:{scrollTop:{handler(){this.delayHidden()},flush:"post"}},mounted(){var $n,Cn;($n=this.scrollbarRef.current)===null||$n===void 0||$n.addEventListener("touchstart",this.onScrollbarTouchStart,supportsPassive$1?{passive:!1}:!1),(Cn=this.thumbRef.current)===null||Cn===void 0||Cn.addEventListener("touchstart",this.onMouseDown,supportsPassive$1?{passive:!1}:!1)},beforeUnmount(){this.removeEvents(),clearTimeout(this.visibleTimeout)},methods:{delayHidden(){clearTimeout(this.visibleTimeout),this.state.visible=!0,this.visibleTimeout=setTimeout(()=>{this.state.visible=!1},2e3)},onScrollbarTouchStart($n){$n.preventDefault()},onContainerMouseDown($n){$n.stopPropagation(),$n.preventDefault()},patchEvents(){window.addEventListener("mousemove",this.onMouseMove),window.addEventListener("mouseup",this.onMouseUp),this.thumbRef.current.addEventListener("touchmove",this.onMouseMove,supportsPassive$1?{passive:!1}:!1),this.thumbRef.current.addEventListener("touchend",this.onMouseUp)},removeEvents(){window.removeEventListener("mousemove",this.onMouseMove),window.removeEventListener("mouseup",this.onMouseUp),this.scrollbarRef.current.removeEventListener("touchstart",this.onScrollbarTouchStart,supportsPassive$1?{passive:!1}:!1),this.thumbRef.current&&(this.thumbRef.current.removeEventListener("touchstart",this.onMouseDown,supportsPassive$1?{passive:!1}:!1),this.thumbRef.current.removeEventListener("touchmove",this.onMouseMove,supportsPassive$1?{passive:!1}:!1),this.thumbRef.current.removeEventListener("touchend",this.onMouseUp)),wrapperRaf.cancel(this.moveRaf)},onMouseDown($n){const{onStartMove:Cn}=this.$props;_extends$1(this.state,{dragging:!0,pageY:getPageY($n),startTop:this.getTop()}),Cn(),this.patchEvents(),$n.stopPropagation(),$n.preventDefault()},onMouseMove($n){const{dragging:Cn,pageY:_n,startTop:Pn}=this.state,{onScroll:In}=this.$props;if(wrapperRaf.cancel(this.moveRaf),Cn){const Nn=getPageY($n)-_n,Rn=Pn+Nn,Dn=this.getEnableScrollRange(),Ln=this.getEnableHeightRange(),Fn=Ln?Rn/Ln:0,Bn=Math.ceil(Fn*Dn);this.moveRaf=wrapperRaf(()=>{In(Bn)})}},onMouseUp(){const{onStopMove:$n}=this.$props;this.state.dragging=!1,$n(),this.removeEvents()},getSpinHeight(){const{height:$n,scrollHeight:Cn}=this.$props;let _n=$n/Cn*100;return _n=Math.max(_n,MIN_SIZE),_n=Math.min(_n,$n/2),Math.floor(_n)},getEnableScrollRange(){const{scrollHeight:$n,height:Cn}=this.$props;return $n-Cn||0},getEnableHeightRange(){const{height:$n}=this.$props,Cn=this.getSpinHeight();return $n-Cn||0},getTop(){const{scrollTop:$n}=this.$props,Cn=this.getEnableScrollRange(),_n=this.getEnableHeightRange();return $n===0||Cn===0?0:$n/Cn*_n},showScroll(){const{height:$n,scrollHeight:Cn}=this.$props;return Cn>$n}},render(){const{dragging:$n,visible:Cn}=this.state,{prefixCls:_n}=this.$props,Pn=this.getSpinHeight()+"px",In=this.getTop()+"px",Nn=this.showScroll(),Rn=Nn&&Cn;return createVNode("div",{ref:this.scrollbarRef,class:classNames(`${_n}-scrollbar`,{[`${_n}-scrollbar-show`]:Nn}),style:{width:"8px",top:0,bottom:0,right:0,position:"absolute",display:Rn?void 0:"none"},onMousedown:this.onContainerMouseDown,onMousemove:this.delayHidden},[createVNode("div",{ref:this.thumbRef,class:classNames(`${_n}-scrollbar-thumb`,{[`${_n}-scrollbar-thumb-moving`]:$n}),style:{width:"100%",height:Pn,top:In,left:0,position:"absolute",background:"rgba(0, 0, 0, 0.5)",borderRadius:"99px",cursor:"pointer",userSelect:"none"},onMousedown:this.onMouseDown},null)])}});function useHeights($n,Cn,_n,Pn){const In=new Map,Nn=new Map,Rn=ref(Symbol("update"));watch($n,()=>{Rn.value=Symbol("update")});let Dn;function Ln(){wrapperRaf.cancel(Dn)}function Fn(){Ln(),Dn=wrapperRaf(()=>{In.forEach((Hn,zn)=>{if(Hn&&Hn.offsetParent){const{offsetHeight:Wn}=Hn;Nn.get(zn)!==Wn&&(Rn.value=Symbol("update"),Nn.set(zn,Hn.offsetHeight))}})})}function Bn(Hn,zn){const Wn=Cn(Hn),Yn=In.get(Wn);zn?(In.set(Wn,zn.$el||zn),Fn()):In.delete(Wn),!Yn!=!zn&&(zn?_n==null||_n(Hn):Pn==null||Pn(Hn))}return onUnmounted(()=>{Ln()}),[Bn,Fn,Nn,Rn]}function useScrollTo($n,Cn,_n,Pn,In,Nn,Rn,Dn){let Ln;return Fn=>{if(Fn==null){Dn();return}wrapperRaf.cancel(Ln);const Bn=Cn.value,Hn=Pn.itemHeight;if(typeof Fn=="number")Rn(Fn);else if(Fn&&typeof Fn=="object"){let zn;const{align:Wn}=Fn;"index"in Fn?{index:zn}=Fn:zn=Bn.findIndex(Go=>In(Go)===Fn.key);const{offset:Yn=0}=Fn,Gn=(Go,Xn)=>{if(Go<0||!$n.value)return;const Yo=$n.value.clientHeight;let qo=!1,Jo=Xn;if(Yo){const Zo=Xn||Wn;let rr=0,nr=0,ta=0;const oa=Math.min(Bn.length,zn);for(let la=0;la<=oa;la+=1){const ua=In(Bn[la]);nr=rr;const ga=_n.get(ua);ta=nr+(ga===void 0?Hn:ga),rr=ta,la===zn&&ga===void 0&&(qo=!0)}const ra=$n.value.scrollTop;let ea=null;switch(Zo){case"top":ea=nr-Yn;break;case"bottom":ea=ta-Yo+Yn;break;default:{const la=ra+Yo;nrla&&(Jo="bottom")}}ea!==null&&ea!==ra&&Rn(ea)}Ln=wrapperRaf(()=>{qo&&Nn(),Gn(Go-1,Jo)},2)};Gn(5)}}}const isFF=typeof navigator=="object"&&/Firefox/i.test(navigator.userAgent),useOriginScroll=($n,Cn)=>{let _n=!1,Pn=null;function In(){clearTimeout(Pn),_n=!0,Pn=setTimeout(()=>{_n=!1},50)}return function(Nn){let Rn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const Dn=Nn<0&&$n.value||Nn>0&&Cn.value;return Rn&&Dn?(clearTimeout(Pn),_n=!1):(!Dn||_n)&&In(),!_n&&Dn}};function useFrameWheel($n,Cn,_n,Pn){let In=0,Nn=null,Rn=null,Dn=!1;const Ln=useOriginScroll(Cn,_n);function Fn(Hn){if(!$n.value)return;wrapperRaf.cancel(Nn);const{deltaY:zn}=Hn;In+=zn,Rn=zn,!Ln(zn)&&(isFF||Hn.preventDefault(),Nn=wrapperRaf(()=>{Pn(In*(Dn?10:1)),In=0}))}function Bn(Hn){$n.value&&(Dn=Hn.detail===Rn)}return[Fn,Bn]}const SMOOTH_PTG=14/15;function useMobileTouchMove($n,Cn,_n){let Pn=!1,In=0,Nn=null,Rn=null;const Dn=()=>{Nn&&(Nn.removeEventListener("touchmove",Ln),Nn.removeEventListener("touchend",Fn))},Ln=zn=>{if(Pn){const Wn=Math.ceil(zn.touches[0].pageY);let Yn=In-Wn;In=Wn,_n(Yn)&&zn.preventDefault(),clearInterval(Rn),Rn=setInterval(()=>{Yn*=SMOOTH_PTG,(!_n(Yn,!0)||Math.abs(Yn)<=.1)&&clearInterval(Rn)},16)}},Fn=()=>{Pn=!1,Dn()},Bn=zn=>{Dn(),zn.touches.length===1&&!Pn&&(Pn=!0,In=Math.ceil(zn.touches[0].pageY),Nn=zn.target,Nn.addEventListener("touchmove",Ln,{passive:!1}),Nn.addEventListener("touchend",Fn))},Hn=()=>{};onMounted(()=>{document.addEventListener("touchmove",Hn,{passive:!1}),watch($n,zn=>{Cn.value.removeEventListener("touchstart",Bn),Dn(),clearInterval(Rn),zn&&Cn.value.addEventListener("touchstart",Bn,{passive:!1})},{immediate:!0})}),onBeforeUnmount(()=>{document.removeEventListener("touchmove",Hn)})}var __rest$18=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const Fn=Cn+Ln,Bn=In(Dn,Fn,{}),Hn=Rn(Dn);return createVNode(Item$2,{key:Hn,setRef:zn=>Pn(Dn,zn)},{default:()=>[Bn]})})}const List$3=defineComponent({compatConfig:{MODE:3},name:"List",inheritAttrs:!1,props:{prefixCls:String,data:PropTypes.array,height:Number,itemHeight:Number,fullHeight:{type:Boolean,default:void 0},itemKey:{type:[String,Number,Function],required:!0},component:{type:[String,Object]},virtual:{type:Boolean,default:void 0},children:Function,onScroll:Function,onMousedown:Function,onMouseenter:Function,onVisibleChange:Function},setup($n,Cn){let{expose:_n}=Cn;const Pn=computed(()=>{const{height:fa,itemHeight:ma,virtual:ya}=$n;return!!(ya!==!1&&fa&&ma)}),In=computed(()=>{const{height:fa,itemHeight:ma,data:ya}=$n;return Pn.value&&ya&&ma*ya.length>fa}),Nn=reactive({scrollTop:0,scrollMoving:!1}),Rn=computed(()=>$n.data||EMPTY_DATA$1),Dn=shallowRef([]);watch(Rn,()=>{Dn.value=toRaw(Rn.value).slice()},{immediate:!0});const Ln=shallowRef(fa=>{});watch(()=>$n.itemKey,fa=>{typeof fa=="function"?Ln.value=fa:Ln.value=ma=>ma==null?void 0:ma[fa]},{immediate:!0});const Fn=shallowRef(),Bn=shallowRef(),Hn=shallowRef(),zn=fa=>Ln.value(fa),Wn={getKey:zn};function Yn(fa){let ma;typeof fa=="function"?ma=fa(Nn.scrollTop):ma=fa;const ya=rr(ma);Fn.value&&(Fn.value.scrollTop=ya),Nn.scrollTop=ya}const[Gn,Go,Xn,Yo]=useHeights(Dn,zn,null,null),qo=reactive({scrollHeight:void 0,start:0,end:0,offset:void 0}),Jo=shallowRef(0);onMounted(()=>{nextTick(()=>{var fa;Jo.value=((fa=Bn.value)===null||fa===void 0?void 0:fa.offsetHeight)||0})}),onUpdated(()=>{nextTick(()=>{var fa;Jo.value=((fa=Bn.value)===null||fa===void 0?void 0:fa.offsetHeight)||0})}),watch([Pn,Dn],()=>{Pn.value||_extends$1(qo,{scrollHeight:void 0,start:0,end:Dn.value.length-1,offset:void 0})},{immediate:!0}),watch([Pn,Dn,Jo,In],()=>{Pn.value&&!In.value&&_extends$1(qo,{scrollHeight:Jo.value,start:0,end:Dn.value.length-1,offset:void 0}),Fn.value&&(Nn.scrollTop=Fn.value.scrollTop)},{immediate:!0}),watch([In,Pn,()=>Nn.scrollTop,Dn,Yo,()=>$n.height,Jo],()=>{if(!Pn.value||!In.value)return;let fa=0,ma,ya,ba;const Ia=Dn.value.length,Ea=Dn.value,xa=Nn.scrollTop,{itemHeight:Ta,height:wa}=$n,La=xa+wa;for(let Na=0;Na=xa&&(ma=Na,ya=fa),ba===void 0&&da>La&&(ba=Na),fa=da}ma===void 0&&(ma=0,ya=0,ba=Math.ceil(wa/Ta)),ba===void 0&&(ba=Ia-1),ba=Math.min(ba+1,Ia),_extends$1(qo,{scrollHeight:fa,start:ma,end:ba,offset:ya})},{immediate:!0});const Zo=computed(()=>qo.scrollHeight-$n.height);function rr(fa){let ma=fa;return Number.isNaN(Zo.value)||(ma=Math.min(ma,Zo.value)),ma=Math.max(ma,0),ma}const nr=computed(()=>Nn.scrollTop<=0),ta=computed(()=>Nn.scrollTop>=Zo.value),oa=useOriginScroll(nr,ta);function ra(fa){Yn(fa)}function ea(fa){var ma;const{scrollTop:ya}=fa.currentTarget;ya!==Nn.scrollTop&&Yn(ya),(ma=$n.onScroll)===null||ma===void 0||ma.call($n,fa)}const[la,ua]=useFrameWheel(Pn,nr,ta,fa=>{Yn(ma=>ma+fa)});useMobileTouchMove(Pn,Fn,(fa,ma)=>oa(fa,ma)?!1:(la({preventDefault(){},deltaY:fa}),!0));function ga(fa){Pn.value&&fa.preventDefault()}const aa=()=>{Fn.value&&(Fn.value.removeEventListener("wheel",la,supportsPassive$1?{passive:!1}:!1),Fn.value.removeEventListener("DOMMouseScroll",ua),Fn.value.removeEventListener("MozMousePixelScroll",ga))};watchEffect(()=>{nextTick(()=>{Fn.value&&(aa(),Fn.value.addEventListener("wheel",la,supportsPassive$1?{passive:!1}:!1),Fn.value.addEventListener("DOMMouseScroll",ua),Fn.value.addEventListener("MozMousePixelScroll",ga))})}),onBeforeUnmount(()=>{aa()});const ca=useScrollTo(Fn,Dn,Xn,$n,zn,Go,Yn,()=>{var fa;(fa=Hn.value)===null||fa===void 0||fa.delayHidden()});_n({scrollTo:ca});const sa=computed(()=>{let fa=null;return $n.height&&(fa=_extends$1({[$n.fullHeight?"height":"maxHeight"]:$n.height+"px"},ScrollStyle),Pn.value&&(fa.overflowY="hidden",Nn.scrollMoving&&(fa.pointerEvents="none"))),fa});return watch([()=>qo.start,()=>qo.end,Dn],()=>{if($n.onVisibleChange){const fa=Dn.value.slice(qo.start,qo.end+1);$n.onVisibleChange(fa,Dn.value)}},{flush:"post"}),{state:Nn,mergedData:Dn,componentStyle:sa,onFallbackScroll:ea,onScrollBar:ra,componentRef:Fn,useVirtual:Pn,calRes:qo,collectHeight:Go,setInstance:Gn,sharedConfig:Wn,scrollBarRef:Hn,fillerInnerRef:Bn,delayHideScrollBar:()=>{var fa;(fa=Hn.value)===null||fa===void 0||fa.delayHidden()}}},render(){const $n=_extends$1(_extends$1({},this.$props),this.$attrs),{prefixCls:Cn="rc-virtual-list",height:_n,itemHeight:Pn,fullHeight:In,data:Nn,itemKey:Rn,virtual:Dn,component:Ln="div",onScroll:Fn,children:Bn=this.$slots.default,style:Hn,class:zn}=$n,Wn=__rest$18($n,["prefixCls","height","itemHeight","fullHeight","data","itemKey","virtual","component","onScroll","children","style","class"]),Yn=classNames(Cn,zn),{scrollTop:Gn}=this.state,{scrollHeight:Go,offset:Xn,start:Yo,end:qo}=this.calRes,{componentStyle:Jo,onFallbackScroll:Zo,onScrollBar:rr,useVirtual:nr,collectHeight:ta,sharedConfig:oa,setInstance:ra,mergedData:ea,delayHideScrollBar:la}=this;return createVNode("div",_objectSpread2$1({style:_extends$1(_extends$1({},Hn),{position:"relative"}),class:Yn},Wn),[createVNode(Ln,{class:`${Cn}-holder`,style:Jo,ref:"componentRef",onScroll:Zo,onMouseenter:la},{default:()=>[createVNode(Filler,{prefixCls:Cn,height:Go,offset:Xn,onInnerResize:ta,ref:"fillerInnerRef"},{default:()=>renderChildren(ea,Yo,qo,ra,Bn,oa)})]}),nr&&createVNode(ScrollBar,{ref:"scrollBarRef",prefixCls:Cn,scrollTop:Gn,height:_n,scrollHeight:Go,count:ea.length,onScroll:rr,onStartMove:()=>{this.state.scrollMoving=!0},onStopMove:()=>{this.state.scrollMoving=!1}},null)])}}),List$4=List$3;function useMemo($n,Cn,_n){const Pn=ref($n());return watch(Cn,(In,Nn)=>{_n?_n(In,Nn)&&(Pn.value=$n()):Pn.value=$n()}),Pn}function isPlatformMac(){return/(mac\sos|macintosh)/i.test(navigator.appVersion)}const SelectContextKey=Symbol("SelectContextKey");function useProvideSelectProps($n){return provide(SelectContextKey,$n)}function useSelectProps(){return inject(SelectContextKey,{})}var __rest$17=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In`${In.prefixCls}-item`),Dn=useMemo(()=>Nn.flattenOptions,[()=>In.open,()=>Nn.flattenOptions],Zo=>Zo[0]),Ln=createRef(),Fn=Zo=>{Zo.preventDefault()},Bn=Zo=>{Ln.current&&Ln.current.scrollTo(typeof Zo=="number"?{index:Zo}:Zo)},Hn=function(Zo){let rr=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1;const nr=Dn.value.length;for(let ta=0;ta1&&arguments[1]!==void 0?arguments[1]:!1;zn.activeIndex=Zo;const nr={source:rr?"keyboard":"mouse"},ta=Dn.value[Zo];if(!ta){Nn.onActiveValue(null,-1,nr);return}Nn.onActiveValue(ta.value,Zo,nr)};watch([()=>Dn.value.length,()=>In.searchValue],()=>{Wn(Nn.defaultActiveFirstOption!==!1?Hn(0):-1)},{immediate:!0});const Yn=Zo=>Nn.rawValues.has(Zo)&&In.mode!=="combobox";watch([()=>In.open,()=>In.searchValue],()=>{if(!In.multiple&&In.open&&Nn.rawValues.size===1){const Zo=Array.from(Nn.rawValues)[0],rr=toRaw(Dn.value).findIndex(nr=>{let{data:ta}=nr;return ta[Nn.fieldNames.value]===Zo});rr!==-1&&(Wn(rr),nextTick(()=>{Bn(rr)}))}In.open&&nextTick(()=>{var Zo;(Zo=Ln.current)===null||Zo===void 0||Zo.scrollTo(void 0)})},{immediate:!0,flush:"post"});const Gn=Zo=>{Zo!==void 0&&Nn.onSelect(Zo,{selected:!Nn.rawValues.has(Zo)}),In.multiple||In.toggleOpen(!1)},Go=Zo=>typeof Zo.label=="function"?Zo.label():Zo.label;function Xn(Zo){const rr=Dn.value[Zo];if(!rr)return null;const nr=rr.data||{},{value:ta}=nr,{group:oa}=rr,ra=pickAttrs(nr,!0),ea=Go(rr);return rr?createVNode("div",_objectSpread2$1(_objectSpread2$1({"aria-label":typeof ea=="string"&&!oa?ea:null},ra),{},{key:Zo,role:oa?"presentation":"option",id:`${In.id}_list_${Zo}`,"aria-selected":Yn(ta)}),[ta]):null}return _n({onKeydown:Zo=>{const{which:rr,ctrlKey:nr}=Zo;switch(rr){case KeyCode$1.N:case KeyCode$1.P:case KeyCode$1.UP:case KeyCode$1.DOWN:{let ta=0;if(rr===KeyCode$1.UP?ta=-1:rr===KeyCode$1.DOWN?ta=1:isPlatformMac()&&nr&&(rr===KeyCode$1.N?ta=1:rr===KeyCode$1.P&&(ta=-1)),ta!==0){const oa=Hn(zn.activeIndex+ta,ta);Bn(oa),Wn(oa,!0)}break}case KeyCode$1.ENTER:{const ta=Dn.value[zn.activeIndex];ta&&!ta.data.disabled?Gn(ta.value):Gn(void 0),In.open&&Zo.preventDefault();break}case KeyCode$1.ESC:In.toggleOpen(!1),In.open&&Zo.stopPropagation()}},onKeyup:()=>{},scrollTo:Zo=>{Bn(Zo)}}),()=>{const{id:Zo,notFoundContent:rr,onPopupScroll:nr}=In,{menuItemSelectedIcon:ta,fieldNames:oa,virtual:ra,listHeight:ea,listItemHeight:la}=Nn,ua=Pn.option,{activeIndex:ga}=zn,aa=Object.keys(oa).map(ca=>oa[ca]);return Dn.value.length===0?createVNode("div",{role:"listbox",id:`${Zo}_list`,class:`${Rn.value}-empty`,onMousedown:Fn},[rr]):createVNode(Fragment,null,[createVNode("div",{role:"listbox",id:`${Zo}_list`,style:{height:0,width:0,overflow:"hidden"}},[Xn(ga-1),Xn(ga),Xn(ga+1)]),createVNode(List$4,{itemKey:"key",ref:Ln,data:Dn.value,height:ea,itemHeight:la,fullHeight:!1,onMousedown:Fn,onScroll:nr,virtual:ra},{default:(ca,sa)=>{var ia;const{group:fa,groupOption:ma,data:ya,value:ba}=ca,{key:Ia}=ya,Ea=typeof ca.label=="function"?ca.label():ca.label;if(fa){const Wa=(ia=ya.title)!==null&&ia!==void 0?ia:isTitleType(Ea)&&Ea;return createVNode("div",{class:classNames(Rn.value,`${Rn.value}-group`),title:Wa},[ua?ua(ya):Ea!==void 0?Ea:Ia])}const{disabled:xa,title:Ta,children:wa,style:La,class:Na,className:$a}=ya,ka=__rest$17(ya,["disabled","title","children","style","class","className"]),Ha=omit$1(ka,aa),da=Yn(ba),pa=`${Rn.value}-option`,Sa=classNames(Rn.value,pa,Na,$a,{[`${pa}-grouped`]:ma,[`${pa}-active`]:ga===sa&&!xa,[`${pa}-disabled`]:xa,[`${pa}-selected`]:da}),Aa=Go(ca),Ra=!ta||typeof ta=="function"||da,Fa=typeof Aa=="number"?Aa:Aa||ba;let za=isTitleType(Fa)?Fa.toString():void 0;return Ta!==void 0&&(za=Ta),createVNode("div",_objectSpread2$1(_objectSpread2$1({},Ha),{},{"aria-selected":da,class:Sa,title:za,onMousemove:Wa=>{ka.onMousemove&&ka.onMousemove(Wa),!(ga===sa||xa)&&Wn(sa)},onClick:Wa=>{xa||Gn(ba),ka.onClick&&ka.onClick(Wa)},style:La}),[createVNode("div",{class:`${pa}-content`},[ua?ua(ya):Fa]),isValidElement(ta)||da,Ra&&createVNode(TransBtn$1,{class:`${Rn.value}-option-state`,customizeIcon:ta,customizeIconProps:{isSelected:da}},{default:()=>[da?"✓":null]})])}})])}}}),OptionList$3=OptionList$2;var __rest$16=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In1&&arguments[1]!==void 0?arguments[1]:!1;return flattenChildren($n).map((Pn,In)=>{var Nn;if(!isValidElement(Pn)||!Pn.type)return null;const{type:{isSelectOptGroup:Rn},key:Dn,children:Ln,props:Fn}=Pn;if(Cn||!Rn)return convertNodeToOption(Pn);const Bn=Ln&&Ln.default?Ln.default():void 0,Hn=(Fn==null?void 0:Fn.label)||((Nn=Ln.label)===null||Nn===void 0?void 0:Nn.call(Ln))||Dn;return _extends$1(_extends$1({key:`__RC_SELECT_GRP__${Dn===null?In:String(Dn)}__`},Fn),{label:Hn,options:convertChildrenToData$1(Bn||[])})}).filter(Pn=>Pn)}function useOptions($n,Cn,_n){const Pn=shallowRef(),In=shallowRef(),Nn=shallowRef(),Rn=shallowRef([]);return watch([$n,Cn],()=>{$n.value?Rn.value=toRaw($n.value).slice():Rn.value=convertChildrenToData$1(Cn.value)},{immediate:!0,deep:!0}),watchEffect(()=>{const Dn=Rn.value,Ln=new Map,Fn=new Map,Bn=_n.value;function Hn(zn){let Wn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;for(let Yn=0;Yn0&&arguments[0]!==void 0?arguments[0]:ref("");const Cn=`rc_select_${getUUID$2()}`;return $n.value||Cn}function toArray$7($n){return Array.isArray($n)?$n:$n!==void 0?[$n]:[]}function includes($n,Cn){return toArray$7($n).join("").toUpperCase().includes(Cn)}const useFilterOptions=($n,Cn,_n,Pn,In)=>computed(()=>{const Nn=_n.value,Rn=In==null?void 0:In.value,Dn=Pn==null?void 0:Pn.value;if(!Nn||Dn===!1)return $n.value;const{options:Ln,label:Fn,value:Bn}=Cn.value,Hn=[],zn=typeof Dn=="function",Wn=Nn.toUpperCase(),Yn=zn?Dn:(Go,Xn)=>Rn?includes(Xn[Rn],Wn):Xn[Ln]?includes(Xn[Fn!=="children"?Fn:"label"],Wn):includes(Xn[Bn],Wn),Gn=zn?Go=>injectPropsWithOption(Go):Go=>Go;return $n.value.forEach(Go=>{if(Go[Ln]){if(Yn(Nn,Gn(Go)))Hn.push(Go);else{const Yo=Go[Ln].filter(qo=>Yn(Nn,Gn(qo)));Yo.length&&Hn.push(_extends$1(_extends$1({},Go),{[Ln]:Yo}))}return}Yn(Nn,Gn(Go))&&Hn.push(Go)}),Hn}),useCache$1=($n,Cn)=>{const _n=shallowRef({values:new Map,options:new Map});return[computed(()=>{const{values:Nn,options:Rn}=_n.value,Dn=$n.value.map(Bn=>{var Hn;return Bn.label===void 0?_extends$1(_extends$1({},Bn),{label:(Hn=Nn.get(Bn.value))===null||Hn===void 0?void 0:Hn.label}):Bn}),Ln=new Map,Fn=new Map;return Dn.forEach(Bn=>{Ln.set(Bn.value,Bn),Fn.set(Bn.value,Cn.value.get(Bn.value)||Rn.get(Bn.value))}),_n.value.values=Ln,_n.value.options=Fn,Dn}),Nn=>Cn.value.get(Nn)||_n.value.options.get(Nn)]};function useMergedState($n,Cn){const{defaultValue:_n,value:Pn=ref()}=Cn||{};let In=typeof $n=="function"?$n():$n;Pn.value!==void 0&&(In=unref(Pn)),_n!==void 0&&(In=typeof _n=="function"?_n():_n);const Nn=ref(In),Rn=ref(In);watchEffect(()=>{let Ln=Pn.value!==void 0?Pn.value:Nn.value;Cn.postState&&(Ln=Cn.postState(Ln)),Rn.value=Ln});function Dn(Ln){const Fn=Rn.value;Nn.value=Ln,toRaw(Rn.value)!==Ln&&Cn.onChange&&Cn.onChange(Ln,Fn)}return watch(Pn,()=>{Nn.value=Pn.value}),[Rn,Dn]}function useState($n){const Cn=typeof $n=="function"?$n():$n,_n=ref(Cn);function Pn(In){_n.value=In}return[_n,Pn]}const OMIT_DOM_PROPS=["inputValue"];function selectProps$1(){return _extends$1(_extends$1({},baseSelectPropsWithoutPrivate()),{prefixCls:String,id:String,backfill:{type:Boolean,default:void 0},fieldNames:Object,inputValue:String,searchValue:String,onSearch:Function,autoClearSearchValue:{type:Boolean,default:void 0},onSelect:Function,onDeselect:Function,filterOption:{type:[Boolean,Function],default:void 0},filterSort:Function,optionFilterProp:String,optionLabelProp:String,options:Array,defaultActiveFirstOption:{type:Boolean,default:void 0},virtual:{type:Boolean,default:void 0},listHeight:Number,listItemHeight:Number,menuItemSelectedIcon:PropTypes.any,mode:String,labelInValue:{type:Boolean,default:void 0},value:PropTypes.any,defaultValue:PropTypes.any,onChange:Function,children:Array})}function isRawValue$1($n){return!$n||typeof $n!="object"}const Select$1=defineComponent({compatConfig:{MODE:3},name:"VcSelect",inheritAttrs:!1,props:initDefaultProps(selectProps$1(),{prefixCls:"vc-select",autoClearSearchValue:!0,listHeight:200,listItemHeight:20,dropdownMatchSelectWidth:!0}),setup($n,Cn){let{expose:_n,attrs:Pn,slots:In}=Cn;const Nn=useId$1(toRef($n,"id")),Rn=computed(()=>isMultiple($n.mode)),Dn=computed(()=>!!(!$n.options&&$n.children)),Ln=computed(()=>$n.filterOption===void 0&&$n.mode==="combobox"?!1:$n.filterOption),Fn=computed(()=>fillFieldNames$3($n.fieldNames,Dn.value)),[Bn,Hn]=useMergedState("",{value:computed(()=>$n.searchValue!==void 0?$n.searchValue:$n.inputValue),postState:Na=>Na||""}),zn=useOptions(toRef($n,"options"),toRef($n,"children"),Fn),{valueOptions:Wn,labelOptions:Yn,options:Gn}=zn,Go=Na=>toArray$7(Na).map(ka=>{var Ha,da;let pa,Sa,Aa,Ra;isRawValue$1(ka)?pa=ka:(Aa=ka.key,Sa=ka.label,pa=(Ha=ka.value)!==null&&Ha!==void 0?Ha:Aa);const Fa=Wn.value.get(pa);return Fa&&(Sa===void 0&&(Sa=Fa==null?void 0:Fa[$n.optionLabelProp||Fn.value.label]),Aa===void 0&&(Aa=(da=Fa==null?void 0:Fa.key)!==null&&da!==void 0?da:pa),Ra=Fa==null?void 0:Fa.disabled),{label:Sa,value:pa,key:Aa,disabled:Ra,option:Fa}}),[Xn,Yo]=useMergedState($n.defaultValue,{value:toRef($n,"value")}),qo=computed(()=>{var Na;const $a=Go(Xn.value);return $n.mode==="combobox"&&!(!((Na=$a[0])===null||Na===void 0)&&Na.value)?[]:$a}),[Jo,Zo]=useCache$1(qo,Wn),rr=computed(()=>{if(!$n.mode&&Jo.value.length===1){const Na=Jo.value[0];if(Na.value===null&&(Na.label===null||Na.label===void 0))return[]}return Jo.value.map(Na=>{var $a;return _extends$1(_extends$1({},Na),{label:($a=typeof Na.label=="function"?Na.label():Na.label)!==null&&$a!==void 0?$a:Na.value})})}),nr=computed(()=>new Set(Jo.value.map(Na=>Na.value)));watchEffect(()=>{var Na;if($n.mode==="combobox"){const $a=(Na=Jo.value[0])===null||Na===void 0?void 0:Na.value;$a!=null&&Hn(String($a))}},{flush:"post"});const ta=(Na,$a)=>{const ka=$a??Na;return{[Fn.value.value]:Na,[Fn.value.label]:ka}},oa=shallowRef();watchEffect(()=>{if($n.mode!=="tags"){oa.value=Gn.value;return}const Na=Gn.value.slice(),$a=ka=>Wn.value.has(ka);[...Jo.value].sort((ka,Ha)=>ka.value{const Ha=ka.value;$a(Ha)||Na.push(ta(Ha,ka.label))}),oa.value=Na});const ra=useFilterOptions(oa,Fn,Bn,Ln,toRef($n,"optionFilterProp")),ea=computed(()=>$n.mode!=="tags"||!Bn.value||ra.value.some(Na=>Na[$n.optionFilterProp||"value"]===Bn.value)?ra.value:[ta(Bn.value),...ra.value]),la=computed(()=>$n.filterSort?[...ea.value].sort((Na,$a)=>$n.filterSort(Na,$a)):ea.value),ua=computed(()=>flattenOptions(la.value,{fieldNames:Fn.value,childrenAsData:Dn.value})),ga=Na=>{const $a=Go(Na);if(Yo($a),$n.onChange&&($a.length!==Jo.value.length||$a.some((ka,Ha)=>{var da;return((da=Jo.value[Ha])===null||da===void 0?void 0:da.value)!==(ka==null?void 0:ka.value)}))){const ka=$n.labelInValue?$a.map(da=>_extends$1(_extends$1({},da),{originLabel:da.label,label:typeof da.label=="function"?da.label():da.label})):$a.map(da=>da.value),Ha=$a.map(da=>injectPropsWithOption(Zo(da.value)));$n.onChange(Rn.value?ka:ka[0],Rn.value?Ha:Ha[0])}},[aa,ca]=useState(null),[sa,ia]=useState(0),fa=computed(()=>$n.defaultActiveFirstOption!==void 0?$n.defaultActiveFirstOption:$n.mode!=="combobox"),ma=function(Na,$a){let{source:ka="keyboard"}=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};ia($a),$n.backfill&&$n.mode==="combobox"&&Na!==null&&ka==="keyboard"&&ca(String(Na))},ya=(Na,$a)=>{const ka=()=>{var Ha;const da=Zo(Na),pa=da==null?void 0:da[Fn.value.label];return[$n.labelInValue?{label:typeof pa=="function"?pa():pa,originLabel:pa,value:Na,key:(Ha=da==null?void 0:da.key)!==null&&Ha!==void 0?Ha:Na}:Na,injectPropsWithOption(da)]};if($a&&$n.onSelect){const[Ha,da]=ka();$n.onSelect(Ha,da)}else if(!$a&&$n.onDeselect){const[Ha,da]=ka();$n.onDeselect(Ha,da)}},ba=(Na,$a)=>{let ka;const Ha=Rn.value?$a.selected:!0;Ha?ka=Rn.value?[...Jo.value,Na]:[Na]:ka=Jo.value.filter(da=>da.value!==Na),ga(ka),ya(Na,Ha),$n.mode==="combobox"?ca(""):(!Rn.value||$n.autoClearSearchValue)&&(Hn(""),ca(""))},Ia=(Na,$a)=>{ga(Na),($a.type==="remove"||$a.type==="clear")&&$a.values.forEach(ka=>{ya(ka.value,!1)})},Ea=(Na,$a)=>{var ka;if(Hn(Na),ca(null),$a.source==="submit"){const Ha=(Na||"").trim();if(Ha){const da=Array.from(new Set([...nr.value,Ha]));ga(da),ya(Ha,!0),Hn("")}return}$a.source!=="blur"&&($n.mode==="combobox"&&ga(Na),(ka=$n.onSearch)===null||ka===void 0||ka.call($n,Na))},xa=Na=>{let $a=Na;$n.mode!=="tags"&&($a=Na.map(Ha=>{const da=Yn.value.get(Ha);return da==null?void 0:da.value}).filter(Ha=>Ha!==void 0));const ka=Array.from(new Set([...nr.value,...$a]));ga(ka),ka.forEach(Ha=>{ya(Ha,!0)})},Ta=computed(()=>$n.virtual!==!1&&$n.dropdownMatchSelectWidth!==!1);useProvideSelectProps(toReactive(_extends$1(_extends$1({},zn),{flattenOptions:ua,onActiveValue:ma,defaultActiveFirstOption:fa,onSelect:ba,menuItemSelectedIcon:toRef($n,"menuItemSelectedIcon"),rawValues:nr,fieldNames:Fn,virtual:Ta,listHeight:toRef($n,"listHeight"),listItemHeight:toRef($n,"listItemHeight"),childrenAsData:Dn})));const wa=ref();_n({focus(){var Na;(Na=wa.value)===null||Na===void 0||Na.focus()},blur(){var Na;(Na=wa.value)===null||Na===void 0||Na.blur()},scrollTo(Na){var $a;($a=wa.value)===null||$a===void 0||$a.scrollTo(Na)}});const La=computed(()=>omit$1($n,["id","mode","prefixCls","backfill","fieldNames","inputValue","searchValue","onSearch","autoClearSearchValue","onSelect","onDeselect","dropdownMatchSelectWidth","filterOption","filterSort","optionFilterProp","optionLabelProp","options","children","defaultActiveFirstOption","menuItemSelectedIcon","virtual","listHeight","listItemHeight","value","defaultValue","labelInValue","onChange"]));return()=>createVNode(BaseSelect,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},La.value),Pn),{},{id:Nn,prefixCls:$n.prefixCls,ref:wa,omitDomProps:OMIT_DOM_PROPS,mode:$n.mode,displayValues:rr.value,onDisplayValuesChange:Ia,searchValue:Bn.value,onSearch:Ea,onSearchSplit:xa,dropdownMatchSelectWidth:$n.dropdownMatchSelectWidth,OptionList:OptionList$3,emptyOptions:!ua.value.length,activeValue:aa.value,activeDescendantId:`${Nn}_list_${sa.value}`}),In)}}),Option$2=()=>null;Option$2.isSelectOption=!0;Option$2.displayName="ASelectOption";const Option$3=Option$2,OptGroup$2=()=>null;OptGroup$2.isSelectOptGroup=!0;OptGroup$2.displayName="ASelectOptGroup";const OptGroup$3=OptGroup$2;var DownOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"}}]},name:"down",theme:"outlined"};const DownOutlinedSvg=DownOutlined$2;var contextKey$1=Symbol("iconContext"),useInjectIconContext=function(){return inject(contextKey$1,{prefixCls:ref("anticon"),rootClassName:ref(""),csp:ref()})};function canUseDom(){return!!(typeof window<"u"&&window.document&&window.document.createElement)}function contains$1($n,Cn){return $n&&$n.contains?$n.contains(Cn):!1}var APPEND_ORDER="data-vc-order",MARK_KEY="vc-icon-key",containerCache=new Map;function getMark(){var $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},Cn=$n.mark;return Cn?Cn.startsWith("data-")?Cn:"data-".concat(Cn):MARK_KEY}function getContainer$1($n){if($n.attachTo)return $n.attachTo;var Cn=document.querySelector("head");return Cn||document.body}function getOrder($n){return $n==="queue"?"prependQueue":$n?"prepend":"append"}function findStyles($n){return Array.from((containerCache.get($n)||$n).children).filter(function(Cn){return Cn.tagName==="STYLE"})}function injectCSS($n){var Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!canUseDom())return null;var _n=Cn.csp,Pn=Cn.prepend,In=document.createElement("style");In.setAttribute(APPEND_ORDER,getOrder(Pn)),_n&&_n.nonce&&(In.nonce=_n.nonce),In.innerHTML=$n;var Nn=getContainer$1(Cn),Rn=Nn.firstChild;if(Pn){if(Pn==="queue"){var Dn=findStyles(Nn).filter(function(Ln){return["prepend","prependQueue"].includes(Ln.getAttribute(APPEND_ORDER))});if(Dn.length)return Nn.insertBefore(In,Dn[Dn.length-1].nextSibling),In}Nn.insertBefore(In,Rn)}else Nn.appendChild(In);return In}function findExistNode($n){var Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_n=getContainer$1(Cn);return findStyles(_n).find(function(Pn){return Pn.getAttribute(getMark(Cn))===$n})}function syncRealContainer($n,Cn){var _n=containerCache.get($n);if(!_n||!contains$1(document,_n)){var Pn=injectCSS("",Cn),In=Pn.parentNode;containerCache.set($n,In),$n.removeChild(Pn)}}function updateCSS($n,Cn){var _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},Pn=getContainer$1(_n);syncRealContainer(Pn,_n);var In=findExistNode(Cn,_n);if(In)return _n.csp&&_n.csp.nonce&&In.nonce!==_n.csp.nonce&&(In.nonce=_n.csp.nonce),In.innerHTML!==$n&&(In.innerHTML=$n),In;var Nn=injectCSS($n,_n);return Nn.setAttribute(getMark(_n),Cn),Nn}function _objectSpread$W($n){for(var Cn=1;Cn * { - line-height: 1; -} - -.anticon svg { - display: inline-block; -} - -.anticon::before { - display: none; -} - -.anticon .anticon-icon { - display: block; -} - -.anticon[tabindex] { - cursor: pointer; -} - -.anticon-spin::before, -.anticon-spin { - display: inline-block; - -webkit-animation: loadingCircle 1s infinite linear; - animation: loadingCircle 1s infinite linear; -} - -@-webkit-keyframes loadingCircle { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes loadingCircle { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -`;function getRoot($n){return $n&&$n.getRootNode&&$n.getRootNode()}function inShadow($n){return canUseDom()?getRoot($n)instanceof ShadowRoot:!1}function getShadowRoot($n){return inShadow($n)?getRoot($n):null}var useInsertStyles=function(){var Cn=useInjectIconContext(),_n=Cn.prefixCls,Pn=Cn.csp,In=getCurrentInstance(),Nn=iconStyles;_n&&(Nn=Nn.replace(/anticon/g,_n.value)),nextTick(function(){if(canUseDom()){var Rn=In.vnode.el,Dn=getShadowRoot(Rn);updateCSS(Nn,"@ant-design-vue-icons",{prepend:!0,csp:Pn.value,attachTo:Dn})}})},_excluded$1=["icon","primaryColor","secondaryColor"];function _objectWithoutProperties$1($n,Cn){if($n==null)return{};var _n=_objectWithoutPropertiesLoose$1($n,Cn),Pn,In;if(Object.getOwnPropertySymbols){var Nn=Object.getOwnPropertySymbols($n);for(In=0;In=0)&&Object.prototype.propertyIsEnumerable.call($n,Pn)&&(_n[Pn]=$n[Pn])}return _n}function _objectWithoutPropertiesLoose$1($n,Cn){if($n==null)return{};var _n={},Pn=Object.keys($n),In,Nn;for(Nn=0;Nn=0)&&(_n[In]=$n[In]);return _n}function _objectSpread$V($n){for(var Cn=1;Cn$n.length)&&(Cn=$n.length);for(var _n=0,Pn=new Array(Cn);_n$n.length)&&(Cn=$n.length);for(var _n=0,Pn=new Array(Cn);_n=0)&&Object.prototype.propertyIsEnumerable.call($n,Pn)&&(_n[Pn]=$n[Pn])}return _n}function _objectWithoutPropertiesLoose($n,Cn){if($n==null)return{};var _n={},Pn=Object.keys($n),In,Nn;for(Nn=0;Nn=0)&&(_n[In]=$n[In]);return _n}setTwoToneColor(blue.primary);var Icon$1=function(Cn,_n){var Pn,In=_objectSpread$U({},Cn,_n.attrs),Nn=In.class,Rn=In.icon,Dn=In.spin,Ln=In.rotate,Fn=In.tabindex,Bn=In.twoToneColor,Hn=In.onClick,zn=_objectWithoutProperties(In,_excluded),Wn=useInjectIconContext(),Yn=Wn.prefixCls,Gn=Wn.rootClassName,Go=(Pn={},_defineProperty$U(Pn,Gn.value,!!Gn.value),_defineProperty$U(Pn,Yn.value,!0),_defineProperty$U(Pn,"".concat(Yn.value,"-").concat(Rn.name),!!Rn.name),_defineProperty$U(Pn,"".concat(Yn.value,"-spin"),!!Dn||Rn.name==="loading"),Pn),Xn=Fn;Xn===void 0&&Hn&&(Xn=-1);var Yo=Ln?{msTransform:"rotate(".concat(Ln,"deg)"),transform:"rotate(".concat(Ln,"deg)")}:void 0,qo=normalizeTwoToneColors(Bn),Jo=_slicedToArray(qo,2),Zo=Jo[0],rr=Jo[1];return createVNode("span",_objectSpread$U({role:"img","aria-label":Rn.name},zn,{onClick:Hn,class:[Go,Nn],tabindex:Xn}),[createVNode(VueIcon,{icon:Rn,primaryColor:Zo,secondaryColor:rr,style:Yo},null),createVNode(InsertStyles,null,null)])};Icon$1.props={spin:Boolean,rotate:Number,icon:Object,twoToneColor:[String,Array]};Icon$1.displayName="AntdIcon";Icon$1.inheritAttrs=!1;Icon$1.getTwoToneColor=getTwoToneColor;Icon$1.setTwoToneColor=setTwoToneColor;const AntdIcon=Icon$1;function _objectSpread$T($n){for(var Cn=1;Cn1&&arguments[1]!==void 0?arguments[1]:{};const{loading:_n,multiple:Pn,prefixCls:In,hasFeedback:Nn,feedbackIcon:Rn,showArrow:Dn}=$n,Ln=$n.suffixIcon||Cn.suffixIcon&&Cn.suffixIcon(),Fn=$n.clearIcon||Cn.clearIcon&&Cn.clearIcon(),Bn=$n.menuItemSelectedIcon||Cn.menuItemSelectedIcon&&Cn.menuItemSelectedIcon(),Hn=$n.removeIcon||Cn.removeIcon&&Cn.removeIcon(),zn=Fn??createVNode(CloseCircleFilled$1,null,null),Wn=Xn=>createVNode(Fragment,null,[Dn!==!1&&Xn,Nn&&Rn]);let Yn=null;if(Ln!==void 0)Yn=Wn(Ln);else if(_n)Yn=Wn(createVNode(LoadingOutlined$1,{spin:!0},null));else{const Xn=`${In}-suffix`;Yn=Yo=>{let{open:qo,showSearch:Jo}=Yo;return Wn(qo&&Jo?createVNode(SearchOutlined$1,{class:Xn},null):createVNode(DownOutlined$1,{class:Xn},null))}}let Gn=null;Bn!==void 0?Gn=Bn:Pn?Gn=createVNode(CheckOutlined$1,null,null):Gn=null;let Go=null;return Hn!==void 0?Go=Hn:Go=createVNode(CloseOutlined$1,null,null),{clearIcon:zn,suffixIcon:Yn,itemIcon:Gn,removeIcon:Go}}function createContext($n){const Cn=Symbol("contextKey");return{useProvide:(In,Nn)=>{const Rn=reactive({});return provide(Cn,Rn),watchEffect(()=>{_extends$1(Rn,In,Nn||{})}),Rn},useInject:()=>inject(Cn,$n)||{}}}const ContextKey$1=Symbol("ContextProps"),InternalContextKey=Symbol("InternalContextProps"),useProvideFormItemContext=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:computed(()=>!0);const _n=ref(new Map),Pn=(Nn,Rn)=>{_n.value.set(Nn,Rn),_n.value=new Map(_n.value)},In=Nn=>{_n.value.delete(Nn),_n.value=new Map(_n.value)};getCurrentInstance(),watch([Cn,_n],()=>{}),provide(ContextKey$1,$n),provide(InternalContextKey,{addFormItemField:Pn,removeFormItemField:In})},defaultContext={id:computed(()=>{}),onFieldBlur:()=>{},onFieldChange:()=>{},clearValidate:()=>{}},defaultInternalContext={addFormItemField:()=>{},removeFormItemField:()=>{}},useInjectFormItemContext=()=>{const $n=inject(InternalContextKey,defaultInternalContext),Cn=Symbol("FormItemFieldKey"),_n=getCurrentInstance();return $n.addFormItemField(Cn,_n.type),onBeforeUnmount(()=>{$n.removeFormItemField(Cn)}),provide(InternalContextKey,defaultInternalContext),provide(ContextKey$1,defaultContext),inject(ContextKey$1,defaultContext)},FormItemRest=defineComponent({compatConfig:{MODE:3},name:"AFormItemRest",setup($n,Cn){let{slots:_n}=Cn;return provide(InternalContextKey,defaultInternalContext),provide(ContextKey$1,defaultContext),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),FormItemInputContext=createContext({}),NoFormStatus=defineComponent({name:"NoFormStatus",setup($n,Cn){let{slots:_n}=Cn;return FormItemInputContext.useProvide({}),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}});function getStatusClassNames($n,Cn,_n){return classNames({[`${$n}-status-success`]:Cn==="success",[`${$n}-status-warning`]:Cn==="warning",[`${$n}-status-error`]:Cn==="error",[`${$n}-status-validating`]:Cn==="validating",[`${$n}-has-feedback`]:_n})}const getMergedStatus=($n,Cn)=>Cn||$n,genSpaceCompactStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{display:"inline-flex","&-block":{display:"flex",width:"100%"},"&-vertical":{flexDirection:"column"}}}},genSpaceCompactStyle$1=genSpaceCompactStyle,genSpaceStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{display:"inline-flex","&-rtl":{direction:"rtl"},"&-vertical":{flexDirection:"column"},"&-align":{flexDirection:"column","&-center":{alignItems:"center"},"&-start":{alignItems:"flex-start"},"&-end":{alignItems:"flex-end"},"&-baseline":{alignItems:"baseline"}},[`${Cn}-space-item`]:{"&:empty":{display:"none"}}}}},useStyle$W=genComponentStyleHook("Space",$n=>[genSpaceStyle($n),genSpaceCompactStyle$1($n)]);var symbolTag$2="[object Symbol]";function isSymbol($n){return typeof $n=="symbol"||isObjectLike($n)&&baseGetTag($n)==symbolTag$2}function arrayMap($n,Cn){for(var _n=-1,Pn=$n==null?0:$n.length,In=Array(Pn);++_n0){if(++Cn>=HOT_COUNT)return arguments[0]}else Cn=0;return $n.apply(void 0,arguments)}}function constant($n){return function(){return $n}}var defineProperty=function(){try{var $n=getNative(Object,"defineProperty");return $n({},"",{}),$n}catch{}}(),baseSetToString=defineProperty?function($n,Cn){return defineProperty($n,"toString",{configurable:!0,enumerable:!1,value:constant(Cn),writable:!0})}:identity;const baseSetToString$1=baseSetToString;var setToString=shortOut(baseSetToString$1);function arrayEach($n,Cn){for(var _n=-1,Pn=$n==null?0:$n.length;++_n-1}function baseAssignValue($n,Cn,_n){Cn=="__proto__"&&defineProperty?defineProperty($n,Cn,{configurable:!0,enumerable:!0,value:_n,writable:!0}):$n[Cn]=_n}var objectProto$4=Object.prototype,hasOwnProperty$5=objectProto$4.hasOwnProperty;function assignValue($n,Cn,_n){var Pn=$n[Cn];(!(hasOwnProperty$5.call($n,Cn)&&eq(Pn,_n))||_n===void 0&&!(Cn in $n))&&baseAssignValue($n,Cn,_n)}function copyObject($n,Cn,_n,Pn){var In=!_n;_n||(_n={});for(var Nn=-1,Rn=Cn.length;++Nn1?_n[In-1]:void 0,Rn=In>2?_n[2]:void 0;for(Nn=$n.length>3&&typeof Nn=="function"?(In--,Nn):void 0,Rn&&isIterateeCall(_n[0],_n[1],Rn)&&(Nn=In<3?void 0:Nn,In=1),Cn=Object(Cn);++Pn0&&_n(Dn)?Cn>1?baseFlatten(Dn,Cn-1,_n,Pn,In):arrayPush(In,Dn):Pn||(In[In.length]=Dn)}return In}function flatten($n){var Cn=$n==null?0:$n.length;return Cn?baseFlatten($n,1):[]}function flatRest($n){return setToString(overRest($n,void 0,flatten),$n+"")}var getPrototype=overArg(Object.getPrototypeOf,Object),objectTag$1="[object Object]",funcProto=Function.prototype,objectProto$2=Object.prototype,funcToString=funcProto.toString,hasOwnProperty$3=objectProto$2.hasOwnProperty,objectCtorString=funcToString.call(Object);function isPlainObject$2($n){if(!isObjectLike($n)||baseGetTag($n)!=objectTag$1)return!1;var Cn=getPrototype($n);if(Cn===null)return!0;var _n=hasOwnProperty$3.call(Cn,"constructor")&&Cn.constructor;return typeof _n=="function"&&_n instanceof _n&&funcToString.call(_n)==objectCtorString}function baseSlice($n,Cn,_n){var Pn=-1,In=$n.length;Cn<0&&(Cn=-Cn>In?0:In+Cn),_n=_n>In?In:_n,_n<0&&(_n+=In),In=Cn>_n?0:_n-Cn>>>0,Cn>>>=0;for(var Nn=Array(In);++Pn=Cn||nr<0||Hn&&ta>=Nn}function Xn(){var rr=now$3();if(Go(rr))return Yo(rr);Dn=setTimeout(Xn,Gn(rr))}function Yo(rr){return Dn=void 0,zn&&Pn?Wn(rr):(Pn=In=void 0,Rn)}function qo(){Dn!==void 0&&clearTimeout(Dn),Fn=0,Pn=Ln=In=Dn=void 0}function Jo(){return Dn===void 0?Rn:Yo(now$3())}function Zo(){var rr=now$3(),nr=Go(rr);if(Pn=arguments,In=this,Ln=rr,nr){if(Dn===void 0)return Yn(Ln);if(Hn)return clearTimeout(Dn),Dn=setTimeout(Xn,Cn),Wn(Ln)}return Dn===void 0&&(Dn=setTimeout(Xn,Cn)),Rn}return Zo.cancel=qo,Zo.flush=Jo,Zo}function assignMergeValue($n,Cn,_n){(_n!==void 0&&!eq($n[Cn],_n)||_n===void 0&&!(Cn in $n))&&baseAssignValue($n,Cn,_n)}function isArrayLikeObject($n){return isObjectLike($n)&&isArrayLike($n)}function safeGet($n,Cn){if(!(Cn==="constructor"&&typeof $n[Cn]=="function")&&Cn!="__proto__")return $n[Cn]}function toPlainObject($n){return copyObject($n,keysIn($n))}function baseMergeDeep($n,Cn,_n,Pn,In,Nn,Rn){var Dn=safeGet($n,_n),Ln=safeGet(Cn,_n),Fn=Rn.get(Ln);if(Fn){assignMergeValue($n,_n,Fn);return}var Bn=Nn?Nn(Dn,Ln,_n+"",$n,Cn,Rn):void 0,Hn=Bn===void 0;if(Hn){var zn=isArray$2(Ln),Wn=!zn&&isBuffer(Ln),Yn=!zn&&!Wn&&isTypedArray$1(Ln);Bn=Ln,zn||Wn||Yn?isArray$2(Dn)?Bn=Dn:isArrayLikeObject(Dn)?Bn=copyArray(Dn):Wn?(Hn=!1,Bn=cloneBuffer(Ln,!0)):Yn?(Hn=!1,Bn=cloneTypedArray(Ln,!0)):Bn=[]:isPlainObject$2(Ln)||isArguments(Ln)?(Bn=Dn,isArguments(Dn)?Bn=toPlainObject(Dn):(!isObject$5(Dn)||isFunction$1(Dn))&&(Bn=initCloneObject(Ln))):Hn=!1}Hn&&(Rn.set(Ln,Bn),In(Bn,Ln,Pn,Nn,Rn),Rn.delete(Ln)),assignMergeValue($n,_n,Bn)}function baseMerge($n,Cn,_n,Pn,In){$n!==Cn&&baseFor(Cn,function(Nn,Rn){if(In||(In=new Stack),isObject$5(Nn))baseMergeDeep($n,Cn,Rn,_n,baseMerge,Pn,In);else{var Dn=Pn?Pn(safeGet($n,Rn),Nn,Rn+"",$n,Cn,In):void 0;Dn===void 0&&(Dn=Nn),assignMergeValue($n,Rn,Dn)}},keysIn)}function arrayIncludesWith($n,Cn,_n){for(var Pn=-1,In=$n==null?0:$n.length;++Pn-1?In[Nn?Cn[Rn]:Rn]:void 0}}var nativeMax=Math.max;function findIndex($n,Cn,_n){var Pn=$n==null?0:$n.length;if(!Pn)return-1;var In=_n==null?0:toInteger(_n);return In<0&&(In=nativeMax(Pn+In,0)),baseFindIndex($n,baseIteratee(Cn),In)}var find=createFind(findIndex);function fromPairs($n){for(var Cn=-1,_n=$n==null?0:$n.length,Pn={};++Cn<_n;){var In=$n[Cn];Pn[In[0]]=In[1]}return Pn}var nativeMin=Math.min;function baseIntersection($n,Cn,_n){for(var Pn=_n?arrayIncludesWith:arrayIncludes,In=$n[0].length,Nn=$n.length,Rn=Nn,Dn=Array(Nn),Ln=1/0,Fn=[];Rn--;){var Bn=$n[Rn];Rn&&Cn&&(Bn=arrayMap(Bn,baseUnary(Cn))),Ln=nativeMin(Bn.length,Ln),Dn[Rn]=!_n&&(Cn||In>=120&&Bn.length>=120)?new SetCache(Rn&&Bn):void 0}Bn=$n[0];var Hn=-1,zn=Dn[0];e:for(;++Hn1),Nn}),copyObject($n,getAllKeysIn($n),_n),Pn&&(_n=baseClone(_n,CLONE_DEEP_FLAG|CLONE_FLAT_FLAG|CLONE_SYMBOLS_FLAG,customOmitClone));for(var In=Cn.length;In--;)baseUnset(_n,Cn[In]);return _n});function baseSet($n,Cn,_n,Pn){if(!isObject$5($n))return $n;Cn=castPath(Cn,$n);for(var In=-1,Nn=Cn.length,Rn=Nn-1,Dn=$n;Dn!=null&&++In=LARGE_ARRAY_SIZE){var Fn=Cn?null:createSet($n);if(Fn)return setToArray(Fn);Rn=!1,In=cacheHas,Ln=new SetCache}else Ln=Cn?[]:Dn;e:for(;++Pn({compactSize:String,compactDirection:PropTypes.oneOf(tuple$1("horizontal","vertical")).def("horizontal"),isFirstItem:booleanType(),isLastItem:booleanType()}),SpaceCompactItemContext=createContext(null),useCompactItemContext=($n,Cn)=>{const _n=SpaceCompactItemContext.useInject(),Pn=computed(()=>{if(!_n||isEmpty$1(_n))return"";const{compactDirection:In,isFirstItem:Nn,isLastItem:Rn}=_n,Dn=In==="vertical"?"-vertical-":"-";return classNames({[`${$n.value}-compact${Dn}item`]:!0,[`${$n.value}-compact${Dn}first-item`]:Nn,[`${$n.value}-compact${Dn}last-item`]:Rn,[`${$n.value}-compact${Dn}item-rtl`]:Cn.value==="rtl"})});return{compactSize:computed(()=>_n==null?void 0:_n.compactSize),compactDirection:computed(()=>_n==null?void 0:_n.compactDirection),compactItemClassnames:Pn}},NoCompactStyle=defineComponent({name:"NoCompactStyle",setup($n,Cn){let{slots:_n}=Cn;return SpaceCompactItemContext.useProvide(null),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),spaceCompactProps=()=>({prefixCls:String,size:{type:String},direction:PropTypes.oneOf(tuple$1("horizontal","vertical")).def("horizontal"),align:PropTypes.oneOf(tuple$1("start","end","center","baseline")),block:{type:Boolean,default:void 0}}),CompactItem=defineComponent({name:"CompactItem",props:spaceCompactItemProps(),setup($n,Cn){let{slots:_n}=Cn;return SpaceCompactItemContext.useProvide($n),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),Compact=defineComponent({name:"ASpaceCompact",inheritAttrs:!1,props:spaceCompactProps(),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("space-compact",$n),Rn=SpaceCompactItemContext.useInject(),[Dn,Ln]=useStyle$W(In),Fn=computed(()=>classNames(In.value,Ln.value,{[`${In.value}-rtl`]:Nn.value==="rtl",[`${In.value}-block`]:$n.block,[`${In.value}-vertical`]:$n.direction==="vertical"}));return()=>{var Bn;const Hn=flattenChildren(((Bn=Pn.default)===null||Bn===void 0?void 0:Bn.call(Pn))||[]);return Hn.length===0?null:Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{class:[Fn.value,_n.class]}),[Hn.map((zn,Wn)=>{var Yn;const Gn=zn&&zn.key||`${In.value}-item-${Wn}`,Go=!Rn||isEmpty$1(Rn);return createVNode(CompactItem,{key:Gn,compactSize:(Yn=$n.size)!==null&&Yn!==void 0?Yn:"middle",compactDirection:$n.direction,isFirstItem:Wn===0&&(Go||(Rn==null?void 0:Rn.isFirstItem)),isLastItem:Wn===Hn.length-1&&(Go||(Rn==null?void 0:Rn.isLastItem))},{default:()=>[zn]})})]))}}}),Compact$1=Compact,initMotionCommon=$n=>({animationDuration:$n,animationFillMode:"both"}),initMotionCommonLeave=$n=>({animationDuration:$n,animationFillMode:"both"}),initMotion=function($n,Cn,_n,Pn){const Nn=(arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1)?"&":"";return{[` - ${Nn}${$n}-enter, - ${Nn}${$n}-appear - `]:_extends$1(_extends$1({},initMotionCommon(Pn)),{animationPlayState:"paused"}),[`${Nn}${$n}-leave`]:_extends$1(_extends$1({},initMotionCommonLeave(Pn)),{animationPlayState:"paused"}),[` - ${Nn}${$n}-enter${$n}-enter-active, - ${Nn}${$n}-appear${$n}-appear-active - `]:{animationName:Cn,animationPlayState:"running"},[`${Nn}${$n}-leave${$n}-leave-active`]:{animationName:_n,animationPlayState:"running",pointerEvents:"none"}}},fadeIn=new Keyframes("antFadeIn",{"0%":{opacity:0},"100%":{opacity:1}}),fadeOut=new Keyframes("antFadeOut",{"0%":{opacity:1},"100%":{opacity:0}}),initFadeMotion=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const{antCls:_n}=$n,Pn=`${_n}-fade`,In=Cn?"&":"";return[initMotion(Pn,fadeIn,fadeOut,$n.motionDurationMid,Cn),{[` - ${In}${Pn}-enter, - ${In}${Pn}-appear - `]:{opacity:0,animationTimingFunction:"linear"},[`${In}${Pn}-leave`]:{animationTimingFunction:"linear"}}]},moveDownIn=new Keyframes("antMoveDownIn",{"0%":{transform:"translate3d(0, 100%, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),moveDownOut=new Keyframes("antMoveDownOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(0, 100%, 0)",transformOrigin:"0 0",opacity:0}}),moveLeftIn=new Keyframes("antMoveLeftIn",{"0%":{transform:"translate3d(-100%, 0, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),moveLeftOut=new Keyframes("antMoveLeftOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(-100%, 0, 0)",transformOrigin:"0 0",opacity:0}}),moveRightIn=new Keyframes("antMoveRightIn",{"0%":{transform:"translate3d(100%, 0, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),moveRightOut=new Keyframes("antMoveRightOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(100%, 0, 0)",transformOrigin:"0 0",opacity:0}}),moveUpIn=new Keyframes("antMoveUpIn",{"0%":{transform:"translate3d(0, -100%, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),moveUpOut=new Keyframes("antMoveUpOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(0, -100%, 0)",transformOrigin:"0 0",opacity:0}}),moveMotion={"move-up":{inKeyframes:moveUpIn,outKeyframes:moveUpOut},"move-down":{inKeyframes:moveDownIn,outKeyframes:moveDownOut},"move-left":{inKeyframes:moveLeftIn,outKeyframes:moveLeftOut},"move-right":{inKeyframes:moveRightIn,outKeyframes:moveRightOut}},initMoveMotion=($n,Cn)=>{const{antCls:_n}=$n,Pn=`${_n}-${Cn}`,{inKeyframes:In,outKeyframes:Nn}=moveMotion[Cn];return[initMotion(Pn,In,Nn,$n.motionDurationMid),{[` - ${Pn}-enter, - ${Pn}-appear - `]:{opacity:0,animationTimingFunction:$n.motionEaseOutCirc},[`${Pn}-leave`]:{animationTimingFunction:$n.motionEaseInOutCirc}}]},slideUpIn=new Keyframes("antSlideUpIn",{"0%":{transform:"scaleY(0.8)",transformOrigin:"0% 0%",opacity:0},"100%":{transform:"scaleY(1)",transformOrigin:"0% 0%",opacity:1}}),slideUpOut=new Keyframes("antSlideUpOut",{"0%":{transform:"scaleY(1)",transformOrigin:"0% 0%",opacity:1},"100%":{transform:"scaleY(0.8)",transformOrigin:"0% 0%",opacity:0}}),slideDownIn=new Keyframes("antSlideDownIn",{"0%":{transform:"scaleY(0.8)",transformOrigin:"100% 100%",opacity:0},"100%":{transform:"scaleY(1)",transformOrigin:"100% 100%",opacity:1}}),slideDownOut=new Keyframes("antSlideDownOut",{"0%":{transform:"scaleY(1)",transformOrigin:"100% 100%",opacity:1},"100%":{transform:"scaleY(0.8)",transformOrigin:"100% 100%",opacity:0}}),slideLeftIn=new Keyframes("antSlideLeftIn",{"0%":{transform:"scaleX(0.8)",transformOrigin:"0% 0%",opacity:0},"100%":{transform:"scaleX(1)",transformOrigin:"0% 0%",opacity:1}}),slideLeftOut=new Keyframes("antSlideLeftOut",{"0%":{transform:"scaleX(1)",transformOrigin:"0% 0%",opacity:1},"100%":{transform:"scaleX(0.8)",transformOrigin:"0% 0%",opacity:0}}),slideRightIn=new Keyframes("antSlideRightIn",{"0%":{transform:"scaleX(0.8)",transformOrigin:"100% 0%",opacity:0},"100%":{transform:"scaleX(1)",transformOrigin:"100% 0%",opacity:1}}),slideRightOut=new Keyframes("antSlideRightOut",{"0%":{transform:"scaleX(1)",transformOrigin:"100% 0%",opacity:1},"100%":{transform:"scaleX(0.8)",transformOrigin:"100% 0%",opacity:0}}),slideMotion={"slide-up":{inKeyframes:slideUpIn,outKeyframes:slideUpOut},"slide-down":{inKeyframes:slideDownIn,outKeyframes:slideDownOut},"slide-left":{inKeyframes:slideLeftIn,outKeyframes:slideLeftOut},"slide-right":{inKeyframes:slideRightIn,outKeyframes:slideRightOut}},initSlideMotion=($n,Cn)=>{const{antCls:_n}=$n,Pn=`${_n}-${Cn}`,{inKeyframes:In,outKeyframes:Nn}=slideMotion[Cn];return[initMotion(Pn,In,Nn,$n.motionDurationMid),{[` - ${Pn}-enter, - ${Pn}-appear - `]:{transform:"scale(0)",transformOrigin:"0% 0%",opacity:0,animationTimingFunction:$n.motionEaseOutQuint},[`${Pn}-leave`]:{animationTimingFunction:$n.motionEaseInQuint}}]},zoomIn=new Keyframes("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),zoomOut=new Keyframes("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),zoomBigIn=new Keyframes("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),zoomBigOut=new Keyframes("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),zoomUpIn=new Keyframes("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),zoomUpOut=new Keyframes("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),zoomLeftIn=new Keyframes("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),zoomLeftOut=new Keyframes("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),zoomRightIn=new Keyframes("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),zoomRightOut=new Keyframes("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),zoomDownIn=new Keyframes("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),zoomDownOut=new Keyframes("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),zoomMotion={zoom:{inKeyframes:zoomIn,outKeyframes:zoomOut},"zoom-big":{inKeyframes:zoomBigIn,outKeyframes:zoomBigOut},"zoom-big-fast":{inKeyframes:zoomBigIn,outKeyframes:zoomBigOut},"zoom-left":{inKeyframes:zoomLeftIn,outKeyframes:zoomLeftOut},"zoom-right":{inKeyframes:zoomRightIn,outKeyframes:zoomRightOut},"zoom-up":{inKeyframes:zoomUpIn,outKeyframes:zoomUpOut},"zoom-down":{inKeyframes:zoomDownIn,outKeyframes:zoomDownOut}},initZoomMotion=($n,Cn)=>{const{antCls:_n}=$n,Pn=`${_n}-${Cn}`,{inKeyframes:In,outKeyframes:Nn}=zoomMotion[Cn];return[initMotion(Pn,In,Nn,Cn==="zoom-big-fast"?$n.motionDurationFast:$n.motionDurationMid),{[` - ${Pn}-enter, - ${Pn}-appear - `]:{transform:"scale(0)",opacity:0,animationTimingFunction:$n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${Pn}-leave`]:{animationTimingFunction:$n.motionEaseInOutCirc}}]},genCollapseMotion=$n=>({[$n.componentCls]:{[`${$n.antCls}-motion-collapse-legacy`]:{overflow:"hidden","&-active":{transition:`height ${$n.motionDurationMid} ${$n.motionEaseInOut}, - opacity ${$n.motionDurationMid} ${$n.motionEaseInOut} !important`}},[`${$n.antCls}-motion-collapse`]:{overflow:"hidden",transition:`height ${$n.motionDurationMid} ${$n.motionEaseInOut}, - opacity ${$n.motionDurationMid} ${$n.motionEaseInOut} !important`}}}),genCollapseMotion$1=genCollapseMotion,genItemStyle=$n=>{const{controlPaddingHorizontal:Cn}=$n;return{position:"relative",display:"block",minHeight:$n.controlHeight,padding:`${($n.controlHeight-$n.fontSize*$n.lineHeight)/2}px ${Cn}px`,color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize,lineHeight:$n.lineHeight,boxSizing:"border-box"}},genSingleStyle$1=$n=>{const{antCls:Cn,componentCls:_n}=$n,Pn=`${_n}-item`;return[{[`${_n}-dropdown`]:_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:-9999,zIndex:$n.zIndexPopup,boxSizing:"border-box",padding:$n.paddingXXS,overflow:"hidden",fontSize:$n.fontSize,fontVariant:"initial",backgroundColor:$n.colorBgElevated,borderRadius:$n.borderRadiusLG,outline:"none",boxShadow:$n.boxShadowSecondary,[` - &${Cn}-slide-up-enter${Cn}-slide-up-enter-active${_n}-dropdown-placement-bottomLeft, - &${Cn}-slide-up-appear${Cn}-slide-up-appear-active${_n}-dropdown-placement-bottomLeft - `]:{animationName:slideUpIn},[` - &${Cn}-slide-up-enter${Cn}-slide-up-enter-active${_n}-dropdown-placement-topLeft, - &${Cn}-slide-up-appear${Cn}-slide-up-appear-active${_n}-dropdown-placement-topLeft - `]:{animationName:slideDownIn},[`&${Cn}-slide-up-leave${Cn}-slide-up-leave-active${_n}-dropdown-placement-bottomLeft`]:{animationName:slideUpOut},[`&${Cn}-slide-up-leave${Cn}-slide-up-leave-active${_n}-dropdown-placement-topLeft`]:{animationName:slideDownOut},"&-hidden":{display:"none"},"&-empty":{color:$n.colorTextDisabled},[`${Pn}-empty`]:_extends$1(_extends$1({},genItemStyle($n)),{color:$n.colorTextDisabled}),[`${Pn}`]:_extends$1(_extends$1({},genItemStyle($n)),{cursor:"pointer",transition:`background ${$n.motionDurationSlow} ease`,borderRadius:$n.borderRadiusSM,"&-group":{color:$n.colorTextDescription,fontSize:$n.fontSizeSM,cursor:"default"},"&-option":{display:"flex","&-content":_extends$1({flex:"auto"},textEllipsis),"&-state":{flex:"none"},[`&-active:not(${Pn}-option-disabled)`]:{backgroundColor:$n.controlItemBgHover},[`&-selected:not(${Pn}-option-disabled)`]:{color:$n.colorText,fontWeight:$n.fontWeightStrong,backgroundColor:$n.controlItemBgActive,[`${Pn}-option-state`]:{color:$n.colorPrimary}},"&-disabled":{[`&${Pn}-option-selected`]:{backgroundColor:$n.colorBgContainerDisabled},color:$n.colorTextDisabled,cursor:"not-allowed"},"&-grouped":{paddingInlineStart:$n.controlPaddingHorizontal*2}}}),"&-rtl":{direction:"rtl"}})},initSlideMotion($n,"slide-up"),initSlideMotion($n,"slide-down"),initMoveMotion($n,"move-up"),initMoveMotion($n,"move-down")]},genDropdownStyle$1=genSingleStyle$1,FIXED_ITEM_MARGIN=2;function getSelectItemStyle($n){let{controlHeightSM:Cn,controlHeight:_n,lineWidth:Pn}=$n;const In=(_n-Cn)/2-Pn,Nn=Math.ceil(In/2);return[In,Nn]}function genSizeStyle$4($n,Cn){const{componentCls:_n,iconCls:Pn}=$n,In=`${_n}-selection-overflow`,Nn=$n.controlHeightSM,[Rn]=getSelectItemStyle($n),Dn=Cn?`${_n}-${Cn}`:"";return{[`${_n}-multiple${Dn}`]:{fontSize:$n.fontSize,[In]:{position:"relative",display:"flex",flex:"auto",flexWrap:"wrap",maxWidth:"100%","&-item":{flex:"none",alignSelf:"center",maxWidth:"100%",display:"inline-flex"}},[`${_n}-selector`]:{display:"flex",flexWrap:"wrap",alignItems:"center",padding:`${Rn-FIXED_ITEM_MARGIN}px ${FIXED_ITEM_MARGIN*2}px`,borderRadius:$n.borderRadius,[`${_n}-show-search&`]:{cursor:"text"},[`${_n}-disabled&`]:{background:$n.colorBgContainerDisabled,cursor:"not-allowed"},"&:after":{display:"inline-block",width:0,margin:`${FIXED_ITEM_MARGIN}px 0`,lineHeight:`${Nn}px`,content:'"\\a0"'}},[` - &${_n}-show-arrow ${_n}-selector, - &${_n}-allow-clear ${_n}-selector - `]:{paddingInlineEnd:$n.fontSizeIcon+$n.controlPaddingHorizontal},[`${_n}-selection-item`]:{position:"relative",display:"flex",flex:"none",boxSizing:"border-box",maxWidth:"100%",height:Nn,marginTop:FIXED_ITEM_MARGIN,marginBottom:FIXED_ITEM_MARGIN,lineHeight:`${Nn-$n.lineWidth*2}px`,background:$n.colorFillSecondary,border:`${$n.lineWidth}px solid ${$n.colorSplit}`,borderRadius:$n.borderRadiusSM,cursor:"default",transition:`font-size ${$n.motionDurationSlow}, line-height ${$n.motionDurationSlow}, height ${$n.motionDurationSlow}`,userSelect:"none",marginInlineEnd:FIXED_ITEM_MARGIN*2,paddingInlineStart:$n.paddingXS,paddingInlineEnd:$n.paddingXS/2,[`${_n}-disabled&`]:{color:$n.colorTextDisabled,borderColor:$n.colorBorder,cursor:"not-allowed"},"&-content":{display:"inline-block",marginInlineEnd:$n.paddingXS/2,overflow:"hidden",whiteSpace:"pre",textOverflow:"ellipsis"},"&-remove":_extends$1(_extends$1({},resetIcon()),{display:"inline-block",color:$n.colorIcon,fontWeight:"bold",fontSize:10,lineHeight:"inherit",cursor:"pointer",[`> ${Pn}`]:{verticalAlign:"-0.2em"},"&:hover":{color:$n.colorIconHover}})},[`${In}-item + ${In}-item`]:{[`${_n}-selection-search`]:{marginInlineStart:0}},[`${_n}-selection-search`]:{display:"inline-flex",position:"relative",maxWidth:"100%",marginInlineStart:$n.inputPaddingHorizontalBase-Rn,"\n &-input,\n &-mirror\n ":{height:Nn,fontFamily:$n.fontFamily,lineHeight:`${Nn}px`,transition:`all ${$n.motionDurationSlow}`},"&-input":{width:"100%",minWidth:4.1},"&-mirror":{position:"absolute",top:0,insetInlineStart:0,insetInlineEnd:"auto",zIndex:999,whiteSpace:"pre",visibility:"hidden"}},[`${_n}-selection-placeholder `]:{position:"absolute",top:"50%",insetInlineStart:$n.inputPaddingHorizontalBase,insetInlineEnd:$n.inputPaddingHorizontalBase,transform:"translateY(-50%)",transition:`all ${$n.motionDurationSlow}`}}}}function genMultipleStyle($n){const{componentCls:Cn}=$n,_n=merge$1($n,{controlHeight:$n.controlHeightSM,controlHeightSM:$n.controlHeightXS,borderRadius:$n.borderRadiusSM,borderRadiusSM:$n.borderRadiusXS}),[,Pn]=getSelectItemStyle($n);return[genSizeStyle$4($n),genSizeStyle$4(_n,"sm"),{[`${Cn}-multiple${Cn}-sm`]:{[`${Cn}-selection-placeholder`]:{insetInlineStart:$n.controlPaddingHorizontalSM-$n.lineWidth,insetInlineEnd:"auto"},[`${Cn}-selection-search`]:{marginInlineStart:Pn}}},genSizeStyle$4(merge$1($n,{fontSize:$n.fontSizeLG,controlHeight:$n.controlHeightLG,controlHeightSM:$n.controlHeight,borderRadius:$n.borderRadiusLG,borderRadiusSM:$n.borderRadius}),"lg")]}function genSizeStyle$3($n,Cn){const{componentCls:_n,inputPaddingHorizontalBase:Pn,borderRadius:In}=$n,Nn=$n.controlHeight-$n.lineWidth*2,Rn=Math.ceil($n.fontSize*1.25),Dn=Cn?`${_n}-${Cn}`:"";return{[`${_n}-single${Dn}`]:{fontSize:$n.fontSize,[`${_n}-selector`]:_extends$1(_extends$1({},resetComponent($n)),{display:"flex",borderRadius:In,[`${_n}-selection-search`]:{position:"absolute",top:0,insetInlineStart:Pn,insetInlineEnd:Pn,bottom:0,"&-input":{width:"100%"}},[` - ${_n}-selection-item, - ${_n}-selection-placeholder - `]:{padding:0,lineHeight:`${Nn}px`,transition:`all ${$n.motionDurationSlow}`,"@supports (-moz-appearance: meterbar)":{lineHeight:`${Nn}px`}},[`${_n}-selection-item`]:{position:"relative",userSelect:"none"},[`${_n}-selection-placeholder`]:{transition:"none",pointerEvents:"none"},[["&:after",`${_n}-selection-item:after`,`${_n}-selection-placeholder:after`].join(",")]:{display:"inline-block",width:0,visibility:"hidden",content:'"\\a0"'}}),[` - &${_n}-show-arrow ${_n}-selection-item, - &${_n}-show-arrow ${_n}-selection-placeholder - `]:{paddingInlineEnd:Rn},[`&${_n}-open ${_n}-selection-item`]:{color:$n.colorTextPlaceholder},[`&:not(${_n}-customize-input)`]:{[`${_n}-selector`]:{width:"100%",height:$n.controlHeight,padding:`0 ${Pn}px`,[`${_n}-selection-search-input`]:{height:Nn},"&:after":{lineHeight:`${Nn}px`}}},[`&${_n}-customize-input`]:{[`${_n}-selector`]:{"&:after":{display:"none"},[`${_n}-selection-search`]:{position:"static",width:"100%"},[`${_n}-selection-placeholder`]:{position:"absolute",insetInlineStart:0,insetInlineEnd:0,padding:`0 ${Pn}px`,"&:after":{display:"none"}}}}}}}function genSingleStyle($n){const{componentCls:Cn}=$n,_n=$n.controlPaddingHorizontalSM-$n.lineWidth;return[genSizeStyle$3($n),genSizeStyle$3(merge$1($n,{controlHeight:$n.controlHeightSM,borderRadius:$n.borderRadiusSM}),"sm"),{[`${Cn}-single${Cn}-sm`]:{[`&:not(${Cn}-customize-input)`]:{[`${Cn}-selection-search`]:{insetInlineStart:_n,insetInlineEnd:_n},[`${Cn}-selector`]:{padding:`0 ${_n}px`},[`&${Cn}-show-arrow ${Cn}-selection-search`]:{insetInlineEnd:_n+$n.fontSize*1.5},[` - &${Cn}-show-arrow ${Cn}-selection-item, - &${Cn}-show-arrow ${Cn}-selection-placeholder - `]:{paddingInlineEnd:$n.fontSize*1.5}}}},genSizeStyle$3(merge$1($n,{controlHeight:$n.controlHeightLG,fontSize:$n.fontSizeLG,borderRadius:$n.borderRadiusLG}),"lg")]}function compactItemBorder($n,Cn,_n){const{focusElCls:Pn,focus:In,borderElCls:Nn}=_n,Rn=Nn?"> *":"",Dn=["hover",In?"focus":null,"active"].filter(Boolean).map(Ln=>`&:${Ln} ${Rn}`).join(",");return{[`&-item:not(${Cn}-last-item)`]:{marginInlineEnd:-$n.lineWidth},"&-item":_extends$1(_extends$1({[Dn]:{zIndex:2}},Pn?{[`&${Pn}`]:{zIndex:2}}:{}),{[`&[disabled] ${Rn}`]:{zIndex:0}})}}function compactItemBorderRadius($n,Cn,_n){const{borderElCls:Pn}=_n,In=Pn?`> ${Pn}`:"";return{[`&-item:not(${Cn}-first-item):not(${Cn}-last-item) ${In}`]:{borderRadius:0},[`&-item:not(${Cn}-last-item)${Cn}-first-item`]:{[`& ${In}, &${$n}-sm ${In}, &${$n}-lg ${In}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`&-item:not(${Cn}-first-item)${Cn}-last-item`]:{[`& ${In}, &${$n}-sm ${In}, &${$n}-lg ${In}`]:{borderStartStartRadius:0,borderEndStartRadius:0}}}}function genCompactItemStyle($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{focus:!0};const{componentCls:_n}=$n,Pn=`${_n}-compact`;return{[Pn]:_extends$1(_extends$1({},compactItemBorder($n,Pn,Cn)),compactItemBorderRadius(_n,Pn,Cn))}}const genSelectorStyle=$n=>{const{componentCls:Cn}=$n;return{position:"relative",backgroundColor:$n.colorBgContainer,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,transition:`all ${$n.motionDurationMid} ${$n.motionEaseInOut}`,input:{cursor:"pointer"},[`${Cn}-show-search&`]:{cursor:"text",input:{cursor:"auto",color:"inherit"}},[`${Cn}-disabled&`]:{color:$n.colorTextDisabled,background:$n.colorBgContainerDisabled,cursor:"not-allowed",[`${Cn}-multiple&`]:{background:$n.colorBgContainerDisabled},input:{cursor:"not-allowed"}}}},genStatusStyle$3=function($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;const{componentCls:Pn,borderHoverColor:In,outlineColor:Nn,antCls:Rn}=Cn,Dn=_n?{[`${Pn}-selector`]:{borderColor:In}}:{};return{[$n]:{[`&:not(${Pn}-disabled):not(${Pn}-customize-input):not(${Rn}-pagination-size-changer)`]:_extends$1(_extends$1({},Dn),{[`${Pn}-focused& ${Pn}-selector`]:{borderColor:In,boxShadow:`0 0 0 ${Cn.controlOutlineWidth}px ${Nn}`,borderInlineEndWidth:`${Cn.controlLineWidth}px !important`,outline:0},[`&:hover ${Pn}-selector`]:{borderColor:In,borderInlineEndWidth:`${Cn.controlLineWidth}px !important`}})}}},getSearchInputWithoutBorderStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-selection-search-input`]:{margin:0,padding:0,background:"transparent",border:"none",outline:"none",appearance:"none","&::-webkit-search-cancel-button":{display:"none","-webkit-appearance":"none"}}}},genBaseStyle$j=$n=>{const{componentCls:Cn,inputPaddingHorizontalBase:_n,iconCls:Pn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-block",cursor:"pointer",[`&:not(${Cn}-customize-input) ${Cn}-selector`]:_extends$1(_extends$1({},genSelectorStyle($n)),getSearchInputWithoutBorderStyle($n)),[`${Cn}-selection-item`]:_extends$1({flex:1,fontWeight:"normal"},textEllipsis),[`${Cn}-selection-placeholder`]:_extends$1(_extends$1({},textEllipsis),{flex:1,color:$n.colorTextPlaceholder,pointerEvents:"none"}),[`${Cn}-arrow`]:_extends$1(_extends$1({},resetIcon()),{position:"absolute",top:"50%",insetInlineStart:"auto",insetInlineEnd:_n,height:$n.fontSizeIcon,marginTop:-$n.fontSizeIcon/2,color:$n.colorTextQuaternary,fontSize:$n.fontSizeIcon,lineHeight:1,textAlign:"center",pointerEvents:"none",display:"flex",alignItems:"center",[Pn]:{verticalAlign:"top",transition:`transform ${$n.motionDurationSlow}`,"> svg":{verticalAlign:"top"},[`&:not(${Cn}-suffix)`]:{pointerEvents:"auto"}},[`${Cn}-disabled &`]:{cursor:"not-allowed"},"> *:not(:last-child)":{marginInlineEnd:8}}),[`${Cn}-clear`]:{position:"absolute",top:"50%",insetInlineStart:"auto",insetInlineEnd:_n,zIndex:1,display:"inline-block",width:$n.fontSizeIcon,height:$n.fontSizeIcon,marginTop:-$n.fontSizeIcon/2,color:$n.colorTextQuaternary,fontSize:$n.fontSizeIcon,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",background:$n.colorBgContainer,cursor:"pointer",opacity:0,transition:`color ${$n.motionDurationMid} ease, opacity ${$n.motionDurationSlow} ease`,textRendering:"auto","&:before":{display:"block"},"&:hover":{color:$n.colorTextTertiary}},"&:hover":{[`${Cn}-clear`]:{opacity:1}}}),[`${Cn}-has-feedback`]:{[`${Cn}-clear`]:{insetInlineEnd:_n+$n.fontSize+$n.paddingXXS}}}},genSelectStyle=$n=>{const{componentCls:Cn}=$n;return[{[Cn]:{[`&-borderless ${Cn}-selector`]:{backgroundColor:"transparent !important",borderColor:"transparent !important",boxShadow:"none !important"},[`&${Cn}-in-form-item`]:{width:"100%"}}},genBaseStyle$j($n),genSingleStyle($n),genMultipleStyle($n),genDropdownStyle$1($n),{[`${Cn}-rtl`]:{direction:"rtl"}},genStatusStyle$3(Cn,merge$1($n,{borderHoverColor:$n.colorPrimaryHover,outlineColor:$n.controlOutline})),genStatusStyle$3(`${Cn}-status-error`,merge$1($n,{borderHoverColor:$n.colorErrorHover,outlineColor:$n.colorErrorOutline}),!0),genStatusStyle$3(`${Cn}-status-warning`,merge$1($n,{borderHoverColor:$n.colorWarningHover,outlineColor:$n.colorWarningOutline}),!0),genCompactItemStyle($n,{borderElCls:`${Cn}-selector`,focusElCls:`${Cn}-focused`})]},useSelectStyle=genComponentStyleHook("Select",($n,Cn)=>{let{rootPrefixCls:_n}=Cn;const Pn=merge$1($n,{rootPrefixCls:_n,inputPaddingHorizontalBase:$n.paddingSM-1});return[genSelectStyle(Pn)]},$n=>({zIndexPopup:$n.zIndexPopupBase+50})),selectProps=()=>_extends$1(_extends$1({},omit$1(selectProps$1(),["inputIcon","mode","getInputElement","getRawInputElement","backfill"])),{value:someType([Array,Object,String,Number]),defaultValue:someType([Array,Object,String,Number]),notFoundContent:PropTypes.any,suffixIcon:PropTypes.any,itemIcon:PropTypes.any,size:stringType(),mode:stringType(),bordered:booleanType(!0),transitionName:String,choiceTransitionName:stringType(""),popupClassName:String,dropdownClassName:String,placement:stringType(),status:stringType(),"onUpdate:value":functionType()}),SECRET_COMBOBOX_MODE_DO_NOT_USE="SECRET_COMBOBOX_MODE_DO_NOT_USE",Select=defineComponent({compatConfig:{MODE:3},name:"ASelect",Option:Option$3,OptGroup:OptGroup$3,inheritAttrs:!1,props:initDefaultProps(selectProps(),{listHeight:256,listItemHeight:24}),SECRET_COMBOBOX_MODE_DO_NOT_USE,slots:Object,setup($n,Cn){let{attrs:_n,emit:Pn,slots:In,expose:Nn}=Cn;const Rn=ref(),Dn=useInjectFormItemContext(),Ln=FormItemInputContext.useInject(),Fn=computed(()=>getMergedStatus(Ln.status,$n.status)),Bn=()=>{var ba;(ba=Rn.value)===null||ba===void 0||ba.focus()},Hn=()=>{var ba;(ba=Rn.value)===null||ba===void 0||ba.blur()},zn=ba=>{var Ia;(Ia=Rn.value)===null||Ia===void 0||Ia.scrollTo(ba)},Wn=computed(()=>{const{mode:ba}=$n;if(ba!=="combobox")return ba===SECRET_COMBOBOX_MODE_DO_NOT_USE?"combobox":ba}),{prefixCls:Yn,direction:Gn,configProvider:Go,renderEmpty:Xn,size:Yo,getPrefixCls:qo,getPopupContainer:Jo,disabled:Zo,select:rr}=useConfigInject("select",$n),{compactSize:nr,compactItemClassnames:ta}=useCompactItemContext(Yn,Gn),oa=computed(()=>nr.value||Yo.value),ra=useInjectDisabled(),ea=computed(()=>{var ba;return(ba=Zo.value)!==null&&ba!==void 0?ba:ra.value}),[la,ua]=useSelectStyle(Yn),ga=computed(()=>qo()),aa=computed(()=>$n.placement!==void 0?$n.placement:Gn.value==="rtl"?"bottomRight":"bottomLeft"),ca=computed(()=>getTransitionName$1(ga.value,getTransitionDirection(aa.value),$n.transitionName)),sa=computed(()=>classNames({[`${Yn.value}-lg`]:oa.value==="large",[`${Yn.value}-sm`]:oa.value==="small",[`${Yn.value}-rtl`]:Gn.value==="rtl",[`${Yn.value}-borderless`]:!$n.bordered,[`${Yn.value}-in-form-item`]:Ln.isFormItemInput},getStatusClassNames(Yn.value,Fn.value,Ln.hasFeedback),ta.value,ua.value)),ia=function(){for(var ba=arguments.length,Ia=new Array(ba),Ea=0;Ea{Pn("blur",ba),Dn.onFieldBlur()};Nn({blur:Hn,focus:Bn,scrollTo:zn});const ma=computed(()=>Wn.value==="multiple"||Wn.value==="tags"),ya=computed(()=>$n.showArrow!==void 0?$n.showArrow:$n.loading||!(ma.value||Wn.value==="combobox"));return()=>{var ba,Ia,Ea,xa;const{notFoundContent:Ta,listHeight:wa=256,listItemHeight:La=24,popupClassName:Na,dropdownClassName:$a,virtual:ka,dropdownMatchSelectWidth:Ha,id:da=Dn.id.value,placeholder:pa=(ba=In.placeholder)===null||ba===void 0?void 0:ba.call(In),showArrow:Sa}=$n,{hasFeedback:Aa,feedbackIcon:Ra}=Ln;let Fa;Ta!==void 0?Fa=Ta:In.notFoundContent?Fa=In.notFoundContent():Wn.value==="combobox"?Fa=null:Fa=(Xn==null?void 0:Xn("Select"))||createVNode(DefaultRenderEmpty,{componentName:"Select"},null);const{suffixIcon:za,itemIcon:Wa,removeIcon:Ya,clearIcon:ja}=getIcons(_extends$1(_extends$1({},$n),{multiple:ma.value,prefixCls:Yn.value,hasFeedback:Aa,feedbackIcon:Ra,showArrow:ya.value}),In),qa=omit$1($n,["prefixCls","suffixIcon","itemIcon","removeIcon","clearIcon","size","bordered","status"]),Xa=classNames(Na||$a,{[`${Yn.value}-dropdown-${Gn.value}`]:Gn.value==="rtl"},ua.value);return la(createVNode(Select$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Rn,virtual:ka,dropdownMatchSelectWidth:Ha},qa),_n),{},{showSearch:(Ia=$n.showSearch)!==null&&Ia!==void 0?Ia:(Ea=rr==null?void 0:rr.value)===null||Ea===void 0?void 0:Ea.showSearch,placeholder:pa,listHeight:wa,listItemHeight:La,mode:Wn.value,prefixCls:Yn.value,direction:Gn.value,inputIcon:za,menuItemSelectedIcon:Wa,removeIcon:Ya,clearIcon:ja,notFoundContent:Fa,class:[sa.value,_n.class],getPopupContainer:Jo==null?void 0:Jo.value,dropdownClassName:Xa,onChange:ia,onBlur:fa,id:da,dropdownRender:qa.dropdownRender||In.dropdownRender,transitionName:ca.value,children:(xa=In.default)===null||xa===void 0?void 0:xa.call(In),tagRender:$n.tagRender||In.tagRender,optionLabelRender:In.optionLabel,maxTagPlaceholder:$n.maxTagPlaceholder||In.maxTagPlaceholder,showArrow:Aa||Sa,disabled:ea.value}),{option:In.option}))}}});Select.install=function($n){return $n.component(Select.name,Select),$n.component(Select.Option.displayName,Select.Option),$n.component(Select.OptGroup.displayName,Select.OptGroup),$n};const SelectOption=Select.Option,SelectOptGroup=Select.OptGroup,VcSelect=Select,Option=()=>null;Option.isSelectOption=!0;Option.displayName="AAutoCompleteOption";const Option$1=Option,OptGroup=()=>null;OptGroup.isSelectOptGroup=!0;OptGroup.displayName="AAutoCompleteOptGroup";const OptGroup$1=OptGroup;function isSelectOptionOrSelectOptGroup($n){var Cn,_n;return((Cn=$n==null?void 0:$n.type)===null||Cn===void 0?void 0:Cn.isSelectOption)||((_n=$n==null?void 0:$n.type)===null||_n===void 0?void 0:_n.isSelectOptGroup)}const autoCompleteProps=()=>_extends$1(_extends$1({},omit$1(selectProps(),["loading","mode","optionLabelProp","labelInValue"])),{dataSource:Array,dropdownMenuStyle:{type:Object,default:void 0},dropdownMatchSelectWidth:{type:[Number,Boolean],default:!0},prefixCls:String,showSearch:{type:Boolean,default:void 0},transitionName:String,choiceTransitionName:{type:String,default:"zoom"},autofocus:{type:Boolean,default:void 0},backfill:{type:Boolean,default:void 0},filterOption:{type:[Boolean,Function],default:!1},defaultActiveFirstOption:{type:Boolean,default:!0},status:String}),AutoCompleteOption=Option$1,AutoCompleteOptGroup=OptGroup$1,AutoComplete=defineComponent({compatConfig:{MODE:3},name:"AAutoComplete",inheritAttrs:!1,props:autoCompleteProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;warning$3(),warning$3(),warning$3(!$n.dropdownClassName);const Nn=ref(),Rn=()=>{var Bn;const Hn=flattenChildren((Bn=_n.default)===null||Bn===void 0?void 0:Bn.call(_n));return Hn.length?Hn[0]:void 0};In({focus:()=>{var Bn;(Bn=Nn.value)===null||Bn===void 0||Bn.focus()},blur:()=>{var Bn;(Bn=Nn.value)===null||Bn===void 0||Bn.blur()}});const{prefixCls:Fn}=useConfigInject("select",$n);return()=>{var Bn,Hn,zn;const{size:Wn,dataSource:Yn,notFoundContent:Gn=(Bn=_n.notFoundContent)===null||Bn===void 0?void 0:Bn.call(_n)}=$n;let Go;const{class:Xn}=Pn,Yo={[Xn]:!!Xn,[`${Fn.value}-lg`]:Wn==="large",[`${Fn.value}-sm`]:Wn==="small",[`${Fn.value}-show-search`]:!0,[`${Fn.value}-auto-complete`]:!0};if($n.options===void 0){const Jo=((Hn=_n.dataSource)===null||Hn===void 0?void 0:Hn.call(_n))||((zn=_n.options)===null||zn===void 0?void 0:zn.call(_n))||[];Jo.length&&isSelectOptionOrSelectOptGroup(Jo[0])?Go=Jo:Go=Yn?Yn.map(Zo=>{if(isValidElement(Zo))return Zo;switch(typeof Zo){case"string":return createVNode(Option$1,{key:Zo,value:Zo},{default:()=>[Zo]});case"object":return createVNode(Option$1,{key:Zo.value,value:Zo.value},{default:()=>[Zo.text]});default:throw new Error("AutoComplete[dataSource] only supports type `string[] | Object[]`.")}}):[]}const qo=omit$1(_extends$1(_extends$1(_extends$1({},$n),Pn),{mode:VcSelect.SECRET_COMBOBOX_MODE_DO_NOT_USE,getInputElement:Rn,notFoundContent:Gn,class:Yo,popupClassName:$n.popupClassName||$n.dropdownClassName,ref:Nn}),["dataSource","loading"]);return createVNode(VcSelect,qo,_objectSpread2$1({default:()=>[Go]},omit$1(_n,["default","dataSource","options"])))}}}),index$s=_extends$1(AutoComplete,{Option:Option$1,OptGroup:OptGroup$1,install($n){return $n.component(AutoComplete.name,AutoComplete),$n.component(Option$1.displayName,Option$1),$n.component(OptGroup$1.displayName,OptGroup$1),$n}});var CheckCircleOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"check-circle",theme:"outlined"};const CheckCircleOutlinedSvg=CheckCircleOutlined$2;function _objectSpread$N($n){for(var Cn=1;Cn({backgroundColor:$n,border:`${Pn.lineWidth}px ${Pn.lineType} ${Cn}`,[`${In}-icon`]:{color:_n}}),genBaseStyle$i=$n=>{const{componentCls:Cn,motionDurationSlow:_n,marginXS:Pn,marginSM:In,fontSize:Nn,fontSizeLG:Rn,lineHeight:Dn,borderRadiusLG:Ln,motionEaseInOutCirc:Fn,alertIconSizeLG:Bn,colorText:Hn,paddingContentVerticalSM:zn,alertPaddingHorizontal:Wn,paddingMD:Yn,paddingContentHorizontalLG:Gn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"flex",alignItems:"center",padding:`${zn}px ${Wn}px`,wordWrap:"break-word",borderRadius:Ln,[`&${Cn}-rtl`]:{direction:"rtl"},[`${Cn}-content`]:{flex:1,minWidth:0},[`${Cn}-icon`]:{marginInlineEnd:Pn,lineHeight:0},"&-description":{display:"none",fontSize:Nn,lineHeight:Dn},"&-message":{color:Hn},[`&${Cn}-motion-leave`]:{overflow:"hidden",opacity:1,transition:`max-height ${_n} ${Fn}, opacity ${_n} ${Fn}, - padding-top ${_n} ${Fn}, padding-bottom ${_n} ${Fn}, - margin-bottom ${_n} ${Fn}`},[`&${Cn}-motion-leave-active`]:{maxHeight:0,marginBottom:"0 !important",paddingTop:0,paddingBottom:0,opacity:0}}),[`${Cn}-with-description`]:{alignItems:"flex-start",paddingInline:Gn,paddingBlock:Yn,[`${Cn}-icon`]:{marginInlineEnd:In,fontSize:Bn,lineHeight:0},[`${Cn}-message`]:{display:"block",marginBottom:Pn,color:Hn,fontSize:Rn},[`${Cn}-description`]:{display:"block"}},[`${Cn}-banner`]:{marginBottom:0,border:"0 !important",borderRadius:0}}},genTypeStyle=$n=>{const{componentCls:Cn,colorSuccess:_n,colorSuccessBorder:Pn,colorSuccessBg:In,colorWarning:Nn,colorWarningBorder:Rn,colorWarningBg:Dn,colorError:Ln,colorErrorBorder:Fn,colorErrorBg:Bn,colorInfo:Hn,colorInfoBorder:zn,colorInfoBg:Wn}=$n;return{[Cn]:{"&-success":genAlertTypeStyle(In,Pn,_n,$n,Cn),"&-info":genAlertTypeStyle(Wn,zn,Hn,$n,Cn),"&-warning":genAlertTypeStyle(Dn,Rn,Nn,$n,Cn),"&-error":_extends$1(_extends$1({},genAlertTypeStyle(Bn,Fn,Ln,$n,Cn)),{[`${Cn}-description > pre`]:{margin:0,padding:0}})}}},genActionStyle=$n=>{const{componentCls:Cn,iconCls:_n,motionDurationMid:Pn,marginXS:In,fontSizeIcon:Nn,colorIcon:Rn,colorIconHover:Dn}=$n;return{[Cn]:{"&-action":{marginInlineStart:In},[`${Cn}-close-icon`]:{marginInlineStart:In,padding:0,overflow:"hidden",fontSize:Nn,lineHeight:`${Nn}px`,backgroundColor:"transparent",border:"none",outline:"none",cursor:"pointer",[`${_n}-close`]:{color:Rn,transition:`color ${Pn}`,"&:hover":{color:Dn}}},"&-close-text":{color:Rn,transition:`color ${Pn}`,"&:hover":{color:Dn}}}}},genAlertStyle=$n=>[genBaseStyle$i($n),genTypeStyle($n),genActionStyle($n)],useStyle$V=genComponentStyleHook("Alert",$n=>{const{fontSizeHeading3:Cn}=$n,_n=merge$1($n,{alertIconSizeLG:Cn,alertPaddingHorizontal:12});return[genAlertStyle(_n)]}),iconMapFilled={success:CheckCircleFilled$1,info:InfoCircleFilled$1,error:CloseCircleFilled$1,warning:ExclamationCircleFilled$1},iconMapOutlined={success:CheckCircleOutlined$1,info:InfoCircleOutlined$1,error:CloseCircleOutlined$1,warning:ExclamationCircleOutlined$1},AlertTypes=tuple$1("success","info","warning","error"),alertProps=()=>({type:PropTypes.oneOf(AlertTypes),closable:{type:Boolean,default:void 0},closeText:PropTypes.any,message:PropTypes.any,description:PropTypes.any,afterClose:Function,showIcon:{type:Boolean,default:void 0},prefixCls:String,banner:{type:Boolean,default:void 0},icon:PropTypes.any,closeIcon:PropTypes.any,onClose:Function}),Alert=defineComponent({compatConfig:{MODE:3},name:"AAlert",inheritAttrs:!1,props:alertProps(),setup($n,Cn){let{slots:_n,emit:Pn,attrs:In,expose:Nn}=Cn;const{prefixCls:Rn,direction:Dn}=useConfigInject("alert",$n),[Ln,Fn]=useStyle$V(Rn),Bn=shallowRef(!1),Hn=shallowRef(!1),zn=shallowRef(),Wn=Xn=>{Xn.preventDefault();const Yo=zn.value;Yo.style.height=`${Yo.offsetHeight}px`,Yo.style.height=`${Yo.offsetHeight}px`,Bn.value=!0,Pn("close",Xn)},Yn=()=>{var Xn;Bn.value=!1,Hn.value=!0,(Xn=$n.afterClose)===null||Xn===void 0||Xn.call($n)},Gn=computed(()=>{const{type:Xn}=$n;return Xn!==void 0?Xn:$n.banner?"warning":"info"});Nn({animationEnd:Yn});const Go=shallowRef({});return()=>{var Xn,Yo,qo,Jo,Zo,rr,nr,ta,oa,ra;const{banner:ea,closeIcon:la=(Xn=_n.closeIcon)===null||Xn===void 0?void 0:Xn.call(_n)}=$n;let{closable:ua,showIcon:ga}=$n;const aa=(Yo=$n.closeText)!==null&&Yo!==void 0?Yo:(qo=_n.closeText)===null||qo===void 0?void 0:qo.call(_n),ca=(Jo=$n.description)!==null&&Jo!==void 0?Jo:(Zo=_n.description)===null||Zo===void 0?void 0:Zo.call(_n),sa=(rr=$n.message)!==null&&rr!==void 0?rr:(nr=_n.message)===null||nr===void 0?void 0:nr.call(_n),ia=(ta=$n.icon)!==null&&ta!==void 0?ta:(oa=_n.icon)===null||oa===void 0?void 0:oa.call(_n),fa=(ra=_n.action)===null||ra===void 0?void 0:ra.call(_n);ga=ea&&ga===void 0?!0:ga;const ma=(ca?iconMapOutlined:iconMapFilled)[Gn.value]||null;aa&&(ua=!0);const ya=Rn.value,ba=classNames(ya,{[`${ya}-${Gn.value}`]:!0,[`${ya}-closing`]:Bn.value,[`${ya}-with-description`]:!!ca,[`${ya}-no-icon`]:!ga,[`${ya}-banner`]:!!ea,[`${ya}-closable`]:ua,[`${ya}-rtl`]:Dn.value==="rtl",[Fn.value]:!0}),Ia=ua?createVNode("button",{type:"button",onClick:Wn,class:`${ya}-close-icon`,tabindex:0},[aa?createVNode("span",{class:`${ya}-close-text`},[aa]):la===void 0?createVNode(CloseOutlined$1,null,null):la]):null,Ea=ia&&(isValidElement(ia)?cloneElement(ia,{class:`${ya}-icon`}):createVNode("span",{class:`${ya}-icon`},[ia]))||createVNode(ma,{class:`${ya}-icon`},null),xa=getTransitionProps(`${ya}-motion`,{appear:!1,css:!0,onAfterLeave:Yn,onBeforeLeave:Ta=>{Ta.style.maxHeight=`${Ta.offsetHeight}px`},onLeave:Ta=>{Ta.style.maxHeight="0px"}});return Ln(Hn.value?null:createVNode(Transition,xa,{default:()=>[withDirectives(createVNode("div",_objectSpread2$1(_objectSpread2$1({role:"alert"},In),{},{style:[In.style,Go.value],class:[In.class,ba],"data-show":!Bn.value,ref:zn}),[ga?Ea:null,createVNode("div",{class:`${ya}-content`},[sa?createVNode("div",{class:`${ya}-message`},[sa]):null,ca?createVNode("div",{class:`${ya}-description`},[ca]):null]),fa?createVNode("div",{class:`${ya}-action`},[fa]):null,Ia]),[[vShow,!Bn.value]])]}))}}}),index$r=withInstall(Alert),responsiveArray=["xxxl","xxl","xl","lg","md","sm","xs"],getResponsiveMap=$n=>({xs:`(max-width: ${$n.screenXSMax}px)`,sm:`(min-width: ${$n.screenSM}px)`,md:`(min-width: ${$n.screenMD}px)`,lg:`(min-width: ${$n.screenLG}px)`,xl:`(min-width: ${$n.screenXL}px)`,xxl:`(min-width: ${$n.screenXXL}px)`,xxxl:`{min-width: ${$n.screenXXXL}px}`});function useResponsiveObserver(){const[,$n]=useToken();return computed(()=>{const Cn=getResponsiveMap($n.value),_n=new Map;let Pn=-1,In={};return{matchHandlers:{},dispatch(Nn){return In=Nn,_n.forEach(Rn=>Rn(In)),_n.size>=1},subscribe(Nn){return _n.size||this.register(),Pn+=1,_n.set(Pn,Nn),Nn(In),Pn},unsubscribe(Nn){_n.delete(Nn),_n.size||this.unregister()},unregister(){Object.keys(Cn).forEach(Nn=>{const Rn=Cn[Nn],Dn=this.matchHandlers[Rn];Dn==null||Dn.mql.removeListener(Dn==null?void 0:Dn.listener)}),_n.clear()},register(){Object.keys(Cn).forEach(Nn=>{const Rn=Cn[Nn],Dn=Fn=>{let{matches:Bn}=Fn;this.dispatch(_extends$1(_extends$1({},In),{[Nn]:Bn}))},Ln=window.matchMedia(Rn);Ln.addListener(Dn),this.matchHandlers[Rn]={mql:Ln,listener:Dn},Dn(Ln)})},responsiveMap:Cn}})}function useBreakpoint(){const $n=shallowRef({});let Cn=null;const _n=useResponsiveObserver();return onMounted(()=>{Cn=_n.value.subscribe(Pn=>{$n.value=Pn})}),onUnmounted(()=>{_n.value.unsubscribe(Cn)}),$n}function eagerComputed($n){const Cn=shallowRef();return watchEffect(()=>{Cn.value=$n()},{flush:"sync"}),Cn}const genBaseStyle$h=$n=>{const{antCls:Cn,componentCls:_n,iconCls:Pn,avatarBg:In,avatarColor:Nn,containerSize:Rn,containerSizeLG:Dn,containerSizeSM:Ln,textFontSize:Fn,textFontSizeLG:Bn,textFontSizeSM:Hn,borderRadius:zn,borderRadiusLG:Wn,borderRadiusSM:Yn,lineWidth:Gn,lineType:Go}=$n,Xn=(Yo,qo,Jo)=>({width:Yo,height:Yo,lineHeight:`${Yo-Gn*2}px`,borderRadius:"50%",[`&${_n}-square`]:{borderRadius:Jo},[`${_n}-string`]:{position:"absolute",left:{_skip_check_:!0,value:"50%"},transformOrigin:"0 center"},[`&${_n}-icon`]:{fontSize:qo,[`> ${Pn}`]:{margin:0}}});return{[_n]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-block",overflow:"hidden",color:Nn,whiteSpace:"nowrap",textAlign:"center",verticalAlign:"middle",background:In,border:`${Gn}px ${Go} transparent`,"&-image":{background:"transparent"},[`${Cn}-image-img`]:{display:"block"}}),Xn(Rn,Fn,zn)),{"&-lg":_extends$1({},Xn(Dn,Bn,Wn)),"&-sm":_extends$1({},Xn(Ln,Hn,Yn)),"> img":{display:"block",width:"100%",height:"100%",objectFit:"cover"}})}},genGroupStyle$3=$n=>{const{componentCls:Cn,groupBorderColor:_n,groupOverlapping:Pn,groupSpace:In}=$n;return{[`${Cn}-group`]:{display:"inline-flex",[`${Cn}`]:{borderColor:_n},"> *:not(:first-child)":{marginInlineStart:Pn}},[`${Cn}-group-popover`]:{[`${Cn} + ${Cn}`]:{marginInlineStart:In}}}},useStyle$U=genComponentStyleHook("Avatar",$n=>{const{colorTextLightSolid:Cn,colorTextPlaceholder:_n}=$n,Pn=merge$1($n,{avatarBg:_n,avatarColor:Cn});return[genBaseStyle$h(Pn),genGroupStyle$3(Pn)]},$n=>{const{controlHeight:Cn,controlHeightLG:_n,controlHeightSM:Pn,fontSize:In,fontSizeLG:Nn,fontSizeXL:Rn,fontSizeHeading3:Dn,marginXS:Ln,marginXXS:Fn,colorBorderBg:Bn}=$n;return{containerSize:Cn,containerSizeLG:_n,containerSizeSM:Pn,textFontSize:Math.round((Nn+Rn)/2),textFontSizeLG:Dn,textFontSizeSM:In,groupSpace:Fn,groupOverlapping:-Ln,groupBorderColor:Bn}}),AvatarContextKey=Symbol("AvatarContextKey"),useAvatarInjectContext=()=>inject(AvatarContextKey,{}),useAvatarProviderContext=$n=>provide(AvatarContextKey,$n),avatarProps$1=()=>({prefixCls:String,shape:{type:String,default:"circle"},size:{type:[Number,String,Object],default:()=>"default"},src:String,srcset:String,icon:PropTypes.any,alt:String,gap:Number,draggable:{type:Boolean,default:void 0},crossOrigin:String,loadError:{type:Function}}),Avatar=defineComponent({compatConfig:{MODE:3},name:"AAvatar",inheritAttrs:!1,props:avatarProps$1(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=shallowRef(!0),Nn=shallowRef(!1),Rn=shallowRef(1),Dn=shallowRef(null),Ln=shallowRef(null),{prefixCls:Fn}=useConfigInject("avatar",$n),[Bn,Hn]=useStyle$U(Fn),zn=useAvatarInjectContext(),Wn=computed(()=>$n.size==="default"?zn.size:$n.size),Yn=useBreakpoint(),Gn=eagerComputed(()=>{if(typeof $n.size!="object")return;const qo=responsiveArray.find(Zo=>Yn.value[Zo]);return $n.size[qo]}),Go=qo=>Gn.value?{width:`${Gn.value}px`,height:`${Gn.value}px`,lineHeight:`${Gn.value}px`,fontSize:`${qo?Gn.value/2:18}px`}:{},Xn=()=>{if(!Dn.value||!Ln.value)return;const qo=Dn.value.offsetWidth,Jo=Ln.value.offsetWidth;if(qo!==0&&Jo!==0){const{gap:Zo=4}=$n;Zo*2{const{loadError:qo}=$n;(qo==null?void 0:qo())!==!1&&(In.value=!1)};return watch(()=>$n.src,()=>{nextTick(()=>{In.value=!0,Rn.value=1})}),watch(()=>$n.gap,()=>{nextTick(()=>{Xn()})}),onMounted(()=>{nextTick(()=>{Xn(),Nn.value=!0})}),()=>{var qo,Jo;const{shape:Zo,src:rr,alt:nr,srcset:ta,draggable:oa,crossOrigin:ra}=$n,ea=(qo=zn.shape)!==null&&qo!==void 0?qo:Zo,la=getPropsSlot(_n,$n,"icon"),ua=Fn.value,ga={[`${Pn.class}`]:!!Pn.class,[ua]:!0,[`${ua}-lg`]:Wn.value==="large",[`${ua}-sm`]:Wn.value==="small",[`${ua}-${ea}`]:!0,[`${ua}-image`]:rr&&In.value,[`${ua}-icon`]:la,[Hn.value]:!0},aa=typeof Wn.value=="number"?{width:`${Wn.value}px`,height:`${Wn.value}px`,lineHeight:`${Wn.value}px`,fontSize:la?`${Wn.value/2}px`:"18px"}:{},ca=(Jo=_n.default)===null||Jo===void 0?void 0:Jo.call(_n);let sa;if(rr&&In.value)sa=createVNode("img",{draggable:oa,src:rr,srcset:ta,onError:Yo,alt:nr,crossorigin:ra},null);else if(la)sa=la;else if(Nn.value||Rn.value!==1){const ia=`scale(${Rn.value}) translateX(-50%)`,fa={msTransform:ia,WebkitTransform:ia,transform:ia},ma=typeof Wn.value=="number"?{lineHeight:`${Wn.value}px`}:{};sa=createVNode(ResizeObserver$1,{onResize:Xn},{default:()=>[createVNode("span",{class:`${ua}-string`,ref:Dn,style:_extends$1(_extends$1({},ma),fa)},[ca])]})}else sa=createVNode("span",{class:`${ua}-string`,ref:Dn,style:{opacity:0}},[ca]);return Bn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{ref:Ln,class:ga,style:[aa,Go(!!la),Pn.style]}),[sa]))}}}),Avatar$1=Avatar,autoAdjustOverflow$2={adjustX:1,adjustY:1},targetOffset$3=[0,0],placements$4={left:{points:["cr","cl"],overflow:autoAdjustOverflow$2,offset:[-4,0],targetOffset:targetOffset$3},right:{points:["cl","cr"],overflow:autoAdjustOverflow$2,offset:[4,0],targetOffset:targetOffset$3},top:{points:["bc","tc"],overflow:autoAdjustOverflow$2,offset:[0,-4],targetOffset:targetOffset$3},bottom:{points:["tc","bc"],overflow:autoAdjustOverflow$2,offset:[0,4],targetOffset:targetOffset$3},topLeft:{points:["bl","tl"],overflow:autoAdjustOverflow$2,offset:[0,-4],targetOffset:targetOffset$3},leftTop:{points:["tr","tl"],overflow:autoAdjustOverflow$2,offset:[-4,0],targetOffset:targetOffset$3},topRight:{points:["br","tr"],overflow:autoAdjustOverflow$2,offset:[0,-4],targetOffset:targetOffset$3},rightTop:{points:["tl","tr"],overflow:autoAdjustOverflow$2,offset:[4,0],targetOffset:targetOffset$3},bottomRight:{points:["tr","br"],overflow:autoAdjustOverflow$2,offset:[0,4],targetOffset:targetOffset$3},rightBottom:{points:["bl","br"],overflow:autoAdjustOverflow$2,offset:[4,0],targetOffset:targetOffset$3},bottomLeft:{points:["tl","bl"],overflow:autoAdjustOverflow$2,offset:[0,4],targetOffset:targetOffset$3},leftBottom:{points:["br","bl"],overflow:autoAdjustOverflow$2,offset:[-4,0],targetOffset:targetOffset$3}},tooltipContentProps={prefixCls:String,id:String,overlayInnerStyle:PropTypes.any},Content$3=defineComponent({compatConfig:{MODE:3},name:"TooltipContent",props:tooltipContentProps,setup($n,Cn){let{slots:_n}=Cn;return()=>{var Pn;return createVNode("div",{class:`${$n.prefixCls}-inner`,id:$n.id,role:"tooltip",style:$n.overlayInnerStyle},[(Pn=_n.overlay)===null||Pn===void 0?void 0:Pn.call(_n)])}}});var __rest$15=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{}),overlayStyle:{type:Object,default:void 0},overlayClassName:String,prefixCls:PropTypes.string.def("rc-tooltip"),mouseEnterDelay:PropTypes.number.def(.1),mouseLeaveDelay:PropTypes.number.def(.1),getPopupContainer:Function,destroyTooltipOnHide:{type:Boolean,default:!1},align:PropTypes.object.def(()=>({})),arrowContent:PropTypes.any.def(null),tipId:String,builtinPlacements:PropTypes.object,overlayInnerStyle:{type:Object,default:void 0},popupVisible:{type:Boolean,default:void 0},onVisibleChange:Function,onPopupAlign:Function},setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;const Nn=shallowRef(),Rn=()=>{const{prefixCls:Bn,tipId:Hn,overlayInnerStyle:zn}=$n;return[createVNode("div",{class:`${Bn}-arrow`,key:"arrow"},[getPropsSlot(_n,$n,"arrowContent")]),createVNode(Content$3,{key:"content",prefixCls:Bn,id:Hn,overlayInnerStyle:zn},{overlay:_n.overlay})]};In({getPopupDomNode:()=>Nn.value.getPopupDomNode(),triggerDOM:Nn,forcePopupAlign:()=>{var Bn;return(Bn=Nn.value)===null||Bn===void 0?void 0:Bn.forcePopupAlign()}});const Ln=shallowRef(!1),Fn=shallowRef(!1);return watchEffect(()=>{const{destroyTooltipOnHide:Bn}=$n;if(typeof Bn=="boolean")Ln.value=Bn;else if(Bn&&typeof Bn=="object"){const{keepParent:Hn}=Bn;Ln.value=Hn===!0,Fn.value=Hn===!1}}),()=>{const{overlayClassName:Bn,trigger:Hn,mouseEnterDelay:zn,mouseLeaveDelay:Wn,overlayStyle:Yn,prefixCls:Gn,afterVisibleChange:Go,transitionName:Xn,animation:Yo,placement:qo,align:Jo,destroyTooltipOnHide:Zo,defaultVisible:rr}=$n,nr=__rest$15($n,["overlayClassName","trigger","mouseEnterDelay","mouseLeaveDelay","overlayStyle","prefixCls","afterVisibleChange","transitionName","animation","placement","align","destroyTooltipOnHide","defaultVisible"]),ta=_extends$1({},nr);$n.visible!==void 0&&(ta.popupVisible=$n.visible);const oa=_extends$1(_extends$1(_extends$1({popupClassName:Bn,prefixCls:Gn,action:Hn,builtinPlacements:placements$4,popupPlacement:qo,popupAlign:Jo,afterPopupVisibleChange:Go,popupTransitionName:Xn,popupAnimation:Yo,defaultPopupVisible:rr,destroyPopupOnHide:Ln.value,autoDestroy:Fn.value,mouseLeaveDelay:Wn,popupStyle:Yn,mouseEnterDelay:zn},ta),Pn),{onPopupVisibleChange:$n.onVisibleChange||noop$b,onPopupAlign:$n.onPopupAlign||noop$b,ref:Nn,popup:Rn()});return createVNode(Trigger,oa,{default:_n.default})}}}),abstractTooltipProps=()=>({trigger:[String,Array],open:{type:Boolean,default:void 0},visible:{type:Boolean,default:void 0},placement:String,color:String,transitionName:String,overlayStyle:objectType(),overlayInnerStyle:objectType(),overlayClassName:String,openClassName:String,prefixCls:String,mouseEnterDelay:Number,mouseLeaveDelay:Number,getPopupContainer:Function,arrowPointAtCenter:{type:Boolean,default:void 0},autoAdjustOverflow:{type:[Boolean,Object],default:void 0},destroyTooltipOnHide:{type:Boolean,default:void 0},align:objectType(),builtinPlacements:objectType(),children:Array,onVisibleChange:Function,"onUpdate:visible":Function,onOpenChange:Function,"onUpdate:open":Function}),autoAdjustOverflowEnabled={adjustX:1,adjustY:1},autoAdjustOverflowDisabled={adjustX:0,adjustY:0},targetOffset$2=[0,0];function getOverflowOptions($n){return typeof $n=="boolean"?$n?autoAdjustOverflowEnabled:autoAdjustOverflowDisabled:_extends$1(_extends$1({},autoAdjustOverflowDisabled),$n)}function getPlacements$1($n){const{arrowWidth:Cn=4,horizontalArrowShift:_n=16,verticalArrowShift:Pn=8,autoAdjustOverflow:In,arrowPointAtCenter:Nn}=$n,Rn={left:{points:["cr","cl"],offset:[-4,0]},right:{points:["cl","cr"],offset:[4,0]},top:{points:["bc","tc"],offset:[0,-4]},bottom:{points:["tc","bc"],offset:[0,4]},topLeft:{points:["bl","tc"],offset:[-(_n+Cn),-4]},leftTop:{points:["tr","cl"],offset:[-4,-(Pn+Cn)]},topRight:{points:["br","tc"],offset:[_n+Cn,-4]},rightTop:{points:["tl","cr"],offset:[4,-(Pn+Cn)]},bottomRight:{points:["tr","bc"],offset:[_n+Cn,4]},rightBottom:{points:["bl","cr"],offset:[4,Pn+Cn]},bottomLeft:{points:["tl","bc"],offset:[-(_n+Cn),4]},leftBottom:{points:["br","cl"],offset:[-4,Pn+Cn]}};return Object.keys(Rn).forEach(Dn=>{Rn[Dn]=Nn?_extends$1(_extends$1({},Rn[Dn]),{overflow:getOverflowOptions(In),targetOffset:targetOffset$2}):_extends$1(_extends$1({},placements$4[Dn]),{overflow:getOverflowOptions(In)}),Rn[Dn].ignoreShake=!0}),Rn}function firstNotUndefined(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];for(let Cn=0,_n=$n.length;Cn<_n;Cn++)if($n[Cn]!==void 0)return $n[Cn]}const inverseColors=PresetColors.map($n=>`${$n}-inverse`),PresetStatusColorTypes=["success","processing","error","default","warning"];function isPresetColor($n){return(arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0)?[...inverseColors,...PresetColors].includes($n):PresetColors.includes($n)}function isPresetStatusColor($n){return PresetStatusColorTypes.includes($n)}function parseColor($n,Cn){const _n=isPresetColor(Cn),Pn=classNames({[`${$n}-${Cn}`]:Cn&&_n}),In={},Nn={};return Cn&&!_n&&(In.background=Cn,Nn["--antd-arrow-background-color"]=Cn),{className:Pn,overlayStyle:In,arrowStyle:Nn}}function connectArrowCls($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";return $n.map(_n=>`${Cn}${_n}`).join(",")}const MAX_VERTICAL_CONTENT_RADIUS=8;function getArrowOffset($n){const Cn=MAX_VERTICAL_CONTENT_RADIUS,{sizePopupArrow:_n,contentRadius:Pn,borderRadiusOuter:In,limitVerticalRadius:Nn}=$n,Rn=_n/2-Math.ceil(In*(Math.sqrt(2)-1)),Dn=(Pn>12?Pn+2:12)-Rn,Ln=Nn?Cn-Rn:Dn;return{dropdownArrowOffset:Dn,dropdownArrowOffsetVertical:Ln}}function getArrowStyle($n,Cn){const{componentCls:_n,sizePopupArrow:Pn,marginXXS:In,borderRadiusXS:Nn,borderRadiusOuter:Rn,boxShadowPopoverArrow:Dn}=$n,{colorBg:Ln,showArrowCls:Fn,contentRadius:Bn=$n.borderRadiusLG,limitVerticalRadius:Hn}=Cn,{dropdownArrowOffsetVertical:zn,dropdownArrowOffset:Wn}=getArrowOffset({sizePopupArrow:Pn,contentRadius:Bn,borderRadiusOuter:Rn,limitVerticalRadius:Hn}),Yn=Pn/2+In;return{[_n]:{[`${_n}-arrow`]:[_extends$1(_extends$1({position:"absolute",zIndex:1,display:"block"},roundedArrow(Pn,Nn,Rn,Ln,Dn)),{"&:before":{background:Ln}})],[[`&-placement-top ${_n}-arrow`,`&-placement-topLeft ${_n}-arrow`,`&-placement-topRight ${_n}-arrow`].join(",")]:{bottom:0,transform:"translateY(100%) rotate(180deg)"},[`&-placement-top ${_n}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%) translateY(100%) rotate(180deg)"},[`&-placement-topLeft ${_n}-arrow`]:{left:{_skip_check_:!0,value:Wn}},[`&-placement-topRight ${_n}-arrow`]:{right:{_skip_check_:!0,value:Wn}},[[`&-placement-bottom ${_n}-arrow`,`&-placement-bottomLeft ${_n}-arrow`,`&-placement-bottomRight ${_n}-arrow`].join(",")]:{top:0,transform:"translateY(-100%)"},[`&-placement-bottom ${_n}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%) translateY(-100%)"},[`&-placement-bottomLeft ${_n}-arrow`]:{left:{_skip_check_:!0,value:Wn}},[`&-placement-bottomRight ${_n}-arrow`]:{right:{_skip_check_:!0,value:Wn}},[[`&-placement-left ${_n}-arrow`,`&-placement-leftTop ${_n}-arrow`,`&-placement-leftBottom ${_n}-arrow`].join(",")]:{right:{_skip_check_:!0,value:0},transform:"translateX(100%) rotate(90deg)"},[`&-placement-left ${_n}-arrow`]:{top:{_skip_check_:!0,value:"50%"},transform:"translateY(-50%) translateX(100%) rotate(90deg)"},[`&-placement-leftTop ${_n}-arrow`]:{top:zn},[`&-placement-leftBottom ${_n}-arrow`]:{bottom:zn},[[`&-placement-right ${_n}-arrow`,`&-placement-rightTop ${_n}-arrow`,`&-placement-rightBottom ${_n}-arrow`].join(",")]:{left:{_skip_check_:!0,value:0},transform:"translateX(-100%) rotate(-90deg)"},[`&-placement-right ${_n}-arrow`]:{top:{_skip_check_:!0,value:"50%"},transform:"translateY(-50%) translateX(-100%) rotate(-90deg)"},[`&-placement-rightTop ${_n}-arrow`]:{top:zn},[`&-placement-rightBottom ${_n}-arrow`]:{bottom:zn},[connectArrowCls(["&-placement-topLeft","&-placement-top","&-placement-topRight"],Fn)]:{paddingBottom:Yn},[connectArrowCls(["&-placement-bottomLeft","&-placement-bottom","&-placement-bottomRight"],Fn)]:{paddingTop:Yn},[connectArrowCls(["&-placement-leftTop","&-placement-left","&-placement-leftBottom"],Fn)]:{paddingRight:{_skip_check_:!0,value:Yn}},[connectArrowCls(["&-placement-rightTop","&-placement-right","&-placement-rightBottom"],Fn)]:{paddingLeft:{_skip_check_:!0,value:Yn}}}}}const genTooltipStyle=$n=>{const{componentCls:Cn,tooltipMaxWidth:_n,tooltipColor:Pn,tooltipBg:In,tooltipBorderRadius:Nn,zIndexPopup:Rn,controlHeight:Dn,boxShadowSecondary:Ln,paddingSM:Fn,paddingXS:Bn,tooltipRadiusOuter:Hn}=$n;return[{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",zIndex:Rn,display:"block","&":[{width:"max-content"},{width:"intrinsic"}],maxWidth:_n,visibility:"visible","&-hidden":{display:"none"},"--antd-arrow-background-color":In,[`${Cn}-inner`]:{minWidth:Dn,minHeight:Dn,padding:`${Fn/2}px ${Bn}px`,color:Pn,textAlign:"start",textDecoration:"none",wordWrap:"break-word",backgroundColor:In,borderRadius:Nn,boxShadow:Ln},[["&-placement-left","&-placement-leftTop","&-placement-leftBottom","&-placement-right","&-placement-rightTop","&-placement-rightBottom"].join(",")]:{[`${Cn}-inner`]:{borderRadius:Math.min(Nn,MAX_VERTICAL_CONTENT_RADIUS)}},[`${Cn}-content`]:{position:"relative"}}),genPresetColor($n,(zn,Wn)=>{let{darkColor:Yn}=Wn;return{[`&${Cn}-${zn}`]:{[`${Cn}-inner`]:{backgroundColor:Yn},[`${Cn}-arrow`]:{"--antd-arrow-background-color":Yn}}}})),{"&-rtl":{direction:"rtl"}})},getArrowStyle(merge$1($n,{borderRadiusOuter:Hn}),{colorBg:"var(--antd-arrow-background-color)",showArrowCls:"",contentRadius:Nn,limitVerticalRadius:!0}),{[`${Cn}-pure`]:{position:"relative",maxWidth:"none"}}]},useStyle$T=($n,Cn)=>genComponentStyleHook("Tooltip",Pn=>{if((Cn==null?void 0:Cn.value)===!1)return[];const{borderRadius:In,colorTextLightSolid:Nn,colorBgDefault:Rn,borderRadiusOuter:Dn}=Pn,Ln=merge$1(Pn,{tooltipMaxWidth:250,tooltipColor:Nn,tooltipBorderRadius:In,tooltipBg:Rn,tooltipRadiusOuter:Dn>4?4:Dn});return[genTooltipStyle(Ln),initZoomMotion(Pn,"zoom-big-fast")]},Pn=>{let{zIndexPopupBase:In,colorBgSpotlight:Nn}=Pn;return{zIndexPopup:In+70,colorBgDefault:Nn}})($n),splitObject=($n,Cn)=>{const _n={},Pn=_extends$1({},$n);return Cn.forEach(In=>{$n&&In in $n&&(_n[In]=$n[In],delete Pn[In])}),{picked:_n,omitted:Pn}},tooltipProps=()=>_extends$1(_extends$1({},abstractTooltipProps()),{title:PropTypes.any}),tooltipDefaultProps=()=>({trigger:"hover",align:{},placement:"top",mouseEnterDelay:.1,mouseLeaveDelay:.1,arrowPointAtCenter:!1,autoAdjustOverflow:!0}),ToolTip=defineComponent({compatConfig:{MODE:3},name:"ATooltip",inheritAttrs:!1,props:initDefaultProps(tooltipProps(),{trigger:"hover",align:{},placement:"top",mouseEnterDelay:.1,mouseLeaveDelay:.1,arrowPointAtCenter:!1,autoAdjustOverflow:!0}),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In,expose:Nn}=Cn;const{prefixCls:Rn,getPopupContainer:Dn,direction:Ln,rootPrefixCls:Fn}=useConfigInject("tooltip",$n),Bn=computed(()=>{var ra;return(ra=$n.open)!==null&&ra!==void 0?ra:$n.visible}),Hn=ref(firstNotUndefined([$n.open,$n.visible])),zn=ref();let Wn;watch(Bn,ra=>{wrapperRaf.cancel(Wn),Wn=wrapperRaf(()=>{Hn.value=!!ra})});const Yn=()=>{var ra;const ea=(ra=$n.title)!==null&&ra!==void 0?ra:_n.title;return!ea&&ea!==0},Gn=ra=>{const ea=Yn();Bn.value===void 0&&(Hn.value=ea?!1:ra),ea||(Pn("update:visible",ra),Pn("visibleChange",ra),Pn("update:open",ra),Pn("openChange",ra))};Nn({getPopupDomNode:()=>zn.value.getPopupDomNode(),open:Hn,forcePopupAlign:()=>{var ra;return(ra=zn.value)===null||ra===void 0?void 0:ra.forcePopupAlign()}});const Xn=computed(()=>{const{builtinPlacements:ra,arrowPointAtCenter:ea,autoAdjustOverflow:la}=$n;return ra||getPlacements$1({arrowPointAtCenter:ea,autoAdjustOverflow:la})}),Yo=ra=>ra||ra==="",qo=ra=>{const ea=ra.type;if(typeof ea=="object"&&ra.props&&((ea.__ANT_BUTTON===!0||ea==="button")&&Yo(ra.props.disabled)||ea.__ANT_SWITCH===!0&&(Yo(ra.props.disabled)||Yo(ra.props.loading))||ea.__ANT_RADIO===!0&&Yo(ra.props.disabled))){const{picked:la,omitted:ua}=splitObject(getStyle$3(ra),["position","left","right","top","bottom","float","display","zIndex"]),ga=_extends$1(_extends$1({display:"inline-block"},la),{cursor:"not-allowed",lineHeight:1,width:ra.props&&ra.props.block?"100%":void 0}),aa=_extends$1(_extends$1({},ua),{pointerEvents:"none"}),ca=cloneElement(ra,{style:aa},!0);return createVNode("span",{style:ga,class:`${Rn.value}-disabled-compatible-wrapper`},[ca])}return ra},Jo=()=>{var ra,ea;return(ra=$n.title)!==null&&ra!==void 0?ra:(ea=_n.title)===null||ea===void 0?void 0:ea.call(_n)},Zo=(ra,ea)=>{const la=Xn.value,ua=Object.keys(la).find(ga=>{var aa,ca;return la[ga].points[0]===((aa=ea.points)===null||aa===void 0?void 0:aa[0])&&la[ga].points[1]===((ca=ea.points)===null||ca===void 0?void 0:ca[1])});if(ua){const ga=ra.getBoundingClientRect(),aa={top:"50%",left:"50%"};ua.indexOf("top")>=0||ua.indexOf("Bottom")>=0?aa.top=`${ga.height-ea.offset[1]}px`:(ua.indexOf("Top")>=0||ua.indexOf("bottom")>=0)&&(aa.top=`${-ea.offset[1]}px`),ua.indexOf("left")>=0||ua.indexOf("Right")>=0?aa.left=`${ga.width-ea.offset[0]}px`:(ua.indexOf("right")>=0||ua.indexOf("Left")>=0)&&(aa.left=`${-ea.offset[0]}px`),ra.style.transformOrigin=`${aa.left} ${aa.top}`}},rr=computed(()=>parseColor(Rn.value,$n.color)),nr=computed(()=>In["data-popover-inject"]),[ta,oa]=useStyle$T(Rn,computed(()=>!nr.value));return()=>{var ra,ea;const{openClassName:la,overlayClassName:ua,overlayStyle:ga,overlayInnerStyle:aa}=$n;let ca=(ea=filterEmpty((ra=_n.default)===null||ra===void 0?void 0:ra.call(_n)))!==null&&ea!==void 0?ea:null;ca=ca.length===1?ca[0]:ca;let sa=Hn.value;if(Bn.value===void 0&&Yn()&&(sa=!1),!ca)return null;const ia=qo(isValidElement(ca)&&!isFragment(ca)?ca:createVNode("span",null,[ca])),fa=classNames({[la||`${Rn.value}-open`]:!0,[ia.props&&ia.props.class]:ia.props&&ia.props.class}),ma=classNames(ua,{[`${Rn.value}-rtl`]:Ln.value==="rtl"},rr.value.className,oa.value),ya=_extends$1(_extends$1({},rr.value.overlayStyle),aa),ba=rr.value.arrowStyle,Ia=_extends$1(_extends$1(_extends$1({},In),$n),{prefixCls:Rn.value,getPopupContainer:Dn==null?void 0:Dn.value,builtinPlacements:Xn.value,visible:sa,ref:zn,overlayClassName:ma,overlayStyle:_extends$1(_extends$1({},ba),ga),overlayInnerStyle:ya,onVisibleChange:Gn,onPopupAlign:Zo,transitionName:getTransitionName$1(Fn.value,"zoom-big-fast",$n.transitionName)});return ta(createVNode(Tooltip$1,Ia,{default:()=>[Hn.value?cloneElement(ia,{class:fa}):ia],arrowContent:()=>createVNode("span",{class:`${Rn.value}-arrow-content`},null),overlay:Jo}))}}}),Tooltip=withInstall(ToolTip),genBaseStyle$g=$n=>{const{componentCls:Cn,popoverBg:_n,popoverColor:Pn,width:In,fontWeightStrong:Nn,popoverPadding:Rn,boxShadowSecondary:Dn,colorTextHeading:Ln,borderRadiusLG:Fn,zIndexPopup:Bn,marginXS:Hn,colorBgElevated:zn}=$n;return[{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:Bn,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--antd-arrow-background-color":zn,"&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${Cn}-content`]:{position:"relative"},[`${Cn}-inner`]:{backgroundColor:_n,backgroundClip:"padding-box",borderRadius:Fn,boxShadow:Dn,padding:Rn},[`${Cn}-title`]:{minWidth:In,marginBottom:Hn,color:Ln,fontWeight:Nn},[`${Cn}-inner-content`]:{color:Pn}})},getArrowStyle($n,{colorBg:"var(--antd-arrow-background-color)"}),{[`${Cn}-pure`]:{position:"relative",maxWidth:"none",[`${Cn}-content`]:{display:"inline-block"}}}]},genColorStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:PresetColors.map(_n=>{const Pn=$n[`${_n}-6`];return{[`&${Cn}-${_n}`]:{"--antd-arrow-background-color":Pn,[`${Cn}-inner`]:{backgroundColor:Pn},[`${Cn}-arrow`]:{background:"transparent"}}}})}},genWireframeStyle$1=$n=>{const{componentCls:Cn,lineWidth:_n,lineType:Pn,colorSplit:In,paddingSM:Nn,controlHeight:Rn,fontSize:Dn,lineHeight:Ln,padding:Fn}=$n,Bn=Rn-Math.round(Dn*Ln),Hn=Bn/2,zn=Bn/2-_n,Wn=Fn;return{[Cn]:{[`${Cn}-inner`]:{padding:0},[`${Cn}-title`]:{margin:0,padding:`${Hn}px ${Wn}px ${zn}px`,borderBottom:`${_n}px ${Pn} ${In}`},[`${Cn}-inner-content`]:{padding:`${Nn}px ${Wn}px`}}}},useStyle$S=genComponentStyleHook("Popover",$n=>{const{colorBgElevated:Cn,colorText:_n,wireframe:Pn}=$n,In=merge$1($n,{popoverBg:Cn,popoverColor:_n,popoverPadding:12});return[genBaseStyle$g(In),genColorStyle(In),Pn&&genWireframeStyle$1(In),initZoomMotion(In,"zoom-big")]},$n=>{let{zIndexPopupBase:Cn}=$n;return{zIndexPopup:Cn+30,width:177}}),popoverProps=()=>_extends$1(_extends$1({},abstractTooltipProps()),{content:anyType(),title:anyType()}),Popover=defineComponent({compatConfig:{MODE:3},name:"APopover",inheritAttrs:!1,props:initDefaultProps(popoverProps(),_extends$1(_extends$1({},tooltipDefaultProps()),{trigger:"hover",placement:"top",mouseEnterDelay:.1,mouseLeaveDelay:.1})),setup($n,Cn){let{expose:_n,slots:Pn,attrs:In}=Cn;const Nn=ref();warning$3($n.visible===void 0),_n({getPopupDomNode:()=>{var zn,Wn;return(Wn=(zn=Nn.value)===null||zn===void 0?void 0:zn.getPopupDomNode)===null||Wn===void 0?void 0:Wn.call(zn)}});const{prefixCls:Rn,configProvider:Dn}=useConfigInject("popover",$n),[Ln,Fn]=useStyle$S(Rn),Bn=computed(()=>Dn.getPrefixCls()),Hn=()=>{var zn,Wn;const{title:Yn=filterEmpty((zn=Pn.title)===null||zn===void 0?void 0:zn.call(Pn)),content:Gn=filterEmpty((Wn=Pn.content)===null||Wn===void 0?void 0:Wn.call(Pn))}=$n,Go=!!(Array.isArray(Yn)?Yn.length:Yn),Xn=!!(Array.isArray(Gn)?Gn.length:Yn);return!Go&&!Xn?null:createVNode(Fragment,null,[Go&&createVNode("div",{class:`${Rn.value}-title`},[Yn]),createVNode("div",{class:`${Rn.value}-inner-content`},[Gn])])};return()=>{const zn=classNames($n.overlayClassName,Fn.value);return Ln(createVNode(Tooltip,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},omit$1($n,["title","content"])),In),{},{prefixCls:Rn.value,ref:Nn,overlayClassName:zn,transitionName:getTransitionName$1(Bn.value,"zoom-big",$n.transitionName),"data-popover-inject":!0}),{title:Hn,default:Pn.default}))}}}),Popover$1=withInstall(Popover),groupProps=()=>({prefixCls:String,maxCount:Number,maxStyle:{type:Object,default:void 0},maxPopoverPlacement:{type:String,default:"top"},maxPopoverTrigger:String,size:{type:[Number,String,Object],default:"default"},shape:{type:String,default:"circle"}}),Group$3=defineComponent({compatConfig:{MODE:3},name:"AAvatarGroup",inheritAttrs:!1,props:groupProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("avatar",$n),Rn=computed(()=>`${In.value}-group`),[Dn,Ln]=useStyle$U(In);return watchEffect(()=>{const Fn={size:$n.size,shape:$n.shape};useAvatarProviderContext(Fn)}),()=>{const{maxPopoverPlacement:Fn="top",maxCount:Bn,maxStyle:Hn,maxPopoverTrigger:zn="hover",shape:Wn}=$n,Yn={[Rn.value]:!0,[`${Rn.value}-rtl`]:Nn.value==="rtl",[`${Pn.class}`]:!!Pn.class,[Ln.value]:!0},Gn=getPropsSlot(_n,$n),Go=flattenChildren(Gn).map((Yo,qo)=>cloneElement(Yo,{key:`avatar-key-${qo}`})),Xn=Go.length;if(Bn&&Bn[createVNode(Avatar$1,{style:Hn,shape:Wn},{default:()=>[`+${Xn-Bn}`]})]})),Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Yn,style:Pn.style}),[Yo]))}return Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Yn,style:Pn.style}),[Go]))}}}),Group$4=Group$3;Avatar$1.Group=Group$4;Avatar$1.install=function($n){return $n.component(Avatar$1.name,Avatar$1),$n.component(Group$4.name,Group$4),$n};function UnitNumber($n){let{prefixCls:Cn,value:_n,current:Pn,offset:In=0}=$n,Nn;return In&&(Nn={position:"absolute",top:`${In}00%`,left:0}),createVNode("p",{style:Nn,class:classNames(`${Cn}-only-unit`,{current:Pn})},[_n])}function getOffset$2($n,Cn,_n){let Pn=$n,In=0;for(;(Pn+10)%10!==Cn;)Pn+=_n,In+=_n;return In}const SingleNumber=defineComponent({compatConfig:{MODE:3},name:"SingleNumber",props:{prefixCls:String,value:String,count:Number},setup($n){const Cn=computed(()=>Number($n.value)),_n=computed(()=>Math.abs($n.count)),Pn=reactive({prevValue:Cn.value,prevCount:_n.value}),In=()=>{Pn.prevValue=Cn.value,Pn.prevCount=_n.value},Nn=ref();return watch(Cn,()=>{clearTimeout(Nn.value),Nn.value=setTimeout(()=>{In()},1e3)},{flush:"post"}),onUnmounted(()=>{clearTimeout(Nn.value)}),()=>{let Rn,Dn={};const Ln=Cn.value;if(Pn.prevValue===Ln||Number.isNaN(Ln)||Number.isNaN(Pn.prevValue))Rn=[UnitNumber(_extends$1(_extends$1({},$n),{current:!0}))],Dn={transition:"none"};else{Rn=[];const Fn=Ln+10,Bn=[];for(let Wn=Ln;Wn<=Fn;Wn+=1)Bn.push(Wn);const Hn=Bn.findIndex(Wn=>Wn%10===Pn.prevValue);Rn=Bn.map((Wn,Yn)=>{const Gn=Wn%10;return UnitNumber(_extends$1(_extends$1({},$n),{value:Gn,offset:Yn-Hn,current:Yn===Hn}))});const zn=Pn.prevCount<_n.value?1:-1;Dn={transform:`translateY(${-getOffset$2(Pn.prevValue,Ln,zn)}00%)`}}return createVNode("span",{class:`${$n.prefixCls}-only`,style:Dn,onTransitionend:()=>In()},[Rn])}}});var __rest$14=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{var Nn;const Rn=_extends$1(_extends$1({},$n),_n),{prefixCls:Dn,count:Ln,title:Fn,show:Bn,component:Hn="sup",class:zn,style:Wn}=Rn,Yn=__rest$14(Rn,["prefixCls","count","title","show","component","class","style"]),Gn=_extends$1(_extends$1({},Yn),{style:Wn,"data-show":$n.show,class:classNames(In.value,zn),title:Fn});let Go=Ln;if(Ln&&Number(Ln)%1===0){const Yo=String(Ln).split("");Go=Yo.map((qo,Jo)=>createVNode(SingleNumber,{prefixCls:In.value,count:Number(Ln),value:qo,key:Yo.length-Jo},null))}Wn&&Wn.borderColor&&(Gn.style=_extends$1(_extends$1({},Wn),{boxShadow:`0 0 0 1px ${Wn.borderColor} inset`}));const Xn=filterEmpty((Nn=Pn.default)===null||Nn===void 0?void 0:Nn.call(Pn));return Xn&&Xn.length?cloneElement(Xn,{class:classNames(`${In.value}-custom-component`)},!1):createVNode(Hn,Gn,{default:()=>[Go]})}}}),antStatusProcessing=new Keyframes("antStatusProcessing",{"0%":{transform:"scale(0.8)",opacity:.5},"100%":{transform:"scale(2.4)",opacity:0}}),antZoomBadgeIn=new Keyframes("antZoomBadgeIn",{"0%":{transform:"scale(0) translate(50%, -50%)",opacity:0},"100%":{transform:"scale(1) translate(50%, -50%)"}}),antZoomBadgeOut=new Keyframes("antZoomBadgeOut",{"0%":{transform:"scale(1) translate(50%, -50%)"},"100%":{transform:"scale(0) translate(50%, -50%)",opacity:0}}),antNoWrapperZoomBadgeIn=new Keyframes("antNoWrapperZoomBadgeIn",{"0%":{transform:"scale(0)",opacity:0},"100%":{transform:"scale(1)"}}),antNoWrapperZoomBadgeOut=new Keyframes("antNoWrapperZoomBadgeOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0)",opacity:0}}),antBadgeLoadingCircle=new Keyframes("antBadgeLoadingCircle",{"0%":{transformOrigin:"50%"},"100%":{transform:"translate(50%, -50%) rotate(360deg)",transformOrigin:"50%"}}),genSharedBadgeStyle=$n=>{const{componentCls:Cn,iconCls:_n,antCls:Pn,badgeFontHeight:In,badgeShadowSize:Nn,badgeHeightSm:Rn,motionDurationSlow:Dn,badgeStatusSize:Ln,marginXS:Fn,badgeRibbonOffset:Bn}=$n,Hn=`${Pn}-scroll-number`,zn=`${Pn}-ribbon`,Wn=`${Pn}-ribbon-wrapper`,Yn=genPresetColor($n,(Go,Xn)=>{let{darkColor:Yo}=Xn;return{[`&${Cn} ${Cn}-color-${Go}`]:{background:Yo,[`&:not(${Cn}-count)`]:{color:Yo}}}}),Gn=genPresetColor($n,(Go,Xn)=>{let{darkColor:Yo}=Xn;return{[`&${zn}-color-${Go}`]:{background:Yo,color:Yo}}});return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-block",width:"fit-content",lineHeight:1,[`${Cn}-count`]:{zIndex:$n.badgeZIndex,minWidth:$n.badgeHeight,height:$n.badgeHeight,color:$n.badgeTextColor,fontWeight:$n.badgeFontWeight,fontSize:$n.badgeFontSize,lineHeight:`${$n.badgeHeight}px`,whiteSpace:"nowrap",textAlign:"center",background:$n.badgeColor,borderRadius:$n.badgeHeight/2,boxShadow:`0 0 0 ${Nn}px ${$n.badgeShadowColor}`,transition:`background ${$n.motionDurationMid}`,a:{color:$n.badgeTextColor},"a:hover":{color:$n.badgeTextColor},"a:hover &":{background:$n.badgeColorHover}},[`${Cn}-count-sm`]:{minWidth:Rn,height:Rn,fontSize:$n.badgeFontSizeSm,lineHeight:`${Rn}px`,borderRadius:Rn/2},[`${Cn}-multiple-words`]:{padding:`0 ${$n.paddingXS}px`},[`${Cn}-dot`]:{zIndex:$n.badgeZIndex,width:$n.badgeDotSize,minWidth:$n.badgeDotSize,height:$n.badgeDotSize,background:$n.badgeColor,borderRadius:"100%",boxShadow:`0 0 0 ${Nn}px ${$n.badgeShadowColor}`},[`${Cn}-dot${Hn}`]:{transition:`background ${Dn}`},[`${Cn}-count, ${Cn}-dot, ${Hn}-custom-component`]:{position:"absolute",top:0,insetInlineEnd:0,transform:"translate(50%, -50%)",transformOrigin:"100% 0%",[`&${_n}-spin`]:{animationName:antBadgeLoadingCircle,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},[`&${Cn}-status`]:{lineHeight:"inherit",verticalAlign:"baseline",[`${Cn}-status-dot`]:{position:"relative",top:-1,display:"inline-block",width:Ln,height:Ln,verticalAlign:"middle",borderRadius:"50%"},[`${Cn}-status-success`]:{backgroundColor:$n.colorSuccess},[`${Cn}-status-processing`]:{overflow:"visible",color:$n.colorPrimary,backgroundColor:$n.colorPrimary,"&::after":{position:"absolute",top:0,insetInlineStart:0,width:"100%",height:"100%",borderWidth:Nn,borderStyle:"solid",borderColor:"inherit",borderRadius:"50%",animationName:antStatusProcessing,animationDuration:$n.badgeProcessingDuration,animationIterationCount:"infinite",animationTimingFunction:"ease-in-out",content:'""'}},[`${Cn}-status-default`]:{backgroundColor:$n.colorTextPlaceholder},[`${Cn}-status-error`]:{backgroundColor:$n.colorError},[`${Cn}-status-warning`]:{backgroundColor:$n.colorWarning},[`${Cn}-status-text`]:{marginInlineStart:Fn,color:$n.colorText,fontSize:$n.fontSize}}}),Yn),{[`${Cn}-zoom-appear, ${Cn}-zoom-enter`]:{animationName:antZoomBadgeIn,animationDuration:$n.motionDurationSlow,animationTimingFunction:$n.motionEaseOutBack,animationFillMode:"both"},[`${Cn}-zoom-leave`]:{animationName:antZoomBadgeOut,animationDuration:$n.motionDurationSlow,animationTimingFunction:$n.motionEaseOutBack,animationFillMode:"both"},[`&${Cn}-not-a-wrapper`]:{[`${Cn}-zoom-appear, ${Cn}-zoom-enter`]:{animationName:antNoWrapperZoomBadgeIn,animationDuration:$n.motionDurationSlow,animationTimingFunction:$n.motionEaseOutBack},[`${Cn}-zoom-leave`]:{animationName:antNoWrapperZoomBadgeOut,animationDuration:$n.motionDurationSlow,animationTimingFunction:$n.motionEaseOutBack},[`&:not(${Cn}-status)`]:{verticalAlign:"middle"},[`${Hn}-custom-component, ${Cn}-count`]:{transform:"none"},[`${Hn}-custom-component, ${Hn}`]:{position:"relative",top:"auto",display:"block",transformOrigin:"50% 50%"}},[`${Hn}`]:{overflow:"hidden",[`${Hn}-only`]:{position:"relative",display:"inline-block",height:$n.badgeHeight,transition:`all ${$n.motionDurationSlow} ${$n.motionEaseOutBack}`,WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden",[`> p${Hn}-only-unit`]:{height:$n.badgeHeight,margin:0,WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden"}},[`${Hn}-symbol`]:{verticalAlign:"top"}},"&-rtl":{direction:"rtl",[`${Cn}-count, ${Cn}-dot, ${Hn}-custom-component`]:{transform:"translate(-50%, -50%)"}}}),[`${Wn}`]:{position:"relative"},[`${zn}`]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:Fn,padding:`0 ${$n.paddingXS}px`,color:$n.colorPrimary,lineHeight:`${In}px`,whiteSpace:"nowrap",backgroundColor:$n.colorPrimary,borderRadius:$n.borderRadiusSM,[`${zn}-text`]:{color:$n.colorTextLightSolid},[`${zn}-corner`]:{position:"absolute",top:"100%",width:Bn,height:Bn,color:"currentcolor",border:`${Bn/2}px solid`,transform:$n.badgeRibbonCornerTransform,transformOrigin:"top",filter:$n.badgeRibbonCornerFilter}}),Gn),{[`&${zn}-placement-end`]:{insetInlineEnd:-Bn,borderEndEndRadius:0,[`${zn}-corner`]:{insetInlineEnd:0,borderInlineEndColor:"transparent",borderBlockEndColor:"transparent"}},[`&${zn}-placement-start`]:{insetInlineStart:-Bn,borderEndStartRadius:0,[`${zn}-corner`]:{insetInlineStart:0,borderBlockEndColor:"transparent",borderInlineStartColor:"transparent"}},"&-rtl":{direction:"rtl"}})}},useStyle$R=genComponentStyleHook("Badge",$n=>{const{fontSize:Cn,lineHeight:_n,fontSizeSM:Pn,lineWidth:In,marginXS:Nn,colorBorderBg:Rn}=$n,Dn=Math.round(Cn*_n),Ln=In,Fn="auto",Bn=Dn-2*Ln,Hn=$n.colorBgContainer,zn="normal",Wn=Pn,Yn=$n.colorError,Gn=$n.colorErrorHover,Go=Cn,Xn=Pn/2,Yo=Pn,qo=Pn/2,Jo=merge$1($n,{badgeFontHeight:Dn,badgeShadowSize:Ln,badgeZIndex:Fn,badgeHeight:Bn,badgeTextColor:Hn,badgeFontWeight:zn,badgeFontSize:Wn,badgeColor:Yn,badgeColorHover:Gn,badgeShadowColor:Rn,badgeHeightSm:Go,badgeDotSize:Xn,badgeFontSizeSm:Yo,badgeStatusSize:qo,badgeProcessingDuration:"1.2s",badgeRibbonOffset:Nn,badgeRibbonCornerTransform:"scaleY(0.75)",badgeRibbonCornerFilter:"brightness(75%)"});return[genSharedBadgeStyle(Jo)]});var __rest$13=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefix:String,color:{type:String},text:PropTypes.any,placement:{type:String,default:"end"}}),Ribbon=defineComponent({compatConfig:{MODE:3},name:"ABadgeRibbon",inheritAttrs:!1,props:ribbonProps(),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("ribbon",$n),[Rn,Dn]=useStyle$R(In),Ln=computed(()=>isPresetColor($n.color,!1)),Fn=computed(()=>[In.value,`${In.value}-placement-${$n.placement}`,{[`${In.value}-rtl`]:Nn.value==="rtl",[`${In.value}-color-${$n.color}`]:Ln.value}]);return()=>{var Bn,Hn;const{class:zn,style:Wn}=_n,Yn=__rest$13(_n,["class","style"]),Gn={},Go={};return $n.color&&!Ln.value&&(Gn.background=$n.color,Go.color=$n.color),Rn(createVNode("div",_objectSpread2$1({class:`${In.value}-wrapper ${Dn.value}`},Yn),[(Bn=Pn.default)===null||Bn===void 0?void 0:Bn.call(Pn),createVNode("div",{class:[Fn.value,zn,Dn.value],style:_extends$1(_extends$1({},Gn),Wn)},[createVNode("span",{class:`${In.value}-text`},[$n.text||((Hn=Pn.text)===null||Hn===void 0?void 0:Hn.call(Pn))]),createVNode("div",{class:`${In.value}-corner`,style:Go},null)])]))}}}),isNumeric=$n=>!isNaN(parseFloat($n))&&isFinite($n),badgeProps=()=>({count:PropTypes.any.def(null),showZero:{type:Boolean,default:void 0},overflowCount:{type:Number,default:99},dot:{type:Boolean,default:void 0},prefixCls:String,scrollNumberPrefixCls:String,status:{type:String},size:{type:String,default:"default"},color:String,text:PropTypes.any,offset:Array,numberStyle:{type:Object,default:void 0},title:String}),Badge=defineComponent({compatConfig:{MODE:3},name:"ABadge",Ribbon,inheritAttrs:!1,props:badgeProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("badge",$n),[Rn,Dn]=useStyle$R(In),Ln=computed(()=>$n.count>$n.overflowCount?`${$n.overflowCount}+`:$n.count),Fn=computed(()=>Ln.value==="0"||Ln.value===0),Bn=computed(()=>$n.count===null||Fn.value&&!$n.showZero),Hn=computed(()=>($n.status!==null&&$n.status!==void 0||$n.color!==null&&$n.color!==void 0)&&Bn.value),zn=computed(()=>$n.dot&&!Fn.value),Wn=computed(()=>zn.value?"":Ln.value),Yn=computed(()=>(Wn.value===null||Wn.value===void 0||Wn.value===""||Fn.value&&!$n.showZero)&&!zn.value),Gn=ref($n.count),Go=ref(Wn.value),Xn=ref(zn.value);watch([()=>$n.count,Wn,zn],()=>{Yn.value||(Gn.value=$n.count,Go.value=Wn.value,Xn.value=zn.value)},{immediate:!0});const Yo=computed(()=>isPresetColor($n.color,!1)),qo=computed(()=>({[`${In.value}-status-dot`]:Hn.value,[`${In.value}-status-${$n.status}`]:!!$n.status,[`${In.value}-color-${$n.color}`]:Yo.value})),Jo=computed(()=>$n.color&&!Yo.value?{background:$n.color,color:$n.color}:{}),Zo=computed(()=>({[`${In.value}-dot`]:Xn.value,[`${In.value}-count`]:!Xn.value,[`${In.value}-count-sm`]:$n.size==="small",[`${In.value}-multiple-words`]:!Xn.value&&Go.value&&Go.value.toString().length>1,[`${In.value}-status-${$n.status}`]:!!$n.status,[`${In.value}-color-${$n.color}`]:Yo.value}));return()=>{var rr,nr;const{offset:ta,title:oa,color:ra}=$n,ea=Pn.style,la=getPropsSlot(_n,$n,"text"),ua=In.value,ga=Gn.value;let aa=flattenChildren((rr=_n.default)===null||rr===void 0?void 0:rr.call(_n));aa=aa.length?aa:null;const ca=!!(!Yn.value||_n.count),sa=(()=>{if(!ta)return _extends$1({},ea);const Ea={marginTop:isNumeric(ta[1])?`${ta[1]}px`:ta[1]};return Nn.value==="rtl"?Ea.left=`${parseInt(ta[0],10)}px`:Ea.right=`${-parseInt(ta[0],10)}px`,_extends$1(_extends$1({},Ea),ea)})(),ia=oa??(typeof ga=="string"||typeof ga=="number"?ga:void 0),fa=ca||!la?null:createVNode("span",{class:`${ua}-status-text`},[la]),ma=typeof ga=="object"||ga===void 0&&_n.count?cloneElement(ga??((nr=_n.count)===null||nr===void 0?void 0:nr.call(_n)),{style:sa},!1):null,ya=classNames(ua,{[`${ua}-status`]:Hn.value,[`${ua}-not-a-wrapper`]:!aa,[`${ua}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value);if(!aa&&Hn.value){const Ea=sa.color;return Rn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:ya,style:sa}),[createVNode("span",{class:qo.value,style:Jo.value},null),createVNode("span",{style:{color:Ea},class:`${ua}-status-text`},[la])]))}const ba=getTransitionProps(aa?`${ua}-zoom`:"",{appear:!1});let Ia=_extends$1(_extends$1({},sa),$n.numberStyle);return ra&&!Yo.value&&(Ia=Ia||{},Ia.background=ra),Rn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:ya}),[aa,createVNode(Transition,ba,{default:()=>[withDirectives(createVNode(ScrollNumber,{prefixCls:$n.scrollNumberPrefixCls,show:ca,class:Zo.value,count:Go.value,title:ia,style:Ia,key:"scrollNumber"},{default:()=>[ma]}),[[vShow,ca]])]}),fa]))}}});Badge.install=function($n){return $n.component(Badge.name,Badge),$n.component(Ribbon.name,Ribbon),$n};const autoAdjustOverflow$1={adjustX:1,adjustY:1},targetOffset$1=[0,0],placements$2={topLeft:{points:["bl","tl"],overflow:autoAdjustOverflow$1,offset:[0,-4],targetOffset:targetOffset$1},topCenter:{points:["bc","tc"],overflow:autoAdjustOverflow$1,offset:[0,-4],targetOffset:targetOffset$1},topRight:{points:["br","tr"],overflow:autoAdjustOverflow$1,offset:[0,-4],targetOffset:targetOffset$1},bottomLeft:{points:["tl","bl"],overflow:autoAdjustOverflow$1,offset:[0,4],targetOffset:targetOffset$1},bottomCenter:{points:["tc","bc"],overflow:autoAdjustOverflow$1,offset:[0,4],targetOffset:targetOffset$1},bottomRight:{points:["tr","br"],overflow:autoAdjustOverflow$1,offset:[0,4],targetOffset:targetOffset$1}},placements$3=placements$2;var __rest$12=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.visible,Wn=>{Wn!==void 0&&(Nn.value=Wn)});const Rn=ref();In({triggerRef:Rn});const Dn=Wn=>{$n.visible===void 0&&(Nn.value=!1),Pn("overlayClick",Wn)},Ln=Wn=>{$n.visible===void 0&&(Nn.value=Wn),Pn("visibleChange",Wn)},Fn=()=>{var Wn;const Yn=(Wn=_n.overlay)===null||Wn===void 0?void 0:Wn.call(_n),Gn={prefixCls:`${$n.prefixCls}-menu`,onClick:Dn};return createVNode(Fragment,{key:skipFlattenKey},[$n.arrow&&createVNode("div",{class:`${$n.prefixCls}-arrow`},null),cloneElement(Yn,Gn,!1)])},Bn=computed(()=>{const{minOverlayWidthMatchTrigger:Wn=!$n.alignPoint}=$n;return Wn}),Hn=()=>{var Wn;const Yn=(Wn=_n.default)===null||Wn===void 0?void 0:Wn.call(_n);return Nn.value&&Yn?cloneElement(Yn[0],{class:$n.openClassName||`${$n.prefixCls}-open`},!1):Yn},zn=computed(()=>!$n.hideAction&&$n.trigger.indexOf("contextmenu")!==-1?["click"]:$n.hideAction);return()=>{const{prefixCls:Wn,arrow:Yn,showAction:Gn,overlayStyle:Go,trigger:Xn,placement:Yo,align:qo,getPopupContainer:Jo,transitionName:Zo,animation:rr,overlayClassName:nr}=$n,ta=__rest$12($n,["prefixCls","arrow","showAction","overlayStyle","trigger","placement","align","getPopupContainer","transitionName","animation","overlayClassName"]);return createVNode(Trigger,_objectSpread2$1(_objectSpread2$1({},ta),{},{prefixCls:Wn,ref:Rn,popupClassName:classNames(nr,{[`${Wn}-show-arrow`]:Yn}),popupStyle:Go,builtinPlacements:placements$3,action:Xn,showAction:Gn,hideAction:zn.value||[],popupPlacement:Yo,popupAlign:qo,popupTransitionName:Zo,popupAnimation:rr,popupVisible:Nn.value,stretch:Bn.value?"minWidth":"",onPopupVisibleChange:Ln,getPopupContainer:Jo}),{popup:Fn,default:Hn})}}}),genWaveStyle=$n=>{const{componentCls:Cn,colorPrimary:_n}=$n;return{[Cn]:{position:"absolute",background:"transparent",pointerEvents:"none",boxSizing:"border-box",color:`var(--wave-color, ${_n})`,boxShadow:"0 0 0 0 currentcolor",opacity:.2,"&.wave-motion-appear":{transition:[`box-shadow 0.4s ${$n.motionEaseOutCirc}`,`opacity 2s ${$n.motionEaseOutCirc}`].join(","),"&-active":{boxShadow:"0 0 0 6px currentcolor",opacity:0}}}}},useStyle$Q=genComponentStyleHook("Wave",$n=>[genWaveStyle($n)]);function isNotGrey($n){const Cn=($n||"").match(/rgba?\((\d*), (\d*), (\d*)(, [\d.]*)?\)/);return Cn&&Cn[1]&&Cn[2]&&Cn[3]?!(Cn[1]===Cn[2]&&Cn[2]===Cn[3]):!0}function isValidWaveColor($n){return $n&&$n!=="#fff"&&$n!=="#ffffff"&&$n!=="rgb(255, 255, 255)"&&$n!=="rgba(255, 255, 255, 1)"&&isNotGrey($n)&&!/rgba\((?:\d*, ){3}0\)/.test($n)&&$n!=="transparent"}function getTargetWaveColor($n){const{borderTopColor:Cn,borderColor:_n,backgroundColor:Pn}=getComputedStyle($n);return isValidWaveColor(Cn)?Cn:isValidWaveColor(_n)?_n:isValidWaveColor(Pn)?Pn:null}function validateNum($n){return Number.isNaN($n)?0:$n}const WaveEffect=defineComponent({props:{target:objectType(),className:String},setup($n){const Cn=shallowRef(null),[_n,Pn]=useState(null),[In,Nn]=useState([]),[Rn,Dn]=useState(0),[Ln,Fn]=useState(0),[Bn,Hn]=useState(0),[zn,Wn]=useState(0),[Yn,Gn]=useState(!1);function Go(){const{target:nr}=$n,ta=getComputedStyle(nr);Pn(getTargetWaveColor(nr));const oa=ta.position==="static",{borderLeftWidth:ra,borderTopWidth:ea}=ta;Dn(oa?nr.offsetLeft:validateNum(-parseFloat(ra))),Fn(oa?nr.offsetTop:validateNum(-parseFloat(ea))),Hn(nr.offsetWidth),Wn(nr.offsetHeight);const{borderTopLeftRadius:la,borderTopRightRadius:ua,borderBottomLeftRadius:ga,borderBottomRightRadius:aa}=ta;Nn([la,ua,aa,ga].map(ca=>validateNum(parseFloat(ca))))}let Xn,Yo,qo;const Jo=()=>{clearTimeout(qo),wrapperRaf.cancel(Yo),Xn==null||Xn.disconnect()},Zo=()=>{var nr;const ta=(nr=Cn.value)===null||nr===void 0?void 0:nr.parentElement;ta&&(render$1(null,ta),ta.parentElement&&ta.parentElement.removeChild(ta))};onMounted(()=>{Jo(),qo=setTimeout(()=>{Zo()},5e3);const{target:nr}=$n;nr&&(Yo=wrapperRaf(()=>{Go(),Gn(!0)}),typeof ResizeObserver<"u"&&(Xn=new ResizeObserver(Go),Xn.observe(nr)))}),onBeforeUnmount(()=>{Jo()});const rr=nr=>{nr.propertyName==="opacity"&&Zo()};return()=>{if(!Yn.value)return null;const nr={left:`${Rn.value}px`,top:`${Ln.value}px`,width:`${Bn.value}px`,height:`${zn.value}px`,borderRadius:In.value.map(ta=>`${ta}px`).join(" ")};return _n&&(nr["--wave-color"]=_n.value),createVNode(Transition,{appear:!0,name:"wave-motion",appearFromClass:"wave-motion-appear",appearActiveClass:"wave-motion-appear",appearToClass:"wave-motion-appear wave-motion-appear-active"},{default:()=>[createVNode("div",{ref:Cn,class:$n.className,style:nr,onTransitionend:rr},null)]})}}});function showWaveEffect($n,Cn){const _n=document.createElement("div");_n.style.position="absolute",_n.style.left="0px",_n.style.top="0px",$n==null||$n.insertBefore(_n,$n==null?void 0:$n.firstChild),render$1(createVNode(WaveEffect,{target:$n,className:Cn},null),_n)}function useWave($n,Cn,_n){function Pn(){var In;const Nn=findDOMNode($n);!((In=_n==null?void 0:_n.value)===null||In===void 0)&&In.disabled||!Nn||showWaveEffect(Nn,Cn.value)}return Pn}const Wave=defineComponent({compatConfig:{MODE:3},name:"Wave",props:{disabled:Boolean},setup($n,Cn){let{slots:_n}=Cn;const Pn=getCurrentInstance(),{prefixCls:In,wave:Nn}=useConfigInject("wave",$n),[,Rn]=useStyle$Q(In),Dn=useWave(Pn,computed(()=>classNames(In.value,Rn.value)),Nn);let Ln;const Fn=()=>{findDOMNode(Pn).removeEventListener("click",Ln,!0)};return onMounted(()=>{watch(()=>$n.disabled,()=>{Fn(),nextTick(()=>{const Bn=findDOMNode(Pn);Bn==null||Bn.removeEventListener("click",Ln,!0),!(!Bn||Bn.nodeType!==1||$n.disabled)&&(Ln=Hn=>{Hn.target.tagName==="INPUT"||!isVisible(Hn.target)||!Bn.getAttribute||Bn.getAttribute("disabled")||Bn.disabled||Bn.className.includes("disabled")||Bn.className.includes("-leave")||Dn()},Bn.addEventListener("click",Ln,!0))})},{immediate:!0,flush:"post"})}),onBeforeUnmount(()=>{Fn()}),()=>{var Bn;return(Bn=_n.default)===null||Bn===void 0?void 0:Bn.call(_n)[0]}}});function convertLegacyProps($n){return $n==="danger"?{danger:!0}:{type:$n}}const buttonProps=()=>({prefixCls:String,type:String,htmlType:{type:String,default:"button"},shape:{type:String},size:{type:String},loading:{type:[Boolean,Object],default:()=>!1},disabled:{type:Boolean,default:void 0},ghost:{type:Boolean,default:void 0},block:{type:Boolean,default:void 0},danger:{type:Boolean,default:void 0},icon:PropTypes.any,href:String,target:String,title:String,onClick:eventType(),onMousedown:eventType()}),getCollapsedWidth=$n=>{$n&&($n.style.width="0px",$n.style.opacity="0",$n.style.transform="scale(0)")},getRealWidth=$n=>{nextTick(()=>{$n&&($n.style.width=`${$n.scrollWidth}px`,$n.style.opacity="1",$n.style.transform="scale(1)")})},resetStyle=$n=>{$n&&$n.style&&($n.style.width=null,$n.style.opacity=null,$n.style.transform=null)},LoadingIcon=defineComponent({compatConfig:{MODE:3},name:"LoadingIcon",props:{prefixCls:String,loading:[Boolean,Object],existIcon:Boolean},setup($n){return()=>{const{existIcon:Cn,prefixCls:_n,loading:Pn}=$n;if(Cn)return createVNode("span",{class:`${_n}-loading-icon`},[createVNode(LoadingOutlined$1,null,null)]);const In=!!Pn;return createVNode(Transition,{name:`${_n}-loading-icon-motion`,onBeforeEnter:getCollapsedWidth,onEnter:getRealWidth,onAfterEnter:resetStyle,onBeforeLeave:getRealWidth,onLeave:Nn=>{setTimeout(()=>{getCollapsedWidth(Nn)})},onAfterLeave:resetStyle},{default:()=>[In?createVNode("span",{class:`${_n}-loading-icon`},[createVNode(LoadingOutlined$1,null,null)]):null]})}}}),genButtonBorderStyle=($n,Cn)=>({[`> span, > ${$n}`]:{"&:not(:last-child)":{[`&, & > ${$n}`]:{"&:not(:disabled)":{borderInlineEndColor:Cn}}},"&:not(:first-child)":{[`&, & > ${$n}`]:{"&:not(:disabled)":{borderInlineStartColor:Cn}}}}}),genGroupStyle$1=$n=>{const{componentCls:Cn,fontSize:_n,lineWidth:Pn,colorPrimaryHover:In,colorErrorHover:Nn}=$n;return{[`${Cn}-group`]:[{position:"relative",display:"inline-flex",[`> span, > ${Cn}`]:{"&:not(:last-child)":{[`&, & > ${Cn}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},"&:not(:first-child)":{marginInlineStart:-Pn,[`&, & > ${Cn}`]:{borderStartStartRadius:0,borderEndStartRadius:0}}},[Cn]:{position:"relative",zIndex:1,"&:hover,\n &:focus,\n &:active":{zIndex:2},"&[disabled]":{zIndex:0}},[`${Cn}-icon-only`]:{fontSize:_n}},genButtonBorderStyle(`${Cn}-primary`,In),genButtonBorderStyle(`${Cn}-danger`,Nn)]}},genGroupStyle$2=genGroupStyle$1;function compactItemVerticalBorder($n,Cn){return{[`&-item:not(${Cn}-last-item)`]:{marginBottom:-$n.lineWidth},"&-item":{"&:hover,&:focus,&:active":{zIndex:2},"&[disabled]":{zIndex:0}}}}function compactItemBorderVerticalRadius($n,Cn){return{[`&-item:not(${Cn}-first-item):not(${Cn}-last-item)`]:{borderRadius:0},[`&-item${Cn}-first-item:not(${Cn}-last-item)`]:{[`&, &${$n}-sm, &${$n}-lg`]:{borderEndEndRadius:0,borderEndStartRadius:0}},[`&-item${Cn}-last-item:not(${Cn}-first-item)`]:{[`&, &${$n}-sm, &${$n}-lg`]:{borderStartStartRadius:0,borderStartEndRadius:0}}}}function genCompactItemVerticalStyle($n){const Cn=`${$n.componentCls}-compact-vertical`;return{[Cn]:_extends$1(_extends$1({},compactItemVerticalBorder($n,Cn)),compactItemBorderVerticalRadius($n.componentCls,Cn))}}const genSharedButtonStyle=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[Cn]:{outline:"none",position:"relative",display:"inline-block",fontWeight:400,whiteSpace:"nowrap",textAlign:"center",backgroundImage:"none",backgroundColor:"transparent",border:`${$n.lineWidth}px ${$n.lineType} transparent`,cursor:"pointer",transition:`all ${$n.motionDurationMid} ${$n.motionEaseInOut}`,userSelect:"none",touchAction:"manipulation",lineHeight:$n.lineHeight,color:$n.colorText,"> span":{display:"inline-block"},[`> ${_n} + span, > span + ${_n}`]:{marginInlineStart:$n.marginXS},"> a":{color:"currentColor"},"&:not(:disabled)":_extends$1({},genFocusStyle($n)),[`&-icon-only${Cn}-compact-item`]:{flex:"none"},[`&-compact-item${Cn}-primary`]:{[`&:not([disabled]) + ${Cn}-compact-item${Cn}-primary:not([disabled])`]:{position:"relative","&:before":{position:"absolute",top:-$n.lineWidth,insetInlineStart:-$n.lineWidth,display:"inline-block",width:$n.lineWidth,height:`calc(100% + ${$n.lineWidth*2}px)`,backgroundColor:$n.colorPrimaryHover,content:'""'}}},"&-compact-vertical-item":{[`&${Cn}-primary`]:{[`&:not([disabled]) + ${Cn}-compact-vertical-item${Cn}-primary:not([disabled])`]:{position:"relative","&:before":{position:"absolute",top:-$n.lineWidth,insetInlineStart:-$n.lineWidth,display:"inline-block",width:`calc(100% + ${$n.lineWidth*2}px)`,height:$n.lineWidth,backgroundColor:$n.colorPrimaryHover,content:'""'}}}}}}},genHoverActiveButtonStyle=($n,Cn)=>({"&:not(:disabled)":{"&:hover":$n,"&:active":Cn}}),genCircleButtonStyle=$n=>({minWidth:$n.controlHeight,paddingInlineStart:0,paddingInlineEnd:0,borderRadius:"50%"}),genRoundButtonStyle=$n=>({borderRadius:$n.controlHeight,paddingInlineStart:$n.controlHeight/2,paddingInlineEnd:$n.controlHeight/2}),genDisabledStyle$1=$n=>({cursor:"not-allowed",borderColor:$n.colorBorder,color:$n.colorTextDisabled,backgroundColor:$n.colorBgContainerDisabled,boxShadow:"none"}),genGhostButtonStyle=($n,Cn,_n,Pn,In,Nn,Rn)=>({[`&${$n}-background-ghost`]:_extends$1(_extends$1({color:Cn||void 0,backgroundColor:"transparent",borderColor:_n||void 0,boxShadow:"none"},genHoverActiveButtonStyle(_extends$1({backgroundColor:"transparent"},Nn),_extends$1({backgroundColor:"transparent"},Rn))),{"&:disabled":{cursor:"not-allowed",color:Pn||void 0,borderColor:In||void 0}})}),genSolidDisabledButtonStyle=$n=>({"&:disabled":_extends$1({},genDisabledStyle$1($n))}),genSolidButtonStyle=$n=>_extends$1({},genSolidDisabledButtonStyle($n)),genPureDisabledButtonStyle=$n=>({"&:disabled":{cursor:"not-allowed",color:$n.colorTextDisabled}}),genDefaultButtonStyle=$n=>_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},genSolidButtonStyle($n)),{backgroundColor:$n.colorBgContainer,borderColor:$n.colorBorder,boxShadow:`0 ${$n.controlOutlineWidth}px 0 ${$n.controlTmpOutline}`}),genHoverActiveButtonStyle({color:$n.colorPrimaryHover,borderColor:$n.colorPrimaryHover},{color:$n.colorPrimaryActive,borderColor:$n.colorPrimaryActive})),genGhostButtonStyle($n.componentCls,$n.colorBgContainer,$n.colorBgContainer,$n.colorTextDisabled,$n.colorBorder)),{[`&${$n.componentCls}-dangerous`]:_extends$1(_extends$1(_extends$1({color:$n.colorError,borderColor:$n.colorError},genHoverActiveButtonStyle({color:$n.colorErrorHover,borderColor:$n.colorErrorBorderHover},{color:$n.colorErrorActive,borderColor:$n.colorErrorActive})),genGhostButtonStyle($n.componentCls,$n.colorError,$n.colorError,$n.colorTextDisabled,$n.colorBorder)),genSolidDisabledButtonStyle($n))}),genPrimaryButtonStyle=$n=>_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},genSolidButtonStyle($n)),{color:$n.colorTextLightSolid,backgroundColor:$n.colorPrimary,boxShadow:`0 ${$n.controlOutlineWidth}px 0 ${$n.controlOutline}`}),genHoverActiveButtonStyle({color:$n.colorTextLightSolid,backgroundColor:$n.colorPrimaryHover},{color:$n.colorTextLightSolid,backgroundColor:$n.colorPrimaryActive})),genGhostButtonStyle($n.componentCls,$n.colorPrimary,$n.colorPrimary,$n.colorTextDisabled,$n.colorBorder,{color:$n.colorPrimaryHover,borderColor:$n.colorPrimaryHover},{color:$n.colorPrimaryActive,borderColor:$n.colorPrimaryActive})),{[`&${$n.componentCls}-dangerous`]:_extends$1(_extends$1(_extends$1({backgroundColor:$n.colorError,boxShadow:`0 ${$n.controlOutlineWidth}px 0 ${$n.colorErrorOutline}`},genHoverActiveButtonStyle({backgroundColor:$n.colorErrorHover},{backgroundColor:$n.colorErrorActive})),genGhostButtonStyle($n.componentCls,$n.colorError,$n.colorError,$n.colorTextDisabled,$n.colorBorder,{color:$n.colorErrorHover,borderColor:$n.colorErrorHover},{color:$n.colorErrorActive,borderColor:$n.colorErrorActive})),genSolidDisabledButtonStyle($n))}),genDashedButtonStyle=$n=>_extends$1(_extends$1({},genDefaultButtonStyle($n)),{borderStyle:"dashed"}),genLinkButtonStyle=$n=>_extends$1(_extends$1(_extends$1({color:$n.colorLink},genHoverActiveButtonStyle({color:$n.colorLinkHover},{color:$n.colorLinkActive})),genPureDisabledButtonStyle($n)),{[`&${$n.componentCls}-dangerous`]:_extends$1(_extends$1({color:$n.colorError},genHoverActiveButtonStyle({color:$n.colorErrorHover},{color:$n.colorErrorActive})),genPureDisabledButtonStyle($n))}),genTextButtonStyle=$n=>_extends$1(_extends$1(_extends$1({},genHoverActiveButtonStyle({color:$n.colorText,backgroundColor:$n.colorBgTextHover},{color:$n.colorText,backgroundColor:$n.colorBgTextActive})),genPureDisabledButtonStyle($n)),{[`&${$n.componentCls}-dangerous`]:_extends$1(_extends$1({color:$n.colorError},genPureDisabledButtonStyle($n)),genHoverActiveButtonStyle({color:$n.colorErrorHover,backgroundColor:$n.colorErrorBg},{color:$n.colorErrorHover,backgroundColor:$n.colorErrorBg}))}),genDisabledButtonStyle=$n=>_extends$1(_extends$1({},genDisabledStyle$1($n)),{[`&${$n.componentCls}:hover`]:_extends$1({},genDisabledStyle$1($n))}),genTypeButtonStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-default`]:genDefaultButtonStyle($n),[`${Cn}-primary`]:genPrimaryButtonStyle($n),[`${Cn}-dashed`]:genDashedButtonStyle($n),[`${Cn}-link`]:genLinkButtonStyle($n),[`${Cn}-text`]:genTextButtonStyle($n),[`${Cn}-disabled`]:genDisabledButtonStyle($n)}},genSizeButtonStyle=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";const{componentCls:_n,iconCls:Pn,controlHeight:In,fontSize:Nn,lineHeight:Rn,lineWidth:Dn,borderRadius:Ln,buttonPaddingHorizontal:Fn}=$n,Bn=Math.max(0,(In-Nn*Rn)/2-Dn),Hn=Fn-Dn,zn=`${_n}-icon-only`;return[{[`${_n}${Cn}`]:{fontSize:Nn,height:In,padding:`${Bn}px ${Hn}px`,borderRadius:Ln,[`&${zn}`]:{width:In,paddingInlineStart:0,paddingInlineEnd:0,[`&${_n}-round`]:{width:"auto"},"> span":{transform:"scale(1.143)"}},[`&${_n}-loading`]:{opacity:$n.opacityLoading,cursor:"default"},[`${_n}-loading-icon`]:{transition:`width ${$n.motionDurationSlow} ${$n.motionEaseInOut}, opacity ${$n.motionDurationSlow} ${$n.motionEaseInOut}`},[`&:not(${zn}) ${_n}-loading-icon > ${Pn}`]:{marginInlineEnd:$n.marginXS}}},{[`${_n}${_n}-circle${Cn}`]:genCircleButtonStyle($n)},{[`${_n}${_n}-round${Cn}`]:genRoundButtonStyle($n)}]},genSizeBaseButtonStyle=$n=>genSizeButtonStyle($n),genSizeSmallButtonStyle=$n=>{const Cn=merge$1($n,{controlHeight:$n.controlHeightSM,padding:$n.paddingXS,buttonPaddingHorizontal:8,borderRadius:$n.borderRadiusSM});return genSizeButtonStyle(Cn,`${$n.componentCls}-sm`)},genSizeLargeButtonStyle=$n=>{const Cn=merge$1($n,{controlHeight:$n.controlHeightLG,fontSize:$n.fontSizeLG,borderRadius:$n.borderRadiusLG});return genSizeButtonStyle(Cn,`${$n.componentCls}-lg`)},genBlockButtonStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{[`&${Cn}-block`]:{width:"100%"}}}},useStyle$P=genComponentStyleHook("Button",$n=>{const{controlTmpOutline:Cn,paddingContentHorizontal:_n}=$n,Pn=merge$1($n,{colorOutlineDefault:Cn,buttonPaddingHorizontal:_n});return[genSharedButtonStyle(Pn),genSizeSmallButtonStyle(Pn),genSizeBaseButtonStyle(Pn),genSizeLargeButtonStyle(Pn),genBlockButtonStyle(Pn),genTypeButtonStyle(Pn),genGroupStyle$2(Pn),genCompactItemStyle($n,{focus:!1}),genCompactItemVerticalStyle($n)]}),buttonGroupProps=()=>({prefixCls:String,size:{type:String}}),GroupSizeContext=createContext(),ButtonGroup$1=defineComponent({compatConfig:{MODE:3},name:"AButtonGroup",props:buttonGroupProps(),setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn,direction:In}=useConfigInject("btn-group",$n),[,,Nn]=useToken();GroupSizeContext.useProvide(reactive({size:computed(()=>$n.size)}));const Rn=computed(()=>{const{size:Dn}=$n;let Ln="";switch(Dn){case"large":Ln="lg";break;case"small":Ln="sm";break;case"middle":case void 0:break;default:devWarning(!Dn,"Button.Group","Invalid prop `size`.")}return{[`${Pn.value}`]:!0,[`${Pn.value}-${Ln}`]:Ln,[`${Pn.value}-rtl`]:In.value==="rtl",[Nn.value]:!0}});return()=>{var Dn;return createVNode("div",{class:Rn.value},[flattenChildren((Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n))])}}}),rxTwoCNChar=/^[\u4e00-\u9fa5]{2}$/,isTwoCNChar=rxTwoCNChar.test.bind(rxTwoCNChar);function isUnBorderedButtonType($n){return $n==="text"||$n==="link"}const Button$1=defineComponent({compatConfig:{MODE:3},name:"AButton",inheritAttrs:!1,__ANT_BUTTON:!0,props:initDefaultProps(buttonProps(),{type:"default"}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,emit:In,expose:Nn}=Cn;const{prefixCls:Rn,autoInsertSpaceInButton:Dn,direction:Ln,size:Fn}=useConfigInject("btn",$n),[Bn,Hn]=useStyle$P(Rn),zn=GroupSizeContext.useInject(),Wn=useInjectDisabled(),Yn=computed(()=>{var aa;return(aa=$n.disabled)!==null&&aa!==void 0?aa:Wn.value}),Gn=shallowRef(null),Go=shallowRef(void 0);let Xn=!1;const Yo=shallowRef(!1),qo=shallowRef(!1),Jo=computed(()=>Dn.value!==!1),{compactSize:Zo,compactItemClassnames:rr}=useCompactItemContext(Rn,Ln),nr=computed(()=>typeof $n.loading=="object"&&$n.loading.delay?$n.loading.delay||!0:!!$n.loading);watch(nr,aa=>{clearTimeout(Go.value),typeof nr.value=="number"?Go.value=setTimeout(()=>{Yo.value=aa},nr.value):Yo.value=aa},{immediate:!0});const ta=computed(()=>{const{type:aa,shape:ca="default",ghost:sa,block:ia,danger:fa}=$n,ma=Rn.value,ya={large:"lg",small:"sm",middle:void 0},ba=Zo.value||(zn==null?void 0:zn.size)||Fn.value,Ia=ba&&ya[ba]||"";return[rr.value,{[Hn.value]:!0,[`${ma}`]:!0,[`${ma}-${ca}`]:ca!=="default"&&ca,[`${ma}-${aa}`]:aa,[`${ma}-${Ia}`]:Ia,[`${ma}-loading`]:Yo.value,[`${ma}-background-ghost`]:sa&&!isUnBorderedButtonType(aa),[`${ma}-two-chinese-chars`]:qo.value&&Jo.value,[`${ma}-block`]:ia,[`${ma}-dangerous`]:!!fa,[`${ma}-rtl`]:Ln.value==="rtl"}]}),oa=()=>{const aa=Gn.value;if(!aa||Dn.value===!1)return;const ca=aa.textContent;Xn&&isTwoCNChar(ca)?qo.value||(qo.value=!0):qo.value&&(qo.value=!1)},ra=aa=>{if(Yo.value||Yn.value){aa.preventDefault();return}In("click",aa)},ea=aa=>{In("mousedown",aa)},la=(aa,ca)=>{const sa=ca?" ":"";if(aa.type===Text$2){let ia=aa.children.trim();return isTwoCNChar(ia)&&(ia=ia.split("").join(sa)),createVNode("span",null,[ia])}return aa};return watchEffect(()=>{devWarning(!($n.ghost&&isUnBorderedButtonType($n.type)),"Button","`link` or `text` button can't be a `ghost` button.")}),onMounted(oa),onUpdated(oa),onBeforeUnmount(()=>{Go.value&&clearTimeout(Go.value)}),Nn({focus:()=>{var aa;(aa=Gn.value)===null||aa===void 0||aa.focus()},blur:()=>{var aa;(aa=Gn.value)===null||aa===void 0||aa.blur()}}),()=>{var aa,ca;const{icon:sa=(aa=_n.icon)===null||aa===void 0?void 0:aa.call(_n)}=$n,ia=flattenChildren((ca=_n.default)===null||ca===void 0?void 0:ca.call(_n));Xn=ia.length===1&&!sa&&!isUnBorderedButtonType($n.type);const{type:fa,htmlType:ma,href:ya,title:ba,target:Ia}=$n,Ea=Yo.value?"loading":sa,xa=_extends$1(_extends$1({},Pn),{title:ba,disabled:Yn.value,class:[ta.value,Pn.class,{[`${Rn.value}-icon-only`]:ia.length===0&&!!Ea}],onClick:ra,onMousedown:ea});Yn.value||delete xa.disabled;const Ta=sa&&!Yo.value?sa:createVNode(LoadingIcon,{existIcon:!!sa,prefixCls:Rn.value,loading:!!Yo.value},null),wa=ia.map(Na=>la(Na,Xn&&Jo.value));if(ya!==void 0)return Bn(createVNode("a",_objectSpread2$1(_objectSpread2$1({},xa),{},{href:ya,target:Ia,ref:Gn}),[Ta,wa]));let La=createVNode("button",_objectSpread2$1(_objectSpread2$1({},xa),{},{ref:Gn,type:ma}),[Ta,wa]);if(!isUnBorderedButtonType(fa)){const Na=function(){return La}();La=createVNode(Wave,{ref:"wave",disabled:!!Yo.value},{default:()=>[Na]})}return Bn(La)}}});Button$1.Group=ButtonGroup$1;Button$1.install=function($n){return $n.component(Button$1.name,Button$1),$n.component(ButtonGroup$1.name,ButtonGroup$1),$n};const dropdownProps=()=>({arrow:someType([Boolean,Object]),trigger:{type:[Array,String]},menu:objectType(),overlay:PropTypes.any,visible:booleanType(),open:booleanType(),disabled:booleanType(),danger:booleanType(),autofocus:booleanType(),align:objectType(),getPopupContainer:Function,prefixCls:String,transitionName:String,placement:String,overlayClassName:String,overlayStyle:objectType(),forceRender:booleanType(),mouseEnterDelay:Number,mouseLeaveDelay:Number,openClassName:String,minOverlayWidthMatchTrigger:booleanType(),destroyPopupOnHide:booleanType(),onVisibleChange:{type:Function},"onUpdate:visible":{type:Function},onOpenChange:{type:Function},"onUpdate:open":{type:Function}}),buttonTypesProps=buttonProps(),dropdownButtonProps=()=>_extends$1(_extends$1({},dropdownProps()),{type:buttonTypesProps.type,size:String,htmlType:buttonTypesProps.htmlType,href:String,disabled:booleanType(),prefixCls:String,icon:PropTypes.any,title:String,loading:buttonTypesProps.loading,onClick:eventType()});var EllipsisOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"ellipsis",theme:"outlined"};const EllipsisOutlinedSvg=EllipsisOutlined$2;function _objectSpread$G($n){for(var Cn=1;Cn{const{componentCls:Cn,antCls:_n,paddingXS:Pn,opacityLoading:In}=$n;return{[`${Cn}-button`]:{whiteSpace:"nowrap",[`&${_n}-btn-group > ${_n}-btn`]:{[`&-loading, &-loading + ${_n}-btn`]:{cursor:"default",pointerEvents:"none",opacity:In},[`&:last-child:not(:first-child):not(${_n}-btn-icon-only)`]:{paddingInline:Pn}}}}},genButtonStyle$1=genButtonStyle,genStatusStyle$1=$n=>{const{componentCls:Cn,menuCls:_n,colorError:Pn,colorTextLightSolid:In}=$n,Nn=`${_n}-item`;return{[`${Cn}, ${Cn}-menu-submenu`]:{[`${_n} ${Nn}`]:{[`&${Nn}-danger:not(${Nn}-disabled)`]:{color:Pn,"&:hover":{color:In,backgroundColor:Pn}}}}}},genStatusStyle$2=genStatusStyle$1,genBaseStyle$f=$n=>{const{componentCls:Cn,menuCls:_n,zIndexPopup:Pn,dropdownArrowDistance:In,dropdownArrowOffset:Nn,sizePopupArrow:Rn,antCls:Dn,iconCls:Ln,motionDurationMid:Fn,dropdownPaddingVertical:Bn,fontSize:Hn,dropdownEdgeChildPadding:zn,colorTextDisabled:Wn,fontSizeIcon:Yn,controlPaddingHorizontal:Gn,colorBgElevated:Go,boxShadowPopoverArrow:Xn}=$n;return[{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:-9999,left:{_skip_check_:!0,value:-9999},zIndex:Pn,display:"block","&::before":{position:"absolute",insetBlock:-In+Rn/2,zIndex:-9999,opacity:1e-4,content:'""'},[`${Cn}-wrap`]:{position:"relative",[`${Dn}-btn > ${Ln}-down`]:{fontSize:Yn},[`${Ln}-down::before`]:{transition:`transform ${Fn}`}},[`${Cn}-wrap-open`]:{[`${Ln}-down::before`]:{transform:"rotate(180deg)"}},"\n &-hidden,\n &-menu-hidden,\n &-menu-submenu-hidden\n ":{display:"none"},[` - &-show-arrow${Cn}-placement-topLeft, - &-show-arrow${Cn}-placement-top, - &-show-arrow${Cn}-placement-topRight - `]:{paddingBottom:In},[` - &-show-arrow${Cn}-placement-bottomLeft, - &-show-arrow${Cn}-placement-bottom, - &-show-arrow${Cn}-placement-bottomRight - `]:{paddingTop:In},[`${Cn}-arrow`]:_extends$1({position:"absolute",zIndex:1,display:"block"},roundedArrow(Rn,$n.borderRadiusXS,$n.borderRadiusOuter,Go,Xn)),[` - &-placement-top > ${Cn}-arrow, - &-placement-topLeft > ${Cn}-arrow, - &-placement-topRight > ${Cn}-arrow - `]:{bottom:In,transform:"translateY(100%) rotate(180deg)"},[`&-placement-top > ${Cn}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%) translateY(100%) rotate(180deg)"},[`&-placement-topLeft > ${Cn}-arrow`]:{left:{_skip_check_:!0,value:Nn}},[`&-placement-topRight > ${Cn}-arrow`]:{right:{_skip_check_:!0,value:Nn}},[` - &-placement-bottom > ${Cn}-arrow, - &-placement-bottomLeft > ${Cn}-arrow, - &-placement-bottomRight > ${Cn}-arrow - `]:{top:In,transform:"translateY(-100%)"},[`&-placement-bottom > ${Cn}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateY(-100%) translateX(-50%)"},[`&-placement-bottomLeft > ${Cn}-arrow`]:{left:{_skip_check_:!0,value:Nn}},[`&-placement-bottomRight > ${Cn}-arrow`]:{right:{_skip_check_:!0,value:Nn}},[`&${Dn}-slide-down-enter${Dn}-slide-down-enter-active${Cn}-placement-bottomLeft, - &${Dn}-slide-down-appear${Dn}-slide-down-appear-active${Cn}-placement-bottomLeft, - &${Dn}-slide-down-enter${Dn}-slide-down-enter-active${Cn}-placement-bottom, - &${Dn}-slide-down-appear${Dn}-slide-down-appear-active${Cn}-placement-bottom, - &${Dn}-slide-down-enter${Dn}-slide-down-enter-active${Cn}-placement-bottomRight, - &${Dn}-slide-down-appear${Dn}-slide-down-appear-active${Cn}-placement-bottomRight`]:{animationName:slideUpIn},[`&${Dn}-slide-up-enter${Dn}-slide-up-enter-active${Cn}-placement-topLeft, - &${Dn}-slide-up-appear${Dn}-slide-up-appear-active${Cn}-placement-topLeft, - &${Dn}-slide-up-enter${Dn}-slide-up-enter-active${Cn}-placement-top, - &${Dn}-slide-up-appear${Dn}-slide-up-appear-active${Cn}-placement-top, - &${Dn}-slide-up-enter${Dn}-slide-up-enter-active${Cn}-placement-topRight, - &${Dn}-slide-up-appear${Dn}-slide-up-appear-active${Cn}-placement-topRight`]:{animationName:slideDownIn},[`&${Dn}-slide-down-leave${Dn}-slide-down-leave-active${Cn}-placement-bottomLeft, - &${Dn}-slide-down-leave${Dn}-slide-down-leave-active${Cn}-placement-bottom, - &${Dn}-slide-down-leave${Dn}-slide-down-leave-active${Cn}-placement-bottomRight`]:{animationName:slideUpOut},[`&${Dn}-slide-up-leave${Dn}-slide-up-leave-active${Cn}-placement-topLeft, - &${Dn}-slide-up-leave${Dn}-slide-up-leave-active${Cn}-placement-top, - &${Dn}-slide-up-leave${Dn}-slide-up-leave-active${Cn}-placement-topRight`]:{animationName:slideDownOut}})},{[`${Cn} ${_n}`]:{position:"relative",margin:0},[`${_n}-submenu-popup`]:{position:"absolute",zIndex:Pn,background:"transparent",boxShadow:"none",transformOrigin:"0 0","ul,li":{listStyle:"none"},ul:{marginInline:"0.3em"}},[`${Cn}, ${Cn}-menu-submenu`]:{[_n]:_extends$1(_extends$1({padding:zn,listStyleType:"none",backgroundColor:Go,backgroundClip:"padding-box",borderRadius:$n.borderRadiusLG,outline:"none",boxShadow:$n.boxShadowSecondary},genFocusStyle($n)),{[`${_n}-item-group-title`]:{padding:`${Bn}px ${Gn}px`,color:$n.colorTextDescription,transition:`all ${Fn}`},[`${_n}-item`]:{position:"relative",display:"flex",alignItems:"center",borderRadius:$n.borderRadiusSM},[`${_n}-item-icon`]:{minWidth:Hn,marginInlineEnd:$n.marginXS,fontSize:$n.fontSizeSM},[`${_n}-title-content`]:{flex:"auto","> a":{color:"inherit",transition:`all ${Fn}`,"&:hover":{color:"inherit"},"&::after":{position:"absolute",inset:0,content:'""'}}},[`${_n}-item, ${_n}-submenu-title`]:_extends$1(_extends$1({clear:"both",margin:0,padding:`${Bn}px ${Gn}px`,color:$n.colorText,fontWeight:"normal",fontSize:Hn,lineHeight:$n.lineHeight,cursor:"pointer",transition:`all ${Fn}`,"&:hover, &-active":{backgroundColor:$n.controlItemBgHover}},genFocusStyle($n)),{"&-selected":{color:$n.colorPrimary,backgroundColor:$n.controlItemBgActive,"&:hover, &-active":{backgroundColor:$n.controlItemBgActiveHover}},"&-disabled":{color:Wn,cursor:"not-allowed","&:hover":{color:Wn,backgroundColor:Go,cursor:"not-allowed"},a:{pointerEvents:"none"}},"&-divider":{height:1,margin:`${$n.marginXXS}px 0`,overflow:"hidden",lineHeight:0,backgroundColor:$n.colorSplit},[`${Cn}-menu-submenu-expand-icon`]:{position:"absolute",insetInlineEnd:$n.paddingXS,[`${Cn}-menu-submenu-arrow-icon`]:{marginInlineEnd:"0 !important",color:$n.colorTextDescription,fontSize:Yn,fontStyle:"normal"}}}),[`${_n}-item-group-list`]:{margin:`0 ${$n.marginXS}px`,padding:0,listStyle:"none"},[`${_n}-submenu-title`]:{paddingInlineEnd:Gn+$n.fontSizeSM},[`${_n}-submenu-vertical`]:{position:"relative"},[`${_n}-submenu${_n}-submenu-disabled ${Cn}-menu-submenu-title`]:{[`&, ${Cn}-menu-submenu-arrow-icon`]:{color:Wn,backgroundColor:Go,cursor:"not-allowed"}},[`${_n}-submenu-selected ${Cn}-menu-submenu-title`]:{color:$n.colorPrimary}})}},[initSlideMotion($n,"slide-up"),initSlideMotion($n,"slide-down"),initMoveMotion($n,"move-up"),initMoveMotion($n,"move-down"),initZoomMotion($n,"zoom-big")]]},useStyle$O=genComponentStyleHook("Dropdown",($n,Cn)=>{let{rootPrefixCls:_n}=Cn;const{marginXXS:Pn,sizePopupArrow:In,controlHeight:Nn,fontSize:Rn,lineHeight:Dn,paddingXXS:Ln,componentCls:Fn,borderRadiusOuter:Bn,borderRadiusLG:Hn}=$n,zn=(Nn-Rn*Dn)/2,{dropdownArrowOffset:Wn}=getArrowOffset({sizePopupArrow:In,contentRadius:Hn,borderRadiusOuter:Bn}),Yn=merge$1($n,{menuCls:`${Fn}-menu`,rootPrefixCls:_n,dropdownArrowDistance:In/2+Pn,dropdownArrowOffset:Wn,dropdownPaddingVertical:zn,dropdownEdgeChildPadding:Ln});return[genBaseStyle$f(Yn),genButtonStyle$1(Yn),genStatusStyle$2(Yn)]},$n=>({zIndexPopup:$n.zIndexPopupBase+50}));var __rest$11=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{In("update:visible",zn),In("visibleChange",zn),In("update:open",zn),In("openChange",zn)},{prefixCls:Rn,direction:Dn,getPopupContainer:Ln}=useConfigInject("dropdown",$n),Fn=computed(()=>`${Rn.value}-button`),[Bn,Hn]=useStyle$O(Rn);return()=>{var zn,Wn;const Yn=_extends$1(_extends$1({},$n),Pn),{type:Gn="default",disabled:Go,danger:Xn,loading:Yo,htmlType:qo,class:Jo="",overlay:Zo=(zn=_n.overlay)===null||zn===void 0?void 0:zn.call(_n),trigger:rr,align:nr,open:ta,visible:oa,onVisibleChange:ra,placement:ea=Dn.value==="rtl"?"bottomLeft":"bottomRight",href:la,title:ua,icon:ga=((Wn=_n.icon)===null||Wn===void 0?void 0:Wn.call(_n))||createVNode(EllipsisOutlined$1,null,null),mouseEnterDelay:aa,mouseLeaveDelay:ca,overlayClassName:sa,overlayStyle:ia,destroyPopupOnHide:fa,onClick:ma,"onUpdate:open":ya}=Yn,ba=__rest$11(Yn,["type","disabled","danger","loading","htmlType","class","overlay","trigger","align","open","visible","onVisibleChange","placement","href","title","icon","mouseEnterDelay","mouseLeaveDelay","overlayClassName","overlayStyle","destroyPopupOnHide","onClick","onUpdate:open"]),Ia={align:nr,disabled:Go,trigger:Go?[]:rr,placement:ea,getPopupContainer:Ln==null?void 0:Ln.value,onOpenChange:Nn,mouseEnterDelay:aa,mouseLeaveDelay:ca,open:ta??oa,overlayClassName:sa,overlayStyle:ia,destroyPopupOnHide:fa},Ea=createVNode(Button$1,{danger:Xn,type:Gn,disabled:Go,loading:Yo,onClick:ma,htmlType:qo,href:la,title:ua},{default:_n.default}),xa=createVNode(Button$1,{danger:Xn,type:Gn,icon:ga},null);return Bn(createVNode(ButtonGroup,_objectSpread2$1(_objectSpread2$1({},ba),{},{class:classNames(Fn.value,Jo,Hn.value)}),{default:()=>[_n.leftButton?_n.leftButton({button:Ea}):Ea,createVNode(Dropdown$1,Ia,{default:()=>[_n.rightButton?_n.rightButton({button:xa}):xa],overlay:()=>Zo})]}))}}});var RightOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"};const RightOutlinedSvg=RightOutlined$2;function _objectSpread$F($n){for(var Cn=1;Cninject(OverrideContextKey,void 0),useProvideOverride=$n=>{var Cn,_n,Pn;const{prefixCls:In,mode:Nn,selectable:Rn,validator:Dn,onClick:Ln,expandIcon:Fn}=useInjectOverride()||{};provide(OverrideContextKey,{prefixCls:computed(()=>{var Bn,Hn;return(Hn=(Bn=$n.prefixCls)===null||Bn===void 0?void 0:Bn.value)!==null&&Hn!==void 0?Hn:In==null?void 0:In.value}),mode:computed(()=>{var Bn,Hn;return(Hn=(Bn=$n.mode)===null||Bn===void 0?void 0:Bn.value)!==null&&Hn!==void 0?Hn:Nn==null?void 0:Nn.value}),selectable:computed(()=>{var Bn,Hn;return(Hn=(Bn=$n.selectable)===null||Bn===void 0?void 0:Bn.value)!==null&&Hn!==void 0?Hn:Rn==null?void 0:Rn.value}),validator:(Cn=$n.validator)!==null&&Cn!==void 0?Cn:Dn,onClick:(_n=$n.onClick)!==null&&_n!==void 0?_n:Ln,expandIcon:(Pn=$n.expandIcon)!==null&&Pn!==void 0?Pn:Fn==null?void 0:Fn.value})},Dropdown=defineComponent({compatConfig:{MODE:3},name:"ADropdown",inheritAttrs:!1,props:initDefaultProps(dropdownProps(),{mouseEnterDelay:.15,mouseLeaveDelay:.1,placement:"bottomLeft",trigger:"hover"}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,emit:In}=Cn;const{prefixCls:Nn,rootPrefixCls:Rn,direction:Dn,getPopupContainer:Ln}=useConfigInject("dropdown",$n),[Fn,Bn]=useStyle$O(Nn),Hn=computed(()=>{const{placement:Go="",transitionName:Xn}=$n;return Xn!==void 0?Xn:Go.includes("top")?`${Rn.value}-slide-down`:`${Rn.value}-slide-up`});useProvideOverride({prefixCls:computed(()=>`${Nn.value}-menu`),expandIcon:computed(()=>createVNode("span",{class:`${Nn.value}-menu-submenu-arrow`},[createVNode(RightOutlined$1,{class:`${Nn.value}-menu-submenu-arrow-icon`},null)])),mode:computed(()=>"vertical"),selectable:computed(()=>!1),onClick:()=>{},validator:Go=>{warning$3()}});const zn=()=>{var Go,Xn,Yo;const qo=$n.overlay||((Go=_n.overlay)===null||Go===void 0?void 0:Go.call(_n)),Jo=Array.isArray(qo)?qo[0]:qo;if(!Jo)return null;const Zo=Jo.props||{};devWarning(!Zo.mode||Zo.mode==="vertical","Dropdown",`mode="${Zo.mode}" is not supported for Dropdown's Menu.`);const{selectable:rr=!1,expandIcon:nr=(Yo=(Xn=Jo.children)===null||Xn===void 0?void 0:Xn.expandIcon)===null||Yo===void 0?void 0:Yo.call(Xn)}=Zo,ta=typeof nr<"u"&&isValidElement(nr)?nr:createVNode("span",{class:`${Nn.value}-menu-submenu-arrow`},[createVNode(RightOutlined$1,{class:`${Nn.value}-menu-submenu-arrow-icon`},null)]);return isValidElement(Jo)?cloneElement(Jo,{mode:"vertical",selectable:rr,expandIcon:()=>ta}):Jo},Wn=computed(()=>{const Go=$n.placement;if(!Go)return Dn.value==="rtl"?"bottomRight":"bottomLeft";if(Go.includes("Center")){const Xn=Go.slice(0,Go.indexOf("Center"));return devWarning(!Go.includes("Center"),"Dropdown",`You are using '${Go}' placement in Dropdown, which is deprecated. Try to use '${Xn}' instead.`),Xn}return Go}),Yn=computed(()=>typeof $n.visible=="boolean"?$n.visible:$n.open),Gn=Go=>{In("update:visible",Go),In("visibleChange",Go),In("update:open",Go),In("openChange",Go)};return()=>{var Go,Xn;const{arrow:Yo,trigger:qo,disabled:Jo,overlayClassName:Zo}=$n,rr=(Go=_n.default)===null||Go===void 0?void 0:Go.call(_n)[0],nr=cloneElement(rr,_extends$1({class:classNames((Xn=rr==null?void 0:rr.props)===null||Xn===void 0?void 0:Xn.class,{[`${Nn.value}-rtl`]:Dn.value==="rtl"},`${Nn.value}-trigger`)},Jo?{disabled:Jo}:{})),ta=classNames(Zo,Bn.value,{[`${Nn.value}-rtl`]:Dn.value==="rtl"}),oa=Jo?[]:qo;let ra;oa&&oa.includes("contextmenu")&&(ra=!0);const ea=getPlacements$1({arrowPointAtCenter:typeof Yo=="object"&&Yo.pointAtCenter,autoAdjustOverflow:!0}),la=omit$1(_extends$1(_extends$1(_extends$1({},$n),Pn),{visible:Yn.value,builtinPlacements:ea,overlayClassName:ta,arrow:!!Yo,alignPoint:ra,prefixCls:Nn.value,getPopupContainer:Ln==null?void 0:Ln.value,transitionName:Hn.value,trigger:oa,onVisibleChange:Gn,placement:Wn.value}),["overlay","onUpdate:visible"]);return Fn(createVNode(Dropdown$2,la,{default:()=>[nr],overlay:zn}))}}});Dropdown.Button=DropdownButton;const Dropdown$1=Dropdown;var __rest$10=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,href:String,separator:PropTypes.any,dropdownProps:objectType(),overlay:PropTypes.any,onClick:eventType()}),BreadcrumbItem=defineComponent({compatConfig:{MODE:3},name:"ABreadcrumbItem",inheritAttrs:!1,__ANT_BREADCRUMB_ITEM:!0,props:breadcrumbItemProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,emit:In}=Cn;const{prefixCls:Nn}=useConfigInject("breadcrumb",$n),Rn=(Ln,Fn)=>{const Bn=getPropsSlot(_n,$n,"overlay");return Bn?createVNode(Dropdown$1,_objectSpread2$1(_objectSpread2$1({},$n.dropdownProps),{},{overlay:Bn,placement:"bottom"}),{default:()=>[createVNode("span",{class:`${Fn}-overlay-link`},[Ln,createVNode(DownOutlined$1,null,null)])]}):Ln},Dn=Ln=>{In("click",Ln)};return()=>{var Ln;const Fn=(Ln=getPropsSlot(_n,$n,"separator"))!==null&&Ln!==void 0?Ln:"/",Bn=getPropsSlot(_n,$n),{class:Hn,style:zn}=Pn,Wn=__rest$10(Pn,["class","style"]);let Yn;return $n.href!==void 0?Yn=createVNode("a",_objectSpread2$1({class:`${Nn.value}-link`,onClick:Dn},Wn),[Bn]):Yn=createVNode("span",_objectSpread2$1({class:`${Nn.value}-link`,onClick:Dn},Wn),[Bn]),Yn=Rn(Yn,Nn.value),Bn!=null?createVNode("li",{class:Hn,style:zn},[Yn,Fn&&createVNode("span",{class:`${Nn.value}-separator`},[Fn])]):null}}});function shallowEqual($n,Cn,_n,Pn){let In=_n?_n.call(Pn,$n,Cn):void 0;if(In!==void 0)return!!In;if($n===Cn)return!0;if(typeof $n!="object"||!$n||typeof Cn!="object"||!Cn)return!1;const Nn=Object.keys($n),Rn=Object.keys(Cn);if(Nn.length!==Rn.length)return!1;const Dn=Object.prototype.hasOwnProperty.bind(Cn);for(let Ln=0;Ln{provide(MenuContextKey,$n)},useInjectMenu=()=>inject(MenuContextKey),ForceRenderKey=Symbol("ForceRenderKey"),useProvideForceRender=$n=>{provide(ForceRenderKey,$n)},useInjectForceRender=()=>inject(ForceRenderKey,!1),MenuFirstLevelContextKey=Symbol("menuFirstLevelContextKey"),useProvideFirstLevel=$n=>{provide(MenuFirstLevelContextKey,$n)},useInjectFirstLevel=()=>inject(MenuFirstLevelContextKey,!0),MenuContextProvider=defineComponent({compatConfig:{MODE:3},name:"MenuContextProvider",inheritAttrs:!1,props:{mode:{type:String,default:void 0},overflowDisabled:{type:Boolean,default:void 0}},setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectMenu(),In=_extends$1({},Pn);return $n.mode!==void 0&&(In.mode=toRef($n,"mode")),$n.overflowDisabled!==void 0&&(In.overflowDisabled=toRef($n,"overflowDisabled")),useProvideMenu(In),()=>{var Nn;return(Nn=_n.default)===null||Nn===void 0?void 0:Nn.call(_n)}}}),useProvideMenu$1=useProvideMenu,SiderCollapsedKey=Symbol("siderCollapsed"),SiderHookProviderKey=Symbol("siderHookProvider"),OVERFLOW_KEY="$$__vc-menu-more__key",KeyPathContext=Symbol("KeyPathContext"),useInjectKeyPath=()=>inject(KeyPathContext,{parentEventKeys:computed(()=>[]),parentKeys:computed(()=>[]),parentInfo:{}}),useProvideKeyPath=($n,Cn,_n)=>{const{parentEventKeys:Pn,parentKeys:In}=useInjectKeyPath(),Nn=computed(()=>[...Pn.value,$n]),Rn=computed(()=>[...In.value,Cn]);return provide(KeyPathContext,{parentEventKeys:Nn,parentKeys:Rn,parentInfo:_n}),Rn},measure$1=Symbol("measure"),PathContext=defineComponent({compatConfig:{MODE:3},setup($n,Cn){let{slots:_n}=Cn;return provide(measure$1,!0),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),useMeasure=()=>inject(measure$1,!1),useProvideKeyPath$1=useProvideKeyPath;function useDirectionStyle($n){const{mode:Cn,rtl:_n,inlineIndent:Pn}=useInjectMenu();return computed(()=>Cn.value!=="inline"?null:_n.value?{paddingRight:`${$n.value*Pn.value}px`}:{paddingLeft:`${$n.value*Pn.value}px`})}let indexGuid$3=0;const menuItemProps=()=>({id:String,role:String,disabled:Boolean,danger:Boolean,title:{type:[String,Boolean],default:void 0},icon:PropTypes.any,onMouseenter:Function,onMouseleave:Function,onClick:Function,onKeydown:Function,onFocus:Function,originItemValue:objectType()}),MenuItem$1=defineComponent({compatConfig:{MODE:3},name:"AMenuItem",inheritAttrs:!1,props:menuItemProps(),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const Nn=getCurrentInstance(),Rn=useMeasure(),Dn=typeof Nn.vnode.key=="symbol"?String(Nn.vnode.key):Nn.vnode.key;devWarning(typeof Nn.vnode.key!="symbol","MenuItem",`MenuItem \`:key="${String(Dn)}"\` not support Symbol type`);const Ln=`menu_item_${++indexGuid$3}_$$_${Dn}`,{parentEventKeys:Fn,parentKeys:Bn}=useInjectKeyPath(),{prefixCls:Hn,activeKeys:zn,disabled:Wn,changeActiveKeys:Yn,rtl:Gn,inlineCollapsed:Go,siderCollapsed:Xn,onItemClick:Yo,selectedKeys:qo,registerMenuInfo:Jo,unRegisterMenuInfo:Zo}=useInjectMenu(),rr=useInjectFirstLevel(),nr=shallowRef(!1),ta=computed(()=>[...Bn.value,Dn]);Jo(Ln,{eventKey:Ln,key:Dn,parentEventKeys:Fn,parentKeys:Bn,isLeaf:!0}),onBeforeUnmount(()=>{Zo(Ln)}),watch(zn,()=>{nr.value=!!zn.value.find(ya=>ya===Dn)},{immediate:!0});const ra=computed(()=>Wn.value||$n.disabled),ea=computed(()=>qo.value.includes(Dn)),la=computed(()=>{const ya=`${Hn.value}-item`;return{[`${ya}`]:!0,[`${ya}-danger`]:$n.danger,[`${ya}-active`]:nr.value,[`${ya}-selected`]:ea.value,[`${ya}-disabled`]:ra.value}}),ua=ya=>({key:Dn,eventKey:Ln,keyPath:ta.value,eventKeyPath:[...Fn.value,Ln],domEvent:ya,item:_extends$1(_extends$1({},$n),In)}),ga=ya=>{if(ra.value)return;const ba=ua(ya);Pn("click",ya),Yo(ba)},aa=ya=>{ra.value||(Yn(ta.value),Pn("mouseenter",ya))},ca=ya=>{ra.value||(Yn([]),Pn("mouseleave",ya))},sa=ya=>{if(Pn("keydown",ya),ya.which===KeyCode$1.ENTER){const ba=ua(ya);Pn("click",ya),Yo(ba)}},ia=ya=>{Yn(ta.value),Pn("focus",ya)},fa=(ya,ba)=>{const Ia=createVNode("span",{class:`${Hn.value}-title-content`},[ba]);return(!ya||isValidElement(ba)&&ba.type==="span")&&ba&&Go.value&&rr&&typeof ba=="string"?createVNode("div",{class:`${Hn.value}-inline-collapsed-noicon`},[ba.charAt(0)]):Ia},ma=useDirectionStyle(computed(()=>ta.value.length));return()=>{var ya,ba,Ia,Ea,xa;if(Rn)return null;const Ta=(ya=$n.title)!==null&&ya!==void 0?ya:(ba=_n.title)===null||ba===void 0?void 0:ba.call(_n),wa=flattenChildren((Ia=_n.default)===null||Ia===void 0?void 0:Ia.call(_n)),La=wa.length;let Na=Ta;typeof Ta>"u"?Na=rr&&La?wa:"":Ta===!1&&(Na="");const $a={title:Na};!Xn.value&&!Go.value&&($a.title=null,$a.open=!1);const ka={};$n.role==="option"&&(ka["aria-selected"]=ea.value);const Ha=(Ea=$n.icon)!==null&&Ea!==void 0?Ea:(xa=_n.icon)===null||xa===void 0?void 0:xa.call(_n,$n);return createVNode(Tooltip,_objectSpread2$1(_objectSpread2$1({},$a),{},{placement:Gn.value?"left":"right",overlayClassName:`${Hn.value}-inline-collapsed-tooltip`}),{default:()=>[createVNode(Overflow$1.Item,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({component:"li"},In),{},{id:$n.id,style:_extends$1(_extends$1({},In.style||{}),ma.value),class:[la.value,{[`${In.class}`]:!!In.class,[`${Hn.value}-item-only-child`]:(Ha?La+1:La)===1}],role:$n.role||"menuitem",tabindex:$n.disabled?null:-1,"data-menu-id":Dn,"aria-disabled":$n.disabled},ka),{},{onMouseenter:aa,onMouseleave:ca,onClick:ga,onKeydown:sa,onFocus:ia,title:typeof Ta=="string"?Ta:void 0}),{default:()=>[cloneElement(typeof Ha=="function"?Ha($n.originItemValue):Ha,{class:`${Hn.value}-item-icon`},!1),fa(Ha,wa)]})]})}}}),autoAdjustOverflow={adjustX:1,adjustY:1},placements$1={topLeft:{points:["bl","tl"],overflow:autoAdjustOverflow,offset:[0,-7]},bottomLeft:{points:["tl","bl"],overflow:autoAdjustOverflow,offset:[0,7]},leftTop:{points:["tr","tl"],overflow:autoAdjustOverflow,offset:[-4,0]},rightTop:{points:["tl","tr"],overflow:autoAdjustOverflow,offset:[4,0]}},placementsRtl={topLeft:{points:["bl","tl"],overflow:autoAdjustOverflow,offset:[0,-7]},bottomLeft:{points:["tl","bl"],overflow:autoAdjustOverflow,offset:[0,7]},rightTop:{points:["tr","tl"],overflow:autoAdjustOverflow,offset:[-4,0]},leftTop:{points:["tl","tr"],overflow:autoAdjustOverflow,offset:[4,0]}},popupPlacementMap={horizontal:"bottomLeft",vertical:"rightTop","vertical-left":"rightTop","vertical-right":"leftTop"},PopupTrigger=defineComponent({compatConfig:{MODE:3},name:"PopupTrigger",inheritAttrs:!1,props:{prefixCls:String,mode:String,visible:Boolean,popupClassName:String,popupOffset:Array,disabled:Boolean,onVisibleChange:Function},slots:Object,emits:["visibleChange"],setup($n,Cn){let{slots:_n,emit:Pn}=Cn;const In=shallowRef(!1),{getPopupContainer:Nn,rtl:Rn,subMenuOpenDelay:Dn,subMenuCloseDelay:Ln,builtinPlacements:Fn,triggerSubMenuAction:Bn,forceSubMenuRender:Hn,motion:zn,defaultMotions:Wn,rootClassName:Yn}=useInjectMenu(),Gn=useInjectForceRender(),Go=computed(()=>Rn.value?_extends$1(_extends$1({},placementsRtl),Fn.value):_extends$1(_extends$1({},placements$1),Fn.value)),Xn=computed(()=>popupPlacementMap[$n.mode]),Yo=shallowRef();watch(()=>$n.visible,Zo=>{wrapperRaf.cancel(Yo.value),Yo.value=wrapperRaf(()=>{In.value=Zo})},{immediate:!0}),onBeforeUnmount(()=>{wrapperRaf.cancel(Yo.value)});const qo=Zo=>{Pn("visibleChange",Zo)},Jo=computed(()=>{var Zo,rr;const nr=zn.value||((Zo=Wn.value)===null||Zo===void 0?void 0:Zo[$n.mode])||((rr=Wn.value)===null||rr===void 0?void 0:rr.other),ta=typeof nr=="function"?nr():nr;return ta?getTransitionProps(ta.name,{css:!0}):void 0});return()=>{const{prefixCls:Zo,popupClassName:rr,mode:nr,popupOffset:ta,disabled:oa}=$n;return createVNode(Trigger,{prefixCls:Zo,popupClassName:classNames(`${Zo}-popup`,{[`${Zo}-rtl`]:Rn.value},rr,Yn.value),stretch:nr==="horizontal"?"minWidth":null,getPopupContainer:Nn.value,builtinPlacements:Go.value,popupPlacement:Xn.value,popupVisible:In.value,popupAlign:ta&&{offset:ta},action:oa?[]:[Bn.value],mouseEnterDelay:Dn.value,mouseLeaveDelay:Ln.value,onPopupVisibleChange:qo,forceRender:Gn||Hn.value,popupAnimation:Jo.value},{popup:_n.popup,default:_n.default})}}}),InternalSubMenuList=($n,Cn)=>{let{slots:_n,attrs:Pn}=Cn;var In;const{prefixCls:Nn,mode:Rn}=useInjectMenu();return createVNode("ul",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:classNames(Nn.value,`${Nn.value}-sub`,`${Nn.value}-${Rn.value==="inline"?"inline":"vertical"}`),"data-menu-list":!0}),[(In=_n.default)===null||In===void 0?void 0:In.call(_n)])};InternalSubMenuList.displayName="SubMenuList";const SubMenuList=InternalSubMenuList,InlineSubMenuList=defineComponent({compatConfig:{MODE:3},name:"InlineSubMenuList",inheritAttrs:!1,props:{id:String,open:Boolean,keyPath:Array},setup($n,Cn){let{slots:_n}=Cn;const Pn=computed(()=>"inline"),{motion:In,mode:Nn,defaultMotions:Rn}=useInjectMenu(),Dn=computed(()=>Nn.value===Pn.value),Ln=ref(!Dn.value),Fn=computed(()=>Dn.value?$n.open:!1);watch(Nn,()=>{Dn.value&&(Ln.value=!1)},{flush:"post"});const Bn=computed(()=>{var Hn,zn;const Wn=In.value||((Hn=Rn.value)===null||Hn===void 0?void 0:Hn[Pn.value])||((zn=Rn.value)===null||zn===void 0?void 0:zn.other),Yn=typeof Wn=="function"?Wn():Wn;return _extends$1(_extends$1({},Yn),{appear:$n.keyPath.length<=1})});return()=>{var Hn;return Ln.value?null:createVNode(MenuContextProvider,{mode:Pn.value},{default:()=>[createVNode(Transition,Bn.value,{default:()=>[withDirectives(createVNode(SubMenuList,{id:$n.id},{default:()=>[(Hn=_n.default)===null||Hn===void 0?void 0:Hn.call(_n)]}),[[vShow,Fn.value]])]})]})}}});let indexGuid$2=0;const subMenuProps=()=>({icon:PropTypes.any,title:PropTypes.any,disabled:Boolean,level:Number,popupClassName:String,popupOffset:Array,internalPopupClose:Boolean,eventKey:String,expandIcon:Function,theme:String,onMouseenter:Function,onMouseleave:Function,onTitleClick:Function,originItemValue:objectType()}),SubMenu$1=defineComponent({compatConfig:{MODE:3},name:"ASubMenu",inheritAttrs:!1,props:subMenuProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,emit:In}=Cn;var Nn,Rn;useProvideFirstLevel(!1);const Dn=useMeasure(),Ln=getCurrentInstance(),Fn=typeof Ln.vnode.key=="symbol"?String(Ln.vnode.key):Ln.vnode.key;devWarning(typeof Ln.vnode.key!="symbol","SubMenu",`SubMenu \`:key="${String(Fn)}"\` not support Symbol type`);const Bn=isValid$2(Fn)?Fn:`sub_menu_${++indexGuid$2}_$$_not_set_key`,Hn=(Nn=$n.eventKey)!==null&&Nn!==void 0?Nn:isValid$2(Fn)?`sub_menu_${++indexGuid$2}_$$_${Fn}`:Bn,{parentEventKeys:zn,parentInfo:Wn,parentKeys:Yn}=useInjectKeyPath(),Gn=computed(()=>[...Yn.value,Bn]),Go=shallowRef([]),Xn={eventKey:Hn,key:Bn,parentEventKeys:zn,childrenEventKeys:Go,parentKeys:Yn};(Rn=Wn.childrenEventKeys)===null||Rn===void 0||Rn.value.push(Hn),onBeforeUnmount(()=>{var za;Wn.childrenEventKeys&&(Wn.childrenEventKeys.value=(za=Wn.childrenEventKeys)===null||za===void 0?void 0:za.value.filter(Wa=>Wa!=Hn))}),useProvideKeyPath$1(Hn,Bn,Xn);const{prefixCls:Yo,activeKeys:qo,disabled:Jo,changeActiveKeys:Zo,mode:rr,inlineCollapsed:nr,openKeys:ta,overflowDisabled:oa,onOpenChange:ra,registerMenuInfo:ea,unRegisterMenuInfo:la,selectedSubMenuKeys:ua,expandIcon:ga,theme:aa}=useInjectMenu(),ca=Fn!=null,sa=!Dn&&(useInjectForceRender()||!ca);useProvideForceRender(sa),(Dn&&ca||!Dn&&!ca||sa)&&(ea(Hn,Xn),onBeforeUnmount(()=>{la(Hn)}));const ia=computed(()=>`${Yo.value}-submenu`),fa=computed(()=>Jo.value||$n.disabled),ma=shallowRef(),ya=shallowRef(),ba=computed(()=>ta.value.includes(Bn)),Ia=computed(()=>!oa.value&&ba.value),Ea=computed(()=>ua.value.includes(Bn)),xa=shallowRef(!1);watch(qo,()=>{xa.value=!!qo.value.find(za=>za===Bn)},{immediate:!0});const Ta=za=>{fa.value||(In("titleClick",za,Bn),rr.value==="inline"&&ra(Bn,!ba.value))},wa=za=>{fa.value||(Zo(Gn.value),In("mouseenter",za))},La=za=>{fa.value||(Zo([]),In("mouseleave",za))},Na=useDirectionStyle(computed(()=>Gn.value.length)),$a=za=>{rr.value!=="inline"&&ra(Bn,za)},ka=()=>{Zo(Gn.value)},Ha=Hn&&`${Hn}-popup`,da=computed(()=>classNames(Yo.value,`${Yo.value}-${$n.theme||aa.value}`,$n.popupClassName)),pa=(za,Wa)=>{if(!Wa)return nr.value&&!Yn.value.length&&za&&typeof za=="string"?createVNode("div",{class:`${Yo.value}-inline-collapsed-noicon`},[za.charAt(0)]):createVNode("span",{class:`${Yo.value}-title-content`},[za]);const Ya=isValidElement(za)&&za.type==="span";return createVNode(Fragment,null,[cloneElement(typeof Wa=="function"?Wa($n.originItemValue):Wa,{class:`${Yo.value}-item-icon`},!1),Ya?za:createVNode("span",{class:`${Yo.value}-title-content`},[za])])},Sa=computed(()=>rr.value!=="inline"&&Gn.value.length>1?"vertical":rr.value),Aa=computed(()=>rr.value==="horizontal"?"vertical":rr.value),Ra=computed(()=>Sa.value==="horizontal"?"vertical":Sa.value),Fa=()=>{var za,Wa;const Ya=ia.value,ja=(za=$n.icon)!==null&&za!==void 0?za:(Wa=_n.icon)===null||Wa===void 0?void 0:Wa.call(_n,$n),qa=$n.expandIcon||_n.expandIcon||ga.value,Xa=pa(getPropsSlot(_n,$n,"title"),ja);return createVNode("div",{style:Na.value,class:`${Ya}-title`,tabindex:fa.value?null:-1,ref:ma,title:typeof Xa=="string"?Xa:null,"data-menu-id":Bn,"aria-expanded":Ia.value,"aria-haspopup":!0,"aria-controls":Ha,"aria-disabled":fa.value,onClick:Ta,onFocus:ka},[Xa,rr.value!=="horizontal"&&qa?qa(_extends$1(_extends$1({},$n),{isOpen:Ia.value})):createVNode("i",{class:`${Ya}-arrow`},null)])};return()=>{var za;if(Dn)return ca?(za=_n.default)===null||za===void 0?void 0:za.call(_n):null;const Wa=ia.value;let Ya=()=>null;if(!oa.value&&rr.value!=="inline"){const ja=rr.value==="horizontal"?[0,8]:[10,0];Ya=()=>createVNode(PopupTrigger,{mode:Sa.value,prefixCls:Wa,visible:!$n.internalPopupClose&&Ia.value,popupClassName:da.value,popupOffset:$n.popupOffset||ja,disabled:fa.value,onVisibleChange:$a},{default:()=>[Fa()],popup:()=>createVNode(MenuContextProvider,{mode:Ra.value},{default:()=>[createVNode(SubMenuList,{id:Ha,ref:ya},{default:_n.default})]})})}else Ya=()=>createVNode(PopupTrigger,null,{default:Fa});return createVNode(MenuContextProvider,{mode:Aa.value},{default:()=>[createVNode(Overflow$1.Item,_objectSpread2$1(_objectSpread2$1({component:"li"},Pn),{},{role:"none",class:classNames(Wa,`${Wa}-${rr.value}`,Pn.class,{[`${Wa}-open`]:Ia.value,[`${Wa}-active`]:xa.value,[`${Wa}-selected`]:Ea.value,[`${Wa}-disabled`]:fa.value}),onMouseenter:wa,onMouseleave:La,"data-submenu-id":Bn}),{default:()=>createVNode(Fragment,null,[Ya(),!oa.value&&createVNode(InlineSubMenuList,{id:Ha,open:Ia.value,keyPath:Gn.value},{default:_n.default})])})]})}}});function hasClass($n,Cn){return $n.classList?$n.classList.contains(Cn):` ${$n.className} `.indexOf(` ${Cn} `)>-1}function addClass($n,Cn){$n.classList?$n.classList.add(Cn):hasClass($n,Cn)||($n.className=`${$n.className} ${Cn}`)}function removeClass($n,Cn){if($n.classList)$n.classList.remove(Cn);else if(hasClass($n,Cn)){const _n=$n.className;$n.className=` ${_n} `.replace(` ${Cn} `," ")}}const collapseMotion=function(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"ant-motion-collapse",Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return{name:$n,appear:Cn,css:!0,onBeforeEnter:_n=>{_n.style.height="0px",_n.style.opacity="0",addClass(_n,$n)},onEnter:_n=>{nextTick(()=>{_n.style.height=`${_n.scrollHeight}px`,_n.style.opacity="1"})},onAfterEnter:_n=>{_n&&(removeClass(_n,$n),_n.style.height=null,_n.style.opacity=null)},onBeforeLeave:_n=>{addClass(_n,$n),_n.style.height=`${_n.offsetHeight}px`,_n.style.opacity=null},onLeave:_n=>{setTimeout(()=>{_n.style.height="0px",_n.style.opacity="0"})},onAfterLeave:_n=>{_n&&(removeClass(_n,$n),_n.style&&(_n.style.height=null,_n.style.opacity=null))}}},collapseMotion$1=collapseMotion,menuItemGroupProps=()=>({title:PropTypes.any,originItemValue:objectType()}),ItemGroup=defineComponent({compatConfig:{MODE:3},name:"AMenuItemGroup",inheritAttrs:!1,props:menuItemGroupProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In}=useInjectMenu(),Nn=computed(()=>`${In.value}-item-group`),Rn=useMeasure();return()=>{var Dn,Ln;return Rn?(Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n):createVNode("li",_objectSpread2$1(_objectSpread2$1({},Pn),{},{onClick:Fn=>Fn.stopPropagation(),class:Nn.value}),[createVNode("div",{title:typeof $n.title=="string"?$n.title:void 0,class:`${Nn.value}-title`},[getPropsSlot(_n,$n,"title")]),createVNode("ul",{class:`${Nn.value}-list`},[(Ln=_n.default)===null||Ln===void 0?void 0:Ln.call(_n)])])}}}),menuDividerProps=()=>({prefixCls:String,dashed:Boolean}),Divider$1=defineComponent({compatConfig:{MODE:3},name:"AMenuDivider",props:menuDividerProps(),setup($n){const{prefixCls:Cn}=useInjectMenu(),_n=computed(()=>({[`${Cn.value}-item-divider`]:!0,[`${Cn.value}-item-divider-dashed`]:!!$n.dashed}));return()=>createVNode("li",{class:_n.value},null)}});var __rest$$=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{if(Pn&&typeof Pn=="object"){const Nn=Pn,{label:Rn,children:Dn,key:Ln,type:Fn}=Nn,Bn=__rest$$(Nn,["label","children","key","type"]),Hn=Ln??`tmp-${In}`,zn=_n?_n.parentKeys.slice():[],Wn=[],Yn={eventKey:Hn,key:Hn,parentEventKeys:ref(zn),parentKeys:ref(zn),childrenEventKeys:ref(Wn),isLeaf:!1};if(Dn||Fn==="group"){if(Fn==="group"){const Go=convertItemsToNodes(Dn,Cn,_n);return createVNode(ItemGroup,_objectSpread2$1(_objectSpread2$1({key:Hn},Bn),{},{title:Rn,originItemValue:Pn}),{default:()=>[Go]})}Cn.set(Hn,Yn),_n&&_n.childrenEventKeys.push(Hn);const Gn=convertItemsToNodes(Dn,Cn,{childrenEventKeys:Wn,parentKeys:[].concat(zn,Hn)});return createVNode(SubMenu$1,_objectSpread2$1(_objectSpread2$1({key:Hn},Bn),{},{title:Rn,originItemValue:Pn}),{default:()=>[Gn]})}return Fn==="divider"?createVNode(Divider$1,_objectSpread2$1({key:Hn},Bn),null):(Yn.isLeaf=!0,Cn.set(Hn,Yn),createVNode(MenuItem$1,_objectSpread2$1(_objectSpread2$1({key:Hn},Bn),{},{originItemValue:Pn}),{default:()=>[Rn]}))}return null}).filter(Pn=>Pn)}function useItems($n){const Cn=shallowRef([]),_n=shallowRef(!1),Pn=shallowRef(new Map);return watch(()=>$n.items,()=>{const In=new Map;_n.value=!1,$n.items?(_n.value=!0,Cn.value=convertItemsToNodes($n.items,In)):Cn.value=void 0,Pn.value=In},{immediate:!0,deep:!0}),{itemsNodes:Cn,store:Pn,hasItmes:_n}}const getHorizontalStyle=$n=>{const{componentCls:Cn,motionDurationSlow:_n,menuHorizontalHeight:Pn,colorSplit:In,lineWidth:Nn,lineType:Rn,menuItemPaddingInline:Dn}=$n;return{[`${Cn}-horizontal`]:{lineHeight:`${Pn}px`,border:0,borderBottom:`${Nn}px ${Rn} ${In}`,boxShadow:"none","&::after":{display:"block",clear:"both",height:0,content:'"\\20"'},[`${Cn}-item, ${Cn}-submenu`]:{position:"relative",display:"inline-block",verticalAlign:"bottom",paddingInline:Dn},[`> ${Cn}-item:hover, - > ${Cn}-item-active, - > ${Cn}-submenu ${Cn}-submenu-title:hover`]:{backgroundColor:"transparent"},[`${Cn}-item, ${Cn}-submenu-title`]:{transition:[`border-color ${_n}`,`background ${_n}`].join(",")},[`${Cn}-submenu-arrow`]:{display:"none"}}}},getHorizontalStyle$1=getHorizontalStyle,getRTLStyle=$n=>{let{componentCls:Cn,menuArrowOffset:_n}=$n;return{[`${Cn}-rtl`]:{direction:"rtl"},[`${Cn}-submenu-rtl`]:{transformOrigin:"100% 0"},[`${Cn}-rtl${Cn}-vertical, - ${Cn}-submenu-rtl ${Cn}-vertical`]:{[`${Cn}-submenu-arrow`]:{"&::before":{transform:`rotate(-45deg) translateY(-${_n})`},"&::after":{transform:`rotate(45deg) translateY(${_n})`}}}}},getRTLStyle$1=getRTLStyle,accessibilityFocus=$n=>_extends$1({},genFocusOutline($n)),getThemeStyle=($n,Cn)=>{const{componentCls:_n,colorItemText:Pn,colorItemTextSelected:In,colorGroupTitle:Nn,colorItemBg:Rn,colorSubItemBg:Dn,colorItemBgSelected:Ln,colorActiveBarHeight:Fn,colorActiveBarWidth:Bn,colorActiveBarBorderSize:Hn,motionDurationSlow:zn,motionEaseInOut:Wn,motionEaseOut:Yn,menuItemPaddingInline:Gn,motionDurationMid:Go,colorItemTextHover:Xn,lineType:Yo,colorSplit:qo,colorItemTextDisabled:Jo,colorDangerItemText:Zo,colorDangerItemTextHover:rr,colorDangerItemTextSelected:nr,colorDangerItemBgActive:ta,colorDangerItemBgSelected:oa,colorItemBgHover:ra,menuSubMenuBg:ea,colorItemTextSelectedHorizontal:la,colorItemBgSelectedHorizontal:ua}=$n;return{[`${_n}-${Cn}`]:{color:Pn,background:Rn,[`&${_n}-root:focus-visible`]:_extends$1({},accessibilityFocus($n)),[`${_n}-item-group-title`]:{color:Nn},[`${_n}-submenu-selected`]:{[`> ${_n}-submenu-title`]:{color:In}},[`${_n}-item-disabled, ${_n}-submenu-disabled`]:{color:`${Jo} !important`},[`${_n}-item:hover, ${_n}-submenu-title:hover`]:{[`&:not(${_n}-item-selected):not(${_n}-submenu-selected)`]:{color:Xn}},[`&:not(${_n}-horizontal)`]:{[`${_n}-item:not(${_n}-item-selected)`]:{"&:hover":{backgroundColor:ra},"&:active":{backgroundColor:Ln}},[`${_n}-submenu-title`]:{"&:hover":{backgroundColor:ra},"&:active":{backgroundColor:Ln}}},[`${_n}-item-danger`]:{color:Zo,[`&${_n}-item:hover`]:{[`&:not(${_n}-item-selected):not(${_n}-submenu-selected)`]:{color:rr}},[`&${_n}-item:active`]:{background:ta}},[`${_n}-item a`]:{"&, &:hover":{color:"inherit"}},[`${_n}-item-selected`]:{color:In,[`&${_n}-item-danger`]:{color:nr},"a, a:hover":{color:"inherit"}},[`& ${_n}-item-selected`]:{backgroundColor:Ln,[`&${_n}-item-danger`]:{backgroundColor:oa}},[`${_n}-item, ${_n}-submenu-title`]:{[`&:not(${_n}-item-disabled):focus-visible`]:_extends$1({},accessibilityFocus($n))},[`&${_n}-submenu > ${_n}`]:{backgroundColor:ea},[`&${_n}-popup > ${_n}`]:{backgroundColor:Rn},[`&${_n}-horizontal`]:_extends$1(_extends$1({},Cn==="dark"?{borderBottom:0}:{}),{[`> ${_n}-item, > ${_n}-submenu`]:{top:Hn,marginTop:-Hn,marginBottom:0,borderRadius:0,"&::after":{position:"absolute",insetInline:Gn,bottom:0,borderBottom:`${Fn}px solid transparent`,transition:`border-color ${zn} ${Wn}`,content:'""'},"&:hover, &-active, &-open":{"&::after":{borderBottomWidth:Fn,borderBottomColor:la}},"&-selected":{color:la,backgroundColor:ua,"&::after":{borderBottomWidth:Fn,borderBottomColor:la}}}}),[`&${_n}-root`]:{[`&${_n}-inline, &${_n}-vertical`]:{borderInlineEnd:`${Hn}px ${Yo} ${qo}`}},[`&${_n}-inline`]:{[`${_n}-sub${_n}-inline`]:{background:Dn},[`${_n}-item, ${_n}-submenu-title`]:Hn&&Bn?{width:`calc(100% + ${Hn}px)`}:{},[`${_n}-item`]:{position:"relative","&::after":{position:"absolute",insetBlock:0,insetInlineEnd:0,borderInlineEnd:`${Bn}px solid ${In}`,transform:"scaleY(0.0001)",opacity:0,transition:[`transform ${Go} ${Yn}`,`opacity ${Go} ${Yn}`].join(","),content:'""'},[`&${_n}-item-danger`]:{"&::after":{borderInlineEndColor:nr}}},[`${_n}-selected, ${_n}-item-selected`]:{"&::after":{transform:"scaleY(1)",opacity:1,transition:[`transform ${Go} ${Wn}`,`opacity ${Go} ${Wn}`].join(",")}}}}}},getThemeStyle$1=getThemeStyle,getVerticalInlineStyle=$n=>{const{componentCls:Cn,menuItemHeight:_n,itemMarginInline:Pn,padding:In,menuArrowSize:Nn,marginXS:Rn,marginXXS:Dn}=$n,Ln=In+Nn+Rn;return{[`${Cn}-item`]:{position:"relative"},[`${Cn}-item, ${Cn}-submenu-title`]:{height:_n,lineHeight:`${_n}px`,paddingInline:In,overflow:"hidden",textOverflow:"ellipsis",marginInline:Pn,marginBlock:Dn,width:`calc(100% - ${Pn*2}px)`},[`${Cn}-submenu`]:{paddingBottom:.02},[`> ${Cn}-item, - > ${Cn}-submenu > ${Cn}-submenu-title`]:{height:_n,lineHeight:`${_n}px`},[`${Cn}-item-group-list ${Cn}-submenu-title, - ${Cn}-submenu-title`]:{paddingInlineEnd:Ln}}},getVerticalStyle=$n=>{const{componentCls:Cn,iconCls:_n,menuItemHeight:Pn,colorTextLightSolid:In,dropdownWidth:Nn,controlHeightLG:Rn,motionDurationMid:Dn,motionEaseOut:Ln,paddingXL:Fn,fontSizeSM:Bn,fontSizeLG:Hn,motionDurationSlow:zn,paddingXS:Wn,boxShadowSecondary:Yn}=$n,Gn={height:Pn,lineHeight:`${Pn}px`,listStylePosition:"inside",listStyleType:"disc"};return[{[Cn]:{"&-inline, &-vertical":_extends$1({[`&${Cn}-root`]:{boxShadow:"none"}},getVerticalInlineStyle($n))},[`${Cn}-submenu-popup`]:{[`${Cn}-vertical`]:_extends$1(_extends$1({},getVerticalInlineStyle($n)),{boxShadow:Yn})}},{[`${Cn}-submenu-popup ${Cn}-vertical${Cn}-sub`]:{minWidth:Nn,maxHeight:`calc(100vh - ${Rn*2.5}px)`,padding:"0",overflow:"hidden",borderInlineEnd:0,"&:not([class*='-active'])":{overflowX:"hidden",overflowY:"auto"}}},{[`${Cn}-inline`]:{width:"100%",[`&${Cn}-root`]:{[`${Cn}-item, ${Cn}-submenu-title`]:{display:"flex",alignItems:"center",transition:[`border-color ${zn}`,`background ${zn}`,`padding ${Dn} ${Ln}`].join(","),[`> ${Cn}-title-content`]:{flex:"auto",minWidth:0,overflow:"hidden",textOverflow:"ellipsis"},"> *":{flex:"none"}}},[`${Cn}-sub${Cn}-inline`]:{padding:0,border:0,borderRadius:0,boxShadow:"none",[`& > ${Cn}-submenu > ${Cn}-submenu-title`]:Gn,[`& ${Cn}-item-group-title`]:{paddingInlineStart:Fn}},[`${Cn}-item`]:Gn}},{[`${Cn}-inline-collapsed`]:{width:Pn*2,[`&${Cn}-root`]:{[`${Cn}-item, ${Cn}-submenu ${Cn}-submenu-title`]:{[`> ${Cn}-inline-collapsed-noicon`]:{fontSize:Hn,textAlign:"center"}}},[`> ${Cn}-item, - > ${Cn}-item-group > ${Cn}-item-group-list > ${Cn}-item, - > ${Cn}-item-group > ${Cn}-item-group-list > ${Cn}-submenu > ${Cn}-submenu-title, - > ${Cn}-submenu > ${Cn}-submenu-title`]:{insetInlineStart:0,paddingInline:`calc(50% - ${Bn}px)`,textOverflow:"clip",[` - ${Cn}-submenu-arrow, - ${Cn}-submenu-expand-icon - `]:{opacity:0},[`${Cn}-item-icon, ${_n}`]:{margin:0,fontSize:Hn,lineHeight:`${Pn}px`,"+ span":{display:"inline-block",opacity:0}}},[`${Cn}-item-icon, ${_n}`]:{display:"inline-block"},"&-tooltip":{pointerEvents:"none",[`${Cn}-item-icon, ${_n}`]:{display:"none"},"a, a:hover":{color:In}},[`${Cn}-item-group-title`]:_extends$1(_extends$1({},textEllipsis),{paddingInline:Wn})}}]},getVerticalStyle$1=getVerticalStyle,genMenuItemStyle=$n=>{const{componentCls:Cn,fontSize:_n,motionDurationSlow:Pn,motionDurationMid:In,motionEaseInOut:Nn,motionEaseOut:Rn,iconCls:Dn,controlHeightSM:Ln}=$n;return{[`${Cn}-item, ${Cn}-submenu-title`]:{position:"relative",display:"block",margin:0,whiteSpace:"nowrap",cursor:"pointer",transition:[`border-color ${Pn}`,`background ${Pn}`,`padding ${Pn} ${Nn}`].join(","),[`${Cn}-item-icon, ${Dn}`]:{minWidth:_n,fontSize:_n,transition:[`font-size ${In} ${Rn}`,`margin ${Pn} ${Nn}`,`color ${Pn}`].join(","),"+ span":{marginInlineStart:Ln-_n,opacity:1,transition:[`opacity ${Pn} ${Nn}`,`margin ${Pn}`,`color ${Pn}`].join(",")}},[`${Cn}-item-icon`]:_extends$1({},resetIcon()),[`&${Cn}-item-only-child`]:{[`> ${Dn}, > ${Cn}-item-icon`]:{marginInlineEnd:0}}},[`${Cn}-item-disabled, ${Cn}-submenu-disabled`]:{background:"none !important",cursor:"not-allowed","&::after":{borderColor:"transparent !important"},a:{color:"inherit !important"},[`> ${Cn}-submenu-title`]:{color:"inherit !important",cursor:"not-allowed"}}}},genSubMenuArrowStyle=$n=>{const{componentCls:Cn,motionDurationSlow:_n,motionEaseInOut:Pn,borderRadius:In,menuArrowSize:Nn,menuArrowOffset:Rn}=$n;return{[`${Cn}-submenu`]:{"&-expand-icon, &-arrow":{position:"absolute",top:"50%",insetInlineEnd:$n.margin,width:Nn,color:"currentcolor",transform:"translateY(-50%)",transition:`transform ${_n} ${Pn}, opacity ${_n}`},"&-arrow":{"&::before, &::after":{position:"absolute",width:Nn*.6,height:Nn*.15,backgroundColor:"currentcolor",borderRadius:In,transition:[`background ${_n} ${Pn}`,`transform ${_n} ${Pn}`,`top ${_n} ${Pn}`,`color ${_n} ${Pn}`].join(","),content:'""'},"&::before":{transform:`rotate(45deg) translateY(-${Rn})`},"&::after":{transform:`rotate(-45deg) translateY(${Rn})`}}}}},getBaseStyle=$n=>{const{antCls:Cn,componentCls:_n,fontSize:Pn,motionDurationSlow:In,motionDurationMid:Nn,motionEaseInOut:Rn,lineHeight:Dn,paddingXS:Ln,padding:Fn,colorSplit:Bn,lineWidth:Hn,zIndexPopup:zn,borderRadiusLG:Wn,radiusSubMenuItem:Yn,menuArrowSize:Gn,menuArrowOffset:Go,lineType:Xn,menuPanelMaskInset:Yo}=$n;return[{"":{[`${_n}`]:_extends$1(_extends$1({},clearFix()),{"&-hidden":{display:"none"}})},[`${_n}-submenu-hidden`]:{display:"none"}},{[_n]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),clearFix()),{marginBottom:0,paddingInlineStart:0,fontSize:Pn,lineHeight:0,listStyle:"none",outline:"none",transition:`width ${In} cubic-bezier(0.2, 0, 0, 1) 0s`,"ul, ol":{margin:0,padding:0,listStyle:"none"},"&-overflow":{display:"flex",[`${_n}-item`]:{flex:"none"}},[`${_n}-item, ${_n}-submenu, ${_n}-submenu-title`]:{borderRadius:$n.radiusItem},[`${_n}-item-group-title`]:{padding:`${Ln}px ${Fn}px`,fontSize:Pn,lineHeight:Dn,transition:`all ${In}`},[`&-horizontal ${_n}-submenu`]:{transition:[`border-color ${In} ${Rn}`,`background ${In} ${Rn}`].join(",")},[`${_n}-submenu, ${_n}-submenu-inline`]:{transition:[`border-color ${In} ${Rn}`,`background ${In} ${Rn}`,`padding ${Nn} ${Rn}`].join(",")},[`${_n}-submenu ${_n}-sub`]:{cursor:"initial",transition:[`background ${In} ${Rn}`,`padding ${In} ${Rn}`].join(",")},[`${_n}-title-content`]:{transition:`color ${In}`},[`${_n}-item a`]:{"&::before":{position:"absolute",inset:0,backgroundColor:"transparent",content:'""'}},[`${_n}-item-divider`]:{overflow:"hidden",lineHeight:0,borderColor:Bn,borderStyle:Xn,borderWidth:0,borderTopWidth:Hn,marginBlock:Hn,padding:0,"&-dashed":{borderStyle:"dashed"}}}),genMenuItemStyle($n)),{[`${_n}-item-group`]:{[`${_n}-item-group-list`]:{margin:0,padding:0,[`${_n}-item, ${_n}-submenu-title`]:{paddingInline:`${Pn*2}px ${Fn}px`}}},"&-submenu":{"&-popup":{position:"absolute",zIndex:zn,background:"transparent",borderRadius:Wn,boxShadow:"none",transformOrigin:"0 0","&::before":{position:"absolute",inset:`${Yo}px 0 0`,zIndex:-1,width:"100%",height:"100%",opacity:0,content:'""'}},"&-placement-rightTop::before":{top:0,insetInlineStart:Yo},[`> ${_n}`]:_extends$1(_extends$1(_extends$1({borderRadius:Wn},genMenuItemStyle($n)),genSubMenuArrowStyle($n)),{[`${_n}-item, ${_n}-submenu > ${_n}-submenu-title`]:{borderRadius:Yn},[`${_n}-submenu-title::after`]:{transition:`transform ${In} ${Rn}`}})}}),genSubMenuArrowStyle($n)),{[`&-inline-collapsed ${_n}-submenu-arrow, - &-inline ${_n}-submenu-arrow`]:{"&::before":{transform:`rotate(-45deg) translateX(${Go})`},"&::after":{transform:`rotate(45deg) translateX(-${Go})`}},[`${_n}-submenu-open${_n}-submenu-inline > ${_n}-submenu-title > ${_n}-submenu-arrow`]:{transform:`translateY(-${Gn*.2}px)`,"&::after":{transform:`rotate(-45deg) translateX(-${Go})`},"&::before":{transform:`rotate(45deg) translateX(${Go})`}}})},{[`${Cn}-layout-header`]:{[_n]:{lineHeight:"inherit"}}}]},useStyle$N=($n,Cn)=>genComponentStyleHook("Menu",(Pn,In)=>{let{overrideComponentToken:Nn}=In;if((Cn==null?void 0:Cn.value)===!1)return[];const{colorBgElevated:Rn,colorPrimary:Dn,colorError:Ln,colorErrorHover:Fn,colorTextLightSolid:Bn}=Pn,{controlHeightLG:Hn,fontSize:zn}=Pn,Wn=zn/7*5,Yn=merge$1(Pn,{menuItemHeight:Hn,menuItemPaddingInline:Pn.margin,menuArrowSize:Wn,menuHorizontalHeight:Hn*1.15,menuArrowOffset:`${Wn*.25}px`,menuPanelMaskInset:-7,menuSubMenuBg:Rn}),Gn=new TinyColor(Bn).setAlpha(.65).toRgbString(),Go=merge$1(Yn,{colorItemText:Gn,colorItemTextHover:Bn,colorGroupTitle:Gn,colorItemTextSelected:Bn,colorItemBg:"#001529",colorSubItemBg:"#000c17",colorItemBgActive:"transparent",colorItemBgSelected:Dn,colorActiveBarWidth:0,colorActiveBarHeight:0,colorActiveBarBorderSize:0,colorItemTextDisabled:new TinyColor(Bn).setAlpha(.25).toRgbString(),colorDangerItemText:Ln,colorDangerItemTextHover:Fn,colorDangerItemTextSelected:Bn,colorDangerItemBgActive:Ln,colorDangerItemBgSelected:Ln,menuSubMenuBg:"#001529",colorItemTextSelectedHorizontal:Bn,colorItemBgSelectedHorizontal:Dn},_extends$1({},Nn));return[getBaseStyle(Yn),getHorizontalStyle$1(Yn),getVerticalStyle$1(Yn),getThemeStyle$1(Yn,"light"),getThemeStyle$1(Go,"dark"),getRTLStyle$1(Yn),genCollapseMotion$1(Yn),initSlideMotion(Yn,"slide-up"),initSlideMotion(Yn,"slide-down"),initZoomMotion(Yn,"zoom-big")]},Pn=>{const{colorPrimary:In,colorError:Nn,colorTextDisabled:Rn,colorErrorBg:Dn,colorText:Ln,colorTextDescription:Fn,colorBgContainer:Bn,colorFillAlter:Hn,colorFillContent:zn,lineWidth:Wn,lineWidthBold:Yn,controlItemBgActive:Gn,colorBgTextHover:Go}=Pn;return{dropdownWidth:160,zIndexPopup:Pn.zIndexPopupBase+50,radiusItem:Pn.borderRadiusLG,radiusSubMenuItem:Pn.borderRadiusSM,colorItemText:Ln,colorItemTextHover:Ln,colorItemTextHoverHorizontal:In,colorGroupTitle:Fn,colorItemTextSelected:In,colorItemTextSelectedHorizontal:In,colorItemBg:Bn,colorItemBgHover:Go,colorItemBgActive:zn,colorSubItemBg:Hn,colorItemBgSelected:Gn,colorItemBgSelectedHorizontal:"transparent",colorActiveBarWidth:0,colorActiveBarHeight:Yn,colorActiveBarBorderSize:Wn,colorItemTextDisabled:Rn,colorDangerItemText:Nn,colorDangerItemTextHover:Nn,colorDangerItemTextSelected:Nn,colorDangerItemBgActive:Dn,colorDangerItemBgSelected:Dn,itemMarginInline:Pn.marginXXS}})($n),menuProps=()=>({id:String,prefixCls:String,items:Array,disabled:Boolean,inlineCollapsed:Boolean,disabledOverflow:Boolean,forceSubMenuRender:Boolean,openKeys:Array,selectedKeys:Array,activeKey:String,selectable:{type:Boolean,default:!0},multiple:{type:Boolean,default:!1},tabindex:{type:[Number,String]},motion:Object,role:String,theme:{type:String,default:"light"},mode:{type:String,default:"vertical"},inlineIndent:{type:Number,default:24},subMenuOpenDelay:{type:Number,default:0},subMenuCloseDelay:{type:Number,default:.1},builtinPlacements:{type:Object},triggerSubMenuAction:{type:String,default:"hover"},getPopupContainer:Function,expandIcon:Function,onOpenChange:Function,onSelect:Function,onDeselect:Function,onClick:[Function,Array],onFocus:Function,onBlur:Function,onMousedown:Function,"onUpdate:openKeys":Function,"onUpdate:selectedKeys":Function,"onUpdate:activeKey":Function}),EMPTY_LIST$2=[],Menu=defineComponent({compatConfig:{MODE:3},name:"AMenu",inheritAttrs:!1,props:menuProps(),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const{direction:Nn,getPrefixCls:Rn}=useConfigInject("menu",$n),Dn=useInjectOverride(),Ln=computed(()=>{var Ta;return Rn("menu",$n.prefixCls||((Ta=Dn==null?void 0:Dn.prefixCls)===null||Ta===void 0?void 0:Ta.value))}),[Fn,Bn]=useStyle$N(Ln,computed(()=>!Dn)),Hn=shallowRef(new Map),zn=inject(SiderCollapsedKey,ref(void 0)),Wn=computed(()=>zn.value!==void 0?zn.value:$n.inlineCollapsed),{itemsNodes:Yn}=useItems($n),Gn=shallowRef(!1);onMounted(()=>{Gn.value=!0}),watchEffect(()=>{devWarning(!($n.inlineCollapsed===!0&&$n.mode!=="inline"),"Menu","`inlineCollapsed` should only be used when `mode` is inline."),devWarning(!(zn.value!==void 0&&$n.inlineCollapsed===!0),"Menu","`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.")});const Go=ref([]),Xn=ref([]),Yo=ref({});watch(Hn,()=>{const Ta={};for(const wa of Hn.value.values())Ta[wa.key]=wa;Yo.value=Ta},{flush:"post"}),watchEffect(()=>{if($n.activeKey!==void 0){let Ta=[];const wa=$n.activeKey?Yo.value[$n.activeKey]:void 0;wa&&$n.activeKey!==void 0?Ta=uniq([].concat(unref(wa.parentKeys),$n.activeKey)):Ta=[],shallowequal(Go.value,Ta)||(Go.value=Ta)}}),watch(()=>$n.selectedKeys,Ta=>{Ta&&(Xn.value=Ta.slice())},{immediate:!0,deep:!0});const qo=ref([]);watch([Yo,Xn],()=>{let Ta=[];Xn.value.forEach(wa=>{const La=Yo.value[wa];La&&(Ta=Ta.concat(unref(La.parentKeys)))}),Ta=uniq(Ta),shallowequal(qo.value,Ta)||(qo.value=Ta)},{immediate:!0});const Jo=Ta=>{if($n.selectable){const{key:wa}=Ta,La=Xn.value.includes(wa);let Na;$n.multiple?La?Na=Xn.value.filter(ka=>ka!==wa):Na=[...Xn.value,wa]:Na=[wa];const $a=_extends$1(_extends$1({},Ta),{selectedKeys:Na});shallowequal(Na,Xn.value)||($n.selectedKeys===void 0&&(Xn.value=Na),Pn("update:selectedKeys",Na),La&&$n.multiple?Pn("deselect",$a):Pn("select",$a))}ra.value!=="inline"&&!$n.multiple&&Zo.value.length&&ua(EMPTY_LIST$2)},Zo=ref([]);watch(()=>$n.openKeys,function(){let Ta=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Zo.value;shallowequal(Zo.value,Ta)||(Zo.value=Ta.slice())},{immediate:!0,deep:!0});let rr;const nr=Ta=>{clearTimeout(rr),rr=setTimeout(()=>{$n.activeKey===void 0&&(Go.value=Ta),Pn("update:activeKey",Ta[Ta.length-1])})},ta=computed(()=>!!$n.disabled),oa=computed(()=>Nn.value==="rtl"),ra=ref("vertical"),ea=shallowRef(!1);watchEffect(()=>{var Ta;($n.mode==="inline"||$n.mode==="vertical")&&Wn.value?(ra.value="vertical",ea.value=Wn.value):(ra.value=$n.mode,ea.value=!1),!((Ta=Dn==null?void 0:Dn.mode)===null||Ta===void 0)&&Ta.value&&(ra.value=Dn.mode.value)});const la=computed(()=>ra.value==="inline"),ua=Ta=>{Zo.value=Ta,Pn("update:openKeys",Ta),Pn("openChange",Ta)},ga=ref(Zo.value),aa=shallowRef(!1);watch(Zo,()=>{la.value&&(ga.value=Zo.value)},{immediate:!0}),watch(la,()=>{if(!aa.value){aa.value=!0;return}la.value?Zo.value=ga.value:ua(EMPTY_LIST$2)},{immediate:!0});const ca=computed(()=>({[`${Ln.value}`]:!0,[`${Ln.value}-root`]:!0,[`${Ln.value}-${ra.value}`]:!0,[`${Ln.value}-inline-collapsed`]:ea.value,[`${Ln.value}-rtl`]:oa.value,[`${Ln.value}-${$n.theme}`]:!0})),sa=computed(()=>Rn()),ia=computed(()=>({horizontal:{name:`${sa.value}-slide-up`},inline:collapseMotion$1(`${sa.value}-motion-collapse`),other:{name:`${sa.value}-zoom-big`}}));useProvideFirstLevel(!0);const fa=function(){let Ta=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];const wa=[],La=Hn.value;return Ta.forEach(Na=>{const{key:$a,childrenEventKeys:ka}=La.get(Na);wa.push($a,...fa(unref(ka)))}),wa},ma=Ta=>{var wa;Pn("click",Ta),Jo(Ta),(wa=Dn==null?void 0:Dn.onClick)===null||wa===void 0||wa.call(Dn)},ya=(Ta,wa)=>{var La;const Na=((La=Yo.value[Ta])===null||La===void 0?void 0:La.childrenEventKeys)||[];let $a=Zo.value.filter(ka=>ka!==Ta);if(wa)$a.push(Ta);else if(ra.value!=="inline"){const ka=fa(unref(Na));$a=uniq($a.filter(Ha=>!ka.includes(Ha)))}shallowequal(Zo,$a)||ua($a)},ba=(Ta,wa)=>{Hn.value.set(Ta,wa),Hn.value=new Map(Hn.value)},Ia=Ta=>{Hn.value.delete(Ta),Hn.value=new Map(Hn.value)},Ea=ref(0),xa=computed(()=>{var Ta;return $n.expandIcon||_n.expandIcon||!((Ta=Dn==null?void 0:Dn.expandIcon)===null||Ta===void 0)&&Ta.value?wa=>{let La=$n.expandIcon||_n.expandIcon;return La=typeof La=="function"?La(wa):La,cloneElement(La,{class:`${Ln.value}-submenu-expand-icon`},!1)}:null});return useProvideMenu$1({prefixCls:Ln,activeKeys:Go,openKeys:Zo,selectedKeys:Xn,changeActiveKeys:nr,disabled:ta,rtl:oa,mode:ra,inlineIndent:computed(()=>$n.inlineIndent),subMenuCloseDelay:computed(()=>$n.subMenuCloseDelay),subMenuOpenDelay:computed(()=>$n.subMenuOpenDelay),builtinPlacements:computed(()=>$n.builtinPlacements),triggerSubMenuAction:computed(()=>$n.triggerSubMenuAction),getPopupContainer:computed(()=>$n.getPopupContainer),inlineCollapsed:ea,theme:computed(()=>$n.theme),siderCollapsed:zn,defaultMotions:computed(()=>Gn.value?ia.value:null),motion:computed(()=>Gn.value?$n.motion:null),overflowDisabled:shallowRef(void 0),onOpenChange:ya,onItemClick:ma,registerMenuInfo:ba,unRegisterMenuInfo:Ia,selectedSubMenuKeys:qo,expandIcon:xa,forceSubMenuRender:computed(()=>$n.forceSubMenuRender),rootClassName:Bn}),()=>{var Ta,wa;const La=Yn.value||flattenChildren((Ta=_n.default)===null||Ta===void 0?void 0:Ta.call(_n)),Na=Ea.value>=La.length-1||ra.value!=="horizontal"||$n.disabledOverflow,$a=ra.value!=="horizontal"||$n.disabledOverflow?La:La.map((Ha,da)=>createVNode(MenuContextProvider,{key:Ha.key,overflowDisabled:da>Ea.value},{default:()=>Ha})),ka=((wa=_n.overflowedIndicator)===null||wa===void 0?void 0:wa.call(_n))||createVNode(EllipsisOutlined$1,null,null);return Fn(createVNode(Overflow$1,_objectSpread2$1(_objectSpread2$1({},In),{},{onMousedown:$n.onMousedown,prefixCls:`${Ln.value}-overflow`,component:"ul",itemComponent:MenuItem$1,class:[ca.value,In.class,Bn.value],role:"menu",id:$n.id,data:$a,renderRawItem:Ha=>Ha,renderRawRest:Ha=>{const da=Ha.length,pa=da?La.slice(-da):null;return createVNode(Fragment,null,[createVNode(SubMenu$1,{eventKey:OVERFLOW_KEY,key:OVERFLOW_KEY,title:ka,disabled:Na,internalPopupClose:da===0},{default:()=>pa}),createVNode(PathContext,null,{default:()=>[createVNode(SubMenu$1,{eventKey:OVERFLOW_KEY,key:OVERFLOW_KEY,title:ka,disabled:Na,internalPopupClose:da===0},{default:()=>pa})]})])},maxCount:ra.value!=="horizontal"||$n.disabledOverflow?Overflow$1.INVALIDATE:Overflow$1.RESPONSIVE,ssr:"full","data-menu-list":!0,onVisibleChange:Ha=>{Ea.value=Ha}}),{default:()=>[createVNode(Teleport,{to:"body"},{default:()=>[createVNode("div",{style:{display:"none"},"aria-hidden":!0},[createVNode(PathContext,null,{default:()=>[$a]})])]})]}))}}});Menu.install=function($n){return $n.component(Menu.name,Menu),$n.component(MenuItem$1.name,MenuItem$1),$n.component(SubMenu$1.name,SubMenu$1),$n.component(Divider$1.name,Divider$1),$n.component(ItemGroup.name,ItemGroup),$n};Menu.Item=MenuItem$1;Menu.Divider=Divider$1;Menu.SubMenu=SubMenu$1;Menu.ItemGroup=ItemGroup;const genBreadcrumbStyle=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{color:$n.breadcrumbBaseColor,fontSize:$n.breadcrumbFontSize,[_n]:{fontSize:$n.breadcrumbIconFontSize},ol:{display:"flex",flexWrap:"wrap",margin:0,padding:0,listStyle:"none"},a:_extends$1({color:$n.breadcrumbLinkColor,transition:`color ${$n.motionDurationMid}`,padding:`0 ${$n.paddingXXS}px`,borderRadius:$n.borderRadiusSM,height:$n.lineHeight*$n.fontSize,display:"inline-block",marginInline:-$n.marginXXS,"&:hover":{color:$n.breadcrumbLinkColorHover,backgroundColor:$n.colorBgTextHover}},genFocusStyle($n)),"li:last-child":{color:$n.breadcrumbLastItemColor,[`& > ${Cn}-separator`]:{display:"none"}},[`${Cn}-separator`]:{marginInline:$n.breadcrumbSeparatorMargin,color:$n.breadcrumbSeparatorColor},[`${Cn}-link`]:{[` - > ${_n} + span, - > ${_n} + a - `]:{marginInlineStart:$n.marginXXS}},[`${Cn}-overlay-link`]:{borderRadius:$n.borderRadiusSM,height:$n.lineHeight*$n.fontSize,display:"inline-block",padding:`0 ${$n.paddingXXS}px`,marginInline:-$n.marginXXS,[`> ${_n}`]:{marginInlineStart:$n.marginXXS,fontSize:$n.fontSizeIcon},"&:hover":{color:$n.breadcrumbLinkColorHover,backgroundColor:$n.colorBgTextHover,a:{color:$n.breadcrumbLinkColorHover}},a:{"&:hover":{backgroundColor:"transparent"}}},[`&${$n.componentCls}-rtl`]:{direction:"rtl"}})}},useStyle$M=genComponentStyleHook("Breadcrumb",$n=>{const Cn=merge$1($n,{breadcrumbBaseColor:$n.colorTextDescription,breadcrumbFontSize:$n.fontSize,breadcrumbIconFontSize:$n.fontSize,breadcrumbLinkColor:$n.colorTextDescription,breadcrumbLinkColorHover:$n.colorText,breadcrumbLastItemColor:$n.colorText,breadcrumbSeparatorMargin:$n.marginXS,breadcrumbSeparatorColor:$n.colorTextDescription});return[genBreadcrumbStyle(Cn)]}),breadcrumbProps=()=>({prefixCls:String,routes:{type:Array},params:PropTypes.any,separator:PropTypes.any,itemRender:{type:Function}});function getBreadcrumbName($n,Cn){if(!$n.breadcrumbName)return null;const _n=Object.keys(Cn).join("|");return $n.breadcrumbName.replace(new RegExp(`:(${_n})`,"g"),(In,Nn)=>Cn[Nn]||In)}function defaultItemRender$1($n){const{route:Cn,params:_n,routes:Pn,paths:In}=$n,Nn=Pn.indexOf(Cn)===Pn.length-1,Rn=getBreadcrumbName(Cn,_n);return Nn?createVNode("span",null,[Rn]):createVNode("a",{href:`#/${In.join("/")}`},[Rn])}const Breadcrumb=defineComponent({compatConfig:{MODE:3},name:"ABreadcrumb",inheritAttrs:!1,props:breadcrumbProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("breadcrumb",$n),[Rn,Dn]=useStyle$M(In),Ln=(Hn,zn)=>(Hn=(Hn||"").replace(/^\//,""),Object.keys(zn).forEach(Wn=>{Hn=Hn.replace(`:${Wn}`,zn[Wn])}),Hn),Fn=(Hn,zn,Wn)=>{const Yn=[...Hn],Gn=Ln(zn||"",Wn);return Gn&&Yn.push(Gn),Yn},Bn=Hn=>{let{routes:zn=[],params:Wn={},separator:Yn,itemRender:Gn=defaultItemRender$1}=Hn;const Go=[];return zn.map(Xn=>{const Yo=Ln(Xn.path,Wn);Yo&&Go.push(Yo);const qo=[...Go];let Jo=null;Xn.children&&Xn.children.length&&(Jo=createVNode(Menu,{items:Xn.children.map(rr=>({key:rr.path||rr.breadcrumbName,label:Gn({route:rr,params:Wn,routes:zn,paths:Fn(qo,rr.path,Wn)})}))},null));const Zo={separator:Yn};return Jo&&(Zo.overlay=Jo),createVNode(BreadcrumbItem,_objectSpread2$1(_objectSpread2$1({},Zo),{},{key:Yo||Xn.breadcrumbName}),{default:()=>[Gn({route:Xn,params:Wn,routes:zn,paths:qo})]})})};return()=>{var Hn;let zn;const{routes:Wn,params:Yn={}}=$n,Gn=flattenChildren(getPropsSlot(_n,$n)),Go=(Hn=getPropsSlot(_n,$n,"separator"))!==null&&Hn!==void 0?Hn:"/",Xn=$n.itemRender||_n.itemRender||defaultItemRender$1;Wn&&Wn.length>0?zn=Bn({routes:Wn,params:Yn,separator:Go,itemRender:Xn}):Gn.length&&(zn=Gn.map((qo,Jo)=>(warning$3(typeof qo.type=="object"&&(qo.type.__ANT_BREADCRUMB_ITEM||qo.type.__ANT_BREADCRUMB_SEPARATOR)),cloneVNode(qo,{separator:Go,key:Jo}))));const Yo={[In.value]:!0,[`${In.value}-rtl`]:Nn.value==="rtl",[`${Pn.class}`]:!!Pn.class,[Dn.value]:!0};return Rn(createVNode("nav",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Yo}),[createVNode("ol",null,[zn])]))}}});var __rest$_=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String}),BreadcrumbSeparator=defineComponent({compatConfig:{MODE:3},name:"ABreadcrumbSeparator",__ANT_BREADCRUMB_SEPARATOR:!0,inheritAttrs:!1,props:breadcrumbSeparatorProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In}=useConfigInject("breadcrumb",$n);return()=>{var Nn;const{separator:Rn,class:Dn}=Pn,Ln=__rest$_(Pn,["separator","class"]),Fn=flattenChildren((Nn=_n.default)===null||Nn===void 0?void 0:Nn.call(_n));return createVNode("span",_objectSpread2$1({class:[`${In.value}-separator`,Dn]},Ln),[Fn.length>0?Fn:"/"])}}});Breadcrumb.Item=BreadcrumbItem;Breadcrumb.Separator=BreadcrumbSeparator;Breadcrumb.install=function($n){return $n.component(Breadcrumb.name,Breadcrumb),$n.component(BreadcrumbItem.name,BreadcrumbItem),$n.component(BreadcrumbSeparator.name,BreadcrumbSeparator),$n};var commonjsGlobal=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function getDefaultExportFromCjs($n){return $n&&$n.__esModule&&Object.prototype.hasOwnProperty.call($n,"default")?$n.default:$n}var dayjs_min$1={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){var _n=1e3,Pn=6e4,In=36e5,Nn="millisecond",Rn="second",Dn="minute",Ln="hour",Fn="day",Bn="week",Hn="month",zn="quarter",Wn="year",Yn="date",Gn="Invalid Date",Go=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,Xn=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,Yo={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(ga){var aa=["th","st","nd","rd"],ca=ga%100;return"["+ga+(aa[(ca-20)%10]||aa[ca]||aa[0])+"]"}},qo=function(ga,aa,ca){var sa=String(ga);return!sa||sa.length>=aa?ga:""+Array(aa+1-sa.length).join(ca)+ga},Jo={s:qo,z:function(ga){var aa=-ga.utcOffset(),ca=Math.abs(aa),sa=Math.floor(ca/60),ia=ca%60;return(aa<=0?"+":"-")+qo(sa,2,"0")+":"+qo(ia,2,"0")},m:function ga(aa,ca){if(aa.date()1)return ga(ma[0])}else{var ya=aa.name;rr[ya]=aa,ia=ya}return!sa&&ia&&(Zo=ia),ia||!sa&&Zo},ra=function(ga,aa){if(ta(ga))return ga.clone();var ca=typeof aa=="object"?aa:{};return ca.date=ga,ca.args=arguments,new la(ca)},ea=Jo;ea.l=oa,ea.i=ta,ea.w=function(ga,aa){return ra(ga,{locale:aa.$L,utc:aa.$u,x:aa.$x,$offset:aa.$offset})};var la=function(){function ga(ca){this.$L=oa(ca.locale,null,!0),this.parse(ca),this.$x=this.$x||ca.x||{},this[nr]=!0}var aa=ga.prototype;return aa.parse=function(ca){this.$d=function(sa){var ia=sa.date,fa=sa.utc;if(ia===null)return new Date(NaN);if(ea.u(ia))return new Date;if(ia instanceof Date)return new Date(ia);if(typeof ia=="string"&&!/Z$/i.test(ia)){var ma=ia.match(Go);if(ma){var ya=ma[2]-1||0,ba=(ma[7]||"0").substring(0,3);return fa?new Date(Date.UTC(ma[1],ya,ma[3]||1,ma[4]||0,ma[5]||0,ma[6]||0,ba)):new Date(ma[1],ya,ma[3]||1,ma[4]||0,ma[5]||0,ma[6]||0,ba)}}return new Date(ia)}(ca),this.init()},aa.init=function(){var ca=this.$d;this.$y=ca.getFullYear(),this.$M=ca.getMonth(),this.$D=ca.getDate(),this.$W=ca.getDay(),this.$H=ca.getHours(),this.$m=ca.getMinutes(),this.$s=ca.getSeconds(),this.$ms=ca.getMilliseconds()},aa.$utils=function(){return ea},aa.isValid=function(){return this.$d.toString()!==Gn},aa.isSame=function(ca,sa){var ia=ra(ca);return this.startOf(sa)<=ia&&ia<=this.endOf(sa)},aa.isAfter=function(ca,sa){return ra(ca)25){var Bn=Rn(this).startOf(Pn).add(1,Pn).date(Fn),Hn=Rn(this).endOf(_n);if(Bn.isBefore(Hn))return 1}var zn=Rn(this).startOf(Pn).date(Fn).startOf(_n).subtract(1,"millisecond"),Wn=this.diff(zn,_n,!0);return Wn<0?Rn(this).startOf("week").week():Math.ceil(Wn)},Dn.weeks=function(Ln){return Ln===void 0&&(Ln=null),this.week(Ln)}}})})(weekOfYear$1);var weekOfYearExports=weekOfYear$1.exports;const weekOfYear=getDefaultExportFromCjs(weekOfYearExports);var weekYear$1={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){return function(_n,Pn){Pn.prototype.weekYear=function(){var In=this.month(),Nn=this.week(),Rn=this.year();return Nn===1&&In===11?Rn+1:In===0&&Nn>=52?Rn-1:Rn}}})})(weekYear$1);var weekYearExports=weekYear$1.exports;const weekYear=getDefaultExportFromCjs(weekYearExports);var quarterOfYear$1={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){var _n="month",Pn="quarter";return function(In,Nn){var Rn=Nn.prototype;Rn.quarter=function(Fn){return this.$utils().u(Fn)?Math.ceil((this.month()+1)/3):this.month(this.month()%3+3*(Fn-1))};var Dn=Rn.add;Rn.add=function(Fn,Bn){return Fn=Number(Fn),this.$utils().p(Bn)===Pn?this.add(3*Fn,_n):Dn.bind(this)(Fn,Bn)};var Ln=Rn.startOf;Rn.startOf=function(Fn,Bn){var Hn=this.$utils(),zn=!!Hn.u(Bn)||Bn;if(Hn.p(Fn)===Pn){var Wn=this.quarter()-1;return zn?this.month(3*Wn).startOf(_n).startOf("day"):this.month(3*Wn+2).endOf(_n).endOf("day")}return Ln.bind(this)(Fn,Bn)}}})})(quarterOfYear$1);var quarterOfYearExports=quarterOfYear$1.exports;const quarterOfYear=getDefaultExportFromCjs(quarterOfYearExports);var advancedFormat$1={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){return function(_n,Pn){var In=Pn.prototype,Nn=In.format;In.format=function(Rn){var Dn=this,Ln=this.$locale();if(!this.isValid())return Nn.bind(this)(Rn);var Fn=this.$utils(),Bn=(Rn||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(Hn){switch(Hn){case"Q":return Math.ceil((Dn.$M+1)/3);case"Do":return Ln.ordinal(Dn.$D);case"gggg":return Dn.weekYear();case"GGGG":return Dn.isoWeekYear();case"wo":return Ln.ordinal(Dn.week(),"W");case"w":case"ww":return Fn.s(Dn.week(),Hn==="w"?1:2,"0");case"W":case"WW":return Fn.s(Dn.isoWeek(),Hn==="W"?1:2,"0");case"k":case"kk":return Fn.s(String(Dn.$H===0?24:Dn.$H),Hn==="k"?1:2,"0");case"X":return Math.floor(Dn.$d.getTime()/1e3);case"x":return Dn.$d.getTime();case"z":return"["+Dn.offsetName()+"]";case"zzz":return"["+Dn.offsetName("long")+"]";default:return Hn}});return Nn.bind(this)(Bn)}}})})(advancedFormat$1);var advancedFormatExports=advancedFormat$1.exports;const advancedFormat=getDefaultExportFromCjs(advancedFormatExports);var customParseFormat$1={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){var _n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Pn=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,In=/\d\d/,Nn=/\d\d?/,Rn=/\d*[^-_:/,()\s\d]+/,Dn={},Ln=function(Gn){return(Gn=+Gn)+(Gn>68?1900:2e3)},Fn=function(Gn){return function(Go){this[Gn]=+Go}},Bn=[/[+-]\d\d:?(\d\d)?|Z/,function(Gn){(this.zone||(this.zone={})).offset=function(Go){if(!Go||Go==="Z")return 0;var Xn=Go.match(/([+-]|\d\d)/g),Yo=60*Xn[1]+(+Xn[2]||0);return Yo===0?0:Xn[0]==="+"?-Yo:Yo}(Gn)}],Hn=function(Gn){var Go=Dn[Gn];return Go&&(Go.indexOf?Go:Go.s.concat(Go.f))},zn=function(Gn,Go){var Xn,Yo=Dn.meridiem;if(Yo){for(var qo=1;qo<=24;qo+=1)if(Gn.indexOf(Yo(qo,0,Go))>-1){Xn=qo>12;break}}else Xn=Gn===(Go?"pm":"PM");return Xn},Wn={A:[Rn,function(Gn){this.afternoon=zn(Gn,!1)}],a:[Rn,function(Gn){this.afternoon=zn(Gn,!0)}],S:[/\d/,function(Gn){this.milliseconds=100*+Gn}],SS:[In,function(Gn){this.milliseconds=10*+Gn}],SSS:[/\d{3}/,function(Gn){this.milliseconds=+Gn}],s:[Nn,Fn("seconds")],ss:[Nn,Fn("seconds")],m:[Nn,Fn("minutes")],mm:[Nn,Fn("minutes")],H:[Nn,Fn("hours")],h:[Nn,Fn("hours")],HH:[Nn,Fn("hours")],hh:[Nn,Fn("hours")],D:[Nn,Fn("day")],DD:[In,Fn("day")],Do:[Rn,function(Gn){var Go=Dn.ordinal,Xn=Gn.match(/\d+/);if(this.day=Xn[0],Go)for(var Yo=1;Yo<=31;Yo+=1)Go(Yo).replace(/\[|\]/g,"")===Gn&&(this.day=Yo)}],M:[Nn,Fn("month")],MM:[In,Fn("month")],MMM:[Rn,function(Gn){var Go=Hn("months"),Xn=(Hn("monthsShort")||Go.map(function(Yo){return Yo.slice(0,3)})).indexOf(Gn)+1;if(Xn<1)throw new Error;this.month=Xn%12||Xn}],MMMM:[Rn,function(Gn){var Go=Hn("months").indexOf(Gn)+1;if(Go<1)throw new Error;this.month=Go%12||Go}],Y:[/[+-]?\d+/,Fn("year")],YY:[In,function(Gn){this.year=Ln(Gn)}],YYYY:[/\d{4}/,Fn("year")],Z:Bn,ZZ:Bn};function Yn(Gn){var Go,Xn;Go=Gn,Xn=Dn&&Dn.formats;for(var Yo=(Gn=Go.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(oa,ra,ea){var la=ea&&ea.toUpperCase();return ra||Xn[ea]||_n[ea]||Xn[la].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(ua,ga,aa){return ga||aa.slice(1)})})).match(Pn),qo=Yo.length,Jo=0;Jo-1)return new Date((sa==="X"?1e3:1)*ca);var fa=Yn(sa)(ca),ma=fa.year,ya=fa.month,ba=fa.day,Ia=fa.hours,Ea=fa.minutes,xa=fa.seconds,Ta=fa.milliseconds,wa=fa.zone,La=new Date,Na=ba||(ma||ya?1:La.getDate()),$a=ma||La.getFullYear(),ka=0;ma&&!ya||(ka=ya>0?ya-1:La.getMonth());var Ha=Ia||0,da=Ea||0,pa=xa||0,Sa=Ta||0;return wa?new Date(Date.UTC($a,ka,Na,Ha,da,pa,Sa+60*wa.offset*1e3)):ia?new Date(Date.UTC($a,ka,Na,Ha,da,pa,Sa)):new Date($a,ka,Na,Ha,da,pa,Sa)}catch{return new Date("")}}(Zo,ta,rr),this.init(),la&&la!==!0&&(this.$L=this.locale(la).$L),ea&&Zo!=this.format(ta)&&(this.$d=new Date("")),Dn={}}else if(ta instanceof Array)for(var ua=ta.length,ga=1;ga<=ua;ga+=1){nr[1]=ta[ga-1];var aa=Xn.apply(this,nr);if(aa.isValid()){this.$d=aa.$d,this.$L=aa.$L,this.init();break}ga===ua&&(this.$d=new Date(""))}else qo.call(this,Jo)}}})})(customParseFormat$1);var customParseFormatExports=customParseFormat$1.exports;const customParseFormat=getDefaultExportFromCjs(customParseFormatExports);dayjs$1.extend(customParseFormat);dayjs$1.extend(advancedFormat);dayjs$1.extend(weekday);dayjs$1.extend(localeData);dayjs$1.extend(weekOfYear);dayjs$1.extend(weekYear);dayjs$1.extend(quarterOfYear);dayjs$1.extend(($n,Cn)=>{const _n=Cn.prototype,Pn=_n.format;_n.format=function(Nn){const Rn=(Nn||"").replace("Wo","wo");return Pn.bind(this)(Rn)}});const localeMap={bn_BD:"bn-bd",by_BY:"be",en_GB:"en-gb",en_US:"en",fr_BE:"fr",fr_CA:"fr-ca",hy_AM:"hy-am",kmr_IQ:"ku",nl_BE:"nl-be",pt_BR:"pt-br",zh_CN:"zh-cn",zh_HK:"zh-hk",zh_TW:"zh-tw"},parseLocale=$n=>localeMap[$n]||$n.split("_")[0],parseNoMatchNotice=()=>{noteOnce(!1,"Not match any format. Please help to fire a issue about this.")},advancedFormatRegex=/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|k{1,2}|S/g;function findTargetStr($n,Cn,_n){const Pn=[...new Set($n.split(_n))];let In=0;for(let Nn=0;NnCn)return Rn;In+=_n.length}}const toDateWithValueFormat=($n,Cn)=>{if(!$n)return null;if(dayjs$1.isDayjs($n))return $n;const _n=Cn.matchAll(advancedFormatRegex);let Pn=dayjs$1($n,Cn);if(_n===null)return Pn;for(const In of _n){const Nn=In[0],Rn=In.index;if(Nn==="Q"){const Dn=$n.slice(Rn-1,Rn),Ln=findTargetStr($n,Rn,Dn).match(/\d+/)[0];Pn=Pn.quarter(parseInt(Ln))}if(Nn.toLowerCase()==="wo"){const Dn=$n.slice(Rn-1,Rn),Ln=findTargetStr($n,Rn,Dn).match(/\d+/)[0];Pn=Pn.week(parseInt(Ln))}Nn.toLowerCase()==="ww"&&(Pn=Pn.week(parseInt($n.slice(Rn,Rn+Nn.length)))),Nn.toLowerCase()==="w"&&(Pn=Pn.week(parseInt($n.slice(Rn,Rn+Nn.length+1))))}return Pn},generateConfig={getNow:()=>dayjs$1(),getFixedDate:$n=>dayjs$1($n,["YYYY-M-DD","YYYY-MM-DD"]),getEndDate:$n=>$n.endOf("month"),getWeekDay:$n=>{const Cn=$n.locale("en");return Cn.weekday()+Cn.localeData().firstDayOfWeek()},getYear:$n=>$n.year(),getMonth:$n=>$n.month(),getDate:$n=>$n.date(),getHour:$n=>$n.hour(),getMinute:$n=>$n.minute(),getSecond:$n=>$n.second(),addYear:($n,Cn)=>$n.add(Cn,"year"),addMonth:($n,Cn)=>$n.add(Cn,"month"),addDate:($n,Cn)=>$n.add(Cn,"day"),setYear:($n,Cn)=>$n.year(Cn),setMonth:($n,Cn)=>$n.month(Cn),setDate:($n,Cn)=>$n.date(Cn),setHour:($n,Cn)=>$n.hour(Cn),setMinute:($n,Cn)=>$n.minute(Cn),setSecond:($n,Cn)=>$n.second(Cn),isAfter:($n,Cn)=>$n.isAfter(Cn),isValidate:$n=>$n.isValid(),locale:{getWeekFirstDay:$n=>dayjs$1().locale(parseLocale($n)).localeData().firstDayOfWeek(),getWeekFirstDate:($n,Cn)=>Cn.locale(parseLocale($n)).weekday(0),getWeek:($n,Cn)=>Cn.locale(parseLocale($n)).week(),getShortWeekDays:$n=>dayjs$1().locale(parseLocale($n)).localeData().weekdaysMin(),getShortMonths:$n=>dayjs$1().locale(parseLocale($n)).localeData().monthsShort(),format:($n,Cn,_n)=>Cn.locale(parseLocale($n)).format(_n),parse:($n,Cn,_n)=>{const Pn=parseLocale($n);for(let In=0;In<_n.length;In+=1){const Nn=_n[In],Rn=Cn;if(Nn.includes("wo")||Nn.includes("Wo")){const Ln=Rn.split("-")[0],Fn=Rn.split("-")[1],Bn=dayjs$1(Ln,"YYYY").startOf("year").locale(Pn);for(let Hn=0;Hn<=52;Hn+=1){const zn=Bn.add(Hn,"week");if(zn.format("Wo")===Fn)return zn}return parseNoMatchNotice(),null}const Dn=dayjs$1(Rn,Nn,!0).locale(Pn);if(Dn.isValid())return Dn}return Cn||parseNoMatchNotice(),null}},toDate:($n,Cn)=>Array.isArray($n)?$n.map(_n=>toDateWithValueFormat(_n,Cn)):toDateWithValueFormat($n,Cn),toString:($n,Cn)=>Array.isArray($n)?$n.map(_n=>dayjs$1.isDayjs(_n)?_n.format(Cn):_n):dayjs$1.isDayjs($n)?$n.format(Cn):$n},dayjsGenerateConfig=generateConfig;function useMergeProps($n){const Cn=useAttrs();return _extends$1(_extends$1({},$n),Cn)}const PanelContextKey=Symbol("PanelContextProps"),useProvidePanel=$n=>{provide(PanelContextKey,$n)},useInjectPanel=()=>inject(PanelContextKey,{}),HIDDEN_STYLE$2={visibility:"hidden"};function Header$2($n,Cn){let{slots:_n}=Cn;var Pn;const In=useMergeProps($n),{prefixCls:Nn,prevIcon:Rn="‹",nextIcon:Dn="›",superPrevIcon:Ln="«",superNextIcon:Fn="»",onSuperPrev:Bn,onSuperNext:Hn,onPrev:zn,onNext:Wn}=In,{hideNextBtn:Yn,hidePrevBtn:Gn}=useInjectPanel();return createVNode("div",{class:Nn},[Bn&&createVNode("button",{type:"button",onClick:Bn,tabindex:-1,class:`${Nn}-super-prev-btn`,style:Gn.value?HIDDEN_STYLE$2:{}},[Ln]),zn&&createVNode("button",{type:"button",onClick:zn,tabindex:-1,class:`${Nn}-prev-btn`,style:Gn.value?HIDDEN_STYLE$2:{}},[Rn]),createVNode("div",{class:`${Nn}-view`},[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)]),Wn&&createVNode("button",{type:"button",onClick:Wn,tabindex:-1,class:`${Nn}-next-btn`,style:Yn.value?HIDDEN_STYLE$2:{}},[Dn]),Hn&&createVNode("button",{type:"button",onClick:Hn,tabindex:-1,class:`${Nn}-super-next-btn`,style:Yn.value?HIDDEN_STYLE$2:{}},[Fn])])}Header$2.displayName="Header";Header$2.inheritAttrs=!1;function DecadeHeader($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,viewDate:In,onPrevDecades:Nn,onNextDecades:Rn}=Cn,{hideHeader:Dn}=useInjectPanel();if(Dn)return null;const Ln=`${_n}-header`,Fn=Pn.getYear(In),Bn=Math.floor(Fn/DECADE_DISTANCE_COUNT)*DECADE_DISTANCE_COUNT,Hn=Bn+DECADE_DISTANCE_COUNT-1;return createVNode(Header$2,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:Ln,onSuperPrev:Nn,onSuperNext:Rn}),{default:()=>[Bn,createTextVNode("-"),Hn]})}DecadeHeader.displayName="DecadeHeader";DecadeHeader.inheritAttrs=!1;function setTime($n,Cn,_n,Pn,In){let Nn=$n.setHour(Cn,_n);return Nn=$n.setMinute(Nn,Pn),Nn=$n.setSecond(Nn,In),Nn}function setDateTime($n,Cn,_n){if(!_n)return Cn;let Pn=Cn;return Pn=$n.setHour(Pn,$n.getHour(_n)),Pn=$n.setMinute(Pn,$n.getMinute(_n)),Pn=$n.setSecond(Pn,$n.getSecond(_n)),Pn}function getLowerBoundTime($n,Cn,_n,Pn,In,Nn){const Rn=Math.floor($n/Pn)*Pn;if(Rn<$n)return[Rn,60-In,60-Nn];const Dn=Math.floor(Cn/In)*In;if(Dn{ga.stopPropagation(),la||Pn(ea)},onMouseenter:()=>{!la&&Xn&&Xn(ea)},onMouseleave:()=>{!la&&Yo&&Yo(ea)}},[zn?zn(ea):createVNode("div",{class:`${Jo}-inner`},[Hn(ea)])]))}Zo.push(createVNode("tr",{key:rr,class:Ln&&Ln(ta)},[nr]))}return createVNode("div",{class:`${Cn}-body`},[createVNode("table",{class:`${Cn}-content`},[Go&&createVNode("thead",null,[createVNode("tr",null,[Go])]),createVNode("tbody",null,[Zo])])])}PanelBody.displayName="PanelBody";PanelBody.inheritAttrs=!1;const DECADE_COL_COUNT=3,DECADE_ROW_COUNT=4;function DecadeBody($n){const Cn=useMergeProps($n),_n=DECADE_UNIT_DIFF-1,{prefixCls:Pn,viewDate:In,generateConfig:Nn}=Cn,Rn=`${Pn}-cell`,Dn=Nn.getYear(In),Ln=Math.floor(Dn/DECADE_UNIT_DIFF)*DECADE_UNIT_DIFF,Fn=Math.floor(Dn/DECADE_DISTANCE_COUNT)*DECADE_DISTANCE_COUNT,Bn=Fn+DECADE_DISTANCE_COUNT-1,Hn=Nn.setYear(In,Fn-Math.ceil((DECADE_COL_COUNT*DECADE_ROW_COUNT*DECADE_UNIT_DIFF-DECADE_DISTANCE_COUNT)/2)),zn=Wn=>{const Yn=Nn.getYear(Wn),Gn=Yn+_n;return{[`${Rn}-in-view`]:Fn<=Yn&&Gn<=Bn,[`${Rn}-selected`]:Yn===Ln}};return createVNode(PanelBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{rowNum:DECADE_ROW_COUNT,colNum:DECADE_COL_COUNT,baseDate:Hn,getCellText:Wn=>{const Yn=Nn.getYear(Wn);return`${Yn}-${Yn+_n}`},getCellClassName:zn,getCellDate:(Wn,Yn)=>Nn.addYear(Wn,Yn*DECADE_UNIT_DIFF)}),null)}DecadeBody.displayName="DecadeBody";DecadeBody.inheritAttrs=!1;const scrollIds=new Map;function waitElementReady($n,Cn){let _n;function Pn(){isVisible($n)?Cn():_n=wrapperRaf(()=>{Pn()})}return Pn(),()=>{wrapperRaf.cancel(_n)}}function scrollTo($n,Cn,_n){if(scrollIds.get($n)&&wrapperRaf.cancel(scrollIds.get($n)),_n<=0){scrollIds.set($n,wrapperRaf(()=>{$n.scrollTop=Cn}));return}const In=(Cn-$n.scrollTop)/_n*10;scrollIds.set($n,wrapperRaf(()=>{$n.scrollTop+=In,$n.scrollTop!==Cn&&scrollTo($n,Cn,_n-10)}))}function createKeydownHandler($n,Cn){let{onLeftRight:_n,onCtrlLeftRight:Pn,onUpDown:In,onPageUpDown:Nn,onEnter:Rn}=Cn;const{which:Dn,ctrlKey:Ln,metaKey:Fn}=$n;switch(Dn){case KeyCode$1.LEFT:if(Ln||Fn){if(Pn)return Pn(-1),!0}else if(_n)return _n(-1),!0;break;case KeyCode$1.RIGHT:if(Ln||Fn){if(Pn)return Pn(1),!0}else if(_n)return _n(1),!0;break;case KeyCode$1.UP:if(In)return In(-1),!0;break;case KeyCode$1.DOWN:if(In)return In(1),!0;break;case KeyCode$1.PAGE_UP:if(Nn)return Nn(-1),!0;break;case KeyCode$1.PAGE_DOWN:if(Nn)return Nn(1),!0;break;case KeyCode$1.ENTER:if(Rn)return Rn(),!0;break}return!1}function getDefaultFormat($n,Cn,_n,Pn){let In=$n;if(!In)switch(Cn){case"time":In=Pn?"hh:mm:ss a":"HH:mm:ss";break;case"week":In="gggg-wo";break;case"month":In="YYYY-MM";break;case"quarter":In="YYYY-[Q]Q";break;case"year":In="YYYY";break;default:In=_n?"YYYY-MM-DD HH:mm:ss":"YYYY-MM-DD"}return In}function getInputSize($n,Cn,_n){const Pn=$n==="time"?8:10,In=typeof Cn=="function"?Cn(_n.getNow()).length:Cn.length;return Math.max(Pn,In)+2}let globalClickFunc=null;const clickCallbacks=new Set;function addGlobalMousedownEvent($n){return!globalClickFunc&&typeof window<"u"&&window.addEventListener&&(globalClickFunc=Cn=>{[...clickCallbacks].forEach(_n=>{_n(Cn)})},window.addEventListener("mousedown",globalClickFunc)),clickCallbacks.add($n),()=>{clickCallbacks.delete($n),clickCallbacks.size===0&&(window.removeEventListener("mousedown",globalClickFunc),globalClickFunc=null)}}function getTargetFromEvent($n){var Cn;const _n=$n.target;return $n.composed&&_n.shadowRoot&&((Cn=$n.composedPath)===null||Cn===void 0?void 0:Cn.call($n)[0])||_n}const getYearNextMode=$n=>$n==="month"||$n==="date"?"year":$n,getMonthNextMode=$n=>$n==="date"?"month":$n,getQuarterNextMode=$n=>$n==="month"||$n==="date"?"quarter":$n,getWeekNextMode=$n=>$n==="date"?"week":$n,PickerModeMap={year:getYearNextMode,month:getMonthNextMode,quarter:getQuarterNextMode,week:getWeekNextMode,time:null,date:null};function elementsContains($n,Cn){return $n.some(_n=>_n&&_n.contains(Cn))}const DECADE_UNIT_DIFF=10,DECADE_DISTANCE_COUNT=DECADE_UNIT_DIFF*10;function DecadePanel($n){const Cn=useMergeProps($n),{prefixCls:_n,onViewDateChange:Pn,generateConfig:In,viewDate:Nn,operationRef:Rn,onSelect:Dn,onPanelChange:Ln}=Cn,Fn=`${_n}-decade-panel`;Rn.value={onKeydown:zn=>createKeydownHandler(zn,{onLeftRight:Wn=>{Dn(In.addYear(Nn,Wn*DECADE_UNIT_DIFF),"key")},onCtrlLeftRight:Wn=>{Dn(In.addYear(Nn,Wn*DECADE_DISTANCE_COUNT),"key")},onUpDown:Wn=>{Dn(In.addYear(Nn,Wn*DECADE_UNIT_DIFF*DECADE_COL_COUNT),"key")},onEnter:()=>{Ln("year",Nn)}})};const Bn=zn=>{const Wn=In.addYear(Nn,zn*DECADE_DISTANCE_COUNT);Pn(Wn),Ln(null,Wn)},Hn=zn=>{Dn(zn,"mouse"),Ln("year",zn)};return createVNode("div",{class:Fn},[createVNode(DecadeHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onPrevDecades:()=>{Bn(-1)},onNextDecades:()=>{Bn(1)}}),null),createVNode(DecadeBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onSelect:Hn}),null)])}DecadePanel.displayName="DecadePanel";DecadePanel.inheritAttrs=!1;const WEEK_DAY_COUNT=7;function isNullEqual($n,Cn){if(!$n&&!Cn)return!0;if(!$n||!Cn)return!1}function isSameDecade($n,Cn,_n){const Pn=isNullEqual(Cn,_n);if(typeof Pn=="boolean")return Pn;const In=Math.floor($n.getYear(Cn)/10),Nn=Math.floor($n.getYear(_n)/10);return In===Nn}function isSameYear($n,Cn,_n){const Pn=isNullEqual(Cn,_n);return typeof Pn=="boolean"?Pn:$n.getYear(Cn)===$n.getYear(_n)}function getQuarter($n,Cn){return Math.floor($n.getMonth(Cn)/3)+1}function isSameQuarter($n,Cn,_n){const Pn=isNullEqual(Cn,_n);return typeof Pn=="boolean"?Pn:isSameYear($n,Cn,_n)&&getQuarter($n,Cn)===getQuarter($n,_n)}function isSameMonth($n,Cn,_n){const Pn=isNullEqual(Cn,_n);return typeof Pn=="boolean"?Pn:isSameYear($n,Cn,_n)&&$n.getMonth(Cn)===$n.getMonth(_n)}function isSameDate($n,Cn,_n){const Pn=isNullEqual(Cn,_n);return typeof Pn=="boolean"?Pn:$n.getYear(Cn)===$n.getYear(_n)&&$n.getMonth(Cn)===$n.getMonth(_n)&&$n.getDate(Cn)===$n.getDate(_n)}function isSameTime($n,Cn,_n){const Pn=isNullEqual(Cn,_n);return typeof Pn=="boolean"?Pn:$n.getHour(Cn)===$n.getHour(_n)&&$n.getMinute(Cn)===$n.getMinute(_n)&&$n.getSecond(Cn)===$n.getSecond(_n)}function isSameWeek($n,Cn,_n,Pn){const In=isNullEqual(_n,Pn);return typeof In=="boolean"?In:$n.locale.getWeek(Cn,_n)===$n.locale.getWeek(Cn,Pn)}function isEqual$1($n,Cn,_n){return isSameDate($n,Cn,_n)&&isSameTime($n,Cn,_n)}function isInRange($n,Cn,_n,Pn){return!Cn||!_n||!Pn?!1:!isSameDate($n,Cn,Pn)&&!isSameDate($n,_n,Pn)&&$n.isAfter(Pn,Cn)&&$n.isAfter(_n,Pn)}function getWeekStartDate($n,Cn,_n){const Pn=Cn.locale.getWeekFirstDay($n),In=Cn.setDate(_n,1),Nn=Cn.getWeekDay(In);let Rn=Cn.addDate(In,Pn-Nn);return Cn.getMonth(Rn)===Cn.getMonth(_n)&&Cn.getDate(Rn)>1&&(Rn=Cn.addDate(Rn,-7)),Rn}function getClosingViewDate($n,Cn,_n){let Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:1;switch(Cn){case"year":return _n.addYear($n,Pn*10);case"quarter":case"month":return _n.addYear($n,Pn);default:return _n.addMonth($n,Pn)}}function formatValue($n,Cn){let{generateConfig:_n,locale:Pn,format:In}=Cn;return typeof In=="function"?In($n):_n.locale.format(Pn.locale,$n,In)}function parseValue$1($n,Cn){let{generateConfig:_n,locale:Pn,formatList:In}=Cn;return!$n||typeof In[0]=="function"?null:_n.locale.parse(Pn.locale,$n,In)}function getCellDateDisabled($n){let{cellDate:Cn,mode:_n,disabledDate:Pn,generateConfig:In}=$n;if(!Pn)return!1;const Nn=(Rn,Dn,Ln)=>{let Fn=Dn;for(;Fn<=Ln;){let Bn;switch(Rn){case"date":{if(Bn=In.setDate(Cn,Fn),!Pn(Bn))return!1;break}case"month":{if(Bn=In.setMonth(Cn,Fn),!getCellDateDisabled({cellDate:Bn,mode:"month",generateConfig:In,disabledDate:Pn}))return!1;break}case"year":{if(Bn=In.setYear(Cn,Fn),!getCellDateDisabled({cellDate:Bn,mode:"year",generateConfig:In,disabledDate:Pn}))return!1;break}}Fn+=1}return!0};switch(_n){case"date":case"week":return Pn(Cn);case"month":{const Dn=In.getDate(In.getEndDate(Cn));return Nn("date",1,Dn)}case"quarter":{const Rn=Math.floor(In.getMonth(Cn)/3)*3,Dn=Rn+2;return Nn("month",Rn,Dn)}case"year":return Nn("month",0,11);case"decade":{const Rn=In.getYear(Cn),Dn=Math.floor(Rn/DECADE_UNIT_DIFF)*DECADE_UNIT_DIFF,Ln=Dn+DECADE_UNIT_DIFF-1;return Nn("year",Dn,Ln)}}}function TimeHeader($n){const Cn=useMergeProps($n),{hideHeader:_n}=useInjectPanel();if(_n.value)return null;const{prefixCls:Pn,generateConfig:In,locale:Nn,value:Rn,format:Dn}=Cn,Ln=`${Pn}-header`;return createVNode(Header$2,{prefixCls:Ln},{default:()=>[Rn?formatValue(Rn,{locale:Nn,format:Dn,generateConfig:In}):" "]})}TimeHeader.displayName="TimeHeader";TimeHeader.inheritAttrs=!1;const TimeUnitColumn=defineComponent({name:"TimeUnitColumn",props:["prefixCls","units","onSelect","value","active","hideDisabledOptions"],setup($n){const{open:Cn}=useInjectPanel(),_n=shallowRef(null),Pn=ref(new Map),In=ref();return watch(()=>$n.value,()=>{const Nn=Pn.value.get($n.value);Nn&&Cn.value!==!1&&scrollTo(_n.value,Nn.offsetTop,120)}),onBeforeUnmount(()=>{var Nn;(Nn=In.value)===null||Nn===void 0||Nn.call(In)}),watch(Cn,()=>{var Nn;(Nn=In.value)===null||Nn===void 0||Nn.call(In),nextTick(()=>{if(Cn.value){const Rn=Pn.value.get($n.value);Rn&&(In.value=waitElementReady(Rn,()=>{scrollTo(_n.value,Rn.offsetTop,0)}))}})},{immediate:!0,flush:"post"}),()=>{const{prefixCls:Nn,units:Rn,onSelect:Dn,value:Ln,active:Fn,hideDisabledOptions:Bn}=$n,Hn=`${Nn}-cell`;return createVNode("ul",{class:classNames(`${Nn}-column`,{[`${Nn}-column-active`]:Fn}),ref:_n,style:{position:"relative"}},[Rn.map(zn=>Bn&&zn.disabled?null:createVNode("li",{key:zn.value,ref:Wn=>{Pn.value.set(zn.value,Wn)},class:classNames(Hn,{[`${Hn}-disabled`]:zn.disabled,[`${Hn}-selected`]:Ln===zn.value}),onClick:()=>{zn.disabled||Dn(zn.value)}},[createVNode("div",{class:`${Hn}-inner`},[zn.label])]))])}}});function leftPad($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"0",Pn=String($n);for(;Pn.length{(_n.startsWith("data-")||_n.startsWith("aria-")||_n==="role"||_n==="name")&&!_n.startsWith("data-__")&&(Cn[_n]=$n[_n])}),Cn}function getValue$2($n,Cn){return $n?$n[Cn]:null}function updateValues($n,Cn,_n){const Pn=[getValue$2($n,0),getValue$2($n,1)];return Pn[_n]=typeof Cn=="function"?Cn(Pn[_n]):Cn,!Pn[0]&&!Pn[1]?null:Pn}function generateUnits($n,Cn,_n,Pn){const In=[];for(let Nn=$n;Nn<=Cn;Nn+=_n)In.push({label:leftPad(Nn,2),value:Nn,disabled:(Pn||[]).includes(Nn)});return In}const TimeBody=defineComponent({compatConfig:{MODE:3},name:"TimeBody",inheritAttrs:!1,props:["generateConfig","prefixCls","operationRef","activeColumnIndex","value","showHour","showMinute","showSecond","use12Hours","hourStep","minuteStep","secondStep","disabledHours","disabledMinutes","disabledSeconds","disabledTime","hideDisabledOptions","onSelect"],setup($n){const Cn=computed(()=>$n.value?$n.generateConfig.getHour($n.value):-1),_n=computed(()=>$n.use12Hours?Cn.value>=12:!1),Pn=computed(()=>$n.use12Hours?Cn.value%12:Cn.value),In=computed(()=>$n.value?$n.generateConfig.getMinute($n.value):-1),Nn=computed(()=>$n.value?$n.generateConfig.getSecond($n.value):-1),Rn=ref($n.generateConfig.getNow()),Dn=ref(),Ln=ref(),Fn=ref();onBeforeUpdate(()=>{Rn.value=$n.generateConfig.getNow()}),watchEffect(()=>{if($n.disabledTime){const Go=$n.disabledTime(Rn);[Dn.value,Ln.value,Fn.value]=[Go.disabledHours,Go.disabledMinutes,Go.disabledSeconds]}else[Dn.value,Ln.value,Fn.value]=[$n.disabledHours,$n.disabledMinutes,$n.disabledSeconds]});const Bn=(Go,Xn,Yo,qo)=>{let Jo=$n.value||$n.generateConfig.getNow();const Zo=Math.max(0,Xn),rr=Math.max(0,Yo),nr=Math.max(0,qo);return Jo=setTime($n.generateConfig,Jo,!$n.use12Hours||!Go?Zo:Zo+12,rr,nr),Jo},Hn=computed(()=>{var Go;return generateUnits(0,23,(Go=$n.hourStep)!==null&&Go!==void 0?Go:1,Dn.value&&Dn.value())}),zn=computed(()=>{if(!$n.use12Hours)return[!1,!1];const Go=[!0,!0];return Hn.value.forEach(Xn=>{let{disabled:Yo,value:qo}=Xn;Yo||(qo>=12?Go[1]=!1:Go[0]=!1)}),Go}),Wn=computed(()=>$n.use12Hours?Hn.value.filter(_n.value?Go=>Go.value>=12:Go=>Go.value<12).map(Go=>{const Xn=Go.value%12,Yo=Xn===0?"12":leftPad(Xn,2);return _extends$1(_extends$1({},Go),{label:Yo,value:Xn})}):Hn.value),Yn=computed(()=>{var Go;return generateUnits(0,59,(Go=$n.minuteStep)!==null&&Go!==void 0?Go:1,Ln.value&&Ln.value(Cn.value))}),Gn=computed(()=>{var Go;return generateUnits(0,59,(Go=$n.secondStep)!==null&&Go!==void 0?Go:1,Fn.value&&Fn.value(Cn.value,In.value))});return()=>{const{prefixCls:Go,operationRef:Xn,activeColumnIndex:Yo,showHour:qo,showMinute:Jo,showSecond:Zo,use12Hours:rr,hideDisabledOptions:nr,onSelect:ta}=$n,oa=[],ra=`${Go}-content`,ea=`${Go}-time-panel`;Xn.value={onUpDown:ga=>{const aa=oa[Yo];if(aa){const ca=aa.units.findIndex(ia=>ia.value===aa.value),sa=aa.units.length;for(let ia=1;ia{ta(Bn(_n.value,ga,In.value,Nn.value),"mouse")}),la(Jo,createVNode(TimeUnitColumn,{key:"minute"},null),In.value,Yn.value,ga=>{ta(Bn(_n.value,Pn.value,ga,Nn.value),"mouse")}),la(Zo,createVNode(TimeUnitColumn,{key:"second"},null),Nn.value,Gn.value,ga=>{ta(Bn(_n.value,Pn.value,In.value,ga),"mouse")});let ua=-1;return typeof _n.value=="boolean"&&(ua=_n.value?1:0),la(rr===!0,createVNode(TimeUnitColumn,{key:"12hours"},null),ua,[{label:"AM",value:0,disabled:zn.value[0]},{label:"PM",value:1,disabled:zn.value[1]}],ga=>{ta(Bn(!!ga,Pn.value,In.value,Nn.value),"mouse")}),createVNode("div",{class:ra},[oa.map(ga=>{let{node:aa}=ga;return aa})])}}}),TimeBody$1=TimeBody,countBoolean=$n=>$n.filter(Cn=>Cn!==!1).length;function TimePanel($n){const Cn=useMergeProps($n),{generateConfig:_n,format:Pn="HH:mm:ss",prefixCls:In,active:Nn,operationRef:Rn,showHour:Dn,showMinute:Ln,showSecond:Fn,use12Hours:Bn=!1,onSelect:Hn,value:zn}=Cn,Wn=`${In}-time-panel`,Yn=ref(),Gn=ref(-1),Go=countBoolean([Dn,Ln,Fn,Bn]);return Rn.value={onKeydown:Xn=>createKeydownHandler(Xn,{onLeftRight:Yo=>{Gn.value=(Gn.value+Yo+Go)%Go},onUpDown:Yo=>{Gn.value===-1?Gn.value=0:Yn.value&&Yn.value.onUpDown(Yo)},onEnter:()=>{Hn(zn||_n.getNow(),"key"),Gn.value=-1}}),onBlur:()=>{Gn.value=-1}},createVNode("div",{class:classNames(Wn,{[`${Wn}-active`]:Nn})},[createVNode(TimeHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{format:Pn,prefixCls:In}),null),createVNode(TimeBody$1,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:In,activeColumnIndex:Gn.value,operationRef:Yn}),null)])}TimePanel.displayName="TimePanel";TimePanel.inheritAttrs=!1;function useCellClassName($n){let{cellPrefixCls:Cn,generateConfig:_n,rangedValue:Pn,hoverRangedValue:In,isInView:Nn,isSameCell:Rn,offsetCell:Dn,today:Ln,value:Fn}=$n;function Bn(Hn){const zn=Dn(Hn,-1),Wn=Dn(Hn,1),Yn=getValue$2(Pn,0),Gn=getValue$2(Pn,1),Go=getValue$2(In,0),Xn=getValue$2(In,1),Yo=isInRange(_n,Go,Xn,Hn);function qo(oa){return Rn(Yn,oa)}function Jo(oa){return Rn(Gn,oa)}const Zo=Rn(Go,Hn),rr=Rn(Xn,Hn),nr=(Yo||rr)&&(!Nn(zn)||Jo(zn)),ta=(Yo||Zo)&&(!Nn(Wn)||qo(Wn));return{[`${Cn}-in-view`]:Nn(Hn),[`${Cn}-in-range`]:isInRange(_n,Yn,Gn,Hn),[`${Cn}-range-start`]:qo(Hn),[`${Cn}-range-end`]:Jo(Hn),[`${Cn}-range-start-single`]:qo(Hn)&&!Gn,[`${Cn}-range-end-single`]:Jo(Hn)&&!Yn,[`${Cn}-range-start-near-hover`]:qo(Hn)&&(Rn(zn,Go)||isInRange(_n,Go,Xn,zn)),[`${Cn}-range-end-near-hover`]:Jo(Hn)&&(Rn(Wn,Xn)||isInRange(_n,Go,Xn,Wn)),[`${Cn}-range-hover`]:Yo,[`${Cn}-range-hover-start`]:Zo,[`${Cn}-range-hover-end`]:rr,[`${Cn}-range-hover-edge-start`]:nr,[`${Cn}-range-hover-edge-end`]:ta,[`${Cn}-range-hover-edge-start-near-range`]:nr&&Rn(zn,Gn),[`${Cn}-range-hover-edge-end-near-range`]:ta&&Rn(Wn,Yn),[`${Cn}-today`]:Rn(Ln,Hn),[`${Cn}-selected`]:Rn(Fn,Hn)}}return Bn}const RangeContextKey=Symbol("RangeContextProps"),useProvideRange=$n=>{provide(RangeContextKey,$n)},useInjectRange=()=>inject(RangeContextKey,{rangedValue:ref(),hoverRangedValue:ref(),inRange:ref(),panelPosition:ref()}),RangeContextProvider=defineComponent({compatConfig:{MODE:3},name:"PanelContextProvider",inheritAttrs:!1,props:{value:{type:Object,default:()=>({})}},setup($n,Cn){let{slots:_n}=Cn;const Pn={rangedValue:ref($n.value.rangedValue),hoverRangedValue:ref($n.value.hoverRangedValue),inRange:ref($n.value.inRange),panelPosition:ref($n.value.panelPosition)};return useProvideRange(Pn),watch(()=>$n.value,()=>{Object.keys($n.value).forEach(In=>{Pn[In]&&(Pn[In].value=$n.value[In])})}),()=>{var In;return(In=_n.default)===null||In===void 0?void 0:In.call(_n)}}});function DateBody($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,prefixColumn:In,locale:Nn,rowCount:Rn,viewDate:Dn,value:Ln,dateRender:Fn}=Cn,{rangedValue:Bn,hoverRangedValue:Hn}=useInjectRange(),zn=getWeekStartDate(Nn.locale,Pn,Dn),Wn=`${_n}-cell`,Yn=Pn.locale.getWeekFirstDay(Nn.locale),Gn=Pn.getNow(),Go=[],Xn=Nn.shortWeekDays||(Pn.locale.getShortWeekDays?Pn.locale.getShortWeekDays(Nn.locale):[]);In&&Go.push(createVNode("th",{key:"empty","aria-label":"empty cell"},null));for(let Jo=0;JoisSameDate(Pn,Jo,Zo),isInView:Jo=>isSameMonth(Pn,Jo,Dn),offsetCell:(Jo,Zo)=>Pn.addDate(Jo,Zo)}),qo=Fn?Jo=>Fn({current:Jo,today:Gn}):void 0;return createVNode(PanelBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{rowNum:Rn,colNum:WEEK_DAY_COUNT,baseDate:zn,getCellNode:qo,getCellText:Pn.getDate,getCellClassName:Yo,getCellDate:Pn.addDate,titleCell:Jo=>formatValue(Jo,{locale:Nn,format:"YYYY-MM-DD",generateConfig:Pn}),headerCells:Go}),null)}DateBody.displayName="DateBody";DateBody.inheritAttrs=!1;DateBody.props=["prefixCls","generateConfig","value?","viewDate","locale","rowCount","onSelect","dateRender?","disabledDate?","prefixColumn?","rowClassName?"];function DateHeader($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,locale:In,viewDate:Nn,onNextMonth:Rn,onPrevMonth:Dn,onNextYear:Ln,onPrevYear:Fn,onYearClick:Bn,onMonthClick:Hn}=Cn,{hideHeader:zn}=useInjectPanel();if(zn.value)return null;const Wn=`${_n}-header`,Yn=In.shortMonths||(Pn.locale.getShortMonths?Pn.locale.getShortMonths(In.locale):[]),Gn=Pn.getMonth(Nn),Go=createVNode("button",{type:"button",key:"year",onClick:Bn,tabindex:-1,class:`${_n}-year-btn`},[formatValue(Nn,{locale:In,format:In.yearFormat,generateConfig:Pn})]),Xn=createVNode("button",{type:"button",key:"month",onClick:Hn,tabindex:-1,class:`${_n}-month-btn`},[In.monthFormat?formatValue(Nn,{locale:In,format:In.monthFormat,generateConfig:Pn}):Yn[Gn]]),Yo=In.monthBeforeYear?[Xn,Go]:[Go,Xn];return createVNode(Header$2,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:Wn,onSuperPrev:Fn,onPrev:Dn,onNext:Rn,onSuperNext:Ln}),{default:()=>[Yo]})}DateHeader.displayName="DateHeader";DateHeader.inheritAttrs=!1;const DATE_ROW_COUNT=6;function DatePanel($n){const Cn=useMergeProps($n),{prefixCls:_n,panelName:Pn="date",keyboardConfig:In,active:Nn,operationRef:Rn,generateConfig:Dn,value:Ln,viewDate:Fn,onViewDateChange:Bn,onPanelChange:Hn,onSelect:zn}=Cn,Wn=`${_n}-${Pn}-panel`;Rn.value={onKeydown:Go=>createKeydownHandler(Go,_extends$1({onLeftRight:Xn=>{zn(Dn.addDate(Ln||Fn,Xn),"key")},onCtrlLeftRight:Xn=>{zn(Dn.addYear(Ln||Fn,Xn),"key")},onUpDown:Xn=>{zn(Dn.addDate(Ln||Fn,Xn*WEEK_DAY_COUNT),"key")},onPageUpDown:Xn=>{zn(Dn.addMonth(Ln||Fn,Xn),"key")}},In))};const Yn=Go=>{const Xn=Dn.addYear(Fn,Go);Bn(Xn),Hn(null,Xn)},Gn=Go=>{const Xn=Dn.addMonth(Fn,Go);Bn(Xn),Hn(null,Xn)};return createVNode("div",{class:classNames(Wn,{[`${Wn}-active`]:Nn})},[createVNode(DateHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,value:Ln,viewDate:Fn,onPrevYear:()=>{Yn(-1)},onNextYear:()=>{Yn(1)},onPrevMonth:()=>{Gn(-1)},onNextMonth:()=>{Gn(1)},onMonthClick:()=>{Hn("month",Fn)},onYearClick:()=>{Hn("year",Fn)}}),null),createVNode(DateBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{onSelect:Go=>zn(Go,"mouse"),prefixCls:_n,value:Ln,viewDate:Fn,rowCount:DATE_ROW_COUNT}),null)])}DatePanel.displayName="DatePanel";DatePanel.inheritAttrs=!1;const ACTIVE_PANEL=tuple("date","time");function DatetimePanel($n){const Cn=useMergeProps($n),{prefixCls:_n,operationRef:Pn,generateConfig:In,value:Nn,defaultValue:Rn,disabledTime:Dn,showTime:Ln,onSelect:Fn}=Cn,Bn=`${_n}-datetime-panel`,Hn=ref(null),zn=ref({}),Wn=ref({}),Yn=typeof Ln=="object"?_extends$1({},Ln):{};function Gn(qo){const Jo=ACTIVE_PANEL.indexOf(Hn.value)+qo;return ACTIVE_PANEL[Jo]||null}const Go=qo=>{Wn.value.onBlur&&Wn.value.onBlur(qo),Hn.value=null};Pn.value={onKeydown:qo=>{if(qo.which===KeyCode$1.TAB){const Jo=Gn(qo.shiftKey?-1:1);return Hn.value=Jo,Jo&&qo.preventDefault(),!0}if(Hn.value){const Jo=Hn.value==="date"?zn:Wn;return Jo.value&&Jo.value.onKeydown&&Jo.value.onKeydown(qo),!0}return[KeyCode$1.LEFT,KeyCode$1.RIGHT,KeyCode$1.UP,KeyCode$1.DOWN].includes(qo.which)?(Hn.value="date",!0):!1},onBlur:Go,onClose:Go};const Xn=(qo,Jo)=>{let Zo=qo;Jo==="date"&&!Nn&&Yn.defaultValue?(Zo=In.setHour(Zo,In.getHour(Yn.defaultValue)),Zo=In.setMinute(Zo,In.getMinute(Yn.defaultValue)),Zo=In.setSecond(Zo,In.getSecond(Yn.defaultValue))):Jo==="time"&&!Nn&&Rn&&(Zo=In.setYear(Zo,In.getYear(Rn)),Zo=In.setMonth(Zo,In.getMonth(Rn)),Zo=In.setDate(Zo,In.getDate(Rn))),Fn&&Fn(Zo,"mouse")},Yo=Dn?Dn(Nn||null):{};return createVNode("div",{class:classNames(Bn,{[`${Bn}-active`]:Hn.value})},[createVNode(DatePanel,_objectSpread2$1(_objectSpread2$1({},Cn),{},{operationRef:zn,active:Hn.value==="date",onSelect:qo=>{Xn(setDateTime(In,qo,!Nn&&typeof Ln=="object"?Ln.defaultValue:null),"date")}}),null),createVNode(TimePanel,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Cn),{},{format:void 0},Yn),Yo),{},{disabledTime:null,defaultValue:void 0,operationRef:Wn,active:Hn.value==="time",onSelect:qo=>{Xn(qo,"time")}}),null)])}DatetimePanel.displayName="DatetimePanel";DatetimePanel.inheritAttrs=!1;function WeekPanel($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,locale:In,value:Nn}=Cn,Rn=`${_n}-cell`,Dn=Bn=>createVNode("td",{key:"week",class:classNames(Rn,`${Rn}-week`)},[Pn.locale.getWeek(In.locale,Bn)]),Ln=`${_n}-week-panel-row`,Fn=Bn=>classNames(Ln,{[`${Ln}-selected`]:isSameWeek(Pn,In.locale,Nn,Bn)});return createVNode(DatePanel,_objectSpread2$1(_objectSpread2$1({},Cn),{},{panelName:"week",prefixColumn:Dn,rowClassName:Fn,keyboardConfig:{onLeftRight:null}}),null)}WeekPanel.displayName="WeekPanel";WeekPanel.inheritAttrs=!1;function MonthHeader($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,locale:In,viewDate:Nn,onNextYear:Rn,onPrevYear:Dn,onYearClick:Ln}=Cn,{hideHeader:Fn}=useInjectPanel();if(Fn.value)return null;const Bn=`${_n}-header`;return createVNode(Header$2,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:Bn,onSuperPrev:Dn,onSuperNext:Rn}),{default:()=>[createVNode("button",{type:"button",onClick:Ln,class:`${_n}-year-btn`},[formatValue(Nn,{locale:In,format:In.yearFormat,generateConfig:Pn})])]})}MonthHeader.displayName="MonthHeader";MonthHeader.inheritAttrs=!1;const MONTH_COL_COUNT=3,MONTH_ROW_COUNT=4;function MonthBody($n){const Cn=useMergeProps($n),{prefixCls:_n,locale:Pn,value:In,viewDate:Nn,generateConfig:Rn,monthCellRender:Dn}=Cn,{rangedValue:Ln,hoverRangedValue:Fn}=useInjectRange(),Bn=`${_n}-cell`,Hn=useCellClassName({cellPrefixCls:Bn,value:In,generateConfig:Rn,rangedValue:Ln.value,hoverRangedValue:Fn.value,isSameCell:(Gn,Go)=>isSameMonth(Rn,Gn,Go),isInView:()=>!0,offsetCell:(Gn,Go)=>Rn.addMonth(Gn,Go)}),zn=Pn.shortMonths||(Rn.locale.getShortMonths?Rn.locale.getShortMonths(Pn.locale):[]),Wn=Rn.setMonth(Nn,0),Yn=Dn?Gn=>Dn({current:Gn,locale:Pn}):void 0;return createVNode(PanelBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{rowNum:MONTH_ROW_COUNT,colNum:MONTH_COL_COUNT,baseDate:Wn,getCellNode:Yn,getCellText:Gn=>Pn.monthFormat?formatValue(Gn,{locale:Pn,format:Pn.monthFormat,generateConfig:Rn}):zn[Rn.getMonth(Gn)],getCellClassName:Hn,getCellDate:Rn.addMonth,titleCell:Gn=>formatValue(Gn,{locale:Pn,format:"YYYY-MM",generateConfig:Rn})}),null)}MonthBody.displayName="MonthBody";MonthBody.inheritAttrs=!1;function MonthPanel($n){const Cn=useMergeProps($n),{prefixCls:_n,operationRef:Pn,onViewDateChange:In,generateConfig:Nn,value:Rn,viewDate:Dn,onPanelChange:Ln,onSelect:Fn}=Cn,Bn=`${_n}-month-panel`;Pn.value={onKeydown:zn=>createKeydownHandler(zn,{onLeftRight:Wn=>{Fn(Nn.addMonth(Rn||Dn,Wn),"key")},onCtrlLeftRight:Wn=>{Fn(Nn.addYear(Rn||Dn,Wn),"key")},onUpDown:Wn=>{Fn(Nn.addMonth(Rn||Dn,Wn*MONTH_COL_COUNT),"key")},onEnter:()=>{Ln("date",Rn||Dn)}})};const Hn=zn=>{const Wn=Nn.addYear(Dn,zn);In(Wn),Ln(null,Wn)};return createVNode("div",{class:Bn},[createVNode(MonthHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onPrevYear:()=>{Hn(-1)},onNextYear:()=>{Hn(1)},onYearClick:()=>{Ln("year",Dn)}}),null),createVNode(MonthBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onSelect:zn=>{Fn(zn,"mouse"),Ln("date",zn)}}),null)])}MonthPanel.displayName="MonthPanel";MonthPanel.inheritAttrs=!1;function QuarterHeader($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,locale:In,viewDate:Nn,onNextYear:Rn,onPrevYear:Dn,onYearClick:Ln}=Cn,{hideHeader:Fn}=useInjectPanel();if(Fn.value)return null;const Bn=`${_n}-header`;return createVNode(Header$2,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:Bn,onSuperPrev:Dn,onSuperNext:Rn}),{default:()=>[createVNode("button",{type:"button",onClick:Ln,class:`${_n}-year-btn`},[formatValue(Nn,{locale:In,format:In.yearFormat,generateConfig:Pn})])]})}QuarterHeader.displayName="QuarterHeader";QuarterHeader.inheritAttrs=!1;const QUARTER_COL_COUNT=4,QUARTER_ROW_COUNT=1;function QuarterBody($n){const Cn=useMergeProps($n),{prefixCls:_n,locale:Pn,value:In,viewDate:Nn,generateConfig:Rn}=Cn,{rangedValue:Dn,hoverRangedValue:Ln}=useInjectRange(),Fn=`${_n}-cell`,Bn=useCellClassName({cellPrefixCls:Fn,value:In,generateConfig:Rn,rangedValue:Dn.value,hoverRangedValue:Ln.value,isSameCell:(zn,Wn)=>isSameQuarter(Rn,zn,Wn),isInView:()=>!0,offsetCell:(zn,Wn)=>Rn.addMonth(zn,Wn*3)}),Hn=Rn.setDate(Rn.setMonth(Nn,0),1);return createVNode(PanelBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{rowNum:QUARTER_ROW_COUNT,colNum:QUARTER_COL_COUNT,baseDate:Hn,getCellText:zn=>formatValue(zn,{locale:Pn,format:Pn.quarterFormat||"[Q]Q",generateConfig:Rn}),getCellClassName:Bn,getCellDate:(zn,Wn)=>Rn.addMonth(zn,Wn*3),titleCell:zn=>formatValue(zn,{locale:Pn,format:"YYYY-[Q]Q",generateConfig:Rn})}),null)}QuarterBody.displayName="QuarterBody";QuarterBody.inheritAttrs=!1;function QuarterPanel($n){const Cn=useMergeProps($n),{prefixCls:_n,operationRef:Pn,onViewDateChange:In,generateConfig:Nn,value:Rn,viewDate:Dn,onPanelChange:Ln,onSelect:Fn}=Cn,Bn=`${_n}-quarter-panel`;Pn.value={onKeydown:zn=>createKeydownHandler(zn,{onLeftRight:Wn=>{Fn(Nn.addMonth(Rn||Dn,Wn*3),"key")},onCtrlLeftRight:Wn=>{Fn(Nn.addYear(Rn||Dn,Wn),"key")},onUpDown:Wn=>{Fn(Nn.addYear(Rn||Dn,Wn),"key")}})};const Hn=zn=>{const Wn=Nn.addYear(Dn,zn);In(Wn),Ln(null,Wn)};return createVNode("div",{class:Bn},[createVNode(QuarterHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onPrevYear:()=>{Hn(-1)},onNextYear:()=>{Hn(1)},onYearClick:()=>{Ln("year",Dn)}}),null),createVNode(QuarterBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onSelect:zn=>{Fn(zn,"mouse")}}),null)])}QuarterPanel.displayName="QuarterPanel";QuarterPanel.inheritAttrs=!1;function YearHeader($n){const Cn=useMergeProps($n),{prefixCls:_n,generateConfig:Pn,viewDate:In,onPrevDecade:Nn,onNextDecade:Rn,onDecadeClick:Dn}=Cn,{hideHeader:Ln}=useInjectPanel();if(Ln.value)return null;const Fn=`${_n}-header`,Bn=Pn.getYear(In),Hn=Math.floor(Bn/YEAR_DECADE_COUNT)*YEAR_DECADE_COUNT,zn=Hn+YEAR_DECADE_COUNT-1;return createVNode(Header$2,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:Fn,onSuperPrev:Nn,onSuperNext:Rn}),{default:()=>[createVNode("button",{type:"button",onClick:Dn,class:`${_n}-decade-btn`},[Hn,createTextVNode("-"),zn])]})}YearHeader.displayName="YearHeader";YearHeader.inheritAttrs=!1;const YEAR_COL_COUNT=3,YEAR_ROW_COUNT=4;function YearBody($n){const Cn=useMergeProps($n),{prefixCls:_n,value:Pn,viewDate:In,locale:Nn,generateConfig:Rn}=Cn,{rangedValue:Dn,hoverRangedValue:Ln}=useInjectRange(),Fn=`${_n}-cell`,Bn=Rn.getYear(In),Hn=Math.floor(Bn/YEAR_DECADE_COUNT)*YEAR_DECADE_COUNT,zn=Hn+YEAR_DECADE_COUNT-1,Wn=Rn.setYear(In,Hn-Math.ceil((YEAR_COL_COUNT*YEAR_ROW_COUNT-YEAR_DECADE_COUNT)/2)),Yn=Go=>{const Xn=Rn.getYear(Go);return Hn<=Xn&&Xn<=zn},Gn=useCellClassName({cellPrefixCls:Fn,value:Pn,generateConfig:Rn,rangedValue:Dn.value,hoverRangedValue:Ln.value,isSameCell:(Go,Xn)=>isSameYear(Rn,Go,Xn),isInView:Yn,offsetCell:(Go,Xn)=>Rn.addYear(Go,Xn)});return createVNode(PanelBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{rowNum:YEAR_ROW_COUNT,colNum:YEAR_COL_COUNT,baseDate:Wn,getCellText:Rn.getYear,getCellClassName:Gn,getCellDate:Rn.addYear,titleCell:Go=>formatValue(Go,{locale:Nn,format:"YYYY",generateConfig:Rn})}),null)}YearBody.displayName="YearBody";YearBody.inheritAttrs=!1;const YEAR_DECADE_COUNT=10;function YearPanel($n){const Cn=useMergeProps($n),{prefixCls:_n,operationRef:Pn,onViewDateChange:In,generateConfig:Nn,value:Rn,viewDate:Dn,sourceMode:Ln,onSelect:Fn,onPanelChange:Bn}=Cn,Hn=`${_n}-year-panel`;Pn.value={onKeydown:Wn=>createKeydownHandler(Wn,{onLeftRight:Yn=>{Fn(Nn.addYear(Rn||Dn,Yn),"key")},onCtrlLeftRight:Yn=>{Fn(Nn.addYear(Rn||Dn,Yn*YEAR_DECADE_COUNT),"key")},onUpDown:Yn=>{Fn(Nn.addYear(Rn||Dn,Yn*YEAR_COL_COUNT),"key")},onEnter:()=>{Bn(Ln==="date"?"date":"month",Rn||Dn)}})};const zn=Wn=>{const Yn=Nn.addYear(Dn,Wn*10);In(Yn),Bn(null,Yn)};return createVNode("div",{class:Hn},[createVNode(YearHeader,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onPrevDecade:()=>{zn(-1)},onNextDecade:()=>{zn(1)},onDecadeClick:()=>{Bn("decade",Dn)}}),null),createVNode(YearBody,_objectSpread2$1(_objectSpread2$1({},Cn),{},{prefixCls:_n,onSelect:Wn=>{Bn(Ln==="date"?"date":"month",Wn),Fn(Wn,"mouse")}}),null)])}YearPanel.displayName="YearPanel";YearPanel.inheritAttrs=!1;function getExtraFooter($n,Cn,_n){return _n?createVNode("div",{class:`${$n}-footer-extra`},[_n(Cn)]):null}function getRanges($n){let{prefixCls:Cn,components:_n={},needConfirmButton:Pn,onNow:In,onOk:Nn,okDisabled:Rn,showNow:Dn,locale:Ln}=$n,Fn,Bn;if(Pn){const Hn=_n.button||"button";In&&Dn!==!1&&(Fn=createVNode("li",{class:`${Cn}-now`},[createVNode("a",{class:`${Cn}-now-btn`,onClick:In},[Ln.now])])),Bn=Pn&&createVNode("li",{class:`${Cn}-ok`},[createVNode(Hn,{disabled:Rn,onClick:zn=>{zn.stopPropagation(),Nn&&Nn()}},{default:()=>[Ln.ok]})])}return!Fn&&!Bn?null:createVNode("ul",{class:`${Cn}-ranges`},[Fn,Bn])}function PickerPanel(){return defineComponent({name:"PickerPanel",inheritAttrs:!1,props:{prefixCls:String,locale:Object,generateConfig:Object,value:Object,defaultValue:Object,pickerValue:Object,defaultPickerValue:Object,disabledDate:Function,mode:String,picker:{type:String,default:"date"},tabindex:{type:[Number,String],default:0},showNow:{type:Boolean,default:void 0},showTime:[Boolean,Object],showToday:Boolean,renderExtraFooter:Function,dateRender:Function,hideHeader:{type:Boolean,default:void 0},onSelect:Function,onChange:Function,onPanelChange:Function,onMousedown:Function,onPickerValueChange:Function,onOk:Function,components:Object,direction:String,hourStep:{type:Number,default:1},minuteStep:{type:Number,default:1},secondStep:{type:Number,default:1}},setup($n,Cn){let{attrs:_n}=Cn;const Pn=computed(()=>$n.picker==="date"&&!!$n.showTime||$n.picker==="time"),In=computed(()=>24%$n.hourStep===0),Nn=computed(()=>60%$n.minuteStep===0),Rn=computed(()=>60%$n.secondStep===0),Dn=useInjectPanel(),{operationRef:Ln,onSelect:Fn,hideRanges:Bn,defaultOpenValue:Hn}=Dn,{inRange:zn,panelPosition:Wn,rangedValue:Yn,hoverRangedValue:Gn}=useInjectRange(),Go=ref({}),[Xn,Yo]=useMergedState(null,{value:toRef($n,"value"),defaultValue:$n.defaultValue,postState:sa=>!sa&&(Hn!=null&&Hn.value)&&$n.picker==="time"?Hn.value:sa}),[qo,Jo]=useMergedState(null,{value:toRef($n,"pickerValue"),defaultValue:$n.defaultPickerValue||Xn.value,postState:sa=>{const{generateConfig:ia,showTime:fa,defaultValue:ma}=$n,ya=ia.getNow();return sa?!Xn.value&&$n.showTime?typeof fa=="object"?setDateTime(ia,Array.isArray(sa)?sa[0]:sa,fa.defaultValue||ya):ma?setDateTime(ia,Array.isArray(sa)?sa[0]:sa,ma):setDateTime(ia,Array.isArray(sa)?sa[0]:sa,ya):sa:ya}}),Zo=sa=>{Jo(sa),$n.onPickerValueChange&&$n.onPickerValueChange(sa)},rr=sa=>{const ia=PickerModeMap[$n.picker];return ia?ia(sa):sa},[nr,ta]=useMergedState(()=>$n.picker==="time"?"time":rr("date"),{value:toRef($n,"mode")});watch(()=>$n.picker,()=>{ta($n.picker)});const oa=ref(nr.value),ra=sa=>{oa.value=sa},ea=(sa,ia)=>{const{onPanelChange:fa,generateConfig:ma}=$n,ya=rr(sa||nr.value);ra(nr.value),ta(ya),fa&&(nr.value!==ya||isEqual$1(ma,qo.value,qo.value))&&fa(ia,ya)},la=function(sa,ia){let fa=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;const{picker:ma,generateConfig:ya,onSelect:ba,onChange:Ia,disabledDate:Ea}=$n;(nr.value===ma||fa)&&(Yo(sa),ba&&ba(sa),Fn&&Fn(sa,ia),Ia&&!isEqual$1(ya,sa,Xn.value)&&!(Ea!=null&&Ea(sa))&&Ia(sa))},ua=sa=>Go.value&&Go.value.onKeydown?([KeyCode$1.LEFT,KeyCode$1.RIGHT,KeyCode$1.UP,KeyCode$1.DOWN,KeyCode$1.PAGE_UP,KeyCode$1.PAGE_DOWN,KeyCode$1.ENTER].includes(sa.which)&&sa.preventDefault(),Go.value.onKeydown(sa)):!1,ga=sa=>{Go.value&&Go.value.onBlur&&Go.value.onBlur(sa)},aa=()=>{const{generateConfig:sa,hourStep:ia,minuteStep:fa,secondStep:ma}=$n,ya=sa.getNow(),ba=getLowerBoundTime(sa.getHour(ya),sa.getMinute(ya),sa.getSecond(ya),In.value?ia:1,Nn.value?fa:1,Rn.value?ma:1),Ia=setTime(sa,ya,ba[0],ba[1],ba[2]);la(Ia,"submit")},ca=computed(()=>{const{prefixCls:sa,direction:ia}=$n;return classNames(`${sa}-panel`,{[`${sa}-panel-has-range`]:Yn&&Yn.value&&Yn.value[0]&&Yn.value[1],[`${sa}-panel-has-range-hover`]:Gn&&Gn.value&&Gn.value[0]&&Gn.value[1],[`${sa}-panel-rtl`]:ia==="rtl"})});return useProvidePanel(_extends$1(_extends$1({},Dn),{mode:nr,hideHeader:computed(()=>{var sa;return $n.hideHeader!==void 0?$n.hideHeader:(sa=Dn.hideHeader)===null||sa===void 0?void 0:sa.value}),hidePrevBtn:computed(()=>zn.value&&Wn.value==="right"),hideNextBtn:computed(()=>zn.value&&Wn.value==="left")})),watch(()=>$n.value,()=>{$n.value&&Jo($n.value)}),()=>{const{prefixCls:sa="ant-picker",locale:ia,generateConfig:fa,disabledDate:ma,picker:ya="date",tabindex:ba=0,showNow:Ia,showTime:Ea,showToday:xa,renderExtraFooter:Ta,onMousedown:wa,onOk:La,components:Na}=$n;Ln&&Wn.value!=="right"&&(Ln.value={onKeydown:ua,onClose:()=>{Go.value&&Go.value.onClose&&Go.value.onClose()}});let $a;const ka=_extends$1(_extends$1(_extends$1({},_n),$n),{operationRef:Go,prefixCls:sa,viewDate:qo.value,value:Xn.value,onViewDateChange:Zo,sourceMode:oa.value,onPanelChange:ea,disabledDate:ma});switch(delete ka.onChange,delete ka.onSelect,nr.value){case"decade":$a=createVNode(DecadePanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;case"year":$a=createVNode(YearPanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;case"month":$a=createVNode(MonthPanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;case"quarter":$a=createVNode(QuarterPanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;case"week":$a=createVNode(WeekPanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;case"time":delete ka.showTime,$a=createVNode(TimePanel,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},ka),typeof Ea=="object"?Ea:null),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null);break;default:Ea?$a=createVNode(DatetimePanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null):$a=createVNode(DatePanel,_objectSpread2$1(_objectSpread2$1({},ka),{},{onSelect:(Sa,Aa)=>{Zo(Sa),la(Sa,Aa)}}),null)}let Ha,da;Bn!=null&&Bn.value||(Ha=getExtraFooter(sa,nr.value,Ta),da=getRanges({prefixCls:sa,components:Na,needConfirmButton:Pn.value,okDisabled:!Xn.value||ma&&ma(Xn.value),locale:ia,showNow:Ia,onNow:Pn.value&&aa,onOk:()=>{Xn.value&&(la(Xn.value,"submit",!0),La&&La(Xn.value))}}));let pa;if(xa&&nr.value==="date"&&ya==="date"&&!Ea){const Sa=fa.getNow(),Aa=`${sa}-today-btn`,Ra=ma&&ma(Sa);pa=createVNode("a",{class:classNames(Aa,Ra&&`${Aa}-disabled`),"aria-disabled":Ra,onClick:()=>{Ra||la(Sa,"mouse",!0)}},[ia.today])}return createVNode("div",{tabindex:ba,class:classNames(ca.value,_n.class),style:_n.style,onKeydown:ua,onBlur:ga,onMousedown:wa},[$a,Ha||da||pa?createVNode("div",{class:`${sa}-footer`},[Ha,da,pa]):null])}}})}const InterPickerPanel=PickerPanel(),PickerPanel$1=$n=>createVNode(InterPickerPanel,$n),BUILT_IN_PLACEMENTS$1={bottomLeft:{points:["tl","bl"],offset:[0,4],overflow:{adjustX:1,adjustY:1}},bottomRight:{points:["tr","br"],offset:[0,4],overflow:{adjustX:1,adjustY:1}},topLeft:{points:["bl","tl"],offset:[0,-4],overflow:{adjustX:0,adjustY:1}},topRight:{points:["br","tr"],offset:[0,-4],overflow:{adjustX:0,adjustY:1}}};function PickerTrigger($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn,popupStyle:In,visible:Nn,dropdownClassName:Rn,dropdownAlign:Dn,transitionName:Ln,getPopupContainer:Fn,range:Bn,popupPlacement:Hn,direction:zn}=useMergeProps($n),Wn=`${Pn}-dropdown`;return createVNode(Trigger,{showAction:[],hideAction:[],popupPlacement:Hn!==void 0?Hn:zn==="rtl"?"bottomRight":"bottomLeft",builtinPlacements:BUILT_IN_PLACEMENTS$1,prefixCls:Wn,popupTransitionName:Ln,popupAlign:Dn,popupVisible:Nn,popupClassName:classNames(Rn,{[`${Wn}-range`]:Bn,[`${Wn}-rtl`]:zn==="rtl"}),popupStyle:In,getPopupContainer:Fn},{default:_n.default,popup:_n.popupElement})}const PresetPanel=defineComponent({name:"PresetPanel",props:{prefixCls:String,presets:{type:Array,default:()=>[]},onClick:Function,onHover:Function},setup($n){return()=>$n.presets.length?createVNode("div",{class:`${$n.prefixCls}-presets`},[createVNode("ul",null,[$n.presets.map((Cn,_n)=>{let{label:Pn,value:In}=Cn;return createVNode("li",{key:_n,onClick:()=>{$n.onClick(In)},onMouseenter:()=>{var Nn;(Nn=$n.onHover)===null||Nn===void 0||Nn.call($n,In)},onMouseleave:()=>{var Nn;(Nn=$n.onHover)===null||Nn===void 0||Nn.call($n,null)}},[Pn])})])]):null}});function usePickerInput($n){let{open:Cn,value:_n,isClickOutside:Pn,triggerOpen:In,forwardKeydown:Nn,onKeydown:Rn,blurToCancel:Dn,onSubmit:Ln,onCancel:Fn,onFocus:Bn,onBlur:Hn}=$n;const zn=shallowRef(!1),Wn=shallowRef(!1),Yn=shallowRef(!1),Gn=shallowRef(!1),Go=shallowRef(!1),Xn=computed(()=>({onMousedown:()=>{zn.value=!0,In(!0)},onKeydown:qo=>{if(Rn(qo,()=>{Go.value=!0}),!Go.value){switch(qo.which){case KeyCode$1.ENTER:{Cn.value?Ln()!==!1&&(zn.value=!0):In(!0),qo.preventDefault();return}case KeyCode$1.TAB:{zn.value&&Cn.value&&!qo.shiftKey?(zn.value=!1,qo.preventDefault()):!zn.value&&Cn.value&&!Nn(qo)&&qo.shiftKey&&(zn.value=!0,qo.preventDefault());return}case KeyCode$1.ESC:{zn.value=!0,Fn();return}}!Cn.value&&![KeyCode$1.SHIFT].includes(qo.which)?In(!0):zn.value||Nn(qo)}},onFocus:qo=>{zn.value=!0,Wn.value=!0,Bn&&Bn(qo)},onBlur:qo=>{if(Yn.value||!Pn(document.activeElement)){Yn.value=!1;return}Dn.value?setTimeout(()=>{let{activeElement:Jo}=document;for(;Jo&&Jo.shadowRoot;)Jo=Jo.shadowRoot.activeElement;Pn(Jo)&&Fn()},0):Cn.value&&(In(!1),Gn.value&&Ln()),Wn.value=!1,Hn&&Hn(qo)}}));watch(Cn,()=>{Gn.value=!1}),watch(_n,()=>{Gn.value=!0});const Yo=shallowRef();return onMounted(()=>{Yo.value=addGlobalMousedownEvent(qo=>{const Jo=getTargetFromEvent(qo);if(Cn.value){const Zo=Pn(Jo);Zo?(!Wn.value||Zo)&&In(!1):(Yn.value=!0,wrapperRaf(()=>{Yn.value=!1}))}})}),onBeforeUnmount(()=>{Yo.value&&Yo.value()}),[Xn,{focused:Wn,typing:zn}]}function useTextValueMapping($n){let{valueTexts:Cn,onTextChange:_n}=$n;const Pn=ref("");function In(Rn){Pn.value=Rn,_n(Rn)}function Nn(){Pn.value=Cn.value[0]}return watch(()=>[...Cn.value],function(Rn){let Dn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[];Rn.join("||")!==Dn.join("||")&&Cn.value.every(Ln=>Ln!==Pn.value)&&Nn()},{immediate:!0}),[Pn,In,Nn]}function useValueTexts($n,Cn){let{formatList:_n,generateConfig:Pn,locale:In}=Cn;const Nn=useMemo(()=>{if(!$n.value)return[[""],""];let Ln="";const Fn=[];for(let Bn=0;Bn<_n.value.length;Bn+=1){const Hn=_n.value[Bn],zn=formatValue($n.value,{generateConfig:Pn.value,locale:In.value,format:Hn});Fn.push(zn),Bn===0&&(Ln=zn)}return[Fn,Ln]},[$n,_n],(Ln,Fn)=>Fn[0]!==Ln[0]||!shallowequal(Fn[1],Ln[1])),Rn=computed(()=>Nn.value[0]),Dn=computed(()=>Nn.value[1]);return[Rn,Dn]}function useHoverValue($n,Cn){let{formatList:_n,generateConfig:Pn,locale:In}=Cn;const Nn=ref(null);let Rn;function Dn(Hn){let zn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(wrapperRaf.cancel(Rn),zn){Nn.value=Hn;return}Rn=wrapperRaf(()=>{Nn.value=Hn})}const[,Ln]=useValueTexts(Nn,{formatList:_n,generateConfig:Pn,locale:In});function Fn(Hn){Dn(Hn)}function Bn(){let Hn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1;Dn(null,Hn)}return watch($n,()=>{Bn(!0)}),onBeforeUnmount(()=>{wrapperRaf.cancel(Rn)}),[Ln,Fn,Bn]}function usePresets($n,Cn){return computed(()=>$n!=null&&$n.value?$n.value:Cn!=null&&Cn.value?(warningOnce(!1,"`ranges` is deprecated. Please use `presets` instead."),Object.keys(Cn.value).map(Pn=>{const In=Cn.value[Pn],Nn=typeof In=="function"?In():In;return{label:Pn,value:Nn}})):[])}function Picker(){return defineComponent({name:"Picker",inheritAttrs:!1,props:["prefixCls","id","tabindex","dropdownClassName","dropdownAlign","popupStyle","transitionName","generateConfig","locale","inputReadOnly","allowClear","autofocus","showTime","showNow","showHour","showMinute","showSecond","picker","format","use12Hours","value","defaultValue","open","defaultOpen","defaultOpenValue","suffixIcon","presets","clearIcon","disabled","disabledDate","placeholder","getPopupContainer","panelRender","inputRender","onChange","onOpenChange","onPanelChange","onFocus","onBlur","onMousedown","onMouseup","onMouseenter","onMouseleave","onContextmenu","onClick","onKeydown","onSelect","direction","autocomplete","showToday","renderExtraFooter","dateRender","minuteStep","hourStep","secondStep","hideDisabledOptions"],setup($n,Cn){let{attrs:_n,expose:Pn}=Cn;const In=ref(null),Nn=computed(()=>$n.presets),Rn=usePresets(Nn),Dn=computed(()=>{var ma;return(ma=$n.picker)!==null&&ma!==void 0?ma:"date"}),Ln=computed(()=>Dn.value==="date"&&!!$n.showTime||Dn.value==="time"),Fn=computed(()=>toArray$6(getDefaultFormat($n.format,Dn.value,$n.showTime,$n.use12Hours))),Bn=ref(null),Hn=ref(null),zn=ref(null),[Wn,Yn]=useMergedState(null,{value:toRef($n,"value"),defaultValue:$n.defaultValue}),Gn=ref(Wn.value),Go=ma=>{Gn.value=ma},Xn=ref(null),[Yo,qo]=useMergedState(!1,{value:toRef($n,"open"),defaultValue:$n.defaultOpen,postState:ma=>$n.disabled?!1:ma,onChange:ma=>{$n.onOpenChange&&$n.onOpenChange(ma),!ma&&Xn.value&&Xn.value.onClose&&Xn.value.onClose()}}),[Jo,Zo]=useValueTexts(Gn,{formatList:Fn,generateConfig:toRef($n,"generateConfig"),locale:toRef($n,"locale")}),[rr,nr,ta]=useTextValueMapping({valueTexts:Jo,onTextChange:ma=>{const ya=parseValue$1(ma,{locale:$n.locale,formatList:Fn.value,generateConfig:$n.generateConfig});ya&&(!$n.disabledDate||!$n.disabledDate(ya))&&Go(ya)}}),oa=ma=>{const{onChange:ya,generateConfig:ba,locale:Ia}=$n;Go(ma),Yn(ma),ya&&!isEqual$1(ba,Wn.value,ma)&&ya(ma,ma?formatValue(ma,{generateConfig:ba,locale:Ia,format:Fn.value[0]}):"")},ra=ma=>{$n.disabled&&ma||qo(ma)},ea=ma=>Yo.value&&Xn.value&&Xn.value.onKeydown?Xn.value.onKeydown(ma):!1,la=function(){$n.onMouseup&&$n.onMouseup(...arguments),In.value&&(In.value.focus(),ra(!0))},[ua,{focused:ga,typing:aa}]=usePickerInput({blurToCancel:Ln,open:Yo,value:rr,triggerOpen:ra,forwardKeydown:ea,isClickOutside:ma=>!elementsContains([Bn.value,Hn.value,zn.value],ma),onSubmit:()=>!Gn.value||$n.disabledDate&&$n.disabledDate(Gn.value)?!1:(oa(Gn.value),ra(!1),ta(),!0),onCancel:()=>{ra(!1),Go(Wn.value),ta()},onKeydown:(ma,ya)=>{var ba;(ba=$n.onKeydown)===null||ba===void 0||ba.call($n,ma,ya)},onFocus:ma=>{var ya;(ya=$n.onFocus)===null||ya===void 0||ya.call($n,ma)},onBlur:ma=>{var ya;(ya=$n.onBlur)===null||ya===void 0||ya.call($n,ma)}});watch([Yo,Jo],()=>{Yo.value||(Go(Wn.value),!Jo.value.length||Jo.value[0]===""?nr(""):Zo.value!==rr.value&&ta())}),watch(Dn,()=>{Yo.value||ta()}),watch(Wn,()=>{Go(Wn.value)});const[ca,sa,ia]=useHoverValue(rr,{formatList:Fn,generateConfig:toRef($n,"generateConfig"),locale:toRef($n,"locale")}),fa=(ma,ya)=>{(ya==="submit"||ya!=="key"&&!Ln.value)&&(oa(ma),ra(!1))};return useProvidePanel({operationRef:Xn,hideHeader:computed(()=>Dn.value==="time"),onSelect:fa,open:Yo,defaultOpenValue:toRef($n,"defaultOpenValue"),onDateMouseenter:sa,onDateMouseleave:ia}),Pn({focus:()=>{In.value&&In.value.focus()},blur:()=>{In.value&&In.value.blur()}}),()=>{const{prefixCls:ma="rc-picker",id:ya,tabindex:ba,dropdownClassName:Ia,dropdownAlign:Ea,popupStyle:xa,transitionName:Ta,generateConfig:wa,locale:La,inputReadOnly:Na,allowClear:$a,autofocus:ka,picker:Ha="date",defaultOpenValue:da,suffixIcon:pa,clearIcon:Sa,disabled:Aa,placeholder:Ra,getPopupContainer:Fa,panelRender:za,onMousedown:Wa,onMouseenter:Ya,onMouseleave:ja,onContextmenu:qa,onClick:Xa,onSelect:Oa,direction:Ma,autocomplete:Ua="off"}=$n,Qa=_extends$1(_extends$1(_extends$1({},$n),_n),{class:classNames({[`${ma}-panel-focused`]:!aa.value}),style:void 0,pickerValue:void 0,onPickerValueChange:void 0,onChange:null});let ri=createVNode("div",{class:`${ma}-panel-layout`},[createVNode(PresetPanel,{prefixCls:ma,presets:Rn.value,onClick:di=>{oa(di),ra(!1)}},null),createVNode(PickerPanel$1,_objectSpread2$1(_objectSpread2$1({},Qa),{},{generateConfig:wa,value:Gn.value,locale:La,tabindex:-1,onSelect:di=>{Oa==null||Oa(di),Go(di)},direction:Ma,onPanelChange:(di,gi)=>{const{onPanelChange:wi}=$n;ia(!0),wi==null||wi(di,gi)}}),null)]);za&&(ri=za(ri));const fi=createVNode("div",{class:`${ma}-panel-container`,ref:Bn,onMousedown:di=>{di.preventDefault()}},[ri]);let ei;pa&&(ei=createVNode("span",{class:`${ma}-suffix`},[pa]));let ti;$a&&Wn.value&&!Aa&&(ti=createVNode("span",{onMousedown:di=>{di.preventDefault(),di.stopPropagation()},onMouseup:di=>{di.preventDefault(),di.stopPropagation(),oa(null),ra(!1)},class:`${ma}-clear`,role:"button"},[Sa||createVNode("span",{class:`${ma}-clear-btn`},null)]));const ni=_extends$1(_extends$1(_extends$1(_extends$1({id:ya,tabindex:ba,disabled:Aa,readonly:Na||typeof Fn.value[0]=="function"||!aa.value,value:ca.value||rr.value,onInput:di=>{nr(di.target.value)},autofocus:ka,placeholder:Ra,ref:In,title:rr.value},ua.value),{size:getInputSize(Ha,Fn.value[0],wa)}),getDataOrAriaProps($n)),{autocomplete:Ua}),ui=$n.inputRender?$n.inputRender(ni):createVNode("input",ni,null),mi=Ma==="rtl"?"bottomRight":"bottomLeft";return createVNode("div",{ref:zn,class:classNames(ma,_n.class,{[`${ma}-disabled`]:Aa,[`${ma}-focused`]:ga.value,[`${ma}-rtl`]:Ma==="rtl"}),style:_n.style,onMousedown:Wa,onMouseup:la,onMouseenter:Ya,onMouseleave:ja,onContextmenu:qa,onClick:Xa},[createVNode("div",{class:classNames(`${ma}-input`,{[`${ma}-input-placeholder`]:!!ca.value}),ref:Hn},[ui,ei,ti]),createVNode(PickerTrigger,{visible:Yo.value,popupStyle:xa,prefixCls:ma,dropdownClassName:Ia,dropdownAlign:Ea,getPopupContainer:Fa,transitionName:Ta,popupPlacement:mi,direction:Ma},{default:()=>[createVNode("div",{style:{pointerEvents:"none",position:"absolute",top:0,bottom:0,left:0,right:0}},null)],popupElement:()=>fi})])}}})}const Picker$1=Picker();function useRangeDisabled($n,Cn){let{picker:_n,locale:Pn,selectedValue:In,disabledDate:Nn,disabled:Rn,generateConfig:Dn}=$n;const Ln=computed(()=>getValue$2(In.value,0)),Fn=computed(()=>getValue$2(In.value,1));function Bn(Gn){return Dn.value.locale.getWeekFirstDate(Pn.value.locale,Gn)}function Hn(Gn){const Go=Dn.value.getYear(Gn),Xn=Dn.value.getMonth(Gn);return Go*100+Xn}function zn(Gn){const Go=Dn.value.getYear(Gn),Xn=getQuarter(Dn.value,Gn);return Go*10+Xn}return[Gn=>{var Go;if(Nn&&(!((Go=Nn==null?void 0:Nn.value)===null||Go===void 0)&&Go.call(Nn,Gn)))return!0;if(Rn[1]&&Fn)return!isSameDate(Dn.value,Gn,Fn.value)&&Dn.value.isAfter(Gn,Fn.value);if(Cn.value[1]&&Fn.value)switch(_n.value){case"quarter":return zn(Gn)>zn(Fn.value);case"month":return Hn(Gn)>Hn(Fn.value);case"week":return Bn(Gn)>Bn(Fn.value);default:return!isSameDate(Dn.value,Gn,Fn.value)&&Dn.value.isAfter(Gn,Fn.value)}return!1},Gn=>{var Go;if(!((Go=Nn.value)===null||Go===void 0)&&Go.call(Nn,Gn))return!0;if(Rn[0]&&Ln)return!isSameDate(Dn.value,Gn,Fn.value)&&Dn.value.isAfter(Ln.value,Gn);if(Cn.value[0]&&Ln.value)switch(_n.value){case"quarter":return zn(Gn)isSameDecade(Pn,Rn,Dn));case"quarter":case"month":return Nn((Rn,Dn)=>isSameYear(Pn,Rn,Dn));default:return Nn((Rn,Dn)=>isSameMonth(Pn,Rn,Dn))}}function getRangeViewDate($n,Cn,_n,Pn){const In=getValue$2($n,0),Nn=getValue$2($n,1);if(Cn===0)return In;if(In&&Nn)switch(getStartEndDistance(In,Nn,_n,Pn)){case"same":return In;case"closing":return In;default:return getClosingViewDate(Nn,_n,Pn,-1)}return In}function useRangeViewDates($n){let{values:Cn,picker:_n,defaultDates:Pn,generateConfig:In}=$n;const Nn=ref([getValue$2(Pn,0),getValue$2(Pn,1)]),Rn=ref(null),Dn=computed(()=>getValue$2(Cn.value,0)),Ln=computed(()=>getValue$2(Cn.value,1)),Fn=Wn=>Nn.value[Wn]?Nn.value[Wn]:getValue$2(Rn.value,Wn)||getRangeViewDate(Cn.value,Wn,_n.value,In.value)||Dn.value||Ln.value||In.value.getNow(),Bn=ref(null),Hn=ref(null);watchEffect(()=>{Bn.value=Fn(0),Hn.value=Fn(1)});function zn(Wn,Yn){if(Wn){let Gn=updateValues(Rn.value,Wn,Yn);Nn.value=updateValues(Nn.value,null,Yn)||[null,null];const Go=(Yn+1)%2;getValue$2(Cn.value,Go)||(Gn=updateValues(Gn,Wn,Go)),Rn.value=Gn}else(Dn.value||Ln.value)&&(Rn.value=null)}return[Bn,Hn,zn]}function tryOnScopeDispose$1($n){return getCurrentScope()?(onScopeDispose($n),!0):!1}function resolveUnref($n){return typeof $n=="function"?$n():unref($n)}function unrefElement$1($n){var Cn;const _n=resolveUnref($n);return(Cn=_n==null?void 0:_n.$el)!==null&&Cn!==void 0?Cn:_n}function tryOnMounted$1($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;getCurrentInstance()?onMounted($n):Cn?$n():nextTick($n)}function useSupported($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const _n=shallowRef(),Pn=()=>_n.value=!!$n();return Pn(),tryOnMounted$1(Pn,Cn),_n}var _a;const isClient$1=typeof window<"u";isClient$1&&(!((_a=window==null?void 0:window.navigator)===null||_a===void 0)&&_a.userAgent)&&/iP(ad|hone|od)/.test(window.navigator.userAgent);const defaultWindow$1=isClient$1?window:void 0;var __rest$Z=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In2&&arguments[2]!==void 0?arguments[2]:{};const{window:Pn=defaultWindow$1}=_n,In=__rest$Z(_n,["window"]);let Nn;const Rn=useSupported(()=>Pn&&"ResizeObserver"in Pn),Dn=()=>{Nn&&(Nn.disconnect(),Nn=void 0)},Ln=watch(()=>unrefElement$1($n),Bn=>{Dn(),Rn.value&&Pn&&Bn&&(Nn=new ResizeObserver(Cn),Nn.observe(Bn,In))},{immediate:!0,flush:"post"}),Fn=()=>{Dn(),Ln()};return tryOnScopeDispose$1(Fn),{isSupported:Rn,stop:Fn}}function useElementSize($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{width:0,height:0},_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const{box:Pn="content-box"}=_n,In=shallowRef(Cn.width),Nn=shallowRef(Cn.height);return useResizeObserver($n,Rn=>{let[Dn]=Rn;const Ln=Pn==="border-box"?Dn.borderBoxSize:Pn==="content-box"?Dn.contentBoxSize:Dn.devicePixelContentBoxSize;Ln?(In.value=Ln.reduce((Fn,Bn)=>{let{inlineSize:Hn}=Bn;return Fn+Hn},0),Nn.value=Ln.reduce((Fn,Bn)=>{let{blockSize:Hn}=Bn;return Fn+Hn},0)):(In.value=Dn.contentRect.width,Nn.value=Dn.contentRect.height)},_n),watch(()=>unrefElement$1($n),Rn=>{In.value=Rn?Cn.width:0,Nn.value=Rn?Cn.height:0}),{width:In,height:Nn}}function reorderValues($n,Cn){return $n&&$n[0]&&$n[1]&&Cn.isAfter($n[0],$n[1])?[$n[1],$n[0]]:$n}function canValueTrigger($n,Cn,_n,Pn){return!!($n||Pn&&Pn[Cn]||_n[(Cn+1)%2])}function RangerPicker(){return defineComponent({name:"RangerPicker",inheritAttrs:!1,props:["prefixCls","id","popupStyle","dropdownClassName","transitionName","dropdownAlign","getPopupContainer","generateConfig","locale","placeholder","autofocus","disabled","format","picker","showTime","showNow","showHour","showMinute","showSecond","use12Hours","separator","value","defaultValue","defaultPickerValue","open","defaultOpen","disabledDate","disabledTime","dateRender","panelRender","ranges","allowEmpty","allowClear","suffixIcon","clearIcon","pickerRef","inputReadOnly","mode","renderExtraFooter","onChange","onOpenChange","onPanelChange","onCalendarChange","onFocus","onBlur","onMousedown","onMouseup","onMouseenter","onMouseleave","onClick","onOk","onKeydown","components","order","direction","activePickerIndex","autocomplete","minuteStep","hourStep","secondStep","hideDisabledOptions","disabledMinutes","presets","prevIcon","nextIcon","superPrevIcon","superNextIcon"],setup($n,Cn){let{attrs:_n,expose:Pn}=Cn;const In=computed(()=>$n.picker==="date"&&!!$n.showTime||$n.picker==="time"),Nn=computed(()=>$n.presets),Rn=computed(()=>$n.ranges),Dn=usePresets(Nn,Rn),Ln=ref({}),Fn=ref(null),Bn=ref(null),Hn=ref(null),zn=ref(null),Wn=ref(null),Yn=ref(null),Gn=ref(null),Go=ref(null),Xn=computed(()=>toArray$6(getDefaultFormat($n.format,$n.picker,$n.showTime,$n.use12Hours))),[Yo,qo]=useMergedState(0,{value:toRef($n,"activePickerIndex")}),Jo=ref(null),Zo=computed(()=>{const{disabled:ci}=$n;return Array.isArray(ci)?ci:[ci||!1,ci||!1]}),[rr,nr]=useMergedState(null,{value:toRef($n,"value"),defaultValue:$n.defaultValue,postState:ci=>$n.picker==="time"&&!$n.order?ci:reorderValues(ci,$n.generateConfig)}),[ta,oa,ra]=useRangeViewDates({values:rr,picker:toRef($n,"picker"),defaultDates:$n.defaultPickerValue,generateConfig:toRef($n,"generateConfig")}),[ea,la]=useMergedState(rr.value,{postState:ci=>{let Ci=ci;if(Zo.value[0]&&Zo.value[1])return Ci;for(let bi=0;bi<2;bi+=1)Zo.value[bi]&&!getValue$2(Ci,bi)&&!getValue$2($n.allowEmpty,bi)&&(Ci=updateValues(Ci,$n.generateConfig.getNow(),bi));return Ci}}),[ua,ga]=useMergedState([$n.picker,$n.picker],{value:toRef($n,"mode")});watch(()=>$n.picker,()=>{ga([$n.picker,$n.picker])});const aa=(ci,Ci)=>{var bi;ga(ci),(bi=$n.onPanelChange)===null||bi===void 0||bi.call($n,Ci,ci)},[ca,sa]=useRangeDisabled({picker:toRef($n,"picker"),selectedValue:ea,locale:toRef($n,"locale"),disabled:Zo,disabledDate:toRef($n,"disabledDate"),generateConfig:toRef($n,"generateConfig")},Ln),[ia,fa]=useMergedState(!1,{value:toRef($n,"open"),defaultValue:$n.defaultOpen,postState:ci=>Zo.value[Yo.value]?!1:ci,onChange:ci=>{var Ci;(Ci=$n.onOpenChange)===null||Ci===void 0||Ci.call($n,ci),!ci&&Jo.value&&Jo.value.onClose&&Jo.value.onClose()}}),ma=computed(()=>ia.value&&Yo.value===0),ya=computed(()=>ia.value&&Yo.value===1),ba=ref(0),Ia=ref(0),Ea=ref(0),{width:xa}=useElementSize(Fn);watch([ia,xa],()=>{!ia.value&&Fn.value&&(Ea.value=xa.value)});const{width:Ta}=useElementSize(Bn),{width:wa}=useElementSize(Go),{width:La}=useElementSize(Hn),{width:Na}=useElementSize(Wn);watch([Yo,ia,Ta,wa,La,Na,()=>$n.direction],()=>{Ia.value=0,Yo.value?Hn.value&&Wn.value&&(Ia.value=La.value+Na.value,Ta.value&&wa.value&&Ia.value>Ta.value-wa.value-($n.direction==="rtl"||Go.value.offsetLeft>Ia.value?0:Go.value.offsetLeft)&&(ba.value=Ia.value)):Yo.value===0&&(ba.value=0)},{immediate:!0});const $a=ref();function ka(ci,Ci){if(ci)clearTimeout($a.value),Ln.value[Ci]=!0,qo(Ci),fa(ci),ia.value||ra(null,Ci);else if(Yo.value===Ci){fa(ci);const bi=Ln.value;$a.value=setTimeout(()=>{bi===Ln.value&&(Ln.value={})})}}function Ha(ci){ka(!0,ci),setTimeout(()=>{const Ci=[Yn,Gn][ci];Ci.value&&Ci.value.focus()},0)}function da(ci,Ci){let bi=ci,Bi=getValue$2(bi,0),nl=getValue$2(bi,1);const{generateConfig:el,locale:gl,picker:ll,order:Rl,onCalendarChange:ml,allowEmpty:hl,onChange:zi,showTime:Pl}=$n;Bi&&nl&&el.isAfter(Bi,nl)&&(ll==="week"&&!isSameWeek(el,gl.locale,Bi,nl)||ll==="quarter"&&!isSameQuarter(el,Bi,nl)||ll!=="week"&&ll!=="quarter"&&ll!=="time"&&!(Pl?isEqual$1(el,Bi,nl):isSameDate(el,Bi,nl))?(Ci===0?(bi=[Bi,null],nl=null):(Bi=null,bi=[null,nl]),Ln.value={[Ci]:!0}):(ll!=="time"||Rl!==!1)&&(bi=reorderValues(bi,el))),la(bi);const Cl=bi&&bi[0]?formatValue(bi[0],{generateConfig:el,locale:gl,format:Xn.value[0]}):"",Fl=bi&&bi[1]?formatValue(bi[1],{generateConfig:el,locale:gl,format:Xn.value[0]}):"";ml&&ml(bi,[Cl,Fl],{range:Ci===0?"start":"end"});const Bl=canValueTrigger(Bi,0,Zo.value,hl),vl=canValueTrigger(nl,1,Zo.value,hl);(bi===null||Bl&&vl)&&(nr(bi),zi&&(!isEqual$1(el,getValue$2(rr.value,0),Bi)||!isEqual$1(el,getValue$2(rr.value,1),nl))&&zi(bi,[Cl,Fl]));let yl=null;Ci===0&&!Zo.value[1]?yl=1:Ci===1&&!Zo.value[0]&&(yl=0),yl!==null&&yl!==Yo.value&&(!Ln.value[yl]||!getValue$2(bi,yl))&&getValue$2(bi,Ci)?Ha(yl):ka(!1,Ci)}const pa=ci=>ia&&Jo.value&&Jo.value.onKeydown?Jo.value.onKeydown(ci):!1,Sa={formatList:Xn,generateConfig:toRef($n,"generateConfig"),locale:toRef($n,"locale")},[Aa,Ra]=useValueTexts(computed(()=>getValue$2(ea.value,0)),Sa),[Fa,za]=useValueTexts(computed(()=>getValue$2(ea.value,1)),Sa),Wa=(ci,Ci)=>{const bi=parseValue$1(ci,{locale:$n.locale,formatList:Xn.value,generateConfig:$n.generateConfig});bi&&!(Ci===0?ca:sa)(bi)&&(la(updateValues(ea.value,bi,Ci)),ra(bi,Ci))},[Ya,ja,qa]=useTextValueMapping({valueTexts:Aa,onTextChange:ci=>Wa(ci,0)}),[Xa,Oa,Ma]=useTextValueMapping({valueTexts:Fa,onTextChange:ci=>Wa(ci,1)}),[Ua,Qa]=useState(null),[ri,fi]=useState(null),[ei,ti,ni]=useHoverValue(Ya,Sa),[ui,mi,di]=useHoverValue(Xa,Sa),gi=ci=>{fi(updateValues(ea.value,ci,Yo.value)),Yo.value===0?ti(ci):mi(ci)},wi=()=>{fi(updateValues(ea.value,null,Yo.value)),Yo.value===0?ni():di()},Ti=(ci,Ci)=>({forwardKeydown:pa,onBlur:bi=>{var Bi;(Bi=$n.onBlur)===null||Bi===void 0||Bi.call($n,bi)},isClickOutside:bi=>!elementsContains([Bn.value,Hn.value,zn.value,Fn.value],bi),onFocus:bi=>{var Bi;qo(ci),(Bi=$n.onFocus)===null||Bi===void 0||Bi.call($n,bi)},triggerOpen:bi=>{ka(bi,ci)},onSubmit:()=>{if(!ea.value||$n.disabledDate&&$n.disabledDate(ea.value[ci]))return!1;da(ea.value,ci),Ci()},onCancel:()=>{ka(!1,ci),la(rr.value),Ci()}}),[Ei,{focused:Ni,typing:Ri}]=usePickerInput(_extends$1(_extends$1({},Ti(0,qa)),{blurToCancel:In,open:ma,value:Ya,onKeydown:(ci,Ci)=>{var bi;(bi=$n.onKeydown)===null||bi===void 0||bi.call($n,ci,Ci)}})),[Zi,{focused:Qi,typing:Ji}]=usePickerInput(_extends$1(_extends$1({},Ti(1,Ma)),{blurToCancel:In,open:ya,value:Xa,onKeydown:(ci,Ci)=>{var bi;(bi=$n.onKeydown)===null||bi===void 0||bi.call($n,ci,Ci)}})),Yi=ci=>{var Ci;(Ci=$n.onClick)===null||Ci===void 0||Ci.call($n,ci),!ia.value&&!Yn.value.contains(ci.target)&&!Gn.value.contains(ci.target)&&(Zo.value[0]?Zo.value[1]||Ha(1):Ha(0))},rl=ci=>{var Ci;(Ci=$n.onMousedown)===null||Ci===void 0||Ci.call($n,ci),ia.value&&(Ni.value||Qi.value)&&!Yn.value.contains(ci.target)&&!Gn.value.contains(ci.target)&&ci.preventDefault()},yi=computed(()=>{var ci;return!((ci=rr.value)===null||ci===void 0)&&ci[0]?formatValue(rr.value[0],{locale:$n.locale,format:"YYYYMMDDHHmmss",generateConfig:$n.generateConfig}):""}),il=computed(()=>{var ci;return!((ci=rr.value)===null||ci===void 0)&&ci[1]?formatValue(rr.value[1],{locale:$n.locale,format:"YYYYMMDDHHmmss",generateConfig:$n.generateConfig}):""});watch([ia,Aa,Fa],()=>{ia.value||(la(rr.value),!Aa.value.length||Aa.value[0]===""?ja(""):Ra.value!==Ya.value&&qa(),!Fa.value.length||Fa.value[0]===""?Oa(""):za.value!==Xa.value&&Ma())}),watch([yi,il],()=>{la(rr.value)}),Pn({focus:()=>{Yn.value&&Yn.value.focus()},blur:()=>{Yn.value&&Yn.value.blur(),Gn.value&&Gn.value.blur()}});const Tl=computed(()=>ia.value&&ri.value&&ri.value[0]&&ri.value[1]&&$n.generateConfig.isAfter(ri.value[1],ri.value[0])?ri.value:null);function ul(){let ci=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,Ci=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const{generateConfig:bi,showTime:Bi,dateRender:nl,direction:el,disabledTime:gl,prefixCls:ll,locale:Rl}=$n;let ml=Bi;if(Bi&&typeof Bi=="object"&&Bi.defaultValue){const zi=Bi.defaultValue;ml=_extends$1(_extends$1({},Bi),{defaultValue:getValue$2(zi,Yo.value)||void 0})}let hl=null;return nl&&(hl=zi=>{let{current:Pl,today:Cl}=zi;return nl({current:Pl,today:Cl,info:{range:Yo.value?"end":"start"}})}),createVNode(RangeContextProvider,{value:{inRange:!0,panelPosition:ci,rangedValue:Ua.value||ea.value,hoverRangedValue:Tl.value}},{default:()=>[createVNode(PickerPanel$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},$n),Ci),{},{dateRender:hl,showTime:ml,mode:ua.value[Yo.value],generateConfig:bi,style:void 0,direction:el,disabledDate:Yo.value===0?ca:sa,disabledTime:zi=>gl?gl(zi,Yo.value===0?"start":"end"):!1,class:classNames({[`${ll}-panel-focused`]:Yo.value===0?!Ri.value:!Ji.value}),value:getValue$2(ea.value,Yo.value),locale:Rl,tabIndex:-1,onPanelChange:(zi,Pl)=>{Yo.value===0&&ni(!0),Yo.value===1&&di(!0),aa(updateValues(ua.value,Pl,Yo.value),updateValues(ea.value,zi,Yo.value));let Cl=zi;ci==="right"&&ua.value[Yo.value]===Pl&&(Cl=getClosingViewDate(Cl,Pl,bi,-1)),ra(Cl,Yo.value)},onOk:null,onSelect:void 0,onChange:void 0,defaultValue:Yo.value===0?getValue$2(ea.value,1):getValue$2(ea.value,0)}),null)]})}const ts=(ci,Ci)=>{const bi=updateValues(ea.value,ci,Yo.value);Ci==="submit"||Ci!=="key"&&!In.value?(da(bi,Yo.value),Yo.value===0?ni():di()):la(bi)};return useProvidePanel({operationRef:Jo,hideHeader:computed(()=>$n.picker==="time"),onDateMouseenter:gi,onDateMouseleave:wi,hideRanges:computed(()=>!0),onSelect:ts,open:ia}),()=>{const{prefixCls:ci="rc-picker",id:Ci,popupStyle:bi,dropdownClassName:Bi,transitionName:nl,dropdownAlign:el,getPopupContainer:gl,generateConfig:ll,locale:Rl,placeholder:ml,autofocus:hl,picker:zi="date",showTime:Pl,separator:Cl="~",disabledDate:Fl,panelRender:Bl,allowClear:vl,suffixIcon:ns,clearIcon:yl,inputReadOnly:js,renderExtraFooter:Ac,onMouseenter:Mc,onMouseleave:rc,onMouseup:ac,onOk:Hs,components:Dc,direction:ps,autocomplete:zs="off"}=$n,ic=ps==="rtl"?{right:`${Ia.value}px`}:{left:`${Ia.value}px`};function lc(){let bl;const jl=getExtraFooter(ci,ua.value[Yo.value],Ac),Es=getRanges({prefixCls:ci,components:Dc,needConfirmButton:In.value,okDisabled:!getValue$2(ea.value,Yo.value)||Fl&&Fl(ea.value[Yo.value]),locale:Rl,onOk:()=>{getValue$2(ea.value,Yo.value)&&(da(ea.value,Yo.value),Hs&&Hs(ea.value))}});if(zi!=="time"&&!Pl){const Ul=Yo.value===0?ta.value:oa.value,Ks=getClosingViewDate(Ul,zi,ll),ms=ua.value[Yo.value]===zi,Gl=ul(ms?"left":!1,{pickerValue:Ul,onPickerValueChange:Ns=>{ra(Ns,Yo.value)}}),Us=ul("right",{pickerValue:Ks,onPickerValueChange:Ns=>{ra(getClosingViewDate(Ns,zi,ll,-1),Yo.value)}});ps==="rtl"?bl=createVNode(Fragment,null,[Us,ms&&Gl]):bl=createVNode(Fragment,null,[Gl,ms&&Us])}else bl=ul();let gs=createVNode("div",{class:`${ci}-panel-layout`},[createVNode(PresetPanel,{prefixCls:ci,presets:Dn.value,onClick:Ul=>{da(Ul,null),ka(!1,Yo.value)},onHover:Ul=>{Qa(Ul)}},null),createVNode("div",null,[createVNode("div",{class:`${ci}-panels`},[bl]),(jl||Es)&&createVNode("div",{class:`${ci}-footer`},[jl,Es])])]);return Bl&&(gs=Bl(gs)),createVNode("div",{class:`${ci}-panel-container`,style:{marginLeft:`${ba.value}px`},ref:Bn,onMousedown:Ul=>{Ul.preventDefault()}},[gs])}const Ws=createVNode("div",{class:classNames(`${ci}-range-wrapper`,`${ci}-${zi}-range-wrapper`),style:{minWidth:`${Ea.value}px`}},[createVNode("div",{ref:Go,class:`${ci}-range-arrow`,style:ic},null),lc()]);let Ps;ns&&(Ps=createVNode("span",{class:`${ci}-suffix`},[ns]));let Is;vl&&(getValue$2(rr.value,0)&&!Zo.value[0]||getValue$2(rr.value,1)&&!Zo.value[1])&&(Is=createVNode("span",{onMousedown:bl=>{bl.preventDefault(),bl.stopPropagation()},onMouseup:bl=>{bl.preventDefault(),bl.stopPropagation();let jl=rr.value;Zo.value[0]||(jl=updateValues(jl,null,0)),Zo.value[1]||(jl=updateValues(jl,null,1)),da(jl,null),ka(!1,Yo.value)},class:`${ci}-clear`},[yl||createVNode("span",{class:`${ci}-clear-btn`},null)]));const sc={size:getInputSize(zi,Xn.value[0],ll)};let Os=0,is=0;Hn.value&&zn.value&&Wn.value&&(Yo.value===0?is=Hn.value.offsetWidth:(Os=Ia.value,is=zn.value.offsetWidth));const cc=ps==="rtl"?{right:`${Os}px`}:{left:`${Os}px`};return createVNode("div",_objectSpread2$1({ref:Fn,class:classNames(ci,`${ci}-range`,_n.class,{[`${ci}-disabled`]:Zo.value[0]&&Zo.value[1],[`${ci}-focused`]:Yo.value===0?Ni.value:Qi.value,[`${ci}-rtl`]:ps==="rtl"}),style:_n.style,onClick:Yi,onMouseenter:Mc,onMouseleave:rc,onMousedown:rl,onMouseup:ac},getDataOrAriaProps($n)),[createVNode("div",{class:classNames(`${ci}-input`,{[`${ci}-input-active`]:Yo.value===0,[`${ci}-input-placeholder`]:!!ei.value}),ref:Hn},[createVNode("input",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({id:Ci,disabled:Zo.value[0],readonly:js||typeof Xn.value[0]=="function"||!Ri.value,value:ei.value||Ya.value,onInput:bl=>{ja(bl.target.value)},autofocus:hl,placeholder:getValue$2(ml,0)||"",ref:Yn},Ei.value),sc),{},{autocomplete:zs}),null)]),createVNode("div",{class:`${ci}-range-separator`,ref:Wn},[Cl]),createVNode("div",{class:classNames(`${ci}-input`,{[`${ci}-input-active`]:Yo.value===1,[`${ci}-input-placeholder`]:!!ui.value}),ref:zn},[createVNode("input",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({disabled:Zo.value[1],readonly:js||typeof Xn.value[0]=="function"||!Ji.value,value:ui.value||Xa.value,onInput:bl=>{Oa(bl.target.value)},placeholder:getValue$2(ml,1)||"",ref:Gn},Zi.value),sc),{},{autocomplete:zs}),null)]),createVNode("div",{class:`${ci}-active-bar`,style:_extends$1(_extends$1({},cc),{width:`${is}px`,position:"absolute"})},null),Ps,Is,createVNode(PickerTrigger,{visible:ia.value,popupStyle:bi,prefixCls:ci,dropdownClassName:Bi,dropdownAlign:el,getPopupContainer:gl,transitionName:nl,range:!0,direction:ps},{default:()=>[createVNode("div",{style:{pointerEvents:"none",position:"absolute",top:0,bottom:0,left:0,right:0}},null)],popupElement:()=>Ws})])}}})}const InterRangerPicker=RangerPicker(),VCRangePicker=InterRangerPicker;var __rest$Y=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.checked,()=>{Nn.value=$n.checked}),In({focus(){var Bn;(Bn=Rn.value)===null||Bn===void 0||Bn.focus()},blur(){var Bn;(Bn=Rn.value)===null||Bn===void 0||Bn.blur()}});const Dn=ref(),Ln=Bn=>{if($n.disabled)return;$n.checked===void 0&&(Nn.value=Bn.target.checked),Bn.shiftKey=Dn.value;const Hn={target:_extends$1(_extends$1({},$n),{checked:Bn.target.checked}),stopPropagation(){Bn.stopPropagation()},preventDefault(){Bn.preventDefault()},nativeEvent:Bn};$n.checked!==void 0&&(Rn.value.checked=!!$n.checked),Pn("change",Hn),Dn.value=!1},Fn=Bn=>{Pn("click",Bn),Dn.value=Bn.shiftKey};return()=>{const{prefixCls:Bn,name:Hn,id:zn,type:Wn,disabled:Yn,readonly:Gn,tabindex:Go,autofocus:Xn,value:Yo,required:qo}=$n,Jo=__rest$Y($n,["prefixCls","name","id","type","disabled","readonly","tabindex","autofocus","value","required"]),{class:Zo,onFocus:rr,onBlur:nr,onKeydown:ta,onKeypress:oa,onKeyup:ra}=_n,ea=_extends$1(_extends$1({},Jo),_n),la=Object.keys(ea).reduce((aa,ca)=>((ca.startsWith("data-")||ca.startsWith("aria-")||ca==="role")&&(aa[ca]=ea[ca]),aa),{}),ua=classNames(Bn,Zo,{[`${Bn}-checked`]:Nn.value,[`${Bn}-disabled`]:Yn}),ga=_extends$1(_extends$1({name:Hn,id:zn,type:Wn,readonly:Gn,disabled:Yn,tabindex:Go,class:`${Bn}-input`,checked:!!Nn.value,autofocus:Xn,value:Yo},la),{onChange:Ln,onClick:Fn,onFocus:rr,onBlur:nr,onKeydown:ta,onKeypress:oa,onKeyup:ra,required:qo});return createVNode("span",{class:ua},[createVNode("input",_objectSpread2$1({ref:Rn},ga),null),createVNode("span",{class:`${Bn}-inner`},null)])}}}),radioGroupContextKey=Symbol("radioGroupContextKey"),useProvideRadioGroupContext=$n=>{provide(radioGroupContextKey,$n)},useInjectRadioGroupContext=()=>inject(radioGroupContextKey,void 0),radioOptionTypeContextKey=Symbol("radioOptionTypeContextKey"),useProvideRadioOptionTypeContext=$n=>{provide(radioOptionTypeContextKey,$n)},useInjectRadioOptionTypeContext=()=>inject(radioOptionTypeContextKey,void 0),antRadioEffect=new Keyframes("antRadioEffect",{"0%":{transform:"scale(1)",opacity:.5},"100%":{transform:"scale(1.6)",opacity:0}}),getGroupRadioStyle=$n=>{const{componentCls:Cn,antCls:_n}=$n,Pn=`${Cn}-group`;return{[Pn]:_extends$1(_extends$1({},resetComponent($n)),{display:"inline-block",fontSize:0,[`&${Pn}-rtl`]:{direction:"rtl"},[`${_n}-badge ${_n}-badge-count`]:{zIndex:1},[`> ${_n}-badge:not(:first-child) > ${_n}-button-wrapper`]:{borderInlineStart:"none"}})}},getRadioBasicStyle=$n=>{const{componentCls:Cn,radioWrapperMarginRight:_n,radioCheckedColor:Pn,radioSize:In,motionDurationSlow:Nn,motionDurationMid:Rn,motionEaseInOut:Dn,motionEaseInOutCirc:Ln,radioButtonBg:Fn,colorBorder:Bn,lineWidth:Hn,radioDotSize:zn,colorBgContainerDisabled:Wn,colorTextDisabled:Yn,paddingXS:Gn,radioDotDisabledColor:Go,lineType:Xn,radioDotDisabledSize:Yo,wireframe:qo,colorWhite:Jo}=$n,Zo=`${Cn}-inner`;return{[`${Cn}-wrapper`]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-flex",alignItems:"baseline",marginInlineStart:0,marginInlineEnd:_n,cursor:"pointer",[`&${Cn}-wrapper-rtl`]:{direction:"rtl"},"&-disabled":{cursor:"not-allowed",color:$n.colorTextDisabled},"&::after":{display:"inline-block",width:0,overflow:"hidden",content:'"\\a0"'},[`${Cn}-checked::after`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:"100%",height:"100%",border:`${Hn}px ${Xn} ${Pn}`,borderRadius:"50%",visibility:"hidden",animationName:antRadioEffect,animationDuration:Nn,animationTimingFunction:Dn,animationFillMode:"both",content:'""'},[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-block",outline:"none",cursor:"pointer",alignSelf:"center"}),[`${Cn}-wrapper:hover &, - &:hover ${Zo}`]:{borderColor:Pn},[`${Cn}-input:focus-visible + ${Zo}`]:_extends$1({},genFocusOutline($n)),[`${Cn}:hover::after, ${Cn}-wrapper:hover &::after`]:{visibility:"visible"},[`${Cn}-inner`]:{"&::after":{boxSizing:"border-box",position:"absolute",insetBlockStart:"50%",insetInlineStart:"50%",display:"block",width:In,height:In,marginBlockStart:In/-2,marginInlineStart:In/-2,backgroundColor:qo?Pn:Jo,borderBlockStart:0,borderInlineStart:0,borderRadius:In,transform:"scale(0)",opacity:0,transition:`all ${Nn} ${Ln}`,content:'""'},boxSizing:"border-box",position:"relative",insetBlockStart:0,insetInlineStart:0,display:"block",width:In,height:In,backgroundColor:Fn,borderColor:Bn,borderStyle:"solid",borderWidth:Hn,borderRadius:"50%",transition:`all ${Rn}`},[`${Cn}-input`]:{position:"absolute",insetBlockStart:0,insetInlineEnd:0,insetBlockEnd:0,insetInlineStart:0,zIndex:1,cursor:"pointer",opacity:0},[`${Cn}-checked`]:{[Zo]:{borderColor:Pn,backgroundColor:qo?Fn:Pn,"&::after":{transform:`scale(${zn/In})`,opacity:1,transition:`all ${Nn} ${Ln}`}}},[`${Cn}-disabled`]:{cursor:"not-allowed",[Zo]:{backgroundColor:Wn,borderColor:Bn,cursor:"not-allowed","&::after":{backgroundColor:Go}},[`${Cn}-input`]:{cursor:"not-allowed"},[`${Cn}-disabled + span`]:{color:Yn,cursor:"not-allowed"},[`&${Cn}-checked`]:{[Zo]:{"&::after":{transform:`scale(${Yo/In})`}}}},[`span${Cn} + *`]:{paddingInlineStart:Gn,paddingInlineEnd:Gn}})}},getRadioButtonStyle=$n=>{const{radioButtonColor:Cn,controlHeight:_n,componentCls:Pn,lineWidth:In,lineType:Nn,colorBorder:Rn,motionDurationSlow:Dn,motionDurationMid:Ln,radioButtonPaddingHorizontal:Fn,fontSize:Bn,radioButtonBg:Hn,fontSizeLG:zn,controlHeightLG:Wn,controlHeightSM:Yn,paddingXS:Gn,borderRadius:Go,borderRadiusSM:Xn,borderRadiusLG:Yo,radioCheckedColor:qo,radioButtonCheckedBg:Jo,radioButtonHoverColor:Zo,radioButtonActiveColor:rr,radioSolidCheckedColor:nr,colorTextDisabled:ta,colorBgContainerDisabled:oa,radioDisabledButtonCheckedColor:ra,radioDisabledButtonCheckedBg:ea}=$n;return{[`${Pn}-button-wrapper`]:{position:"relative",display:"inline-block",height:_n,margin:0,paddingInline:Fn,paddingBlock:0,color:Cn,fontSize:Bn,lineHeight:`${_n-In*2}px`,background:Hn,border:`${In}px ${Nn} ${Rn}`,borderBlockStartWidth:In+.02,borderInlineStartWidth:0,borderInlineEndWidth:In,cursor:"pointer",transition:[`color ${Ln}`,`background ${Ln}`,`border-color ${Ln}`,`box-shadow ${Ln}`].join(","),a:{color:Cn},[`> ${Pn}-button`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,zIndex:-1,width:"100%",height:"100%"},"&:not(:first-child)":{"&::before":{position:"absolute",insetBlockStart:-In,insetInlineStart:-In,display:"block",boxSizing:"content-box",width:1,height:"100%",paddingBlock:In,paddingInline:0,backgroundColor:Rn,transition:`background-color ${Dn}`,content:'""'}},"&:first-child":{borderInlineStart:`${In}px ${Nn} ${Rn}`,borderStartStartRadius:Go,borderEndStartRadius:Go},"&:last-child":{borderStartEndRadius:Go,borderEndEndRadius:Go},"&:first-child:last-child":{borderRadius:Go},[`${Pn}-group-large &`]:{height:Wn,fontSize:zn,lineHeight:`${Wn-In*2}px`,"&:first-child":{borderStartStartRadius:Yo,borderEndStartRadius:Yo},"&:last-child":{borderStartEndRadius:Yo,borderEndEndRadius:Yo}},[`${Pn}-group-small &`]:{height:Yn,paddingInline:Gn-In,paddingBlock:0,lineHeight:`${Yn-In*2}px`,"&:first-child":{borderStartStartRadius:Xn,borderEndStartRadius:Xn},"&:last-child":{borderStartEndRadius:Xn,borderEndEndRadius:Xn}},"&:hover":{position:"relative",color:qo},"&:has(:focus-visible)":_extends$1({},genFocusOutline($n)),[`${Pn}-inner, input[type='checkbox'], input[type='radio']`]:{width:0,height:0,opacity:0,pointerEvents:"none"},[`&-checked:not(${Pn}-button-wrapper-disabled)`]:{zIndex:1,color:qo,background:Jo,borderColor:qo,"&::before":{backgroundColor:qo},"&:first-child":{borderColor:qo},"&:hover":{color:Zo,borderColor:Zo,"&::before":{backgroundColor:Zo}},"&:active":{color:rr,borderColor:rr,"&::before":{backgroundColor:rr}}},[`${Pn}-group-solid &-checked:not(${Pn}-button-wrapper-disabled)`]:{color:nr,background:qo,borderColor:qo,"&:hover":{color:nr,background:Zo,borderColor:Zo},"&:active":{color:nr,background:rr,borderColor:rr}},"&-disabled":{color:ta,backgroundColor:oa,borderColor:Rn,cursor:"not-allowed","&:first-child, &:hover":{color:ta,backgroundColor:oa,borderColor:Rn}},[`&-disabled${Pn}-button-wrapper-checked`]:{color:ra,backgroundColor:ea,borderColor:Rn,boxShadow:"none"}}}},useStyle$L=genComponentStyleHook("Radio",$n=>{const{padding:Cn,lineWidth:_n,controlItemBgActiveDisabled:Pn,colorTextDisabled:In,colorBgContainer:Nn,fontSizeLG:Rn,controlOutline:Dn,colorPrimaryHover:Ln,colorPrimaryActive:Fn,colorText:Bn,colorPrimary:Hn,marginXS:zn,controlOutlineWidth:Wn,colorTextLightSolid:Yn,wireframe:Gn}=$n,Go=`0 0 0 ${Wn}px ${Dn}`,Xn=Go,Yo=Rn,qo=4,Jo=Yo-qo*2,Zo=Gn?Jo:Yo-(qo+_n)*2,rr=Hn,nr=Bn,ta=Ln,oa=Fn,ra=Cn-_n,ua=merge$1($n,{radioFocusShadow:Go,radioButtonFocusShadow:Xn,radioSize:Yo,radioDotSize:Zo,radioDotDisabledSize:Jo,radioCheckedColor:rr,radioDotDisabledColor:In,radioSolidCheckedColor:Yn,radioButtonBg:Nn,radioButtonCheckedBg:Nn,radioButtonColor:nr,radioButtonHoverColor:ta,radioButtonActiveColor:oa,radioButtonPaddingHorizontal:ra,radioDisabledButtonCheckedBg:Pn,radioDisabledButtonCheckedColor:In,radioWrapperMarginRight:zn});return[getGroupRadioStyle(ua),getRadioBasicStyle(ua),getRadioButtonStyle(ua)]});var __rest$X=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,checked:booleanType(),disabled:booleanType(),isGroup:booleanType(),value:PropTypes.any,name:String,id:String,autofocus:booleanType(),onChange:functionType(),onFocus:functionType(),onBlur:functionType(),onClick:functionType(),"onUpdate:checked":functionType(),"onUpdate:value":functionType()}),Radio=defineComponent({compatConfig:{MODE:3},name:"ARadio",inheritAttrs:!1,props:radioProps(),setup($n,Cn){let{emit:_n,expose:Pn,slots:In,attrs:Nn}=Cn;const Rn=useInjectFormItemContext(),Dn=FormItemInputContext.useInject(),Ln=useInjectRadioOptionTypeContext(),Fn=useInjectRadioGroupContext(),Bn=useInjectDisabled(),Hn=computed(()=>{var ta;return(ta=Gn.value)!==null&&ta!==void 0?ta:Bn.value}),zn=ref(),{prefixCls:Wn,direction:Yn,disabled:Gn}=useConfigInject("radio",$n),Go=computed(()=>(Fn==null?void 0:Fn.optionType.value)==="button"||Ln==="button"?`${Wn.value}-button`:Wn.value),Xn=useInjectDisabled(),[Yo,qo]=useStyle$L(Wn);Pn({focus:()=>{zn.value.focus()},blur:()=>{zn.value.blur()}});const rr=ta=>{const oa=ta.target.checked;_n("update:checked",oa),_n("update:value",oa),_n("change",ta),Rn.onFieldChange()},nr=ta=>{_n("change",ta),Fn&&Fn.onChange&&Fn.onChange(ta)};return()=>{var ta;const oa=Fn,{prefixCls:ra,id:ea=Rn.id.value}=$n,la=__rest$X($n,["prefixCls","id"]),ua=_extends$1(_extends$1({prefixCls:Go.value,id:ea},omit$1(la,["onUpdate:checked","onUpdate:value"])),{disabled:(ta=Gn.value)!==null&&ta!==void 0?ta:Xn.value});oa?(ua.name=oa.name.value,ua.onChange=nr,ua.checked=$n.value===oa.value.value,ua.disabled=Hn.value||oa.disabled.value):ua.onChange=rr;const ga=classNames({[`${Go.value}-wrapper`]:!0,[`${Go.value}-wrapper-checked`]:ua.checked,[`${Go.value}-wrapper-disabled`]:ua.disabled,[`${Go.value}-wrapper-rtl`]:Yn.value==="rtl",[`${Go.value}-wrapper-in-form-item`]:Dn.isFormItemInput},Nn.class,qo.value);return Yo(createVNode("label",_objectSpread2$1(_objectSpread2$1({},Nn),{},{class:ga}),[createVNode(VcCheckbox,_objectSpread2$1(_objectSpread2$1({},ua),{},{type:"radio",ref:zn}),null),In.default&&createVNode("span",null,[In.default()])]))}}}),radioGroupProps=()=>({prefixCls:String,value:PropTypes.any,size:stringType(),options:arrayType(),disabled:booleanType(),name:String,buttonStyle:stringType("outline"),id:String,optionType:stringType("default"),onChange:functionType(),"onUpdate:value":functionType()}),Group$2=defineComponent({compatConfig:{MODE:3},name:"ARadioGroup",inheritAttrs:!1,props:radioGroupProps(),setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const Nn=useInjectFormItemContext(),{prefixCls:Rn,direction:Dn,size:Ln}=useConfigInject("radio",$n),[Fn,Bn]=useStyle$L(Rn),Hn=ref($n.value),zn=ref(!1);return watch(()=>$n.value,Yn=>{Hn.value=Yn,zn.value=!1}),useProvideRadioGroupContext({onChange:Yn=>{const Gn=Hn.value,{value:Go}=Yn.target;"value"in $n||(Hn.value=Go),!zn.value&&Go!==Gn&&(zn.value=!0,Pn("update:value",Go),Pn("change",Yn),Nn.onFieldChange()),nextTick(()=>{zn.value=!1})},value:Hn,disabled:computed(()=>$n.disabled),name:computed(()=>$n.name),optionType:computed(()=>$n.optionType)}),()=>{var Yn;const{options:Gn,buttonStyle:Go,id:Xn=Nn.id.value}=$n,Yo=`${Rn.value}-group`,qo=classNames(Yo,`${Yo}-${Go}`,{[`${Yo}-${Ln.value}`]:Ln.value,[`${Yo}-rtl`]:Dn.value==="rtl"},In.class,Bn.value);let Jo=null;return Gn&&Gn.length>0?Jo=Gn.map(Zo=>{if(typeof Zo=="string"||typeof Zo=="number")return createVNode(Radio,{key:Zo,prefixCls:Rn.value,disabled:$n.disabled,value:Zo,checked:Hn.value===Zo},{default:()=>[Zo]});const{value:rr,disabled:nr,label:ta}=Zo;return createVNode(Radio,{key:`radio-group-value-options-${rr}`,prefixCls:Rn.value,disabled:nr||$n.disabled,value:rr,checked:Hn.value===rr},{default:()=>[ta]})}):Jo=(Yn=_n.default)===null||Yn===void 0?void 0:Yn.call(_n),Fn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{class:qo,id:Xn}),[Jo]))}}}),Button=defineComponent({compatConfig:{MODE:3},name:"ARadioButton",inheritAttrs:!1,props:radioProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In}=useConfigInject("radio",$n);return useProvideRadioOptionTypeContext("button"),()=>{var Nn;return createVNode(Radio,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Pn),$n),{},{prefixCls:In.value}),{default:()=>[(Nn=_n.default)===null||Nn===void 0?void 0:Nn.call(_n)]})}}});Radio.Group=Group$2;Radio.Button=Button;Radio.install=function($n){return $n.component(Radio.name,Radio),$n.component(Radio.Group.name,Radio.Group),$n.component(Radio.Button.name,Radio.Button),$n};const YearSelectOffset=10,YearSelectTotal=20;function YearSelect($n){const{fullscreen:Cn,validRange:_n,generateConfig:Pn,locale:In,prefixCls:Nn,value:Rn,onChange:Dn,divRef:Ln}=$n,Fn=Pn.getYear(Rn||Pn.getNow());let Bn=Fn-YearSelectOffset,Hn=Bn+YearSelectTotal;_n&&(Bn=Pn.getYear(_n[0]),Hn=Pn.getYear(_n[1])+1);const zn=In&&In.year==="年"?"年":"",Wn=[];for(let Yn=Bn;Yn{let Gn=Pn.setYear(Rn,Yn);if(_n){const[Go,Xn]=_n,Yo=Pn.getYear(Gn),qo=Pn.getMonth(Gn);Yo===Pn.getYear(Xn)&&qo>Pn.getMonth(Xn)&&(Gn=Pn.setMonth(Gn,Pn.getMonth(Xn))),Yo===Pn.getYear(Go)&&qoLn.value},null)}YearSelect.inheritAttrs=!1;function MonthSelect($n){const{prefixCls:Cn,fullscreen:_n,validRange:Pn,value:In,generateConfig:Nn,locale:Rn,onChange:Dn,divRef:Ln}=$n,Fn=Nn.getMonth(In||Nn.getNow());let Bn=0,Hn=11;if(Pn){const[Yn,Gn]=Pn,Go=Nn.getYear(In);Nn.getYear(Gn)===Go&&(Hn=Nn.getMonth(Gn)),Nn.getYear(Yn)===Go&&(Bn=Nn.getMonth(Yn))}const zn=Rn.shortMonths||Nn.locale.getShortMonths(Rn.locale),Wn=[];for(let Yn=Bn;Yn<=Hn;Yn+=1)Wn.push({label:zn[Yn],value:Yn});return createVNode(VcSelect,{size:_n?void 0:"small",class:`${Cn}-month-select`,value:Fn,options:Wn,onChange:Yn=>{Dn(Nn.setMonth(In,Yn))},getPopupContainer:()=>Ln.value},null)}MonthSelect.inheritAttrs=!1;function ModeSwitch($n){const{prefixCls:Cn,locale:_n,mode:Pn,fullscreen:In,onModeChange:Nn}=$n;return createVNode(Group$2,{onChange:Rn=>{let{target:{value:Dn}}=Rn;Nn(Dn)},value:Pn,size:In?void 0:"small",class:`${Cn}-mode-switch`},{default:()=>[createVNode(Button,{value:"month"},{default:()=>[_n.month]}),createVNode(Button,{value:"year"},{default:()=>[_n.year]})]})}ModeSwitch.inheritAttrs=!1;const CalendarHeader=defineComponent({name:"CalendarHeader",inheritAttrs:!1,props:["mode","prefixCls","value","validRange","generateConfig","locale","mode","fullscreen"],setup($n,Cn){let{attrs:_n}=Cn;const Pn=ref(null),In=FormItemInputContext.useInject();return FormItemInputContext.useProvide(In,{isFormItemInput:!1}),()=>{const Nn=_extends$1(_extends$1({},$n),_n),{prefixCls:Rn,fullscreen:Dn,mode:Ln,onChange:Fn,onModeChange:Bn}=Nn,Hn=_extends$1(_extends$1({},Nn),{fullscreen:Dn,divRef:Pn});return createVNode("div",{class:`${Rn}-header`,ref:Pn},[createVNode(YearSelect,_objectSpread2$1(_objectSpread2$1({},Hn),{},{onChange:zn=>{Fn(zn,"year")}}),null),Ln==="month"&&createVNode(MonthSelect,_objectSpread2$1(_objectSpread2$1({},Hn),{},{onChange:zn=>{Fn(zn,"month")}}),null),createVNode(ModeSwitch,_objectSpread2$1(_objectSpread2$1({},Hn),{},{onModeChange:Bn}),null)])}}}),genPlaceholderStyle=$n=>({"&::-moz-placeholder":{opacity:1},"&::placeholder":{color:$n,userSelect:"none"},"&:placeholder-shown":{textOverflow:"ellipsis"}}),genHoverStyle=$n=>({borderColor:$n.inputBorderHoverColor,borderInlineEndWidth:$n.lineWidth}),genActiveStyle=$n=>({borderColor:$n.inputBorderHoverColor,boxShadow:`0 0 0 ${$n.controlOutlineWidth}px ${$n.controlOutline}`,borderInlineEndWidth:$n.lineWidth,outline:0}),genDisabledStyle=$n=>({color:$n.colorTextDisabled,backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,boxShadow:"none",cursor:"not-allowed",opacity:1,"&:hover":_extends$1({},genHoverStyle(merge$1($n,{inputBorderHoverColor:$n.colorBorder})))}),genInputLargeStyle=$n=>{const{inputPaddingVerticalLG:Cn,fontSizeLG:_n,lineHeightLG:Pn,borderRadiusLG:In,inputPaddingHorizontalLG:Nn}=$n;return{padding:`${Cn}px ${Nn}px`,fontSize:_n,lineHeight:Pn,borderRadius:In}},genInputSmallStyle=$n=>({padding:`${$n.inputPaddingVerticalSM}px ${$n.controlPaddingHorizontalSM-1}px`,borderRadius:$n.borderRadiusSM}),genStatusStyle=($n,Cn)=>{const{componentCls:_n,colorError:Pn,colorWarning:In,colorErrorOutline:Nn,colorWarningOutline:Rn,colorErrorBorderHover:Dn,colorWarningBorderHover:Ln}=$n;return{[`&-status-error:not(${Cn}-disabled):not(${Cn}-borderless)${Cn}`]:{borderColor:Pn,"&:hover":{borderColor:Dn},"&:focus, &-focused":_extends$1({},genActiveStyle(merge$1($n,{inputBorderActiveColor:Pn,inputBorderHoverColor:Pn,controlOutline:Nn}))),[`${_n}-prefix`]:{color:Pn}},[`&-status-warning:not(${Cn}-disabled):not(${Cn}-borderless)${Cn}`]:{borderColor:In,"&:hover":{borderColor:Ln},"&:focus, &-focused":_extends$1({},genActiveStyle(merge$1($n,{inputBorderActiveColor:In,inputBorderHoverColor:In,controlOutline:Rn}))),[`${_n}-prefix`]:{color:In}}}},genBasicInputStyle=$n=>_extends$1(_extends$1({position:"relative",display:"inline-block",width:"100%",minWidth:0,padding:`${$n.inputPaddingVertical}px ${$n.inputPaddingHorizontal}px`,color:$n.colorText,fontSize:$n.fontSize,lineHeight:$n.lineHeight,backgroundColor:$n.colorBgContainer,backgroundImage:"none",borderWidth:$n.lineWidth,borderStyle:$n.lineType,borderColor:$n.colorBorder,borderRadius:$n.borderRadius,transition:`all ${$n.motionDurationMid}`},genPlaceholderStyle($n.colorTextPlaceholder)),{"&:hover":_extends$1({},genHoverStyle($n)),"&:focus, &-focused":_extends$1({},genActiveStyle($n)),"&-disabled, &[disabled]":_extends$1({},genDisabledStyle($n)),"&-borderless":{"&, &:hover, &:focus, &-focused, &-disabled, &[disabled]":{backgroundColor:"transparent",border:"none",boxShadow:"none"}},"textarea&":{maxWidth:"100%",height:"auto",minHeight:$n.controlHeight,lineHeight:$n.lineHeight,verticalAlign:"bottom",transition:`all ${$n.motionDurationSlow}, height 0s`,resize:"vertical"},"&-lg":_extends$1({},genInputLargeStyle($n)),"&-sm":_extends$1({},genInputSmallStyle($n)),"&-rtl":{direction:"rtl"},"&-textarea-rtl":{direction:"rtl"}}),genInputGroupStyle=$n=>{const{componentCls:Cn,antCls:_n}=$n;return{position:"relative",display:"table",width:"100%",borderCollapse:"separate",borderSpacing:0,"&[class*='col-']":{paddingInlineEnd:$n.paddingXS,"&:last-child":{paddingInlineEnd:0}},[`&-lg ${Cn}, &-lg > ${Cn}-group-addon`]:_extends$1({},genInputLargeStyle($n)),[`&-sm ${Cn}, &-sm > ${Cn}-group-addon`]:_extends$1({},genInputSmallStyle($n)),[`> ${Cn}`]:{display:"table-cell","&:not(:first-child):not(:last-child)":{borderRadius:0}},[`${Cn}-group`]:{"&-addon, &-wrap":{display:"table-cell",width:1,whiteSpace:"nowrap",verticalAlign:"middle","&:not(:first-child):not(:last-child)":{borderRadius:0}},"&-wrap > *":{display:"block !important"},"&-addon":{position:"relative",padding:`0 ${$n.inputPaddingHorizontal}px`,color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize,textAlign:"center",backgroundColor:$n.colorFillAlter,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:$n.borderRadius,transition:`all ${$n.motionDurationSlow}`,lineHeight:1,[`${_n}-select`]:{margin:`-${$n.inputPaddingVertical+1}px -${$n.inputPaddingHorizontal}px`,[`&${_n}-select-single:not(${_n}-select-customize-input)`]:{[`${_n}-select-selector`]:{backgroundColor:"inherit",border:`${$n.lineWidth}px ${$n.lineType} transparent`,boxShadow:"none"}},"&-open, &-focused":{[`${_n}-select-selector`]:{color:$n.colorPrimary}}},[`${_n}-cascader-picker`]:{margin:`-9px -${$n.inputPaddingHorizontal}px`,backgroundColor:"transparent",[`${_n}-cascader-input`]:{textAlign:"start",border:0,boxShadow:"none"}}},"&-addon:first-child":{borderInlineEnd:0},"&-addon:last-child":{borderInlineStart:0}},[`${Cn}`]:{float:"inline-start",width:"100%",marginBottom:0,textAlign:"inherit","&:focus":{zIndex:1,borderInlineEndWidth:1},"&:hover":{zIndex:1,borderInlineEndWidth:1,[`${Cn}-search-with-button &`]:{zIndex:0}}},[`> ${Cn}:first-child, ${Cn}-group-addon:first-child`]:{borderStartEndRadius:0,borderEndEndRadius:0,[`${_n}-select ${_n}-select-selector`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`> ${Cn}-affix-wrapper`]:{[`&:not(:first-child) ${Cn}`]:{borderStartStartRadius:0,borderEndStartRadius:0},[`&:not(:last-child) ${Cn}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`> ${Cn}:last-child, ${Cn}-group-addon:last-child`]:{borderStartStartRadius:0,borderEndStartRadius:0,[`${_n}-select ${_n}-select-selector`]:{borderStartStartRadius:0,borderEndStartRadius:0}},[`${Cn}-affix-wrapper`]:{"&:not(:last-child)":{borderStartEndRadius:0,borderEndEndRadius:0,[`${Cn}-search &`]:{borderStartStartRadius:$n.borderRadius,borderEndStartRadius:$n.borderRadius}},[`&:not(:first-child), ${Cn}-search &:not(:first-child)`]:{borderStartStartRadius:0,borderEndStartRadius:0}},[`&${Cn}-group-compact`]:_extends$1(_extends$1({display:"block"},clearFix()),{[`${Cn}-group-addon, ${Cn}-group-wrap, > ${Cn}`]:{"&:not(:first-child):not(:last-child)":{borderInlineEndWidth:$n.lineWidth,"&:hover":{zIndex:1},"&:focus":{zIndex:1}}},"& > *":{display:"inline-block",float:"none",verticalAlign:"top",borderRadius:0},[`& > ${Cn}-affix-wrapper`]:{display:"inline-flex"},[`& > ${_n}-picker-range`]:{display:"inline-flex"},"& > *:not(:last-child)":{marginInlineEnd:-$n.lineWidth,borderInlineEndWidth:$n.lineWidth},[`${Cn}`]:{float:"none"},[`& > ${_n}-select > ${_n}-select-selector, - & > ${_n}-select-auto-complete ${Cn}, - & > ${_n}-cascader-picker ${Cn}, - & > ${Cn}-group-wrapper ${Cn}`]:{borderInlineEndWidth:$n.lineWidth,borderRadius:0,"&:hover":{zIndex:1},"&:focus":{zIndex:1}},[`& > ${_n}-select-focused`]:{zIndex:1},[`& > ${_n}-select > ${_n}-select-arrow`]:{zIndex:1},[`& > *:first-child, - & > ${_n}-select:first-child > ${_n}-select-selector, - & > ${_n}-select-auto-complete:first-child ${Cn}, - & > ${_n}-cascader-picker:first-child ${Cn}`]:{borderStartStartRadius:$n.borderRadius,borderEndStartRadius:$n.borderRadius},[`& > *:last-child, - & > ${_n}-select:last-child > ${_n}-select-selector, - & > ${_n}-cascader-picker:last-child ${Cn}, - & > ${_n}-cascader-picker-focused:last-child ${Cn}`]:{borderInlineEndWidth:$n.lineWidth,borderStartEndRadius:$n.borderRadius,borderEndEndRadius:$n.borderRadius},[`& > ${_n}-select-auto-complete ${Cn}`]:{verticalAlign:"top"},[`${Cn}-group-wrapper + ${Cn}-group-wrapper`]:{marginInlineStart:-$n.lineWidth,[`${Cn}-affix-wrapper`]:{borderRadius:0}},[`${Cn}-group-wrapper:not(:last-child)`]:{[`&${Cn}-search > ${Cn}-group`]:{[`& > ${Cn}-group-addon > ${Cn}-search-button`]:{borderRadius:0},[`& > ${Cn}`]:{borderStartStartRadius:$n.borderRadius,borderStartEndRadius:0,borderEndEndRadius:0,borderEndStartRadius:$n.borderRadius}}}}),[`&&-sm ${_n}-btn`]:{fontSize:$n.fontSizeSM,height:$n.controlHeightSM,lineHeight:"normal"},[`&&-lg ${_n}-btn`]:{fontSize:$n.fontSizeLG,height:$n.controlHeightLG,lineHeight:"normal"},[`&&-lg ${_n}-select-single ${_n}-select-selector`]:{height:`${$n.controlHeightLG}px`,[`${_n}-select-selection-item, ${_n}-select-selection-placeholder`]:{lineHeight:`${$n.controlHeightLG-2}px`},[`${_n}-select-selection-search-input`]:{height:`${$n.controlHeightLG}px`}},[`&&-sm ${_n}-select-single ${_n}-select-selector`]:{height:`${$n.controlHeightSM}px`,[`${_n}-select-selection-item, ${_n}-select-selection-placeholder`]:{lineHeight:`${$n.controlHeightSM-2}px`},[`${_n}-select-selection-search-input`]:{height:`${$n.controlHeightSM}px`}}}},genInputStyle=$n=>{const{componentCls:Cn,controlHeightSM:_n,lineWidth:Pn}=$n,Nn=(_n-Pn*2-16)/2;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),genBasicInputStyle($n)),genStatusStyle($n,Cn)),{'&[type="color"]':{height:$n.controlHeight,[`&${Cn}-lg`]:{height:$n.controlHeightLG},[`&${Cn}-sm`]:{height:_n,paddingTop:Nn,paddingBottom:Nn}}})}},genAllowClearStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-clear-icon`]:{margin:0,color:$n.colorTextQuaternary,fontSize:$n.fontSizeIcon,verticalAlign:-1,cursor:"pointer",transition:`color ${$n.motionDurationSlow}`,"&:hover":{color:$n.colorTextTertiary},"&:active":{color:$n.colorText},"&-hidden":{visibility:"hidden"},"&-has-suffix":{margin:`0 ${$n.inputAffixPadding}px`}},"&-textarea-with-clear-btn":{padding:"0 !important",border:"0 !important",[`${Cn}-clear-icon`]:{position:"absolute",insetBlockStart:$n.paddingXS,insetInlineEnd:$n.paddingXS,zIndex:1}}}},genAffixStyle=$n=>{const{componentCls:Cn,inputAffixPadding:_n,colorTextDescription:Pn,motionDurationSlow:In,colorIcon:Nn,colorIconHover:Rn,iconCls:Dn}=$n;return{[`${Cn}-affix-wrapper`]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},genBasicInputStyle($n)),{display:"inline-flex",[`&:not(${Cn}-affix-wrapper-disabled):hover`]:_extends$1(_extends$1({},genHoverStyle($n)),{zIndex:1,[`${Cn}-search-with-button &`]:{zIndex:0}}),"&-focused, &:focus":{zIndex:1},"&-disabled":{[`${Cn}[disabled]`]:{background:"transparent"}},[`> input${Cn}`]:{padding:0,fontSize:"inherit",border:"none",borderRadius:0,outline:"none","&:focus":{boxShadow:"none !important"}},"&::before":{width:0,visibility:"hidden",content:'"\\a0"'},[`${Cn}`]:{"&-prefix, &-suffix":{display:"flex",flex:"none",alignItems:"center","> *:not(:last-child)":{marginInlineEnd:$n.paddingXS}},"&-show-count-suffix":{color:Pn},"&-show-count-has-suffix":{marginInlineEnd:$n.paddingXXS},"&-prefix":{marginInlineEnd:_n},"&-suffix":{marginInlineStart:_n}}}),genAllowClearStyle($n)),{[`${Dn}${Cn}-password-icon`]:{color:Nn,cursor:"pointer",transition:`all ${In}`,"&:hover":{color:Rn}}}),genStatusStyle($n,`${Cn}-affix-wrapper`))}},genGroupStyle=$n=>{const{componentCls:Cn,colorError:_n,colorSuccess:Pn,borderRadiusLG:In,borderRadiusSM:Nn}=$n;return{[`${Cn}-group`]:_extends$1(_extends$1(_extends$1({},resetComponent($n)),genInputGroupStyle($n)),{"&-rtl":{direction:"rtl"},"&-wrapper":{display:"inline-block",width:"100%",textAlign:"start",verticalAlign:"top","&-rtl":{direction:"rtl"},"&-lg":{[`${Cn}-group-addon`]:{borderRadius:In}},"&-sm":{[`${Cn}-group-addon`]:{borderRadius:Nn}},"&-status-error":{[`${Cn}-group-addon`]:{color:_n,borderColor:_n}},"&-status-warning":{[`${Cn}-group-addon:last-child`]:{color:Pn,borderColor:Pn}}}})}},genSearchInputStyle=$n=>{const{componentCls:Cn,antCls:_n}=$n,Pn=`${Cn}-search`;return{[Pn]:{[`${Cn}`]:{"&:hover, &:focus":{borderColor:$n.colorPrimaryHover,[`+ ${Cn}-group-addon ${Pn}-button:not(${_n}-btn-primary)`]:{borderInlineStartColor:$n.colorPrimaryHover}}},[`${Cn}-affix-wrapper`]:{borderRadius:0},[`${Cn}-lg`]:{lineHeight:$n.lineHeightLG-2e-4},[`> ${Cn}-group`]:{[`> ${Cn}-group-addon:last-child`]:{insetInlineStart:-1,padding:0,border:0,[`${Pn}-button`]:{paddingTop:0,paddingBottom:0,borderStartStartRadius:0,borderStartEndRadius:$n.borderRadius,borderEndEndRadius:$n.borderRadius,borderEndStartRadius:0},[`${Pn}-button:not(${_n}-btn-primary)`]:{color:$n.colorTextDescription,"&:hover":{color:$n.colorPrimaryHover},"&:active":{color:$n.colorPrimaryActive},[`&${_n}-btn-loading::before`]:{insetInlineStart:0,insetInlineEnd:0,insetBlockStart:0,insetBlockEnd:0}}}},[`${Pn}-button`]:{height:$n.controlHeight,"&:hover, &:focus":{zIndex:1}},[`&-large ${Pn}-button`]:{height:$n.controlHeightLG},[`&-small ${Pn}-button`]:{height:$n.controlHeightSM},"&-rtl":{direction:"rtl"},[`&${Cn}-compact-item`]:{[`&:not(${Cn}-compact-last-item)`]:{[`${Cn}-group-addon`]:{[`${Cn}-search-button`]:{marginInlineEnd:-$n.lineWidth,borderRadius:0}}},[`&:not(${Cn}-compact-first-item)`]:{[`${Cn},${Cn}-affix-wrapper`]:{borderRadius:0}},[`> ${Cn}-group-addon ${Cn}-search-button, - > ${Cn}, - ${Cn}-affix-wrapper`]:{"&:hover,&:focus,&:active":{zIndex:2}},[`> ${Cn}-affix-wrapper-focused`]:{zIndex:2}}}}};function initInputToken($n){return merge$1($n,{inputAffixPadding:$n.paddingXXS,inputPaddingVertical:Math.max(Math.round(($n.controlHeight-$n.fontSize*$n.lineHeight)/2*10)/10-$n.lineWidth,3),inputPaddingVerticalLG:Math.ceil(($n.controlHeightLG-$n.fontSizeLG*$n.lineHeightLG)/2*10)/10-$n.lineWidth,inputPaddingVerticalSM:Math.max(Math.round(($n.controlHeightSM-$n.fontSize*$n.lineHeight)/2*10)/10-$n.lineWidth,0),inputPaddingHorizontal:$n.paddingSM-$n.lineWidth,inputPaddingHorizontalSM:$n.paddingXS-$n.lineWidth,inputPaddingHorizontalLG:$n.controlPaddingHorizontal-$n.lineWidth,inputBorderHoverColor:$n.colorPrimaryHover,inputBorderActiveColor:$n.colorPrimaryHover})}const genTextAreaStyle=$n=>{const{componentCls:Cn,inputPaddingHorizontal:_n,paddingLG:Pn}=$n,In=`${Cn}-textarea`;return{[In]:{position:"relative",[`${In}-suffix`]:{position:"absolute",top:0,insetInlineEnd:_n,bottom:0,zIndex:1,display:"inline-flex",alignItems:"center",margin:"auto"},"&-status-error,\n &-status-warning,\n &-status-success,\n &-status-validating":{[`&${In}-has-feedback`]:{[`${Cn}`]:{paddingInlineEnd:Pn}}},"&-show-count":{[`> ${Cn}`]:{height:"100%"},"&::after":{color:$n.colorTextDescription,whiteSpace:"nowrap",content:"attr(data-count)",pointerEvents:"none",float:"right"}},"&-rtl":{"&::after":{float:"left"}}}}},useStyle$K=genComponentStyleHook("Input",$n=>{const Cn=initInputToken($n);return[genInputStyle(Cn),genTextAreaStyle(Cn),genAffixStyle(Cn),genGroupStyle(Cn),genSearchInputStyle(Cn),genCompactItemStyle(Cn)]}),genPikerPadding=($n,Cn,_n,Pn)=>{const{lineHeight:In}=$n,Nn=Math.floor(_n*In)+2,Rn=Math.max((Cn-Nn)/2,0),Dn=Math.max(Cn-Nn-Rn,0);return{padding:`${Rn}px ${Pn}px ${Dn}px`}},genPickerCellInnerStyle=$n=>{const{componentCls:Cn,pickerCellCls:_n,pickerCellInnerCls:Pn,pickerPanelCellHeight:In,motionDurationSlow:Nn,borderRadiusSM:Rn,motionDurationMid:Dn,controlItemBgHover:Ln,lineWidth:Fn,lineType:Bn,colorPrimary:Hn,controlItemBgActive:zn,colorTextLightSolid:Wn,controlHeightSM:Yn,pickerDateHoverRangeBorderColor:Gn,pickerCellBorderGap:Go,pickerBasicCellHoverWithRangeColor:Xn,pickerPanelCellWidth:Yo,colorTextDisabled:qo,colorBgContainerDisabled:Jo}=$n;return{"&::before":{position:"absolute",top:"50%",insetInlineStart:0,insetInlineEnd:0,zIndex:1,height:In,transform:"translateY(-50%)",transition:`all ${Nn}`,content:'""'},[Pn]:{position:"relative",zIndex:2,display:"inline-block",minWidth:In,height:In,lineHeight:`${In}px`,borderRadius:Rn,transition:`background ${Dn}, border ${Dn}`},[`&:hover:not(${_n}-in-view), - &:hover:not(${_n}-selected):not(${_n}-range-start):not(${_n}-range-end):not(${_n}-range-hover-start):not(${_n}-range-hover-end)`]:{[Pn]:{background:Ln}},[`&-in-view${_n}-today ${Pn}`]:{"&::before":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:1,border:`${Fn}px ${Bn} ${Hn}`,borderRadius:Rn,content:'""'}},[`&-in-view${_n}-in-range`]:{position:"relative","&::before":{background:zn}},[`&-in-view${_n}-selected ${Pn}, - &-in-view${_n}-range-start ${Pn}, - &-in-view${_n}-range-end ${Pn}`]:{color:Wn,background:Hn},[`&-in-view${_n}-range-start:not(${_n}-range-start-single), - &-in-view${_n}-range-end:not(${_n}-range-end-single)`]:{"&::before":{background:zn}},[`&-in-view${_n}-range-start::before`]:{insetInlineStart:"50%"},[`&-in-view${_n}-range-end::before`]:{insetInlineEnd:"50%"},[`&-in-view${_n}-range-hover-start:not(${_n}-in-range):not(${_n}-range-start):not(${_n}-range-end), - &-in-view${_n}-range-hover-end:not(${_n}-in-range):not(${_n}-range-start):not(${_n}-range-end), - &-in-view${_n}-range-hover-start${_n}-range-start-single, - &-in-view${_n}-range-hover-start${_n}-range-start${_n}-range-end${_n}-range-end-near-hover, - &-in-view${_n}-range-hover-end${_n}-range-start${_n}-range-end${_n}-range-start-near-hover, - &-in-view${_n}-range-hover-end${_n}-range-end-single, - &-in-view${_n}-range-hover:not(${_n}-in-range)`]:{"&::after":{position:"absolute",top:"50%",zIndex:0,height:Yn,borderTop:`${Fn}px dashed ${Gn}`,borderBottom:`${Fn}px dashed ${Gn}`,transform:"translateY(-50%)",transition:`all ${Nn}`,content:'""'}},"&-range-hover-start::after,\n &-range-hover-end::after,\n &-range-hover::after":{insetInlineEnd:0,insetInlineStart:Go},[`&-in-view${_n}-in-range${_n}-range-hover::before, - &-in-view${_n}-range-start${_n}-range-hover::before, - &-in-view${_n}-range-end${_n}-range-hover::before, - &-in-view${_n}-range-start:not(${_n}-range-start-single)${_n}-range-hover-start::before, - &-in-view${_n}-range-end:not(${_n}-range-end-single)${_n}-range-hover-end::before, - ${Cn}-panel - > :not(${Cn}-date-panel) - &-in-view${_n}-in-range${_n}-range-hover-start::before, - ${Cn}-panel - > :not(${Cn}-date-panel) - &-in-view${_n}-in-range${_n}-range-hover-end::before`]:{background:Xn},[`&-in-view${_n}-range-start:not(${_n}-range-start-single):not(${_n}-range-end) ${Pn}`]:{borderStartStartRadius:Rn,borderEndStartRadius:Rn,borderStartEndRadius:0,borderEndEndRadius:0},[`&-in-view${_n}-range-end:not(${_n}-range-end-single):not(${_n}-range-start) ${Pn}`]:{borderStartStartRadius:0,borderEndStartRadius:0,borderStartEndRadius:Rn,borderEndEndRadius:Rn},[`&-range-hover${_n}-range-end::after`]:{insetInlineStart:"50%"},[`tr > &-in-view${_n}-range-hover:first-child::after, - tr > &-in-view${_n}-range-hover-end:first-child::after, - &-in-view${_n}-start${_n}-range-hover-edge-start${_n}-range-hover-edge-start-near-range::after, - &-in-view${_n}-range-hover-edge-start:not(${_n}-range-hover-edge-start-near-range)::after, - &-in-view${_n}-range-hover-start::after`]:{insetInlineStart:(Yo-In)/2,borderInlineStart:`${Fn}px dashed ${Gn}`,borderStartStartRadius:Fn,borderEndStartRadius:Fn},[`tr > &-in-view${_n}-range-hover:last-child::after, - tr > &-in-view${_n}-range-hover-start:last-child::after, - &-in-view${_n}-end${_n}-range-hover-edge-end${_n}-range-hover-edge-end-near-range::after, - &-in-view${_n}-range-hover-edge-end:not(${_n}-range-hover-edge-end-near-range)::after, - &-in-view${_n}-range-hover-end::after`]:{insetInlineEnd:(Yo-In)/2,borderInlineEnd:`${Fn}px dashed ${Gn}`,borderStartEndRadius:Fn,borderEndEndRadius:Fn},"&-disabled":{color:qo,pointerEvents:"none",[Pn]:{background:"transparent"},"&::before":{background:Jo}},[`&-disabled${_n}-today ${Pn}::before`]:{borderColor:qo}}},genPanelStyle=$n=>{const{componentCls:Cn,pickerCellInnerCls:_n,pickerYearMonthCellWidth:Pn,pickerControlIconSize:In,pickerPanelCellWidth:Nn,paddingSM:Rn,paddingXS:Dn,paddingXXS:Ln,colorBgContainer:Fn,lineWidth:Bn,lineType:Hn,borderRadiusLG:zn,colorPrimary:Wn,colorTextHeading:Yn,colorSplit:Gn,pickerControlIconBorderWidth:Go,colorIcon:Xn,pickerTextHeight:Yo,motionDurationMid:qo,colorIconHover:Jo,fontWeightStrong:Zo,pickerPanelCellHeight:rr,pickerCellPaddingVertical:nr,colorTextDisabled:ta,colorText:oa,fontSize:ra,pickerBasicCellHoverWithRangeColor:ea,motionDurationSlow:la,pickerPanelWithoutTimeCellHeight:ua,pickerQuarterPanelContentHeight:ga,colorLink:aa,colorLinkActive:ca,colorLinkHover:sa,pickerDateHoverRangeBorderColor:ia,borderRadiusSM:fa,colorTextLightSolid:ma,borderRadius:ya,controlItemBgHover:ba,pickerTimePanelColumnHeight:Ia,pickerTimePanelColumnWidth:Ea,pickerTimePanelCellHeight:xa,controlItemBgActive:Ta,marginXXS:wa}=$n,La=Nn*7+Rn*2+4,Na=(La-Dn*2)/3-Pn-Rn;return{[Cn]:{"&-panel":{display:"inline-flex",flexDirection:"column",textAlign:"center",background:Fn,border:`${Bn}px ${Hn} ${Gn}`,borderRadius:zn,outline:"none","&-focused":{borderColor:Wn},"&-rtl":{direction:"rtl",[`${Cn}-prev-icon, - ${Cn}-super-prev-icon`]:{transform:"rotate(45deg)"},[`${Cn}-next-icon, - ${Cn}-super-next-icon`]:{transform:"rotate(-135deg)"}}},"&-decade-panel,\n &-year-panel,\n &-quarter-panel,\n &-month-panel,\n &-week-panel,\n &-date-panel,\n &-time-panel":{display:"flex",flexDirection:"column",width:La},"&-header":{display:"flex",padding:`0 ${Dn}px`,color:Yn,borderBottom:`${Bn}px ${Hn} ${Gn}`,"> *":{flex:"none"},button:{padding:0,color:Xn,lineHeight:`${Yo}px`,background:"transparent",border:0,cursor:"pointer",transition:`color ${qo}`},"> button":{minWidth:"1.6em",fontSize:ra,"&:hover":{color:Jo}},"&-view":{flex:"auto",fontWeight:Zo,lineHeight:`${Yo}px`,button:{color:"inherit",fontWeight:"inherit",verticalAlign:"top","&:not(:first-child)":{marginInlineStart:Dn},"&:hover":{color:Wn}}}},"&-prev-icon,\n &-next-icon,\n &-super-prev-icon,\n &-super-next-icon":{position:"relative",display:"inline-block",width:In,height:In,"&::before":{position:"absolute",top:0,insetInlineStart:0,display:"inline-block",width:In,height:In,border:"0 solid currentcolor",borderBlockStartWidth:Go,borderBlockEndWidth:0,borderInlineStartWidth:Go,borderInlineEndWidth:0,content:'""'}},"&-super-prev-icon,\n &-super-next-icon":{"&::after":{position:"absolute",top:Math.ceil(In/2),insetInlineStart:Math.ceil(In/2),display:"inline-block",width:In,height:In,border:"0 solid currentcolor",borderBlockStartWidth:Go,borderBlockEndWidth:0,borderInlineStartWidth:Go,borderInlineEndWidth:0,content:'""'}},"&-prev-icon,\n &-super-prev-icon":{transform:"rotate(-45deg)"},"&-next-icon,\n &-super-next-icon":{transform:"rotate(135deg)"},"&-content":{width:"100%",tableLayout:"fixed",borderCollapse:"collapse","th, td":{position:"relative",minWidth:rr,fontWeight:"normal"},th:{height:rr+nr*2,color:oa,verticalAlign:"middle"}},"&-cell":_extends$1({padding:`${nr}px 0`,color:ta,cursor:"pointer","&-in-view":{color:oa}},genPickerCellInnerStyle($n)),[`&-date-panel ${Cn}-cell-in-view${Cn}-cell-in-range${Cn}-cell-range-hover-start ${_n}, - &-date-panel ${Cn}-cell-in-view${Cn}-cell-in-range${Cn}-cell-range-hover-end ${_n}`]:{"&::after":{position:"absolute",top:0,bottom:0,zIndex:-1,background:ea,transition:`all ${la}`,content:'""'}},[`&-date-panel - ${Cn}-cell-in-view${Cn}-cell-in-range${Cn}-cell-range-hover-start - ${_n}::after`]:{insetInlineEnd:-(Nn-rr)/2,insetInlineStart:0},[`&-date-panel ${Cn}-cell-in-view${Cn}-cell-in-range${Cn}-cell-range-hover-end ${_n}::after`]:{insetInlineEnd:0,insetInlineStart:-(Nn-rr)/2},[`&-range-hover${Cn}-range-start::after`]:{insetInlineEnd:"50%"},"&-decade-panel,\n &-year-panel,\n &-quarter-panel,\n &-month-panel":{[`${Cn}-content`]:{height:ua*4},[_n]:{padding:`0 ${Dn}px`}},"&-quarter-panel":{[`${Cn}-content`]:{height:ga}},[`&-panel ${Cn}-footer`]:{borderTop:`${Bn}px ${Hn} ${Gn}`},"&-footer":{width:"min-content",minWidth:"100%",lineHeight:`${Yo-2*Bn}px`,textAlign:"center","&-extra":{padding:`0 ${Rn}`,lineHeight:`${Yo-2*Bn}px`,textAlign:"start","&:not(:last-child)":{borderBottom:`${Bn}px ${Hn} ${Gn}`}}},"&-now":{textAlign:"start"},"&-today-btn":{color:aa,"&:hover":{color:sa},"&:active":{color:ca},[`&${Cn}-today-btn-disabled`]:{color:ta,cursor:"not-allowed"}},"&-decade-panel":{[_n]:{padding:`0 ${Dn/2}px`},[`${Cn}-cell::before`]:{display:"none"}},"&-year-panel,\n &-quarter-panel,\n &-month-panel":{[`${Cn}-body`]:{padding:`0 ${Dn}px`},[_n]:{width:Pn},[`${Cn}-cell-range-hover-start::after`]:{insetInlineStart:Na,borderInlineStart:`${Bn}px dashed ${ia}`,borderStartStartRadius:fa,borderBottomStartRadius:fa,borderStartEndRadius:0,borderBottomEndRadius:0,[`${Cn}-panel-rtl &`]:{insetInlineEnd:Na,borderInlineEnd:`${Bn}px dashed ${ia}`,borderStartStartRadius:0,borderBottomStartRadius:0,borderStartEndRadius:fa,borderBottomEndRadius:fa}},[`${Cn}-cell-range-hover-end::after`]:{insetInlineEnd:Na,borderInlineEnd:`${Bn}px dashed ${ia}`,borderStartStartRadius:0,borderEndStartRadius:0,borderStartEndRadius:ya,borderEndEndRadius:ya,[`${Cn}-panel-rtl &`]:{insetInlineStart:Na,borderInlineStart:`${Bn}px dashed ${ia}`,borderStartStartRadius:ya,borderEndStartRadius:ya,borderStartEndRadius:0,borderEndEndRadius:0}}},"&-week-panel":{[`${Cn}-body`]:{padding:`${Dn}px ${Rn}px`},[`${Cn}-cell`]:{[`&:hover ${_n}, - &-selected ${_n}, - ${_n}`]:{background:"transparent !important"}},"&-row":{td:{transition:`background ${qo}`,"&:first-child":{borderStartStartRadius:fa,borderEndStartRadius:fa},"&:last-child":{borderStartEndRadius:fa,borderEndEndRadius:fa}},"&:hover td":{background:ba},"&-selected td,\n &-selected:hover td":{background:Wn,[`&${Cn}-cell-week`]:{color:new TinyColor(ma).setAlpha(.5).toHexString()},[`&${Cn}-cell-today ${_n}::before`]:{borderColor:ma},[_n]:{color:ma}}}},"&-date-panel":{[`${Cn}-body`]:{padding:`${Dn}px ${Rn}px`},[`${Cn}-content`]:{width:Nn*7,th:{width:Nn}}},"&-datetime-panel":{display:"flex",[`${Cn}-time-panel`]:{borderInlineStart:`${Bn}px ${Hn} ${Gn}`},[`${Cn}-date-panel, - ${Cn}-time-panel`]:{transition:`opacity ${la}`},"&-active":{[`${Cn}-date-panel, - ${Cn}-time-panel`]:{opacity:.3,"&-active":{opacity:1}}}},"&-time-panel":{width:"auto",minWidth:"auto",direction:"ltr",[`${Cn}-content`]:{display:"flex",flex:"auto",height:Ia},"&-column":{flex:"1 0 auto",width:Ea,margin:`${Ln}px 0`,padding:0,overflowY:"hidden",textAlign:"start",listStyle:"none",transition:`background ${qo}`,overflowX:"hidden","&::after":{display:"block",height:Ia-xa,content:'""'},"&:not(:first-child)":{borderInlineStart:`${Bn}px ${Hn} ${Gn}`},"&-active":{background:new TinyColor(Ta).setAlpha(.2).toHexString()},"&:hover":{overflowY:"auto"},"> li":{margin:0,padding:0,[`&${Cn}-time-panel-cell`]:{marginInline:wa,[`${Cn}-time-panel-cell-inner`]:{display:"block",width:Ea-2*wa,height:xa,margin:0,paddingBlock:0,paddingInlineEnd:0,paddingInlineStart:(Ea-xa)/2,color:oa,lineHeight:`${xa}px`,borderRadius:fa,cursor:"pointer",transition:`background ${qo}`,"&:hover":{background:ba}},"&-selected":{[`${Cn}-time-panel-cell-inner`]:{background:Ta}},"&-disabled":{[`${Cn}-time-panel-cell-inner`]:{color:ta,background:"transparent",cursor:"not-allowed"}}}}}},[`&-datetime-panel ${Cn}-time-panel-column:after`]:{height:Ia-xa+Ln*2}}}},genPickerStatusStyle=$n=>{const{componentCls:Cn,colorBgContainer:_n,colorError:Pn,colorErrorOutline:In,colorWarning:Nn,colorWarningOutline:Rn}=$n;return{[Cn]:{[`&-status-error${Cn}`]:{"&, &:not([disabled]):hover":{backgroundColor:_n,borderColor:Pn},"&-focused, &:focus":_extends$1({},genActiveStyle(merge$1($n,{inputBorderActiveColor:Pn,inputBorderHoverColor:Pn,controlOutline:In}))),[`${Cn}-active-bar`]:{background:Pn}},[`&-status-warning${Cn}`]:{"&, &:not([disabled]):hover":{backgroundColor:_n,borderColor:Nn},"&-focused, &:focus":_extends$1({},genActiveStyle(merge$1($n,{inputBorderActiveColor:Nn,inputBorderHoverColor:Nn,controlOutline:Rn}))),[`${Cn}-active-bar`]:{background:Nn}}}}},genPickerStyle=$n=>{const{componentCls:Cn,antCls:_n,boxShadowPopoverArrow:Pn,controlHeight:In,fontSize:Nn,inputPaddingHorizontal:Rn,colorBgContainer:Dn,lineWidth:Ln,lineType:Fn,colorBorder:Bn,borderRadius:Hn,motionDurationMid:zn,colorBgContainerDisabled:Wn,colorTextDisabled:Yn,colorTextPlaceholder:Gn,controlHeightLG:Go,fontSizeLG:Xn,controlHeightSM:Yo,inputPaddingHorizontalSM:qo,paddingXS:Jo,marginXS:Zo,colorTextDescription:rr,lineWidthBold:nr,lineHeight:ta,colorPrimary:oa,motionDurationSlow:ra,zIndexPopup:ea,paddingXXS:la,paddingSM:ua,pickerTextHeight:ga,controlItemBgActive:aa,colorPrimaryBorder:ca,sizePopupArrow:sa,borderRadiusXS:ia,borderRadiusOuter:fa,colorBgElevated:ma,borderRadiusLG:ya,boxShadowSecondary:ba,borderRadiusSM:Ia,colorSplit:Ea,controlItemBgHover:xa,presetsWidth:Ta,presetsMaxWidth:wa}=$n;return[{[Cn]:_extends$1(_extends$1(_extends$1({},resetComponent($n)),genPikerPadding($n,In,Nn,Rn)),{position:"relative",display:"inline-flex",alignItems:"center",background:Dn,lineHeight:1,border:`${Ln}px ${Fn} ${Bn}`,borderRadius:Hn,transition:`border ${zn}, box-shadow ${zn}`,"&:hover, &-focused":_extends$1({},genHoverStyle($n)),"&-focused":_extends$1({},genActiveStyle($n)),[`&${Cn}-disabled`]:{background:Wn,borderColor:Bn,cursor:"not-allowed",[`${Cn}-suffix`]:{color:Yn}},[`&${Cn}-borderless`]:{backgroundColor:"transparent !important",borderColor:"transparent !important",boxShadow:"none !important"},[`${Cn}-input`]:{position:"relative",display:"inline-flex",alignItems:"center",width:"100%","> input":_extends$1(_extends$1({},genBasicInputStyle($n)),{flex:"auto",minWidth:1,height:"auto",padding:0,background:"transparent",border:0,"&:focus":{boxShadow:"none"},"&[disabled]":{background:"transparent"}}),"&:hover":{[`${Cn}-clear`]:{opacity:1}},"&-placeholder":{"> input":{color:Gn}}},"&-large":_extends$1(_extends$1({},genPikerPadding($n,Go,Xn,Rn)),{[`${Cn}-input > input`]:{fontSize:Xn}}),"&-small":_extends$1({},genPikerPadding($n,Yo,Nn,qo)),[`${Cn}-suffix`]:{display:"flex",flex:"none",alignSelf:"center",marginInlineStart:Jo/2,color:Yn,lineHeight:1,pointerEvents:"none","> *":{verticalAlign:"top","&:not(:last-child)":{marginInlineEnd:Zo}}},[`${Cn}-clear`]:{position:"absolute",top:"50%",insetInlineEnd:0,color:Yn,lineHeight:1,background:Dn,transform:"translateY(-50%)",cursor:"pointer",opacity:0,transition:`opacity ${zn}, color ${zn}`,"> *":{verticalAlign:"top"},"&:hover":{color:rr}},[`${Cn}-separator`]:{position:"relative",display:"inline-block",width:"1em",height:Xn,color:Yn,fontSize:Xn,verticalAlign:"top",cursor:"default",[`${Cn}-focused &`]:{color:rr},[`${Cn}-range-separator &`]:{[`${Cn}-disabled &`]:{cursor:"not-allowed"}}},"&-range":{position:"relative",display:"inline-flex",[`${Cn}-clear`]:{insetInlineEnd:Rn},"&:hover":{[`${Cn}-clear`]:{opacity:1}},[`${Cn}-active-bar`]:{bottom:-Ln,height:nr,marginInlineStart:Rn,background:oa,opacity:0,transition:`all ${ra} ease-out`,pointerEvents:"none"},[`&${Cn}-focused`]:{[`${Cn}-active-bar`]:{opacity:1}},[`${Cn}-range-separator`]:{alignItems:"center",padding:`0 ${Jo}px`,lineHeight:1},[`&${Cn}-small`]:{[`${Cn}-clear`]:{insetInlineEnd:qo},[`${Cn}-active-bar`]:{marginInlineStart:qo}}},"&-dropdown":_extends$1(_extends$1(_extends$1({},resetComponent($n)),genPanelStyle($n)),{position:"absolute",top:-9999,left:{_skip_check_:!0,value:-9999},zIndex:ea,[`&${Cn}-dropdown-hidden`]:{display:"none"},[`&${Cn}-dropdown-placement-bottomLeft`]:{[`${Cn}-range-arrow`]:{top:0,display:"block",transform:"translateY(-100%)"}},[`&${Cn}-dropdown-placement-topLeft`]:{[`${Cn}-range-arrow`]:{bottom:0,display:"block",transform:"translateY(100%) rotate(180deg)"}},[`&${_n}-slide-up-enter${_n}-slide-up-enter-active${Cn}-dropdown-placement-topLeft, - &${_n}-slide-up-enter${_n}-slide-up-enter-active${Cn}-dropdown-placement-topRight, - &${_n}-slide-up-appear${_n}-slide-up-appear-active${Cn}-dropdown-placement-topLeft, - &${_n}-slide-up-appear${_n}-slide-up-appear-active${Cn}-dropdown-placement-topRight`]:{animationName:slideDownIn},[`&${_n}-slide-up-enter${_n}-slide-up-enter-active${Cn}-dropdown-placement-bottomLeft, - &${_n}-slide-up-enter${_n}-slide-up-enter-active${Cn}-dropdown-placement-bottomRight, - &${_n}-slide-up-appear${_n}-slide-up-appear-active${Cn}-dropdown-placement-bottomLeft, - &${_n}-slide-up-appear${_n}-slide-up-appear-active${Cn}-dropdown-placement-bottomRight`]:{animationName:slideUpIn},[`&${_n}-slide-up-leave${_n}-slide-up-leave-active${Cn}-dropdown-placement-topLeft, - &${_n}-slide-up-leave${_n}-slide-up-leave-active${Cn}-dropdown-placement-topRight`]:{animationName:slideDownOut},[`&${_n}-slide-up-leave${_n}-slide-up-leave-active${Cn}-dropdown-placement-bottomLeft, - &${_n}-slide-up-leave${_n}-slide-up-leave-active${Cn}-dropdown-placement-bottomRight`]:{animationName:slideUpOut},[`${Cn}-panel > ${Cn}-time-panel`]:{paddingTop:la},[`${Cn}-ranges`]:{marginBottom:0,padding:`${la}px ${ua}px`,overflow:"hidden",lineHeight:`${ga-2*Ln-Jo/2}px`,textAlign:"start",listStyle:"none",display:"flex",justifyContent:"space-between","> li":{display:"inline-block"},[`${Cn}-preset > ${_n}-tag-blue`]:{color:oa,background:aa,borderColor:ca,cursor:"pointer"},[`${Cn}-ok`]:{marginInlineStart:"auto"}},[`${Cn}-range-wrapper`]:{display:"flex",position:"relative"},[`${Cn}-range-arrow`]:_extends$1({position:"absolute",zIndex:1,display:"none",marginInlineStart:Rn*1.5,transition:`left ${ra} ease-out`},roundedArrow(sa,ia,fa,ma,Pn)),[`${Cn}-panel-container`]:{overflow:"hidden",verticalAlign:"top",background:ma,borderRadius:ya,boxShadow:ba,transition:`margin ${ra}`,[`${Cn}-panel-layout`]:{display:"flex",flexWrap:"nowrap",alignItems:"stretch"},[`${Cn}-presets`]:{display:"flex",flexDirection:"column",minWidth:Ta,maxWidth:wa,ul:{height:0,flex:"auto",listStyle:"none",overflow:"auto",margin:0,padding:Jo,borderInlineEnd:`${Ln}px ${Fn} ${Ea}`,li:_extends$1(_extends$1({},textEllipsis),{borderRadius:Ia,paddingInline:Jo,paddingBlock:(Yo-Math.round(Nn*ta))/2,cursor:"pointer",transition:`all ${ra}`,"+ li":{marginTop:Zo},"&:hover":{background:xa}})}},[`${Cn}-panels`]:{display:"inline-flex",flexWrap:"nowrap",direction:"ltr",[`${Cn}-panel`]:{borderWidth:`0 0 ${Ln}px`},"&:last-child":{[`${Cn}-panel`]:{borderWidth:0}}},[`${Cn}-panel`]:{verticalAlign:"top",background:"transparent",borderRadius:0,borderWidth:0,[`${Cn}-content, - table`]:{textAlign:"center"},"&-focused":{borderColor:Bn}}}}),"&-dropdown-range":{padding:`${sa*2/3}px 0`,"&-hidden":{display:"none"}},"&-rtl":{direction:"rtl",[`${Cn}-separator`]:{transform:"rotate(180deg)"},[`${Cn}-footer`]:{"&-extra":{direction:"rtl"}}}})},initSlideMotion($n,"slide-up"),initSlideMotion($n,"slide-down"),initMoveMotion($n,"move-up"),initMoveMotion($n,"move-down")]},initPickerPanelToken=$n=>{const{componentCls:_n,controlHeightLG:Pn,controlHeightSM:In,colorPrimary:Nn,paddingXXS:Rn}=$n;return{pickerCellCls:`${_n}-cell`,pickerCellInnerCls:`${_n}-cell-inner`,pickerTextHeight:Pn,pickerPanelCellWidth:In*1.5,pickerPanelCellHeight:In,pickerDateHoverRangeBorderColor:new TinyColor(Nn).lighten(20).toHexString(),pickerBasicCellHoverWithRangeColor:new TinyColor(Nn).lighten(35).toHexString(),pickerPanelWithoutTimeCellHeight:Pn*1.65,pickerYearMonthCellWidth:Pn*1.5,pickerTimePanelColumnHeight:28*8,pickerTimePanelColumnWidth:Pn*1.4,pickerTimePanelCellHeight:28,pickerQuarterPanelContentHeight:Pn*1.4,pickerCellPaddingVertical:Rn,pickerCellBorderGap:2,pickerControlIconSize:7,pickerControlIconBorderWidth:1.5}},useStyle$J=genComponentStyleHook("DatePicker",$n=>{const Cn=merge$1(initInputToken($n),initPickerPanelToken($n));return[genPickerStyle(Cn),genPickerStatusStyle(Cn),genCompactItemStyle($n,{focusElCls:`${$n.componentCls}-focused`})]},$n=>({presetsWidth:120,presetsMaxWidth:200,zIndexPopup:$n.zIndexPopupBase+50})),genCalendarStyles=$n=>{const{calendarCls:Cn,componentCls:_n,calendarFullBg:Pn,calendarFullPanelBg:In,calendarItemActiveBg:Nn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1({},genPanelStyle($n)),resetComponent($n)),{background:Pn,"&-rtl":{direction:"rtl"},[`${Cn}-header`]:{display:"flex",justifyContent:"flex-end",padding:`${$n.paddingSM}px 0`,[`${Cn}-year-select`]:{minWidth:$n.yearControlWidth},[`${Cn}-month-select`]:{minWidth:$n.monthControlWidth,marginInlineStart:$n.marginXS},[`${Cn}-mode-switch`]:{marginInlineStart:$n.marginXS}}}),[`${Cn} ${_n}-panel`]:{background:In,border:0,borderTop:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,borderRadius:0,[`${_n}-month-panel, ${_n}-date-panel`]:{width:"auto"},[`${_n}-body`]:{padding:`${$n.paddingXS}px 0`},[`${_n}-content`]:{width:"100%"}},[`${Cn}-mini`]:{borderRadius:$n.borderRadiusLG,[`${Cn}-header`]:{paddingInlineEnd:$n.paddingXS,paddingInlineStart:$n.paddingXS},[`${_n}-panel`]:{borderRadius:`0 0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px`},[`${_n}-content`]:{height:$n.miniContentHeight,th:{height:"auto",padding:0,lineHeight:`${$n.weekHeight}px`}},[`${_n}-cell::before`]:{pointerEvents:"none"}},[`${Cn}${Cn}-full`]:{[`${_n}-panel`]:{display:"block",width:"100%",textAlign:"end",background:Pn,border:0,[`${_n}-body`]:{"th, td":{padding:0},th:{height:"auto",paddingInlineEnd:$n.paddingSM,paddingBottom:$n.paddingXXS,lineHeight:`${$n.weekHeight}px`}}},[`${_n}-cell`]:{"&::before":{display:"none"},"&:hover":{[`${Cn}-date`]:{background:$n.controlItemBgHover}},[`${Cn}-date-today::before`]:{display:"none"},[`&-in-view${_n}-cell-selected`]:{[`${Cn}-date, ${Cn}-date-today`]:{background:Nn}},"&-selected, &-selected:hover":{[`${Cn}-date, ${Cn}-date-today`]:{[`${Cn}-date-value`]:{color:$n.colorPrimary}}}},[`${Cn}-date`]:{display:"block",width:"auto",height:"auto",margin:`0 ${$n.marginXS/2}px`,padding:`${$n.paddingXS/2}px ${$n.paddingXS}px 0`,border:0,borderTop:`${$n.lineWidthBold}px ${$n.lineType} ${$n.colorSplit}`,borderRadius:0,transition:`background ${$n.motionDurationSlow}`,"&-value":{lineHeight:`${$n.dateValueHeight}px`,transition:`color ${$n.motionDurationSlow}`},"&-content":{position:"static",width:"auto",height:$n.dateContentHeight,overflowY:"auto",color:$n.colorText,lineHeight:$n.lineHeight,textAlign:"start"},"&-today":{borderColor:$n.colorPrimary,[`${Cn}-date-value`]:{color:$n.colorText}}}},[`@media only screen and (max-width: ${$n.screenXS}px) `]:{[`${Cn}`]:{[`${Cn}-header`]:{display:"block",[`${Cn}-year-select`]:{width:"50%"},[`${Cn}-month-select`]:{width:`calc(50% - ${$n.paddingXS}px)`},[`${Cn}-mode-switch`]:{width:"100%",marginTop:$n.marginXS,marginInlineStart:0,"> label":{width:"50%",textAlign:"center"}}}}}}},useStyle$I=genComponentStyleHook("Calendar",$n=>{const Cn=`${$n.componentCls}-calendar`,_n=merge$1(initInputToken($n),initPickerPanelToken($n),{calendarCls:Cn,pickerCellInnerCls:`${$n.componentCls}-cell-inner`,calendarFullBg:$n.colorBgContainer,calendarFullPanelBg:$n.colorBgContainer,calendarItemActiveBg:$n.controlItemBgActive,dateValueHeight:$n.controlHeightSM,weekHeight:$n.controlHeightSM*.75,dateContentHeight:($n.fontSizeSM*$n.lineHeightSM+$n.marginXS)*3+$n.lineWidth*2});return[genCalendarStyles(_n)]},{yearControlWidth:80,monthControlWidth:70,miniContentHeight:256});function generateCalendar($n){function Cn(Nn,Rn){return Nn&&Rn&&$n.getYear(Nn)===$n.getYear(Rn)}function _n(Nn,Rn){return Cn(Nn,Rn)&&$n.getMonth(Nn)===$n.getMonth(Rn)}function Pn(Nn,Rn){return _n(Nn,Rn)&&$n.getDate(Nn)===$n.getDate(Rn)}const In=defineComponent({name:"ACalendar",inheritAttrs:!1,props:{prefixCls:String,locale:{type:Object,default:void 0},validRange:{type:Array,default:void 0},disabledDate:{type:Function,default:void 0},dateFullCellRender:{type:Function,default:void 0},dateCellRender:{type:Function,default:void 0},monthFullCellRender:{type:Function,default:void 0},monthCellRender:{type:Function,default:void 0},headerRender:{type:Function,default:void 0},value:{type:[Object,String],default:void 0},defaultValue:{type:[Object,String],default:void 0},mode:{type:String,default:void 0},fullscreen:{type:Boolean,default:void 0},onChange:{type:Function,default:void 0},"onUpdate:value":{type:Function,default:void 0},onPanelChange:{type:Function,default:void 0},onSelect:{type:Function,default:void 0},valueFormat:{type:String,default:void 0}},slots:Object,setup(Nn,Rn){let{emit:Dn,slots:Ln,attrs:Fn}=Rn;const Bn=Nn,{prefixCls:Hn,direction:zn}=useConfigInject("picker",Bn),[Wn,Yn]=useStyle$I(Hn),Gn=computed(()=>`${Hn.value}-calendar`),Go=aa=>Bn.valueFormat?$n.toString(aa,Bn.valueFormat):aa,Xn=computed(()=>Bn.value?Bn.valueFormat?$n.toDate(Bn.value,Bn.valueFormat):Bn.value:Bn.value===""?void 0:Bn.value),Yo=computed(()=>Bn.defaultValue?Bn.valueFormat?$n.toDate(Bn.defaultValue,Bn.valueFormat):Bn.defaultValue:Bn.defaultValue===""?void 0:Bn.defaultValue),[qo,Jo]=useMergedState(()=>Xn.value||$n.getNow(),{defaultValue:Yo.value,value:Xn}),[Zo,rr]=useMergedState("month",{value:toRef(Bn,"mode")}),nr=computed(()=>Zo.value==="year"?"month":"date"),ta=computed(()=>aa=>{var ca;return(Bn.validRange?$n.isAfter(Bn.validRange[0],aa)||$n.isAfter(aa,Bn.validRange[1]):!1)||!!(!((ca=Bn.disabledDate)===null||ca===void 0)&&ca.call(Bn,aa))}),oa=(aa,ca)=>{Dn("panelChange",Go(aa),ca)},ra=aa=>{if(Jo(aa),!Pn(aa,qo.value)){(nr.value==="date"&&!_n(aa,qo.value)||nr.value==="month"&&!Cn(aa,qo.value))&&oa(aa,Zo.value);const ca=Go(aa);Dn("update:value",ca),Dn("change",ca)}},ea=aa=>{rr(aa),oa(qo.value,aa)},la=(aa,ca)=>{ra(aa),Dn("select",Go(aa),{source:ca})},ua=computed(()=>{const{locale:aa}=Bn,ca=_extends$1(_extends$1({},enUS),aa);return ca.lang=_extends$1(_extends$1({},ca.lang),(aa||{}).lang),ca}),[ga]=useLocaleReceiver("Calendar",ua);return()=>{const aa=$n.getNow(),{dateFullCellRender:ca=Ln==null?void 0:Ln.dateFullCellRender,dateCellRender:sa=Ln==null?void 0:Ln.dateCellRender,monthFullCellRender:ia=Ln==null?void 0:Ln.monthFullCellRender,monthCellRender:fa=Ln==null?void 0:Ln.monthCellRender,headerRender:ma=Ln==null?void 0:Ln.headerRender,fullscreen:ya=!0,validRange:ba}=Bn,Ia=xa=>{let{current:Ta}=xa;return ca?ca({current:Ta}):createVNode("div",{class:classNames(`${Hn.value}-cell-inner`,`${Gn.value}-date`,{[`${Gn.value}-date-today`]:Pn(aa,Ta)})},[createVNode("div",{class:`${Gn.value}-date-value`},[String($n.getDate(Ta)).padStart(2,"0")]),createVNode("div",{class:`${Gn.value}-date-content`},[sa&&sa({current:Ta})])])},Ea=(xa,Ta)=>{let{current:wa}=xa;if(ia)return ia({current:wa});const La=Ta.shortMonths||$n.locale.getShortMonths(Ta.locale);return createVNode("div",{class:classNames(`${Hn.value}-cell-inner`,`${Gn.value}-date`,{[`${Gn.value}-date-today`]:_n(aa,wa)})},[createVNode("div",{class:`${Gn.value}-date-value`},[La[$n.getMonth(wa)]]),createVNode("div",{class:`${Gn.value}-date-content`},[fa&&fa({current:wa})])])};return Wn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Fn),{},{class:classNames(Gn.value,{[`${Gn.value}-full`]:ya,[`${Gn.value}-mini`]:!ya,[`${Gn.value}-rtl`]:zn.value==="rtl"},Fn.class,Yn.value)}),[ma?ma({value:qo.value,type:Zo.value,onChange:xa=>{la(xa,"customize")},onTypeChange:ea}):createVNode(CalendarHeader,{prefixCls:Gn.value,value:qo.value,generateConfig:$n,mode:Zo.value,fullscreen:ya,locale:ga.value.lang,validRange:ba,onChange:la,onModeChange:ea},null),createVNode(PickerPanel$1,{value:qo.value,prefixCls:Hn.value,locale:ga.value.lang,generateConfig:$n,dateRender:Ia,monthCellRender:xa=>Ea(xa,ga.value.lang),onSelect:xa=>{la(xa,nr.value)},mode:nr.value,picker:nr.value,disabledDate:ta.value,hideHeader:!0},null)]))}}});return In.install=function(Nn){return Nn.component(In.name,In),Nn},In}const Calendar=generateCalendar(dayjsGenerateConfig),Calendar$1=withInstall(Calendar);function useRaf($n){const Cn=shallowRef(),_n=shallowRef(!1);function Pn(){for(var In=arguments.length,Nn=new Array(In),Rn=0;Rn{$n(...Nn)}))}return onBeforeUnmount(()=>{_n.value=!0,wrapperRaf.cancel(Cn.value)}),Pn}function useRafState($n){const Cn=shallowRef([]),_n=shallowRef(typeof $n=="function"?$n():$n),Pn=useRaf(()=>{let Nn=_n.value;Cn.value.forEach(Rn=>{Nn=Rn(Nn)}),Cn.value=[],_n.value=Nn});function In(Nn){Cn.value.push(Nn),Pn()}return[_n,In]}const TabNode=defineComponent({compatConfig:{MODE:3},name:"TabNode",props:{id:{type:String},prefixCls:{type:String},tab:{type:Object},active:{type:Boolean},closable:{type:Boolean},editable:{type:Object},onClick:{type:Function},onResize:{type:Function},renderWrapper:{type:Function},removeAriaLabel:{type:String},onFocus:{type:Function}},emits:["click","resize","remove","focus"],setup($n,Cn){let{expose:_n,attrs:Pn}=Cn;const In=ref();function Nn(Ln){var Fn;!((Fn=$n.tab)===null||Fn===void 0)&&Fn.disabled||$n.onClick(Ln)}_n({domRef:In});function Rn(Ln){var Fn;Ln.preventDefault(),Ln.stopPropagation(),$n.editable.onEdit("remove",{key:(Fn=$n.tab)===null||Fn===void 0?void 0:Fn.key,event:Ln})}const Dn=computed(()=>{var Ln;return $n.editable&&$n.closable!==!1&&!(!((Ln=$n.tab)===null||Ln===void 0)&&Ln.disabled)});return()=>{var Ln;const{prefixCls:Fn,id:Bn,active:Hn,tab:{key:zn,tab:Wn,disabled:Yn,closeIcon:Gn},renderWrapper:Go,removeAriaLabel:Xn,editable:Yo,onFocus:qo}=$n,Jo=`${Fn}-tab`,Zo=createVNode("div",{key:zn,ref:In,class:classNames(Jo,{[`${Jo}-with-remove`]:Dn.value,[`${Jo}-active`]:Hn,[`${Jo}-disabled`]:Yn}),style:Pn.style,onClick:Nn},[createVNode("div",{role:"tab","aria-selected":Hn,id:Bn&&`${Bn}-tab-${zn}`,class:`${Jo}-btn`,"aria-controls":Bn&&`${Bn}-panel-${zn}`,"aria-disabled":Yn,tabindex:Yn?null:0,onClick:rr=>{rr.stopPropagation(),Nn(rr)},onKeydown:rr=>{[KeyCode$1.SPACE,KeyCode$1.ENTER].includes(rr.which)&&(rr.preventDefault(),Nn(rr))},onFocus:qo},[typeof Wn=="function"?Wn():Wn]),Dn.value&&createVNode("button",{type:"button","aria-label":Xn||"remove",tabindex:0,class:`${Jo}-remove`,onClick:rr=>{rr.stopPropagation(),Rn(rr)}},[(Gn==null?void 0:Gn())||((Ln=Yo.removeIcon)===null||Ln===void 0?void 0:Ln.call(Yo))||"×"])]);return Go?Go(Zo):Zo}}}),DEFAULT_SIZE$2={width:0,height:0,left:0,top:0};function useOffsets($n,Cn){const _n=ref(new Map);return watchEffect(()=>{var Pn,In;const Nn=new Map,Rn=$n.value,Dn=Cn.value.get((Pn=Rn[0])===null||Pn===void 0?void 0:Pn.key)||DEFAULT_SIZE$2,Ln=Dn.left+Dn.width;for(let Fn=0;Fn{const{prefixCls:Nn,editable:Rn,locale:Dn}=$n;return!Rn||Rn.showAdd===!1?null:createVNode("button",{ref:In,type:"button",class:`${Nn}-nav-add`,style:Pn.style,"aria-label":(Dn==null?void 0:Dn.addAriaLabel)||"Add tab",onClick:Ln=>{Rn.onEdit("add",{event:Ln})}},[Rn.addIcon?Rn.addIcon():"+"])}}}),operationNodeProps={prefixCls:{type:String},id:{type:String},tabs:{type:Object},rtl:{type:Boolean},tabBarGutter:{type:Number},activeKey:{type:[String,Number]},mobile:{type:Boolean},moreIcon:PropTypes.any,moreTransitionName:{type:String},editable:{type:Object},locale:{type:Object,default:void 0},removeAriaLabel:String,onTabClick:{type:Function},popupClassName:String,getPopupContainer:functionType()},OperationNode=defineComponent({compatConfig:{MODE:3},name:"OperationNode",inheritAttrs:!1,props:operationNodeProps,emits:["tabClick"],slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const[In,Nn]=useState(!1),[Rn,Dn]=useState(null),Ln=Wn=>{const Yn=$n.tabs.filter(Xn=>!Xn.disabled);let Gn=Yn.findIndex(Xn=>Xn.key===Rn.value)||0;const Go=Yn.length;for(let Xn=0;Xn{const{which:Yn}=Wn;if(!In.value){[KeyCode$1.DOWN,KeyCode$1.SPACE,KeyCode$1.ENTER].includes(Yn)&&(Nn(!0),Wn.preventDefault());return}switch(Yn){case KeyCode$1.UP:Ln(-1),Wn.preventDefault();break;case KeyCode$1.DOWN:Ln(1),Wn.preventDefault();break;case KeyCode$1.ESC:Nn(!1);break;case KeyCode$1.SPACE:case KeyCode$1.ENTER:Rn.value!==null&&$n.onTabClick(Rn.value,Wn);break}},Bn=computed(()=>`${$n.id}-more-popup`),Hn=computed(()=>Rn.value!==null?`${Bn.value}-${Rn.value}`:null),zn=(Wn,Yn)=>{Wn.preventDefault(),Wn.stopPropagation(),$n.editable.onEdit("remove",{key:Yn,event:Wn})};return onMounted(()=>{watch(Rn,()=>{const Wn=document.getElementById(Hn.value);Wn&&Wn.scrollIntoView&&Wn.scrollIntoView(!1)},{flush:"post",immediate:!0})}),watch(In,()=>{In.value||Dn(null)}),useProvideOverride({}),()=>{var Wn;const{prefixCls:Yn,id:Gn,tabs:Go,locale:Xn,mobile:Yo,moreIcon:qo=((Wn=Pn.moreIcon)===null||Wn===void 0?void 0:Wn.call(Pn))||createVNode(EllipsisOutlined$1,null,null),moreTransitionName:Jo,editable:Zo,tabBarGutter:rr,rtl:nr,onTabClick:ta,popupClassName:oa}=$n;if(!Go.length)return null;const ra=`${Yn}-dropdown`,ea=Xn==null?void 0:Xn.dropdownAriaLabel,la={[nr?"marginRight":"marginLeft"]:rr};Go.length||(la.visibility="hidden",la.order=1);const ua=classNames({[`${ra}-rtl`]:nr,[`${oa}`]:!0}),ga=Yo?null:createVNode(Dropdown$2,{prefixCls:ra,trigger:["hover"],visible:In.value,transitionName:Jo,onVisibleChange:Nn,overlayClassName:ua,mouseEnterDelay:.1,mouseLeaveDelay:.1,getPopupContainer:$n.getPopupContainer},{overlay:()=>createVNode(Menu,{onClick:aa=>{let{key:ca,domEvent:sa}=aa;ta(ca,sa),Nn(!1)},id:Bn.value,tabindex:-1,role:"listbox","aria-activedescendant":Hn.value,selectedKeys:[Rn.value],"aria-label":ea!==void 0?ea:"expanded dropdown"},{default:()=>[Go.map(aa=>{var ca,sa;const ia=Zo&&aa.closable!==!1&&!aa.disabled;return createVNode(MenuItem$1,{key:aa.key,id:`${Bn.value}-${aa.key}`,role:"option","aria-controls":Gn&&`${Gn}-panel-${aa.key}`,disabled:aa.disabled},{default:()=>[createVNode("span",null,[typeof aa.tab=="function"?aa.tab():aa.tab]),ia&&createVNode("button",{type:"button","aria-label":$n.removeAriaLabel||"remove",tabindex:0,class:`${ra}-menu-item-remove`,onClick:fa=>{fa.stopPropagation(),zn(fa,aa.key)}},[((ca=aa.closeIcon)===null||ca===void 0?void 0:ca.call(aa))||((sa=Zo.removeIcon)===null||sa===void 0?void 0:sa.call(Zo))||"×"])]})})]}),default:()=>createVNode("button",{type:"button",class:`${Yn}-nav-more`,style:la,tabindex:-1,"aria-hidden":"true","aria-haspopup":"listbox","aria-controls":Bn.value,id:`${Gn}-more`,"aria-expanded":In.value,onKeydown:Fn},[qo])});return createVNode("div",{class:classNames(`${Yn}-nav-operations`,_n.class),style:_n.style},[ga,createVNode(AddButton,{prefixCls:Yn,locale:Xn,editable:Zo},null)])}}}),TabsContextKey=Symbol("tabsContextKey"),useProvideTabs=$n=>{provide(TabsContextKey,$n)},useInjectTabs=()=>inject(TabsContextKey,{tabs:ref([]),prefixCls:ref()}),MIN_SWIPE_DISTANCE=.1,STOP_SWIPE_DISTANCE=.01,REFRESH_INTERVAL$1=20,SPEED_OFF_MULTIPLE=Math.pow(.995,REFRESH_INTERVAL$1);function useTouchMove($n,Cn){const[_n,Pn]=useState(),[In,Nn]=useState(0),[Rn,Dn]=useState(0),[Ln,Fn]=useState(),Bn=ref();function Hn(Zo){const{screenX:rr,screenY:nr}=Zo.touches[0];Pn({x:rr,y:nr}),clearInterval(Bn.value)}function zn(Zo){if(!_n.value)return;Zo.preventDefault();const{screenX:rr,screenY:nr}=Zo.touches[0],ta=rr-_n.value.x,oa=nr-_n.value.y;Cn(ta,oa),Pn({x:rr,y:nr});const ra=Date.now();Dn(ra-In.value),Nn(ra),Fn({x:ta,y:oa})}function Wn(){if(!_n.value)return;const Zo=Ln.value;if(Pn(null),Fn(null),Zo){const rr=Zo.x/Rn.value,nr=Zo.y/Rn.value,ta=Math.abs(rr),oa=Math.abs(nr);if(Math.max(ta,oa){if(Math.abs(ra)ra?(ta=rr,Yn.value="x"):(ta=nr,Yn.value="y"),Cn(-ta,-ta)&&Zo.preventDefault()}const Go=ref({onTouchStart:Hn,onTouchMove:zn,onTouchEnd:Wn,onWheel:Gn});function Xn(Zo){Go.value.onTouchStart(Zo)}function Yo(Zo){Go.value.onTouchMove(Zo)}function qo(Zo){Go.value.onTouchEnd(Zo)}function Jo(Zo){Go.value.onWheel(Zo)}onMounted(()=>{var Zo,rr;document.addEventListener("touchmove",Yo,{passive:!1}),document.addEventListener("touchend",qo,{passive:!1}),(Zo=$n.value)===null||Zo===void 0||Zo.addEventListener("touchstart",Xn,{passive:!1}),(rr=$n.value)===null||rr===void 0||rr.addEventListener("wheel",Jo,{passive:!1})}),onBeforeUnmount(()=>{document.removeEventListener("touchmove",Yo),document.removeEventListener("touchend",qo)})}function useSyncState($n,Cn){const _n=ref($n);function Pn(In){const Nn=typeof In=="function"?In(_n.value):In;Nn!==_n.value&&Cn(Nn,_n.value),_n.value=Nn}return[_n,Pn]}const useRefs=()=>{const $n=ref(new Map),Cn=_n=>Pn=>{$n.value.set(_n,Pn)};return onBeforeUpdate(()=>{$n.value=new Map}),[Cn,$n]},DEFAULT_SIZE$1={width:0,height:0,left:0,top:0,right:0},tabNavListProps=()=>({id:{type:String},tabPosition:{type:String},activeKey:{type:[String,Number]},rtl:{type:Boolean},animated:objectType(),editable:objectType(),moreIcon:PropTypes.any,moreTransitionName:{type:String},mobile:{type:Boolean},tabBarGutter:{type:Number},renderTabBar:{type:Function},locale:objectType(),popupClassName:String,getPopupContainer:functionType(),onTabClick:{type:Function},onTabScroll:{type:Function}}),TabNavList=defineComponent({compatConfig:{MODE:3},name:"TabNavList",inheritAttrs:!1,props:tabNavListProps(),slots:Object,emits:["tabClick","tabScroll"],setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{tabs:In,prefixCls:Nn}=useInjectTabs(),Rn=shallowRef(),Dn=shallowRef(),Ln=shallowRef(),Fn=shallowRef(),[Bn,Hn]=useRefs(),zn=computed(()=>$n.tabPosition==="top"||$n.tabPosition==="bottom"),[Wn,Yn]=useSyncState(0,(Ra,Fa)=>{zn.value&&$n.onTabScroll&&$n.onTabScroll({direction:Ra>Fa?"left":"right"})}),[Gn,Go]=useSyncState(0,(Ra,Fa)=>{!zn.value&&$n.onTabScroll&&$n.onTabScroll({direction:Ra>Fa?"top":"bottom"})}),[Xn,Yo]=useState(0),[qo,Jo]=useState(0),[Zo,rr]=useState(null),[nr,ta]=useState(null),[oa,ra]=useState(0),[ea,la]=useState(0),[ua,ga]=useRafState(new Map),aa=useOffsets(In,ua),ca=computed(()=>`${Nn.value}-nav-operations-hidden`),sa=shallowRef(0),ia=shallowRef(0);watchEffect(()=>{zn.value?$n.rtl?(sa.value=0,ia.value=Math.max(0,Xn.value-Zo.value)):(sa.value=Math.min(0,Zo.value-Xn.value),ia.value=0):(sa.value=Math.min(0,nr.value-qo.value),ia.value=0)});const fa=Ra=>Raia.value?ia.value:Ra,ma=shallowRef(),[ya,ba]=useState(),Ia=()=>{ba(Date.now())},Ea=()=>{clearTimeout(ma.value)},xa=(Ra,Fa)=>{Ra(za=>fa(za+Fa))};useTouchMove(Rn,(Ra,Fa)=>{if(zn.value){if(Zo.value>=Xn.value)return!1;xa(Yn,Ra)}else{if(nr.value>=qo.value)return!1;xa(Go,Fa)}return Ea(),Ia(),!0}),watch(ya,()=>{Ea(),ya.value&&(ma.value=setTimeout(()=>{ba(0)},100))});const Ta=function(){let Ra=arguments.length>0&&arguments[0]!==void 0?arguments[0]:$n.activeKey;const Fa=aa.value.get(Ra)||{width:0,height:0,left:0,right:0,top:0};if(zn.value){let za=Wn.value;$n.rtl?Fa.rightWn.value+Zo.value&&(za=Fa.right+Fa.width-Zo.value):Fa.left<-Wn.value?za=-Fa.left:Fa.left+Fa.width>-Wn.value+Zo.value&&(za=-(Fa.left+Fa.width-Zo.value)),Go(0),Yn(fa(za))}else{let za=Gn.value;Fa.top<-Gn.value?za=-Fa.top:Fa.top+Fa.height>-Gn.value+nr.value&&(za=-(Fa.top+Fa.height-nr.value)),Yn(0),Go(fa(za))}},wa=shallowRef(0),La=shallowRef(0);watchEffect(()=>{let Ra,Fa,za,Wa,Ya,ja;const qa=aa.value;["top","bottom"].includes($n.tabPosition)?(Ra="width",Wa=Zo.value,Ya=Xn.value,ja=oa.value,Fa=$n.rtl?"right":"left",za=Math.abs(Wn.value)):(Ra="height",Wa=nr.value,Ya=Xn.value,ja=ea.value,Fa="top",za=-Gn.value);let Xa=Wa;Ya+ja>Wa&&Yaza+Xa){Ua=ri-1;break}}let Qa=0;for(let ri=Ma-1;ri>=0;ri-=1)if((qa.get(Oa[ri].key)||DEFAULT_SIZE$1)[Fa]{var Ra,Fa,za,Wa,Ya;const ja=((Ra=Rn.value)===null||Ra===void 0?void 0:Ra.offsetWidth)||0,qa=((Fa=Rn.value)===null||Fa===void 0?void 0:Fa.offsetHeight)||0,Xa=((za=Fn.value)===null||za===void 0?void 0:za.$el)||{},Oa=Xa.offsetWidth||0,Ma=Xa.offsetHeight||0;rr(ja),ta(qa),ra(Oa),la(Ma);const Ua=(((Wa=Dn.value)===null||Wa===void 0?void 0:Wa.offsetWidth)||0)-Oa,Qa=(((Ya=Dn.value)===null||Ya===void 0?void 0:Ya.offsetHeight)||0)-Ma;Yo(Ua),Jo(Qa),ga(()=>{const ri=new Map;return In.value.forEach(fi=>{let{key:ei}=fi;const ti=Hn.value.get(ei),ni=(ti==null?void 0:ti.$el)||ti;ni&&ri.set(ei,{width:ni.offsetWidth,height:ni.offsetHeight,left:ni.offsetLeft,top:ni.offsetTop})}),ri})},$a=computed(()=>[...In.value.slice(0,wa.value),...In.value.slice(La.value+1)]),[ka,Ha]=useState(),da=computed(()=>aa.value.get($n.activeKey)),pa=shallowRef(),Sa=()=>{wrapperRaf.cancel(pa.value)};watch([da,zn,()=>$n.rtl],()=>{const Ra={};da.value&&(zn.value?($n.rtl?Ra.right=toPx(da.value.right):Ra.left=toPx(da.value.left),Ra.width=toPx(da.value.width)):(Ra.top=toPx(da.value.top),Ra.height=toPx(da.value.height))),Sa(),pa.value=wrapperRaf(()=>{Ha(Ra)})}),watch([()=>$n.activeKey,da,aa,zn],()=>{Ta()},{flush:"post"}),watch([()=>$n.rtl,()=>$n.tabBarGutter,()=>$n.activeKey,()=>In.value],()=>{Na()},{flush:"post"});const Aa=Ra=>{let{position:Fa,prefixCls:za,extra:Wa}=Ra;if(!Wa)return null;const Ya=Wa==null?void 0:Wa({position:Fa});return Ya?createVNode("div",{class:`${za}-extra-content`},[Ya]):null};return onBeforeUnmount(()=>{Ea(),Sa()}),()=>{const{id:Ra,animated:Fa,activeKey:za,rtl:Wa,editable:Ya,locale:ja,tabPosition:qa,tabBarGutter:Xa,onTabClick:Oa}=$n,{class:Ma,style:Ua}=_n,Qa=Nn.value,ri=!!$a.value.length,fi=`${Qa}-nav-wrap`;let ei,ti,ni,ui;zn.value?Wa?(ti=Wn.value>0,ei=Wn.value+Zo.value{const{key:Ti}=gi;return createVNode(TabNode,{id:Ra,prefixCls:Qa,key:Ti,tab:gi,style:wi===0?void 0:mi,closable:gi.closable,editable:Ya,active:Ti===za,removeAriaLabel:ja==null?void 0:ja.removeAriaLabel,ref:Bn(Ti),onClick:Ei=>{Oa(Ti,Ei)},onFocus:()=>{Ta(Ti),Ia(),Rn.value&&(Wa||(Rn.value.scrollLeft=0),Rn.value.scrollTop=0)}},Pn)});return createVNode("div",{role:"tablist",class:classNames(`${Qa}-nav`,Ma),style:Ua,onKeydown:()=>{Ia()}},[createVNode(Aa,{position:"left",prefixCls:Qa,extra:Pn.leftExtra},null),createVNode(ResizeObserver$1,{onResize:Na},{default:()=>[createVNode("div",{class:classNames(fi,{[`${fi}-ping-left`]:ei,[`${fi}-ping-right`]:ti,[`${fi}-ping-top`]:ni,[`${fi}-ping-bottom`]:ui}),ref:Rn},[createVNode(ResizeObserver$1,{onResize:Na},{default:()=>[createVNode("div",{ref:Dn,class:`${Qa}-nav-list`,style:{transform:`translate(${Wn.value}px, ${Gn.value}px)`,transition:ya.value?"none":void 0}},[di,createVNode(AddButton,{ref:Fn,prefixCls:Qa,locale:ja,editable:Ya,style:_extends$1(_extends$1({},di.length===0?void 0:mi),{visibility:ri?"hidden":null})},null),createVNode("div",{class:classNames(`${Qa}-ink-bar`,{[`${Qa}-ink-bar-animated`]:Fa.inkBar}),style:ka.value},null)])]})])]}),createVNode(OperationNode,_objectSpread2$1(_objectSpread2$1({},$n),{},{removeAriaLabel:ja==null?void 0:ja.removeAriaLabel,ref:Ln,prefixCls:Qa,tabs:$a.value,class:!ri&&ca.value}),pick(Pn,["moreIcon"])),createVNode(Aa,{position:"right",prefixCls:Qa,extra:Pn.rightExtra},null),createVNode(Aa,{position:"right",prefixCls:Qa,extra:Pn.tabBarExtraContent},null)])}}}),TabPanelList=defineComponent({compatConfig:{MODE:3},name:"TabPanelList",inheritAttrs:!1,props:{activeKey:{type:[String,Number]},id:{type:String},rtl:{type:Boolean},animated:{type:Object,default:void 0},tabPosition:{type:String},destroyInactiveTabPane:{type:Boolean}},setup($n){const{tabs:Cn,prefixCls:_n}=useInjectTabs();return()=>{const{id:Pn,activeKey:In,animated:Nn,tabPosition:Rn,rtl:Dn,destroyInactiveTabPane:Ln}=$n,Fn=Nn.tabPane,Bn=_n.value,Hn=Cn.value.findIndex(zn=>zn.key===In);return createVNode("div",{class:`${Bn}-content-holder`},[createVNode("div",{class:[`${Bn}-content`,`${Bn}-content-${Rn}`,{[`${Bn}-content-animated`]:Fn}],style:Hn&&Fn?{[Dn?"marginRight":"marginLeft"]:`-${Hn}00%`}:null},[Cn.value.map(zn=>cloneElement(zn.node,{key:zn.key,prefixCls:Bn,tabKey:zn.key,id:Pn,animated:Fn,active:zn.key===In,destroyInactiveTabPane:Ln}))])])}}});var PlusOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};const PlusOutlinedSvg=PlusOutlined$2;function _objectSpread$E($n){for(var Cn=1;Cn{const{componentCls:Cn,motionDurationSlow:_n}=$n;return[{[Cn]:{[`${Cn}-switch`]:{"&-appear, &-enter":{transition:"none","&-start":{opacity:0},"&-active":{opacity:1,transition:`opacity ${_n}`}},"&-leave":{position:"absolute",transition:"none",inset:0,"&-start":{opacity:1},"&-active":{opacity:0,transition:`opacity ${_n}`}}}}},[initSlideMotion($n,"slide-up"),initSlideMotion($n,"slide-down")]]},genMotionStyle$5=genMotionStyle$4,genCardStyle$1=$n=>{const{componentCls:Cn,tabsCardHorizontalPadding:_n,tabsCardHeadBackground:Pn,tabsCardGutter:In,colorSplit:Nn}=$n;return{[`${Cn}-card`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab`]:{margin:0,padding:_n,background:Pn,border:`${$n.lineWidth}px ${$n.lineType} ${Nn}`,transition:`all ${$n.motionDurationSlow} ${$n.motionEaseInOut}`},[`${Cn}-tab-active`]:{color:$n.colorPrimary,background:$n.colorBgContainer},[`${Cn}-ink-bar`]:{visibility:"hidden"}},[`&${Cn}-top, &${Cn}-bottom`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab + ${Cn}-tab`]:{marginLeft:{_skip_check_:!0,value:`${In}px`}}}},[`&${Cn}-top`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab`]:{borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`},[`${Cn}-tab-active`]:{borderBottomColor:$n.colorBgContainer}}},[`&${Cn}-bottom`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab`]:{borderRadius:`0 0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px`},[`${Cn}-tab-active`]:{borderTopColor:$n.colorBgContainer}}},[`&${Cn}-left, &${Cn}-right`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab + ${Cn}-tab`]:{marginTop:`${In}px`}}},[`&${Cn}-left`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab`]:{borderRadius:{_skip_check_:!0,value:`${$n.borderRadiusLG}px 0 0 ${$n.borderRadiusLG}px`}},[`${Cn}-tab-active`]:{borderRightColor:{_skip_check_:!0,value:$n.colorBgContainer}}}},[`&${Cn}-right`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab`]:{borderRadius:{_skip_check_:!0,value:`0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0`}},[`${Cn}-tab-active`]:{borderLeftColor:{_skip_check_:!0,value:$n.colorBgContainer}}}}}}},genDropdownStyle=$n=>{const{componentCls:Cn,tabsHoverColor:_n,dropdownEdgeChildVerticalPadding:Pn}=$n;return{[`${Cn}-dropdown`]:_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:-9999,left:{_skip_check_:!0,value:-9999},zIndex:$n.zIndexPopup,display:"block","&-hidden":{display:"none"},[`${Cn}-dropdown-menu`]:{maxHeight:$n.tabsDropdownHeight,margin:0,padding:`${Pn}px 0`,overflowX:"hidden",overflowY:"auto",textAlign:{_skip_check_:!0,value:"left"},listStyleType:"none",backgroundColor:$n.colorBgContainer,backgroundClip:"padding-box",borderRadius:$n.borderRadiusLG,outline:"none",boxShadow:$n.boxShadowSecondary,"&-item":_extends$1(_extends$1({},textEllipsis),{display:"flex",alignItems:"center",minWidth:$n.tabsDropdownWidth,margin:0,padding:`${$n.paddingXXS}px ${$n.paddingSM}px`,color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize,lineHeight:$n.lineHeight,cursor:"pointer",transition:`all ${$n.motionDurationSlow}`,"> span":{flex:1,whiteSpace:"nowrap"},"&-remove":{flex:"none",marginLeft:{_skip_check_:!0,value:$n.marginSM},color:$n.colorTextDescription,fontSize:$n.fontSizeSM,background:"transparent",border:0,cursor:"pointer","&:hover":{color:_n}},"&:hover":{background:$n.controlItemBgHover},"&-disabled":{"&, &:hover":{color:$n.colorTextDisabled,background:"transparent",cursor:"not-allowed"}}})}})}},genPositionStyle=$n=>{const{componentCls:Cn,margin:_n,colorSplit:Pn}=$n;return{[`${Cn}-top, ${Cn}-bottom`]:{flexDirection:"column",[`> ${Cn}-nav, > div > ${Cn}-nav`]:{margin:`0 0 ${_n}px 0`,"&::before":{position:"absolute",right:{_skip_check_:!0,value:0},left:{_skip_check_:!0,value:0},borderBottom:`${$n.lineWidth}px ${$n.lineType} ${Pn}`,content:"''"},[`${Cn}-ink-bar`]:{height:$n.lineWidthBold,"&-animated":{transition:`width ${$n.motionDurationSlow}, left ${$n.motionDurationSlow}, - right ${$n.motionDurationSlow}`}},[`${Cn}-nav-wrap`]:{"&::before, &::after":{top:0,bottom:0,width:$n.controlHeight},"&::before":{left:{_skip_check_:!0,value:0},boxShadow:$n.boxShadowTabsOverflowLeft},"&::after":{right:{_skip_check_:!0,value:0},boxShadow:$n.boxShadowTabsOverflowRight},[`&${Cn}-nav-wrap-ping-left::before`]:{opacity:1},[`&${Cn}-nav-wrap-ping-right::after`]:{opacity:1}}}},[`${Cn}-top`]:{[`> ${Cn}-nav, - > div > ${Cn}-nav`]:{"&::before":{bottom:0},[`${Cn}-ink-bar`]:{bottom:0}}},[`${Cn}-bottom`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{order:1,marginTop:`${_n}px`,marginBottom:0,"&::before":{top:0},[`${Cn}-ink-bar`]:{top:0}},[`> ${Cn}-content-holder, > div > ${Cn}-content-holder`]:{order:0}},[`${Cn}-left, ${Cn}-right`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{flexDirection:"column",minWidth:$n.controlHeight*1.25,[`${Cn}-tab`]:{padding:`${$n.paddingXS}px ${$n.paddingLG}px`,textAlign:"center"},[`${Cn}-tab + ${Cn}-tab`]:{margin:`${$n.margin}px 0 0 0`},[`${Cn}-nav-wrap`]:{flexDirection:"column","&::before, &::after":{right:{_skip_check_:!0,value:0},left:{_skip_check_:!0,value:0},height:$n.controlHeight},"&::before":{top:0,boxShadow:$n.boxShadowTabsOverflowTop},"&::after":{bottom:0,boxShadow:$n.boxShadowTabsOverflowBottom},[`&${Cn}-nav-wrap-ping-top::before`]:{opacity:1},[`&${Cn}-nav-wrap-ping-bottom::after`]:{opacity:1}},[`${Cn}-ink-bar`]:{width:$n.lineWidthBold,"&-animated":{transition:`height ${$n.motionDurationSlow}, top ${$n.motionDurationSlow}`}},[`${Cn}-nav-list, ${Cn}-nav-operations`]:{flex:"1 0 auto",flexDirection:"column"}}},[`${Cn}-left`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-ink-bar`]:{right:{_skip_check_:!0,value:0}}},[`> ${Cn}-content-holder, > div > ${Cn}-content-holder`]:{marginLeft:{_skip_check_:!0,value:`-${$n.lineWidth}px`},borderLeft:{_skip_check_:!0,value:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`},[`> ${Cn}-content > ${Cn}-tabpane`]:{paddingLeft:{_skip_check_:!0,value:$n.paddingLG}}}},[`${Cn}-right`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{order:1,[`${Cn}-ink-bar`]:{left:{_skip_check_:!0,value:0}}},[`> ${Cn}-content-holder, > div > ${Cn}-content-holder`]:{order:0,marginRight:{_skip_check_:!0,value:-$n.lineWidth},borderRight:{_skip_check_:!0,value:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`},[`> ${Cn}-content > ${Cn}-tabpane`]:{paddingRight:{_skip_check_:!0,value:$n.paddingLG}}}}}},genSizeStyle$2=$n=>{const{componentCls:Cn,padding:_n}=$n;return{[Cn]:{"&-small":{[`> ${Cn}-nav`]:{[`${Cn}-tab`]:{padding:`${$n.paddingXS}px 0`,fontSize:$n.fontSize}}},"&-large":{[`> ${Cn}-nav`]:{[`${Cn}-tab`]:{padding:`${_n}px 0`,fontSize:$n.fontSizeLG}}}},[`${Cn}-card`]:{[`&${Cn}-small`]:{[`> ${Cn}-nav`]:{[`${Cn}-tab`]:{padding:`${$n.paddingXXS*1.5}px ${_n}px`}},[`&${Cn}-bottom`]:{[`> ${Cn}-nav ${Cn}-tab`]:{borderRadius:`0 0 ${$n.borderRadius}px ${$n.borderRadius}px`}},[`&${Cn}-top`]:{[`> ${Cn}-nav ${Cn}-tab`]:{borderRadius:`${$n.borderRadius}px ${$n.borderRadius}px 0 0`}},[`&${Cn}-right`]:{[`> ${Cn}-nav ${Cn}-tab`]:{borderRadius:{_skip_check_:!0,value:`0 ${$n.borderRadius}px ${$n.borderRadius}px 0`}}},[`&${Cn}-left`]:{[`> ${Cn}-nav ${Cn}-tab`]:{borderRadius:{_skip_check_:!0,value:`${$n.borderRadius}px 0 0 ${$n.borderRadius}px`}}}},[`&${Cn}-large`]:{[`> ${Cn}-nav`]:{[`${Cn}-tab`]:{padding:`${$n.paddingXS}px ${_n}px ${$n.paddingXXS*1.5}px`}}}}}},genTabStyle=$n=>{const{componentCls:Cn,tabsActiveColor:_n,tabsHoverColor:Pn,iconCls:In,tabsHorizontalGutter:Nn}=$n,Rn=`${Cn}-tab`;return{[Rn]:{position:"relative",display:"inline-flex",alignItems:"center",padding:`${$n.paddingSM}px 0`,fontSize:`${$n.fontSize}px`,background:"transparent",border:0,outline:"none",cursor:"pointer","&-btn, &-remove":_extends$1({"&:focus:not(:focus-visible), &:active":{color:_n}},genFocusStyle($n)),"&-btn":{outline:"none",transition:"all 0.3s"},"&-remove":{flex:"none",marginRight:{_skip_check_:!0,value:-$n.marginXXS},marginLeft:{_skip_check_:!0,value:$n.marginXS},color:$n.colorTextDescription,fontSize:$n.fontSizeSM,background:"transparent",border:"none",outline:"none",cursor:"pointer",transition:`all ${$n.motionDurationSlow}`,"&:hover":{color:$n.colorTextHeading}},"&:hover":{color:Pn},[`&${Rn}-active ${Rn}-btn`]:{color:$n.colorPrimary,textShadow:$n.tabsActiveTextShadow},[`&${Rn}-disabled`]:{color:$n.colorTextDisabled,cursor:"not-allowed"},[`&${Rn}-disabled ${Rn}-btn, &${Rn}-disabled ${Cn}-remove`]:{"&:focus, &:active":{color:$n.colorTextDisabled}},[`& ${Rn}-remove ${In}`]:{margin:0},[In]:{marginRight:{_skip_check_:!0,value:$n.marginSM}}},[`${Rn} + ${Rn}`]:{margin:{_skip_check_:!0,value:`0 0 0 ${Nn}px`}}}},genRtlStyle$3=$n=>{const{componentCls:Cn,tabsHorizontalGutter:_n,iconCls:Pn,tabsCardGutter:In}=$n;return{[`${Cn}-rtl`]:{direction:"rtl",[`${Cn}-nav`]:{[`${Cn}-tab`]:{margin:{_skip_check_:!0,value:`0 0 0 ${_n}px`},[`${Cn}-tab:last-of-type`]:{marginLeft:{_skip_check_:!0,value:0}},[Pn]:{marginRight:{_skip_check_:!0,value:0},marginLeft:{_skip_check_:!0,value:`${$n.marginSM}px`}},[`${Cn}-tab-remove`]:{marginRight:{_skip_check_:!0,value:`${$n.marginXS}px`},marginLeft:{_skip_check_:!0,value:`-${$n.marginXXS}px`},[Pn]:{margin:0}}}},[`&${Cn}-left`]:{[`> ${Cn}-nav`]:{order:1},[`> ${Cn}-content-holder`]:{order:0}},[`&${Cn}-right`]:{[`> ${Cn}-nav`]:{order:0},[`> ${Cn}-content-holder`]:{order:1}},[`&${Cn}-card${Cn}-top, &${Cn}-card${Cn}-bottom`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-tab + ${Cn}-tab`]:{marginRight:{_skip_check_:!0,value:`${In}px`},marginLeft:{_skip_check_:!0,value:0}}}}},[`${Cn}-dropdown-rtl`]:{direction:"rtl"},[`${Cn}-menu-item`]:{[`${Cn}-dropdown-rtl`]:{textAlign:{_skip_check_:!0,value:"right"}}}}},genTabsStyle=$n=>{const{componentCls:Cn,tabsCardHorizontalPadding:_n,tabsCardHeight:Pn,tabsCardGutter:In,tabsHoverColor:Nn,tabsActiveColor:Rn,colorSplit:Dn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{display:"flex",[`> ${Cn}-nav, > div > ${Cn}-nav`]:{position:"relative",display:"flex",flex:"none",alignItems:"center",[`${Cn}-nav-wrap`]:{position:"relative",display:"flex",flex:"auto",alignSelf:"stretch",overflow:"hidden",whiteSpace:"nowrap",transform:"translate(0)","&::before, &::after":{position:"absolute",zIndex:1,opacity:0,transition:`opacity ${$n.motionDurationSlow}`,content:"''",pointerEvents:"none"}},[`${Cn}-nav-list`]:{position:"relative",display:"flex",transition:`opacity ${$n.motionDurationSlow}`},[`${Cn}-nav-operations`]:{display:"flex",alignSelf:"stretch"},[`${Cn}-nav-operations-hidden`]:{position:"absolute",visibility:"hidden",pointerEvents:"none"},[`${Cn}-nav-more`]:{position:"relative",padding:_n,background:"transparent",border:0,"&::after":{position:"absolute",right:{_skip_check_:!0,value:0},bottom:0,left:{_skip_check_:!0,value:0},height:$n.controlHeightLG/8,transform:"translateY(100%)",content:"''"}},[`${Cn}-nav-add`]:_extends$1({minWidth:`${Pn}px`,marginLeft:{_skip_check_:!0,value:`${In}px`},padding:`0 ${$n.paddingXS}px`,background:"transparent",border:`${$n.lineWidth}px ${$n.lineType} ${Dn}`,borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`,outline:"none",cursor:"pointer",color:$n.colorText,transition:`all ${$n.motionDurationSlow} ${$n.motionEaseInOut}`,"&:hover":{color:Nn},"&:active, &:focus:not(:focus-visible)":{color:Rn}},genFocusStyle($n))},[`${Cn}-extra-content`]:{flex:"none"},[`${Cn}-ink-bar`]:{position:"absolute",background:$n.colorPrimary,pointerEvents:"none"}}),genTabStyle($n)),{[`${Cn}-content`]:{position:"relative",display:"flex",width:"100%","&-animated":{transition:"margin 0.3s"}},[`${Cn}-content-holder`]:{flex:"auto",minWidth:0,minHeight:0},[`${Cn}-tabpane`]:{outline:"none",flex:"none",width:"100%"}}),[`${Cn}-centered`]:{[`> ${Cn}-nav, > div > ${Cn}-nav`]:{[`${Cn}-nav-wrap`]:{[`&:not([class*='${Cn}-nav-wrap-ping'])`]:{justifyContent:"center"}}}}}},useStyle$H=genComponentStyleHook("Tabs",$n=>{const Cn=$n.controlHeightLG,_n=merge$1($n,{tabsHoverColor:$n.colorPrimaryHover,tabsActiveColor:$n.colorPrimaryActive,tabsCardHorizontalPadding:`${(Cn-Math.round($n.fontSize*$n.lineHeight))/2-$n.lineWidth}px ${$n.padding}px`,tabsCardHeight:Cn,tabsCardGutter:$n.marginXXS/2,tabsHorizontalGutter:32,tabsCardHeadBackground:$n.colorFillAlter,dropdownEdgeChildVerticalPadding:$n.paddingXXS,tabsActiveTextShadow:"0 0 0.25px currentcolor",tabsDropdownHeight:200,tabsDropdownWidth:120});return[genSizeStyle$2(_n),genRtlStyle$3(_n),genPositionStyle(_n),genDropdownStyle(_n),genCardStyle$1(_n),genTabsStyle(_n),genMotionStyle$5(_n)]},$n=>({zIndexPopup:$n.zIndexPopupBase+50}));let uuid$4=0;const tabsProps=()=>({prefixCls:{type:String},id:{type:String},popupClassName:String,getPopupContainer:functionType(),activeKey:{type:[String,Number]},defaultActiveKey:{type:[String,Number]},direction:stringType(),animated:someType([Boolean,Object]),renderTabBar:functionType(),tabBarGutter:{type:Number},tabBarStyle:objectType(),tabPosition:stringType(),destroyInactiveTabPane:booleanType(),hideAdd:Boolean,type:stringType(),size:stringType(),centered:Boolean,onEdit:functionType(),onChange:functionType(),onTabClick:functionType(),onTabScroll:functionType(),"onUpdate:activeKey":functionType(),locale:objectType(),onPrevClick:functionType(),onNextClick:functionType(),tabBarExtraContent:PropTypes.any});function parseTabList($n){return $n.map(Cn=>{if(isValidElement(Cn)){const _n=_extends$1({},Cn.props||{});for(const[zn,Wn]of Object.entries(_n))delete _n[zn],_n[camelize(zn)]=Wn;const Pn=Cn.children||{},In=Cn.key!==void 0?Cn.key:void 0,{tab:Nn=Pn.tab,disabled:Rn,forceRender:Dn,closable:Ln,animated:Fn,active:Bn,destroyInactiveTabPane:Hn}=_n;return _extends$1(_extends$1({key:In},_n),{node:Cn,closeIcon:Pn.closeIcon,tab:Nn,disabled:Rn===""||Rn,forceRender:Dn===""||Dn,closable:Ln===""||Ln,animated:Fn===""||Fn,active:Bn===""||Bn,destroyInactiveTabPane:Hn===""||Hn})}return null}).filter(Cn=>Cn)}const InternalTabs=defineComponent({compatConfig:{MODE:3},name:"InternalTabs",inheritAttrs:!1,props:_extends$1(_extends$1({},initDefaultProps(tabsProps(),{tabPosition:"top",animated:{inkBar:!0,tabPane:!1}})),{tabs:arrayType()}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;devWarning($n.onPrevClick===void 0&&$n.onNextClick===void 0,"Tabs","`onPrevClick / @prevClick` and `onNextClick / @nextClick` has been removed. Please use `onTabScroll / @tabScroll` instead."),devWarning($n.tabBarExtraContent===void 0,"Tabs","`tabBarExtraContent` prop has been removed. Please use `rightExtra` slot instead."),devWarning(Pn.tabBarExtraContent===void 0,"Tabs","`tabBarExtraContent` slot is deprecated. Please use `rightExtra` slot instead.");const{prefixCls:In,direction:Nn,size:Rn,rootPrefixCls:Dn,getPopupContainer:Ln}=useConfigInject("tabs",$n),[Fn,Bn]=useStyle$H(In),Hn=computed(()=>Nn.value==="rtl"),zn=computed(()=>{const{animated:nr,tabPosition:ta}=$n;return nr===!1||["left","right"].includes(ta)?{inkBar:!1,tabPane:!1}:nr===!0?{inkBar:!0,tabPane:!0}:_extends$1({inkBar:!0,tabPane:!1},typeof nr=="object"?nr:{})}),[Wn,Yn]=useState(!1);onMounted(()=>{Yn(isMobile())});const[Gn,Go]=useMergedState(()=>{var nr;return(nr=$n.tabs[0])===null||nr===void 0?void 0:nr.key},{value:computed(()=>$n.activeKey),defaultValue:$n.defaultActiveKey}),[Xn,Yo]=useState(()=>$n.tabs.findIndex(nr=>nr.key===Gn.value));watchEffect(()=>{var nr;let ta=$n.tabs.findIndex(oa=>oa.key===Gn.value);ta===-1&&(ta=Math.max(0,Math.min(Xn.value,$n.tabs.length-1)),Go((nr=$n.tabs[ta])===null||nr===void 0?void 0:nr.key)),Yo(ta)});const[qo,Jo]=useMergedState(null,{value:computed(()=>$n.id)}),Zo=computed(()=>Wn.value&&!["left","right"].includes($n.tabPosition)?"top":$n.tabPosition);onMounted(()=>{$n.id||(Jo(`rc-tabs-${uuid$4}`),uuid$4+=1)});const rr=(nr,ta)=>{var oa,ra;(oa=$n.onTabClick)===null||oa===void 0||oa.call($n,nr,ta);const ea=nr!==Gn.value;Go(nr),ea&&((ra=$n.onChange)===null||ra===void 0||ra.call($n,nr))};return useProvideTabs({tabs:computed(()=>$n.tabs),prefixCls:In}),()=>{const{id:nr,type:ta,tabBarGutter:oa,tabBarStyle:ra,locale:ea,destroyInactiveTabPane:la,renderTabBar:ua=Pn.renderTabBar,onTabScroll:ga,hideAdd:aa,centered:ca}=$n,sa={id:qo.value,activeKey:Gn.value,animated:zn.value,tabPosition:Zo.value,rtl:Hn.value,mobile:Wn.value};let ia;ta==="editable-card"&&(ia={onEdit:(ba,Ia)=>{let{key:Ea,event:xa}=Ia;var Ta;(Ta=$n.onEdit)===null||Ta===void 0||Ta.call($n,ba==="add"?xa:Ea,ba)},removeIcon:()=>createVNode(CloseOutlined$1,null,null),addIcon:Pn.addIcon?Pn.addIcon:()=>createVNode(PlusOutlined$1,null,null),showAdd:aa!==!0});let fa;const ma=_extends$1(_extends$1({},sa),{moreTransitionName:`${Dn.value}-slide-up`,editable:ia,locale:ea,tabBarGutter:oa,onTabClick:rr,onTabScroll:ga,style:ra,getPopupContainer:Ln.value,popupClassName:classNames($n.popupClassName,Bn.value)});ua?fa=ua(_extends$1(_extends$1({},ma),{DefaultTabBar:TabNavList})):fa=createVNode(TabNavList,ma,pick(Pn,["moreIcon","leftExtra","rightExtra","tabBarExtraContent"]));const ya=In.value;return Fn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{id:nr,class:classNames(ya,`${ya}-${Zo.value}`,{[Bn.value]:!0,[`${ya}-${Rn.value}`]:Rn.value,[`${ya}-card`]:["card","editable-card"].includes(ta),[`${ya}-editable-card`]:ta==="editable-card",[`${ya}-centered`]:ca,[`${ya}-mobile`]:Wn.value,[`${ya}-editable`]:ta==="editable-card",[`${ya}-rtl`]:Hn.value},_n.class)}),[fa,createVNode(TabPanelList,_objectSpread2$1(_objectSpread2$1({destroyInactiveTabPane:la},sa),{},{animated:zn.value}),null)]))}}}),Tabs=defineComponent({compatConfig:{MODE:3},name:"ATabs",inheritAttrs:!1,props:initDefaultProps(tabsProps(),{tabPosition:"top",animated:{inkBar:!0,tabPane:!1}}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const Nn=Rn=>{In("update:activeKey",Rn),In("change",Rn)};return()=>{var Rn;const Dn=parseTabList(flattenChildren((Rn=Pn.default)===null||Rn===void 0?void 0:Rn.call(Pn)));return createVNode(InternalTabs,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},omit$1($n,["onUpdate:activeKey"])),_n),{},{onChange:Nn,tabs:Dn}),Pn)}}}),tabPaneProps=()=>({tab:PropTypes.any,disabled:{type:Boolean},forceRender:{type:Boolean},closable:{type:Boolean},animated:{type:Boolean},active:{type:Boolean},destroyInactiveTabPane:{type:Boolean},prefixCls:{type:String},tabKey:{type:[String,Number]},id:{type:String}}),TabPane$1=defineComponent({compatConfig:{MODE:3},name:"ATabPane",inheritAttrs:!1,__ANT_TAB_PANE:!0,props:tabPaneProps(),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=ref($n.forceRender);watch([()=>$n.active,()=>$n.destroyInactiveTabPane],()=>{$n.active?In.value=!0:$n.destroyInactiveTabPane&&(In.value=!1)},{immediate:!0});const Nn=computed(()=>$n.active?{}:$n.animated?{visibility:"hidden",height:0,overflowY:"hidden"}:{display:"none"});return()=>{var Rn;const{prefixCls:Dn,forceRender:Ln,id:Fn,active:Bn,tabKey:Hn}=$n;return createVNode("div",{id:Fn&&`${Fn}-panel-${Hn}`,role:"tabpanel",tabindex:Bn?0:-1,"aria-labelledby":Fn&&`${Fn}-tab-${Hn}`,"aria-hidden":!Bn,style:[Nn.value,_n.style],class:[`${Dn}-tabpane`,Bn&&`${Dn}-tabpane-active`,_n.class]},[(Bn||In.value||Ln)&&((Rn=Pn.default)===null||Rn===void 0?void 0:Rn.call(Pn))])}}});Tabs.TabPane=TabPane$1;Tabs.install=function($n){return $n.component(Tabs.name,Tabs),$n.component(TabPane$1.name,TabPane$1),$n};const genCardHeadStyle=$n=>{const{antCls:Cn,componentCls:_n,cardHeadHeight:Pn,cardPaddingBase:In,cardHeadTabsMarginBottom:Nn}=$n;return _extends$1(_extends$1({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:Pn,marginBottom:-1,padding:`0 ${In}px`,color:$n.colorTextHeading,fontWeight:$n.fontWeightStrong,fontSize:$n.fontSizeLG,background:"transparent",borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorderSecondary}`,borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`},clearFix()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":_extends$1(_extends$1({display:"inline-block",flex:1},textEllipsis),{[` - > ${_n}-typography, - > ${_n}-typography-edit-content - `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${Cn}-tabs-top`]:{clear:"both",marginBottom:Nn,color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize,"&-bar":{borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorderSecondary}`}}})},genCardGridStyle=$n=>{const{cardPaddingBase:Cn,colorBorderSecondary:_n,cardShadow:Pn,lineWidth:In}=$n;return{width:"33.33%",padding:Cn,border:0,borderRadius:0,boxShadow:` - ${In}px 0 0 0 ${_n}, - 0 ${In}px 0 0 ${_n}, - ${In}px ${In}px 0 0 ${_n}, - ${In}px 0 0 0 ${_n} inset, - 0 ${In}px 0 0 ${_n} inset; - `,transition:`all ${$n.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:Pn}}},genCardActionsStyle=$n=>{const{componentCls:Cn,iconCls:_n,cardActionsLiMargin:Pn,cardActionsIconSize:In,colorBorderSecondary:Nn}=$n;return _extends$1(_extends$1({margin:0,padding:0,listStyle:"none",background:$n.colorBgContainer,borderTop:`${$n.lineWidth}px ${$n.lineType} ${Nn}`,display:"flex",borderRadius:`0 0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px `},clearFix()),{"& > li":{margin:Pn,color:$n.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:$n.cardActionsIconSize*2,fontSize:$n.fontSize,lineHeight:$n.lineHeight,cursor:"pointer","&:hover":{color:$n.colorPrimary,transition:`color ${$n.motionDurationMid}`},[`a:not(${Cn}-btn), > ${_n}`]:{display:"inline-block",width:"100%",color:$n.colorTextDescription,lineHeight:`${$n.fontSize*$n.lineHeight}px`,transition:`color ${$n.motionDurationMid}`,"&:hover":{color:$n.colorPrimary}},[`> ${_n}`]:{fontSize:In,lineHeight:`${In*$n.lineHeight}px`}},"&:not(:last-child)":{borderInlineEnd:`${$n.lineWidth}px ${$n.lineType} ${Nn}`}}})},genCardMetaStyle=$n=>_extends$1(_extends$1({margin:`-${$n.marginXXS}px 0`,display:"flex"},clearFix()),{"&-avatar":{paddingInlineEnd:$n.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:$n.marginXS}},"&-title":_extends$1({color:$n.colorTextHeading,fontWeight:$n.fontWeightStrong,fontSize:$n.fontSizeLG},textEllipsis),"&-description":{color:$n.colorTextDescription}}),genCardTypeInnerStyle=$n=>{const{componentCls:Cn,cardPaddingBase:_n,colorFillAlter:Pn}=$n;return{[`${Cn}-head`]:{padding:`0 ${_n}px`,background:Pn,"&-title":{fontSize:$n.fontSize}},[`${Cn}-body`]:{padding:`${$n.padding}px ${_n}px`}}},genCardLoadingStyle=$n=>{const{componentCls:Cn}=$n;return{overflow:"hidden",[`${Cn}-body`]:{userSelect:"none"}}},genCardStyle=$n=>{const{componentCls:Cn,cardShadow:_n,cardHeadPadding:Pn,colorBorderSecondary:In,boxShadow:Nn,cardPaddingBase:Rn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",background:$n.colorBgContainer,borderRadius:$n.borderRadiusLG,[`&:not(${Cn}-bordered)`]:{boxShadow:Nn},[`${Cn}-head`]:genCardHeadStyle($n),[`${Cn}-extra`]:{marginInlineStart:"auto",color:"",fontWeight:"normal",fontSize:$n.fontSize},[`${Cn}-body`]:_extends$1({padding:Rn,borderRadius:` 0 0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px`},clearFix()),[`${Cn}-grid`]:genCardGridStyle($n),[`${Cn}-cover`]:{"> *":{display:"block",width:"100%"},img:{borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`}},[`${Cn}-actions`]:genCardActionsStyle($n),[`${Cn}-meta`]:genCardMetaStyle($n)}),[`${Cn}-bordered`]:{border:`${$n.lineWidth}px ${$n.lineType} ${In}`,[`${Cn}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${Cn}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${$n.motionDurationMid}, border-color ${$n.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:_n}},[`${Cn}-contain-grid`]:{[`${Cn}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${Cn}-loading) ${Cn}-body`]:{marginBlockStart:-$n.lineWidth,marginInlineStart:-$n.lineWidth,padding:0}},[`${Cn}-contain-tabs`]:{[`> ${Cn}-head`]:{[`${Cn}-head-title, ${Cn}-extra`]:{paddingTop:Pn}}},[`${Cn}-type-inner`]:genCardTypeInnerStyle($n),[`${Cn}-loading`]:genCardLoadingStyle($n),[`${Cn}-rtl`]:{direction:"rtl"}}},genCardSizeStyle=$n=>{const{componentCls:Cn,cardPaddingSM:_n,cardHeadHeightSM:Pn}=$n;return{[`${Cn}-small`]:{[`> ${Cn}-head`]:{minHeight:Pn,padding:`0 ${_n}px`,fontSize:$n.fontSize,[`> ${Cn}-head-wrapper`]:{[`> ${Cn}-extra`]:{fontSize:$n.fontSize}}},[`> ${Cn}-body`]:{padding:_n}},[`${Cn}-small${Cn}-contain-tabs`]:{[`> ${Cn}-head`]:{[`${Cn}-head-title, ${Cn}-extra`]:{minHeight:Pn,paddingTop:0,display:"flex",alignItems:"center"}}}}},useStyle$G=genComponentStyleHook("Card",$n=>{const Cn=merge$1($n,{cardShadow:$n.boxShadowCard,cardHeadHeight:$n.fontSizeLG*$n.lineHeightLG+$n.padding*2,cardHeadHeightSM:$n.fontSize*$n.lineHeight+$n.paddingXS*2,cardHeadPadding:$n.padding,cardPaddingBase:$n.paddingLG,cardHeadTabsMarginBottom:-$n.padding-$n.lineWidth,cardActionsLiMargin:`${$n.paddingSM}px 0`,cardActionsIconSize:$n.fontSize,cardPaddingSM:12});return[genCardStyle(Cn),genCardSizeStyle(Cn)]}),skeletonTitleProps=()=>({prefixCls:String,width:{type:[Number,String]}}),SkeletonTitle=defineComponent({compatConfig:{MODE:3},name:"SkeletonTitle",props:skeletonTitleProps(),setup($n){return()=>{const{prefixCls:Cn,width:_n}=$n,Pn=typeof _n=="number"?`${_n}px`:_n;return createVNode("h3",{class:Cn,style:{width:Pn}},null)}}}),SkeletonTitle$1=SkeletonTitle,skeletonParagraphProps=()=>({prefixCls:String,width:{type:[Number,String,Array]},rows:Number}),SkeletonParagraph=defineComponent({compatConfig:{MODE:3},name:"SkeletonParagraph",props:skeletonParagraphProps(),setup($n){const Cn=_n=>{const{width:Pn,rows:In=2}=$n;if(Array.isArray(Pn))return Pn[_n];if(In-1===_n)return Pn};return()=>{const{prefixCls:_n,rows:Pn}=$n,In=[...Array(Pn)].map((Nn,Rn)=>{const Dn=Cn(Rn);return createVNode("li",{key:Rn,style:{width:typeof Dn=="number"?`${Dn}px`:Dn}},null)});return createVNode("ul",{class:_n},[In])}}}),Paragraph$2=SkeletonParagraph,skeletonElementProps=()=>({prefixCls:String,size:[String,Number],shape:String,active:{type:Boolean,default:void 0}}),Element$1=$n=>{const{prefixCls:Cn,size:_n,shape:Pn}=$n,In=classNames({[`${Cn}-lg`]:_n==="large",[`${Cn}-sm`]:_n==="small"}),Nn=classNames({[`${Cn}-circle`]:Pn==="circle",[`${Cn}-square`]:Pn==="square",[`${Cn}-round`]:Pn==="round"}),Rn=typeof _n=="number"?{width:`${_n}px`,height:`${_n}px`,lineHeight:`${_n}px`}:{};return createVNode("span",{class:classNames(Cn,In,Nn),style:Rn},null)};Element$1.displayName="SkeletonElement";const Element$2=Element$1,skeletonClsLoading=new Keyframes("ant-skeleton-loading",{"0%":{transform:"translateX(-37.5%)"},"100%":{transform:"translateX(37.5%)"}}),genSkeletonElementCommonSize=$n=>({height:$n,lineHeight:`${$n}px`}),genSkeletonElementAvatarSize=$n=>_extends$1({width:$n},genSkeletonElementCommonSize($n)),genSkeletonColor=$n=>({position:"relative",zIndex:0,overflow:"hidden",background:"transparent","&::after":{position:"absolute",top:0,insetInlineEnd:"-150%",bottom:0,insetInlineStart:"-150%",background:$n.skeletonLoadingBackground,animationName:skeletonClsLoading,animationDuration:$n.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite",content:'""'}}),genSkeletonElementInputSize=$n=>_extends$1({width:$n*5,minWidth:$n*5},genSkeletonElementCommonSize($n)),genSkeletonElementAvatar=$n=>{const{skeletonAvatarCls:Cn,color:_n,controlHeight:Pn,controlHeightLG:In,controlHeightSM:Nn}=$n;return{[`${Cn}`]:_extends$1({display:"inline-block",verticalAlign:"top",background:_n},genSkeletonElementAvatarSize(Pn)),[`${Cn}${Cn}-circle`]:{borderRadius:"50%"},[`${Cn}${Cn}-lg`]:_extends$1({},genSkeletonElementAvatarSize(In)),[`${Cn}${Cn}-sm`]:_extends$1({},genSkeletonElementAvatarSize(Nn))}},genSkeletonElementInput=$n=>{const{controlHeight:Cn,borderRadiusSM:_n,skeletonInputCls:Pn,controlHeightLG:In,controlHeightSM:Nn,color:Rn}=$n;return{[`${Pn}`]:_extends$1({display:"inline-block",verticalAlign:"top",background:Rn,borderRadius:_n},genSkeletonElementInputSize(Cn)),[`${Pn}-lg`]:_extends$1({},genSkeletonElementInputSize(In)),[`${Pn}-sm`]:_extends$1({},genSkeletonElementInputSize(Nn))}},genSkeletonElementImageSize=$n=>_extends$1({width:$n},genSkeletonElementCommonSize($n)),genSkeletonElementImage=$n=>{const{skeletonImageCls:Cn,imageSizeBase:_n,color:Pn,borderRadiusSM:In}=$n;return{[`${Cn}`]:_extends$1(_extends$1({display:"flex",alignItems:"center",justifyContent:"center",verticalAlign:"top",background:Pn,borderRadius:In},genSkeletonElementImageSize(_n*2)),{[`${Cn}-path`]:{fill:"#bfbfbf"},[`${Cn}-svg`]:_extends$1(_extends$1({},genSkeletonElementImageSize(_n)),{maxWidth:_n*4,maxHeight:_n*4}),[`${Cn}-svg${Cn}-svg-circle`]:{borderRadius:"50%"}}),[`${Cn}${Cn}-circle`]:{borderRadius:"50%"}}},genSkeletonElementButtonShape=($n,Cn,_n)=>{const{skeletonButtonCls:Pn}=$n;return{[`${_n}${Pn}-circle`]:{width:Cn,minWidth:Cn,borderRadius:"50%"},[`${_n}${Pn}-round`]:{borderRadius:Cn}}},genSkeletonElementButtonSize=$n=>_extends$1({width:$n*2,minWidth:$n*2},genSkeletonElementCommonSize($n)),genSkeletonElementButton=$n=>{const{borderRadiusSM:Cn,skeletonButtonCls:_n,controlHeight:Pn,controlHeightLG:In,controlHeightSM:Nn,color:Rn}=$n;return _extends$1(_extends$1(_extends$1(_extends$1(_extends$1({[`${_n}`]:_extends$1({display:"inline-block",verticalAlign:"top",background:Rn,borderRadius:Cn,width:Pn*2,minWidth:Pn*2},genSkeletonElementButtonSize(Pn))},genSkeletonElementButtonShape($n,Pn,_n)),{[`${_n}-lg`]:_extends$1({},genSkeletonElementButtonSize(In))}),genSkeletonElementButtonShape($n,In,`${_n}-lg`)),{[`${_n}-sm`]:_extends$1({},genSkeletonElementButtonSize(Nn))}),genSkeletonElementButtonShape($n,Nn,`${_n}-sm`))},genBaseStyle$e=$n=>{const{componentCls:Cn,skeletonAvatarCls:_n,skeletonTitleCls:Pn,skeletonParagraphCls:In,skeletonButtonCls:Nn,skeletonInputCls:Rn,skeletonImageCls:Dn,controlHeight:Ln,controlHeightLG:Fn,controlHeightSM:Bn,color:Hn,padding:zn,marginSM:Wn,borderRadius:Yn,skeletonTitleHeight:Gn,skeletonBlockRadius:Go,skeletonParagraphLineHeight:Xn,controlHeightXS:Yo,skeletonParagraphMarginTop:qo}=$n;return{[`${Cn}`]:{display:"table",width:"100%",[`${Cn}-header`]:{display:"table-cell",paddingInlineEnd:zn,verticalAlign:"top",[`${_n}`]:_extends$1({display:"inline-block",verticalAlign:"top",background:Hn},genSkeletonElementAvatarSize(Ln)),[`${_n}-circle`]:{borderRadius:"50%"},[`${_n}-lg`]:_extends$1({},genSkeletonElementAvatarSize(Fn)),[`${_n}-sm`]:_extends$1({},genSkeletonElementAvatarSize(Bn))},[`${Cn}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[`${Pn}`]:{width:"100%",height:Gn,background:Hn,borderRadius:Go,[`+ ${In}`]:{marginBlockStart:Bn}},[`${In}`]:{padding:0,"> li":{width:"100%",height:Xn,listStyle:"none",background:Hn,borderRadius:Go,"+ li":{marginBlockStart:Yo}}},[`${In}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${Cn}-content`]:{[`${Pn}, ${In} > li`]:{borderRadius:Yn}}},[`${Cn}-with-avatar ${Cn}-content`]:{[`${Pn}`]:{marginBlockStart:Wn,[`+ ${In}`]:{marginBlockStart:qo}}},[`${Cn}${Cn}-element`]:_extends$1(_extends$1(_extends$1(_extends$1({display:"inline-block",width:"auto"},genSkeletonElementButton($n)),genSkeletonElementAvatar($n)),genSkeletonElementInput($n)),genSkeletonElementImage($n)),[`${Cn}${Cn}-block`]:{width:"100%",[`${Nn}`]:{width:"100%"},[`${Rn}`]:{width:"100%"}},[`${Cn}${Cn}-active`]:{[` - ${Pn}, - ${In} > li, - ${_n}, - ${Nn}, - ${Rn}, - ${Dn} - `]:_extends$1({},genSkeletonColor($n))}}},useStyle$F=genComponentStyleHook("Skeleton",$n=>{const{componentCls:Cn}=$n,_n=merge$1($n,{skeletonAvatarCls:`${Cn}-avatar`,skeletonTitleCls:`${Cn}-title`,skeletonParagraphCls:`${Cn}-paragraph`,skeletonButtonCls:`${Cn}-button`,skeletonInputCls:`${Cn}-input`,skeletonImageCls:`${Cn}-image`,imageSizeBase:$n.controlHeight*1.5,skeletonTitleHeight:$n.controlHeight/2,skeletonBlockRadius:$n.borderRadiusSM,skeletonParagraphLineHeight:$n.controlHeight/2,skeletonParagraphMarginTop:$n.marginLG+$n.marginXXS,borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${$n.color} 25%, ${$n.colorGradientEnd} 37%, ${$n.color} 63%)`,skeletonLoadingMotionDuration:"1.4s"});return[genBaseStyle$e(_n)]},$n=>{const{colorFillContent:Cn,colorFill:_n}=$n;return{color:Cn,colorGradientEnd:_n}}),skeletonProps=()=>({active:{type:Boolean,default:void 0},loading:{type:Boolean,default:void 0},prefixCls:String,avatar:{type:[Boolean,Object],default:void 0},title:{type:[Boolean,Object],default:void 0},paragraph:{type:[Boolean,Object],default:void 0},round:{type:Boolean,default:void 0}});function getComponentProps($n){return $n&&typeof $n=="object"?$n:{}}function getAvatarBasicProps($n,Cn){return $n&&!Cn?{size:"large",shape:"square"}:{size:"large",shape:"circle"}}function getTitleBasicProps($n,Cn){return!$n&&Cn?{width:"38%"}:$n&&Cn?{width:"50%"}:{}}function getParagraphBasicProps($n,Cn){const _n={};return(!$n||!Cn)&&(_n.width="61%"),!$n&&Cn?_n.rows=3:_n.rows=2,_n}const Skeleton=defineComponent({compatConfig:{MODE:3},name:"ASkeleton",props:initDefaultProps(skeletonProps(),{avatar:!1,title:!0,paragraph:!0}),setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn,direction:In}=useConfigInject("skeleton",$n),[Nn,Rn]=useStyle$F(Pn);return()=>{var Dn;const{loading:Ln,avatar:Fn,title:Bn,paragraph:Hn,active:zn,round:Wn}=$n,Yn=Pn.value;if(Ln||$n.loading===void 0){const Gn=!!Fn||Fn==="",Go=!!Bn||Bn==="",Xn=!!Hn||Hn==="";let Yo;if(Gn){const Zo=_extends$1(_extends$1({prefixCls:`${Yn}-avatar`},getAvatarBasicProps(Go,Xn)),getComponentProps(Fn));Yo=createVNode("div",{class:`${Yn}-header`},[createVNode(Element$2,Zo,null)])}let qo;if(Go||Xn){let Zo;if(Go){const nr=_extends$1(_extends$1({prefixCls:`${Yn}-title`},getTitleBasicProps(Gn,Xn)),getComponentProps(Bn));Zo=createVNode(SkeletonTitle$1,nr,null)}let rr;if(Xn){const nr=_extends$1(_extends$1({prefixCls:`${Yn}-paragraph`},getParagraphBasicProps(Gn,Go)),getComponentProps(Hn));rr=createVNode(Paragraph$2,nr,null)}qo=createVNode("div",{class:`${Yn}-content`},[Zo,rr])}const Jo=classNames(Yn,{[`${Yn}-with-avatar`]:Gn,[`${Yn}-active`]:zn,[`${Yn}-rtl`]:In.value==="rtl",[`${Yn}-round`]:Wn,[Rn.value]:!0});return Nn(createVNode("div",{class:Jo},[Yo,qo]))}return(Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n)}}}),Skeleton$1=Skeleton,skeletonButtonProps=()=>_extends$1(_extends$1({},skeletonElementProps()),{size:String,block:Boolean}),SkeletonButton=defineComponent({compatConfig:{MODE:3},name:"ASkeletonButton",props:initDefaultProps(skeletonButtonProps(),{size:"default"}),setup($n){const{prefixCls:Cn}=useConfigInject("skeleton",$n),[_n,Pn]=useStyle$F(Cn),In=computed(()=>classNames(Cn.value,`${Cn.value}-element`,{[`${Cn.value}-active`]:$n.active,[`${Cn.value}-block`]:$n.block},Pn.value));return()=>_n(createVNode("div",{class:In.value},[createVNode(Element$2,_objectSpread2$1(_objectSpread2$1({},$n),{},{prefixCls:`${Cn.value}-button`}),null)]))}}),SkeletonButton$1=SkeletonButton,SkeletonInput=defineComponent({compatConfig:{MODE:3},name:"ASkeletonInput",props:_extends$1(_extends$1({},omit$1(skeletonElementProps(),["shape"])),{size:String,block:Boolean}),setup($n){const{prefixCls:Cn}=useConfigInject("skeleton",$n),[_n,Pn]=useStyle$F(Cn),In=computed(()=>classNames(Cn.value,`${Cn.value}-element`,{[`${Cn.value}-active`]:$n.active,[`${Cn.value}-block`]:$n.block},Pn.value));return()=>_n(createVNode("div",{class:In.value},[createVNode(Element$2,_objectSpread2$1(_objectSpread2$1({},$n),{},{prefixCls:`${Cn.value}-input`}),null)]))}}),SkeletonInput$1=SkeletonInput,path="M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",SkeletonImage=defineComponent({compatConfig:{MODE:3},name:"ASkeletonImage",props:omit$1(skeletonElementProps(),["size","shape","active"]),setup($n){const{prefixCls:Cn}=useConfigInject("skeleton",$n),[_n,Pn]=useStyle$F(Cn),In=computed(()=>classNames(Cn.value,`${Cn.value}-element`,Pn.value));return()=>_n(createVNode("div",{class:In.value},[createVNode("div",{class:`${Cn.value}-image`},[createVNode("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",class:`${Cn.value}-image-svg`},[createVNode("path",{d:path,class:`${Cn.value}-image-path`},null)])])]))}}),SkeletonImage$1=SkeletonImage,avatarProps=()=>_extends$1(_extends$1({},skeletonElementProps()),{shape:String}),SkeletonAvatar=defineComponent({compatConfig:{MODE:3},name:"ASkeletonAvatar",props:initDefaultProps(avatarProps(),{size:"default",shape:"circle"}),setup($n){const{prefixCls:Cn}=useConfigInject("skeleton",$n),[_n,Pn]=useStyle$F(Cn),In=computed(()=>classNames(Cn.value,`${Cn.value}-element`,{[`${Cn.value}-active`]:$n.active},Pn.value));return()=>_n(createVNode("div",{class:In.value},[createVNode(Element$2,_objectSpread2$1(_objectSpread2$1({},$n),{},{prefixCls:`${Cn.value}-avatar`}),null)]))}}),SkeletonAvatar$1=SkeletonAvatar;Skeleton$1.Button=SkeletonButton$1;Skeleton$1.Avatar=SkeletonAvatar$1;Skeleton$1.Input=SkeletonInput$1;Skeleton$1.Image=SkeletonImage$1;Skeleton$1.Title=SkeletonTitle$1;Skeleton$1.install=function($n){return $n.component(Skeleton$1.name,Skeleton$1),$n.component(Skeleton$1.Button.name,SkeletonButton$1),$n.component(Skeleton$1.Avatar.name,SkeletonAvatar$1),$n.component(Skeleton$1.Input.name,SkeletonInput$1),$n.component(Skeleton$1.Image.name,SkeletonImage$1),$n.component(Skeleton$1.Title.name,SkeletonTitle$1),$n};const{TabPane}=Tabs,cardProps=()=>({prefixCls:String,title:PropTypes.any,extra:PropTypes.any,bordered:{type:Boolean,default:!0},bodyStyle:{type:Object,default:void 0},headStyle:{type:Object,default:void 0},loading:{type:Boolean,default:!1},hoverable:{type:Boolean,default:!1},type:{type:String},size:{type:String},actions:PropTypes.any,tabList:{type:Array},tabBarExtraContent:PropTypes.any,activeTabKey:String,defaultActiveTabKey:String,cover:PropTypes.any,onTabChange:{type:Function}}),Card=defineComponent({compatConfig:{MODE:3},name:"ACard",inheritAttrs:!1,props:cardProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn,size:Rn}=useConfigInject("card",$n),[Dn,Ln]=useStyle$G(In),Fn=zn=>zn.map((Yn,Gn)=>isVNode$1(Yn)&&!isEmptyElement(Yn)||!isVNode$1(Yn)?createVNode("li",{style:{width:`${100/zn.length}%`},key:`action-${Gn}`},[createVNode("span",null,[Yn])]):null),Bn=zn=>{var Wn;(Wn=$n.onTabChange)===null||Wn===void 0||Wn.call($n,zn)},Hn=function(){let zn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],Wn;return zn.forEach(Yn=>{Yn&&isPlainObject$2(Yn.type)&&Yn.type.__ANT_CARD_GRID&&(Wn=!0)}),Wn};return()=>{var zn,Wn,Yn,Gn,Go,Xn;const{headStyle:Yo={},bodyStyle:qo={},loading:Jo,bordered:Zo=!0,type:rr,tabList:nr,hoverable:ta,activeTabKey:oa,defaultActiveTabKey:ra,tabBarExtraContent:ea=filterEmptyWithUndefined((zn=_n.tabBarExtraContent)===null||zn===void 0?void 0:zn.call(_n)),title:la=filterEmptyWithUndefined((Wn=_n.title)===null||Wn===void 0?void 0:Wn.call(_n)),extra:ua=filterEmptyWithUndefined((Yn=_n.extra)===null||Yn===void 0?void 0:Yn.call(_n)),actions:ga=filterEmptyWithUndefined((Gn=_n.actions)===null||Gn===void 0?void 0:Gn.call(_n)),cover:aa=filterEmptyWithUndefined((Go=_n.cover)===null||Go===void 0?void 0:Go.call(_n))}=$n,ca=flattenChildren((Xn=_n.default)===null||Xn===void 0?void 0:Xn.call(_n)),sa=In.value,ia={[`${sa}`]:!0,[Ln.value]:!0,[`${sa}-loading`]:Jo,[`${sa}-bordered`]:Zo,[`${sa}-hoverable`]:!!ta,[`${sa}-contain-grid`]:Hn(ca),[`${sa}-contain-tabs`]:nr&&nr.length,[`${sa}-${Rn.value}`]:Rn.value,[`${sa}-type-${rr}`]:!!rr,[`${sa}-rtl`]:Nn.value==="rtl"},fa=createVNode(Skeleton$1,{loading:!0,active:!0,paragraph:{rows:4},title:!1},{default:()=>[ca]}),ma=oa!==void 0,ya={size:"large",[ma?"activeKey":"defaultActiveKey"]:ma?oa:ra,onChange:Bn,class:`${sa}-head-tabs`};let ba;const Ia=nr&&nr.length?createVNode(Tabs,ya,{default:()=>[nr.map(wa=>{const{tab:La,slots:Na}=wa,$a=Na==null?void 0:Na.tab;devWarning(!Na,"Card","tabList slots is deprecated, Please use `customTab` instead.");let ka=La!==void 0?La:_n[$a]?_n[$a](wa):null;return ka=customRenderSlot(_n,"customTab",wa,()=>[ka]),createVNode(TabPane,{tab:ka,key:wa.key,disabled:wa.disabled},null)})],rightExtra:ea?()=>ea:null}):null;(la||ua||Ia)&&(ba=createVNode("div",{class:`${sa}-head`,style:Yo},[createVNode("div",{class:`${sa}-head-wrapper`},[la&&createVNode("div",{class:`${sa}-head-title`},[la]),ua&&createVNode("div",{class:`${sa}-extra`},[ua])]),Ia]));const Ea=aa?createVNode("div",{class:`${sa}-cover`},[aa]):null,xa=createVNode("div",{class:`${sa}-body`,style:qo},[Jo?fa:ca]),Ta=ga&&ga.length?createVNode("ul",{class:`${sa}-actions`},[Fn(ga)]):null;return Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({ref:"cardContainerRef"},Pn),{},{class:[ia,Pn.class]}),[ba,Ea,ca&&ca.length?xa:null,Ta]))}}}),Card$1=Card,cardMetaProps=()=>({prefixCls:String,title:vNodeType(),description:vNodeType(),avatar:vNodeType()}),Meta=defineComponent({compatConfig:{MODE:3},name:"ACardMeta",props:cardMetaProps(),slots:Object,setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn}=useConfigInject("card",$n);return()=>{const In={[`${Pn.value}-meta`]:!0},Nn=getPropsSlot(_n,$n,"avatar"),Rn=getPropsSlot(_n,$n,"title"),Dn=getPropsSlot(_n,$n,"description"),Ln=Nn?createVNode("div",{class:`${Pn.value}-meta-avatar`},[Nn]):null,Fn=Rn?createVNode("div",{class:`${Pn.value}-meta-title`},[Rn]):null,Bn=Dn?createVNode("div",{class:`${Pn.value}-meta-description`},[Dn]):null,Hn=Fn||Bn?createVNode("div",{class:`${Pn.value}-meta-detail`},[Fn,Bn]):null;return createVNode("div",{class:In},[Ln,Hn])}}}),cardGridProps=()=>({prefixCls:String,hoverable:{type:Boolean,default:!0}}),Grid=defineComponent({compatConfig:{MODE:3},name:"ACardGrid",__ANT_CARD_GRID:!0,props:cardGridProps(),setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn}=useConfigInject("card",$n),In=computed(()=>({[`${Pn.value}-grid`]:!0,[`${Pn.value}-grid-hoverable`]:$n.hoverable}));return()=>{var Nn;return createVNode("div",{class:In.value},[(Nn=_n.default)===null||Nn===void 0?void 0:Nn.call(_n)])}}});Card$1.Meta=Meta;Card$1.Grid=Grid;Card$1.install=function($n){return $n.component(Card$1.name,Card$1),$n.component(Meta.name,Meta),$n.component(Grid.name,Grid),$n};const collapseProps=()=>({prefixCls:String,activeKey:someType([Array,Number,String]),defaultActiveKey:someType([Array,Number,String]),accordion:booleanType(),destroyInactivePanel:booleanType(),bordered:booleanType(),expandIcon:functionType(),openAnimation:PropTypes.object,expandIconPosition:stringType(),collapsible:stringType(),ghost:booleanType(),onChange:functionType(),"onUpdate:activeKey":functionType()}),collapsePanelProps=()=>({openAnimation:PropTypes.object,prefixCls:String,header:PropTypes.any,headerClass:String,showArrow:booleanType(),isActive:booleanType(),destroyInactivePanel:booleanType(),disabled:booleanType(),accordion:booleanType(),forceRender:booleanType(),expandIcon:functionType(),extra:PropTypes.any,panelKey:someType(),collapsible:stringType(),role:String,onItemClick:functionType()}),genBaseStyle$d=$n=>{const{componentCls:Cn,collapseContentBg:_n,padding:Pn,collapseContentPaddingHorizontal:In,collapseHeaderBg:Nn,collapseHeaderPadding:Rn,collapsePanelBorderRadius:Dn,lineWidth:Ln,lineType:Fn,colorBorder:Bn,colorText:Hn,colorTextHeading:zn,colorTextDisabled:Wn,fontSize:Yn,lineHeight:Gn,marginSM:Go,paddingSM:Xn,motionDurationSlow:Yo,fontSizeIcon:qo}=$n,Jo=`${Ln}px ${Fn} ${Bn}`;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{backgroundColor:Nn,border:Jo,borderBottom:0,borderRadius:`${Dn}px`,"&-rtl":{direction:"rtl"},[`& > ${Cn}-item`]:{borderBottom:Jo,"&:last-child":{[` - &, - & > ${Cn}-header`]:{borderRadius:`0 0 ${Dn}px ${Dn}px`}},[`> ${Cn}-header`]:{position:"relative",display:"flex",flexWrap:"nowrap",alignItems:"flex-start",padding:Rn,color:zn,lineHeight:Gn,cursor:"pointer",transition:`all ${Yo}, visibility 0s`,[`> ${Cn}-header-text`]:{flex:"auto"},"&:focus":{outline:"none"},[`${Cn}-expand-icon`]:{height:Yn*Gn,display:"flex",alignItems:"center",paddingInlineEnd:Go},[`${Cn}-arrow`]:_extends$1(_extends$1({},resetIcon()),{fontSize:qo,svg:{transition:`transform ${Yo}`}}),[`${Cn}-header-text`]:{marginInlineEnd:"auto"}},[`${Cn}-header-collapsible-only`]:{cursor:"default",[`${Cn}-header-text`]:{flex:"none",cursor:"pointer"},[`${Cn}-expand-icon`]:{cursor:"pointer"}},[`${Cn}-icon-collapsible-only`]:{cursor:"default",[`${Cn}-expand-icon`]:{cursor:"pointer"}},[`&${Cn}-no-arrow`]:{[`> ${Cn}-header`]:{paddingInlineStart:Xn}}},[`${Cn}-content`]:{color:Hn,backgroundColor:_n,borderTop:Jo,[`& > ${Cn}-content-box`]:{padding:`${Pn}px ${In}px`},"&-hidden":{display:"none"}},[`${Cn}-item:last-child`]:{[`> ${Cn}-content`]:{borderRadius:`0 0 ${Dn}px ${Dn}px`}},[`& ${Cn}-item-disabled > ${Cn}-header`]:{"\n &,\n & > .arrow\n ":{color:Wn,cursor:"not-allowed"}},[`&${Cn}-icon-position-end`]:{[`& > ${Cn}-item`]:{[`> ${Cn}-header`]:{[`${Cn}-expand-icon`]:{order:1,paddingInlineEnd:0,paddingInlineStart:Go}}}}})}},genArrowStyle=$n=>{const{componentCls:Cn}=$n,_n=`> ${Cn}-item > ${Cn}-header ${Cn}-arrow svg`;return{[`${Cn}-rtl`]:{[_n]:{transform:"rotate(180deg)"}}}},genBorderlessStyle=$n=>{const{componentCls:Cn,collapseHeaderBg:_n,paddingXXS:Pn,colorBorder:In}=$n;return{[`${Cn}-borderless`]:{backgroundColor:_n,border:0,[`> ${Cn}-item`]:{borderBottom:`1px solid ${In}`},[` - > ${Cn}-item:last-child, - > ${Cn}-item:last-child ${Cn}-header - `]:{borderRadius:0},[`> ${Cn}-item:last-child`]:{borderBottom:0},[`> ${Cn}-item > ${Cn}-content`]:{backgroundColor:"transparent",borderTop:0},[`> ${Cn}-item > ${Cn}-content > ${Cn}-content-box`]:{paddingTop:Pn}}}},genGhostStyle=$n=>{const{componentCls:Cn,paddingSM:_n}=$n;return{[`${Cn}-ghost`]:{backgroundColor:"transparent",border:0,[`> ${Cn}-item`]:{borderBottom:0,[`> ${Cn}-content`]:{backgroundColor:"transparent",border:0,[`> ${Cn}-content-box`]:{paddingBlock:_n}}}}}},useStyle$E=genComponentStyleHook("Collapse",$n=>{const Cn=merge$1($n,{collapseContentBg:$n.colorBgContainer,collapseHeaderBg:$n.colorFillAlter,collapseHeaderPadding:`${$n.paddingSM}px ${$n.padding}px`,collapsePanelBorderRadius:$n.borderRadiusLG,collapseContentPaddingHorizontal:16});return[genBaseStyle$d(Cn),genBorderlessStyle(Cn),genGhostStyle(Cn),genArrowStyle(Cn),genCollapseMotion$1(Cn)]});function getActiveKeysArray($n){let Cn=$n;if(!Array.isArray(Cn)){const _n=typeof Cn;Cn=_n==="number"||_n==="string"?[Cn]:[]}return Cn.map(_n=>String(_n))}const Collapse=defineComponent({compatConfig:{MODE:3},name:"ACollapse",inheritAttrs:!1,props:initDefaultProps(collapseProps(),{accordion:!1,destroyInactivePanel:!1,bordered:!0,expandIconPosition:"start"}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const Nn=ref(getActiveKeysArray(firstNotUndefined([$n.activeKey,$n.defaultActiveKey])));watch(()=>$n.activeKey,()=>{Nn.value=getActiveKeysArray($n.activeKey)},{deep:!0});const{prefixCls:Rn,direction:Dn,rootPrefixCls:Ln}=useConfigInject("collapse",$n),[Fn,Bn]=useStyle$E(Rn),Hn=computed(()=>{const{expandIconPosition:Xn}=$n;return Xn!==void 0?Xn:Dn.value==="rtl"?"end":"start"}),zn=Xn=>{const{expandIcon:Yo=Pn.expandIcon}=$n,qo=Yo?Yo(Xn):createVNode(RightOutlined$1,{rotate:Xn.isActive?90:void 0},null);return createVNode("div",{class:[`${Rn.value}-expand-icon`,Bn.value],onClick:()=>["header","icon"].includes($n.collapsible)&&Yn(Xn.panelKey)},[isValidElement(Array.isArray(Yo)?qo[0]:qo)?cloneElement(qo,{class:`${Rn.value}-arrow`},!1):qo])},Wn=Xn=>{$n.activeKey===void 0&&(Nn.value=Xn);const Yo=$n.accordion?Xn[0]:Xn;In("update:activeKey",Yo),In("change",Yo)},Yn=Xn=>{let Yo=Nn.value;if($n.accordion)Yo=Yo[0]===Xn?[]:[Xn];else{Yo=[...Yo];const qo=Yo.indexOf(Xn);qo>-1?Yo.splice(qo,1):Yo.push(Xn)}Wn(Yo)},Gn=(Xn,Yo)=>{var qo,Jo,Zo;if(isEmptyElement(Xn))return;const rr=Nn.value,{accordion:nr,destroyInactivePanel:ta,collapsible:oa,openAnimation:ra}=$n,ea=ra||collapseMotion$1(`${Ln.value}-motion-collapse`),la=String((qo=Xn.key)!==null&&qo!==void 0?qo:Yo),{header:ua=(Zo=(Jo=Xn.children)===null||Jo===void 0?void 0:Jo.header)===null||Zo===void 0?void 0:Zo.call(Jo),headerClass:ga,collapsible:aa,disabled:ca}=Xn.props||{};let sa=!1;nr?sa=rr[0]===la:sa=rr.indexOf(la)>-1;let ia=aa??oa;(ca||ca==="")&&(ia="disabled");const fa={key:la,panelKey:la,header:ua,headerClass:ga,isActive:sa,prefixCls:Rn.value,destroyInactivePanel:ta,openAnimation:ea,accordion:nr,onItemClick:ia==="disabled"?null:Yn,expandIcon:zn,collapsible:ia};return cloneElement(Xn,fa)},Go=()=>{var Xn;return flattenChildren((Xn=Pn.default)===null||Xn===void 0?void 0:Xn.call(Pn)).map(Gn)};return()=>{const{accordion:Xn,bordered:Yo,ghost:qo}=$n,Jo=classNames(Rn.value,{[`${Rn.value}-borderless`]:!Yo,[`${Rn.value}-icon-position-${Hn.value}`]:!0,[`${Rn.value}-rtl`]:Dn.value==="rtl",[`${Rn.value}-ghost`]:!!qo,[_n.class]:!!_n.class},Bn.value);return Fn(createVNode("div",_objectSpread2$1(_objectSpread2$1({class:Jo},getDataAndAriaProps(_n)),{},{style:_n.style,role:Xn?"tablist":null}),[Go()]))}}}),PanelContent=defineComponent({compatConfig:{MODE:3},name:"PanelContent",props:collapsePanelProps(),setup($n,Cn){let{slots:_n}=Cn;const Pn=shallowRef(!1);return watchEffect(()=>{($n.isActive||$n.forceRender)&&(Pn.value=!0)}),()=>{var In;if(!Pn.value)return null;const{prefixCls:Nn,isActive:Rn,role:Dn}=$n;return createVNode("div",{class:classNames(`${Nn}-content`,{[`${Nn}-content-active`]:Rn,[`${Nn}-content-inactive`]:!Rn}),role:Dn},[createVNode("div",{class:`${Nn}-content-box`},[(In=_n.default)===null||In===void 0?void 0:In.call(_n)])])}}}),CollapsePanel=defineComponent({compatConfig:{MODE:3},name:"ACollapsePanel",inheritAttrs:!1,props:initDefaultProps(collapsePanelProps(),{showArrow:!0,isActive:!1,onItemClick(){},headerClass:"",forceRender:!1}),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;devWarning($n.disabled===void 0,"Collapse.Panel",'`disabled` is deprecated. Please use `collapsible="disabled"` instead.');const{prefixCls:Nn}=useConfigInject("collapse",$n),Rn=()=>{Pn("itemClick",$n.panelKey)},Dn=Ln=>{(Ln.key==="Enter"||Ln.keyCode===13||Ln.which===13)&&Rn()};return()=>{var Ln,Fn;const{header:Bn=(Ln=_n.header)===null||Ln===void 0?void 0:Ln.call(_n),headerClass:Hn,isActive:zn,showArrow:Wn,destroyInactivePanel:Yn,accordion:Gn,forceRender:Go,openAnimation:Xn,expandIcon:Yo=_n.expandIcon,extra:qo=(Fn=_n.extra)===null||Fn===void 0?void 0:Fn.call(_n),collapsible:Jo}=$n,Zo=Jo==="disabled",rr=Nn.value,nr=classNames(`${rr}-header`,{[Hn]:Hn,[`${rr}-header-collapsible-only`]:Jo==="header",[`${rr}-icon-collapsible-only`]:Jo==="icon"}),ta=classNames({[`${rr}-item`]:!0,[`${rr}-item-active`]:zn,[`${rr}-item-disabled`]:Zo,[`${rr}-no-arrow`]:!Wn,[`${In.class}`]:!!In.class});let oa=createVNode("i",{class:"arrow"},null);Wn&&typeof Yo=="function"&&(oa=Yo($n));const ra=withDirectives(createVNode(PanelContent,{prefixCls:rr,isActive:zn,forceRender:Go,role:Gn?"tabpanel":null},{default:_n.default}),[[vShow,zn]]),ea=_extends$1({appear:!1,css:!1},Xn);return createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{class:ta}),[createVNode("div",{class:nr,onClick:()=>!["header","icon"].includes(Jo)&&Rn(),role:Gn?"tab":"button",tabindex:Zo?-1:0,"aria-expanded":zn,onKeypress:Dn},[Wn&&oa,createVNode("span",{onClick:()=>Jo==="header"&&Rn(),class:`${rr}-header-text`},[Bn]),qo&&createVNode("div",{class:`${rr}-extra`},[qo])]),createVNode(Transition,ea,{default:()=>[!Yn||zn?ra:null]})])}}});Collapse.Panel=CollapsePanel;Collapse.install=function($n){return $n.component(Collapse.name,Collapse),$n.component(CollapsePanel.name,CollapsePanel),$n};const camel2hyphen=function($n){return $n.replace(/[A-Z]/g,function(Cn){return"-"+Cn.toLowerCase()}).toLowerCase()},isDimension=function($n){return/[height|width]$/.test($n)},obj2mq=function($n){let Cn="";const _n=Object.keys($n);return _n.forEach(function(Pn,In){let Nn=$n[Pn];Pn=camel2hyphen(Pn),isDimension(Pn)&&typeof Nn=="number"&&(Nn=Nn+"px"),Nn===!0?Cn+=Pn:Nn===!1?Cn+="not "+Pn:Cn+="("+Pn+": "+Nn+")",In<_n.length-1&&(Cn+=" and ")}),Cn};function json2mq($n){let Cn="";return typeof $n=="string"?$n:$n instanceof Array?($n.forEach(function(_n,Pn){Cn+=obj2mq(_n),Pn<$n.length-1&&(Cn+=", ")}),Cn):obj2mq($n)}const defaultProps$2={accessibility:{type:Boolean,default:!0},adaptiveHeight:{type:Boolean,default:!1},afterChange:PropTypes.any.def(null),arrows:{type:Boolean,default:!0},autoplay:{type:Boolean,default:!1},autoplaySpeed:PropTypes.number.def(3e3),beforeChange:PropTypes.any.def(null),centerMode:{type:Boolean,default:!1},centerPadding:PropTypes.string.def("50px"),cssEase:PropTypes.string.def("ease"),dots:{type:Boolean,default:!1},dotsClass:PropTypes.string.def("slick-dots"),draggable:{type:Boolean,default:!0},unslick:{type:Boolean,default:!1},easing:PropTypes.string.def("linear"),edgeFriction:PropTypes.number.def(.35),fade:{type:Boolean,default:!1},focusOnSelect:{type:Boolean,default:!1},infinite:{type:Boolean,default:!0},initialSlide:PropTypes.number.def(0),lazyLoad:PropTypes.any.def(null),verticalSwiping:{type:Boolean,default:!1},asNavFor:PropTypes.any.def(null),pauseOnDotsHover:{type:Boolean,default:!1},pauseOnFocus:{type:Boolean,default:!1},pauseOnHover:{type:Boolean,default:!0},responsive:PropTypes.array,rows:PropTypes.number.def(1),rtl:{type:Boolean,default:!1},slide:PropTypes.string.def("div"),slidesPerRow:PropTypes.number.def(1),slidesToScroll:PropTypes.number.def(1),slidesToShow:PropTypes.number.def(1),speed:PropTypes.number.def(500),swipe:{type:Boolean,default:!0},swipeEvent:PropTypes.any.def(null),swipeToSlide:{type:Boolean,default:!1},touchMove:{type:Boolean,default:!0},touchThreshold:PropTypes.number.def(5),useCSS:{type:Boolean,default:!0},useTransform:{type:Boolean,default:!0},variableWidth:{type:Boolean,default:!1},vertical:{type:Boolean,default:!1},waitForAnimate:{type:Boolean,default:!0},children:PropTypes.array,__propsSymbol__:PropTypes.any},defaultProps$3=defaultProps$2,initialState={animating:!1,autoplaying:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,dragging:!1,edgeDragged:!1,initialized:!1,lazyLoadedList:[],listHeight:null,listWidth:null,scrolling:!1,slideCount:null,slideHeight:null,slideWidth:null,swipeLeft:null,swiped:!1,swiping:!1,touchObject:{startX:0,startY:0,curX:0,curY:0},trackStyle:{},trackWidth:0,targetSlide:0},initialState$1=initialState;function clamp($n,Cn,_n){return Math.max(Cn,Math.min($n,_n))}const safePreventDefault=$n=>{["touchstart","touchmove","wheel"].includes($n.type)||$n.preventDefault()},getOnDemandLazySlides=$n=>{const Cn=[],_n=lazyStartIndex($n),Pn=lazyEndIndex($n);for(let In=_n;In$n.currentSlide-lazySlidesOnLeft($n),lazyEndIndex=$n=>$n.currentSlide+lazySlidesOnRight($n),lazySlidesOnLeft=$n=>$n.centerMode?Math.floor($n.slidesToShow/2)+(parseInt($n.centerPadding)>0?1:0):0,lazySlidesOnRight=$n=>$n.centerMode?Math.floor(($n.slidesToShow-1)/2)+1+(parseInt($n.centerPadding)>0?1:0):$n.slidesToShow,getWidth=$n=>$n&&$n.offsetWidth||0,getHeight=$n=>$n&&$n.offsetHeight||0,getSwipeDirection=function($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,_n;const Pn=$n.startX-$n.curX,In=$n.startY-$n.curY,Nn=Math.atan2(In,Pn);return _n=Math.round(Nn*180/Math.PI),_n<0&&(_n=360-Math.abs(_n)),_n<=45&&_n>=0||_n<=360&&_n>=315?"left":_n>=135&&_n<=225?"right":Cn===!0?_n>=35&&_n<=135?"up":"down":"vertical"},canGoNext=$n=>{let Cn=!0;return $n.infinite||($n.centerMode&&$n.currentSlide>=$n.slideCount-1||$n.slideCount<=$n.slidesToShow||$n.currentSlide>=$n.slideCount-$n.slidesToShow)&&(Cn=!1),Cn},extractObject=($n,Cn)=>{const _n={};return Cn.forEach(Pn=>_n[Pn]=$n[Pn]),_n},initializedState=$n=>{const Cn=$n.children.length,_n=$n.listRef,Pn=Math.ceil(getWidth(_n)),In=$n.trackRef,Nn=Math.ceil(getWidth(In));let Rn;if($n.vertical)Rn=Pn;else{let Wn=$n.centerMode&&parseInt($n.centerPadding)*2;typeof $n.centerPadding=="string"&&$n.centerPadding.slice(-1)==="%"&&(Wn*=Pn/100),Rn=Math.ceil((Pn-Wn)/$n.slidesToShow)}const Dn=_n&&getHeight(_n.querySelector('[data-index="0"]')),Ln=Dn*$n.slidesToShow;let Fn=$n.currentSlide===void 0?$n.initialSlide:$n.currentSlide;$n.rtl&&$n.currentSlide===void 0&&(Fn=Cn-1-$n.initialSlide);let Bn=$n.lazyLoadedList||[];const Hn=getOnDemandLazySlides(_extends$1(_extends$1({},$n),{currentSlide:Fn,lazyLoadedList:Bn}));Bn=Bn.concat(Hn);const zn={slideCount:Cn,slideWidth:Rn,listWidth:Pn,trackWidth:Nn,currentSlide:Fn,slideHeight:Dn,listHeight:Ln,lazyLoadedList:Bn};return $n.autoplaying===null&&$n.autoplay&&(zn.autoplaying="playing"),zn},slideHandler=$n=>{const{waitForAnimate:Cn,animating:_n,fade:Pn,infinite:In,index:Nn,slideCount:Rn,lazyLoad:Dn,currentSlide:Ln,centerMode:Fn,slidesToScroll:Bn,slidesToShow:Hn,useCSS:zn}=$n;let{lazyLoadedList:Wn}=$n;if(Cn&&_n)return{};let Yn=Nn,Gn,Go,Xn,Yo={},qo={};const Jo=In?Nn:clamp(Nn,0,Rn-1);if(Pn){if(!In&&(Nn<0||Nn>=Rn))return{};Nn<0?Yn=Nn+Rn:Nn>=Rn&&(Yn=Nn-Rn),Dn&&Wn.indexOf(Yn)<0&&(Wn=Wn.concat(Yn)),Yo={animating:!0,currentSlide:Yn,lazyLoadedList:Wn,targetSlide:Yn},qo={animating:!1,targetSlide:Yn}}else Gn=Yn,Yn<0?(Gn=Yn+Rn,In?Rn%Bn!==0&&(Gn=Rn-Rn%Bn):Gn=0):!canGoNext($n)&&Yn>Ln?Yn=Gn=Ln:Fn&&Yn>=Rn?(Yn=In?Rn:Rn-1,Gn=In?0:Rn-1):Yn>=Rn&&(Gn=Yn-Rn,In?Rn%Bn!==0&&(Gn=0):Gn=Rn-Hn),!In&&Yn+Hn>=Rn&&(Gn=Rn-Hn),Go=getTrackLeft(_extends$1(_extends$1({},$n),{slideIndex:Yn})),Xn=getTrackLeft(_extends$1(_extends$1({},$n),{slideIndex:Gn})),In||(Go===Xn&&(Yn=Gn),Go=Xn),Dn&&(Wn=Wn.concat(getOnDemandLazySlides(_extends$1(_extends$1({},$n),{currentSlide:Yn})))),zn?(Yo={animating:!0,currentSlide:Gn,trackStyle:getTrackAnimateCSS(_extends$1(_extends$1({},$n),{left:Go})),lazyLoadedList:Wn,targetSlide:Jo},qo={animating:!1,currentSlide:Gn,trackStyle:getTrackCSS(_extends$1(_extends$1({},$n),{left:Xn})),swipeLeft:null,targetSlide:Jo}):Yo={currentSlide:Gn,trackStyle:getTrackCSS(_extends$1(_extends$1({},$n),{left:Xn})),lazyLoadedList:Wn,targetSlide:Jo};return{state:Yo,nextState:qo}},changeSlide=($n,Cn)=>{let _n,Pn,In;const{slidesToScroll:Nn,slidesToShow:Rn,slideCount:Dn,currentSlide:Ln,targetSlide:Fn,lazyLoad:Bn,infinite:Hn}=$n,Wn=Dn%Nn!==0?0:(Dn-Ln)%Nn;if(Cn.message==="previous")Pn=Wn===0?Nn:Rn-Wn,In=Ln-Pn,Bn&&!Hn&&(_n=Ln-Pn,In=_n===-1?Dn-1:_n),Hn||(In=Fn-Nn);else if(Cn.message==="next")Pn=Wn===0?Nn:Wn,In=Ln+Pn,Bn&&!Hn&&(In=(Ln+Nn)%Dn+Wn),Hn||(In=Fn+Nn);else if(Cn.message==="dots")In=Cn.index*Cn.slidesToScroll;else if(Cn.message==="children"){if(In=Cn.index,Hn){const Yn=siblingDirection(_extends$1(_extends$1({},$n),{targetSlide:In}));In>Cn.currentSlide&&Yn==="left"?In=In-Dn:In$n.target.tagName.match("TEXTAREA|INPUT|SELECT")||!Cn?"":$n.keyCode===37?_n?"next":"previous":$n.keyCode===39?_n?"previous":"next":"",swipeStart=($n,Cn,_n)=>($n.target.tagName==="IMG"&&safePreventDefault($n),!Cn||!_n&&$n.type.indexOf("mouse")!==-1?"":{dragging:!0,touchObject:{startX:$n.touches?$n.touches[0].pageX:$n.clientX,startY:$n.touches?$n.touches[0].pageY:$n.clientY,curX:$n.touches?$n.touches[0].pageX:$n.clientX,curY:$n.touches?$n.touches[0].pageY:$n.clientY}}),swipeMove=($n,Cn)=>{const{scrolling:_n,animating:Pn,vertical:In,swipeToSlide:Nn,verticalSwiping:Rn,rtl:Dn,currentSlide:Ln,edgeFriction:Fn,edgeDragged:Bn,onEdge:Hn,swiped:zn,swiping:Wn,slideCount:Yn,slidesToScroll:Gn,infinite:Go,touchObject:Xn,swipeEvent:Yo,listHeight:qo,listWidth:Jo}=Cn;if(_n)return;if(Pn)return safePreventDefault($n);In&&Nn&&Rn&&safePreventDefault($n);let Zo,rr={};const nr=getTrackLeft(Cn);Xn.curX=$n.touches?$n.touches[0].pageX:$n.clientX,Xn.curY=$n.touches?$n.touches[0].pageY:$n.clientY,Xn.swipeLength=Math.round(Math.sqrt(Math.pow(Xn.curX-Xn.startX,2)));const ta=Math.round(Math.sqrt(Math.pow(Xn.curY-Xn.startY,2)));if(!Rn&&!Wn&&ta>10)return{scrolling:!0};Rn&&(Xn.swipeLength=ta);let oa=(Dn?-1:1)*(Xn.curX>Xn.startX?1:-1);Rn&&(oa=Xn.curY>Xn.startY?1:-1);const ra=Math.ceil(Yn/Gn),ea=getSwipeDirection(Cn.touchObject,Rn);let la=Xn.swipeLength;return Go||(Ln===0&&(ea==="right"||ea==="down")||Ln+1>=ra&&(ea==="left"||ea==="up")||!canGoNext(Cn)&&(ea==="left"||ea==="up"))&&(la=Xn.swipeLength*Fn,Bn===!1&&Hn&&(Hn(ea),rr.edgeDragged=!0)),!zn&&Yo&&(Yo(ea),rr.swiped=!0),In?Zo=nr+la*(qo/Jo)*oa:Dn?Zo=nr-la*oa:Zo=nr+la*oa,Rn&&(Zo=nr+la*oa),rr=_extends$1(_extends$1({},rr),{touchObject:Xn,swipeLeft:Zo,trackStyle:getTrackCSS(_extends$1(_extends$1({},Cn),{left:Zo}))}),Math.abs(Xn.curX-Xn.startX)10&&(rr.swiping=!0,safePreventDefault($n)),rr},swipeEnd=($n,Cn)=>{const{dragging:_n,swipe:Pn,touchObject:In,listWidth:Nn,touchThreshold:Rn,verticalSwiping:Dn,listHeight:Ln,swipeToSlide:Fn,scrolling:Bn,onSwipe:Hn,targetSlide:zn,currentSlide:Wn,infinite:Yn}=Cn;if(!_n)return Pn&&safePreventDefault($n),{};const Gn=Dn?Ln/Rn:Nn/Rn,Go=getSwipeDirection(In,Dn),Xn={dragging:!1,edgeDragged:!1,scrolling:!1,swiping:!1,swiped:!1,swipeLeft:null,touchObject:{}};if(Bn||!In.swipeLength)return Xn;if(In.swipeLength>Gn){safePreventDefault($n),Hn&&Hn(Go);let Yo,qo;const Jo=Yn?Wn:zn;switch(Go){case"left":case"up":qo=Jo+getSlideCount(Cn),Yo=Fn?checkNavigable(Cn,qo):qo,Xn.currentDirection=0;break;case"right":case"down":qo=Jo-getSlideCount(Cn),Yo=Fn?checkNavigable(Cn,qo):qo,Xn.currentDirection=1;break;default:Yo=Jo}Xn.triggerSlideHandler=Yo}else{const Yo=getTrackLeft(Cn);Xn.trackStyle=getTrackAnimateCSS(_extends$1(_extends$1({},Cn),{left:Yo}))}return Xn},getNavigableIndexes=$n=>{const Cn=$n.infinite?$n.slideCount*2:$n.slideCount;let _n=$n.infinite?$n.slidesToShow*-1:0,Pn=$n.infinite?$n.slidesToShow*-1:0;const In=[];for(;_n{const _n=getNavigableIndexes($n);let Pn=0;if(Cn>_n[_n.length-1])Cn=_n[_n.length-1];else for(const In in _n){if(Cn<_n[In]){Cn=Pn;break}Pn=_n[In]}return Cn},getSlideCount=$n=>{const Cn=$n.centerMode?$n.slideWidth*Math.floor($n.slidesToShow/2):0;if($n.swipeToSlide){let _n;const Pn=$n.listRef,In=Pn.querySelectorAll&&Pn.querySelectorAll(".slick-slide")||[];if(Array.from(In).every(Dn=>{if($n.vertical){if(Dn.offsetTop+getHeight(Dn)/2>$n.swipeLeft*-1)return _n=Dn,!1}else if(Dn.offsetLeft-Cn+getWidth(Dn)/2>$n.swipeLeft*-1)return _n=Dn,!1;return!0}),!_n)return 0;const Nn=$n.rtl===!0?$n.slideCount-$n.currentSlide:$n.currentSlide;return Math.abs(_n.dataset.index-Nn)||1}else return $n.slidesToScroll},checkSpecKeys=($n,Cn)=>Cn.reduce((_n,Pn)=>_n&&$n.hasOwnProperty(Pn),!0)?null:console.error("Keys Missing:",$n),getTrackCSS=$n=>{checkSpecKeys($n,["left","variableWidth","slideCount","slidesToShow","slideWidth"]);let Cn,_n;const Pn=$n.slideCount+2*$n.slidesToShow;$n.vertical?_n=Pn*$n.slideHeight:Cn=getTotalSlides($n)*$n.slideWidth;let In={opacity:1,transition:"",WebkitTransition:""};if($n.useTransform){const Nn=$n.vertical?"translate3d(0px, "+$n.left+"px, 0px)":"translate3d("+$n.left+"px, 0px, 0px)",Rn=$n.vertical?"translate3d(0px, "+$n.left+"px, 0px)":"translate3d("+$n.left+"px, 0px, 0px)",Dn=$n.vertical?"translateY("+$n.left+"px)":"translateX("+$n.left+"px)";In=_extends$1(_extends$1({},In),{WebkitTransform:Nn,transform:Rn,msTransform:Dn})}else $n.vertical?In.top=$n.left:In.left=$n.left;return $n.fade&&(In={opacity:1}),Cn&&(In.width=Cn+"px"),_n&&(In.height=_n+"px"),window&&!window.addEventListener&&window.attachEvent&&($n.vertical?In.marginTop=$n.left+"px":In.marginLeft=$n.left+"px"),In},getTrackAnimateCSS=$n=>{checkSpecKeys($n,["left","variableWidth","slideCount","slidesToShow","slideWidth","speed","cssEase"]);const Cn=getTrackCSS($n);return $n.useTransform?(Cn.WebkitTransition="-webkit-transform "+$n.speed+"ms "+$n.cssEase,Cn.transition="transform "+$n.speed+"ms "+$n.cssEase):$n.vertical?Cn.transition="top "+$n.speed+"ms "+$n.cssEase:Cn.transition="left "+$n.speed+"ms "+$n.cssEase,Cn},getTrackLeft=$n=>{if($n.unslick)return 0;checkSpecKeys($n,["slideIndex","trackRef","infinite","centerMode","slideCount","slidesToShow","slidesToScroll","slideWidth","listWidth","variableWidth","slideHeight"]);const{slideIndex:Cn,trackRef:_n,infinite:Pn,centerMode:In,slideCount:Nn,slidesToShow:Rn,slidesToScroll:Dn,slideWidth:Ln,listWidth:Fn,variableWidth:Bn,slideHeight:Hn,fade:zn,vertical:Wn}=$n;let Yn=0,Gn,Go,Xn=0;if(zn||$n.slideCount===1)return 0;let Yo=0;if(Pn?(Yo=-getPreClones($n),Nn%Dn!==0&&Cn+Dn>Nn&&(Yo=-(Cn>Nn?Rn-(Cn-Nn):Nn%Dn)),In&&(Yo+=parseInt(Rn/2))):(Nn%Dn!==0&&Cn+Dn>Nn&&(Yo=Rn-Nn%Dn),In&&(Yo=parseInt(Rn/2))),Yn=Yo*Ln,Xn=Yo*Hn,Wn?Gn=Cn*Hn*-1+Xn:Gn=Cn*Ln*-1+Yn,Bn===!0){let qo;const Jo=_n;if(qo=Cn+getPreClones($n),Go=Jo&&Jo.childNodes[qo],Gn=Go?Go.offsetLeft*-1:0,In===!0){qo=Pn?Cn+getPreClones($n):Cn,Go=Jo&&Jo.children[qo],Gn=0;for(let Zo=0;Zo$n.unslick||!$n.infinite?0:$n.variableWidth?$n.slideCount:$n.slidesToShow+($n.centerMode?1:0),getPostClones=$n=>$n.unslick||!$n.infinite?0:$n.slideCount,getTotalSlides=$n=>$n.slideCount===1?1:getPreClones($n)+$n.slideCount+getPostClones($n),siblingDirection=$n=>$n.targetSlide>$n.currentSlide?$n.targetSlide>$n.currentSlide+slidesOnRight($n)?"left":"right":$n.targetSlide<$n.currentSlide-slidesOnLeft($n)?"right":"left",slidesOnRight=$n=>{let{slidesToShow:Cn,centerMode:_n,rtl:Pn,centerPadding:In}=$n;if(_n){let Nn=(Cn-1)/2+1;return parseInt(In)>0&&(Nn+=1),Pn&&Cn%2===0&&(Nn+=1),Nn}return Pn?0:Cn-1},slidesOnLeft=$n=>{let{slidesToShow:Cn,centerMode:_n,rtl:Pn,centerPadding:In}=$n;if(_n){let Nn=(Cn-1)/2+1;return parseInt(In)>0&&(Nn+=1),!Pn&&Cn%2===0&&(Nn+=1),Nn}return Pn?Cn-1:0},canUseDOM=()=>!!(typeof window<"u"&&window.document&&window.document.createElement),getSlideClasses=$n=>{let Cn,_n,Pn,In;$n.rtl?In=$n.slideCount-1-$n.index:In=$n.index;const Nn=In<0||In>=$n.slideCount;$n.centerMode?(Pn=Math.floor($n.slidesToShow/2),_n=(In-$n.currentSlide)%$n.slideCount===0,In>$n.currentSlide-Pn-1&&In<=$n.currentSlide+Pn&&(Cn=!0)):Cn=$n.currentSlide<=In&&In<$n.currentSlide+$n.slidesToShow;let Rn;return $n.targetSlide<0?Rn=$n.targetSlide+$n.slideCount:$n.targetSlide>=$n.slideCount?Rn=$n.targetSlide-$n.slideCount:Rn=$n.targetSlide,{"slick-slide":!0,"slick-active":Cn,"slick-center":_n,"slick-cloned":Nn,"slick-current":In===Rn}},getSlideStyle=function($n){const Cn={};return($n.variableWidth===void 0||$n.variableWidth===!1)&&(Cn.width=$n.slideWidth+(typeof $n.slideWidth=="number"?"px":"")),$n.fade&&(Cn.position="relative",$n.vertical?Cn.top=-$n.index*parseInt($n.slideHeight)+"px":Cn.left=-$n.index*parseInt($n.slideWidth)+"px",Cn.opacity=$n.currentSlide===$n.index?1:0,$n.useCSS&&(Cn.transition="opacity "+$n.speed+"ms "+$n.cssEase+", visibility "+$n.speed+"ms "+$n.cssEase)),Cn},getKey$1=($n,Cn)=>$n.key+"-"+Cn,renderSlides=function($n,Cn){let _n;const Pn=[],In=[],Nn=[],Rn=Cn.length,Dn=lazyStartIndex($n),Ln=lazyEndIndex($n);return Cn.forEach((Fn,Bn)=>{let Hn;const zn={message:"children",index:Bn,slidesToScroll:$n.slidesToScroll,currentSlide:$n.currentSlide};!$n.lazyLoad||$n.lazyLoad&&$n.lazyLoadedList.indexOf(Bn)>=0?Hn=Fn:Hn=createVNode("div");const Wn=getSlideStyle(_extends$1(_extends$1({},$n),{index:Bn})),Yn=Hn.props.class||"";let Gn=getSlideClasses(_extends$1(_extends$1({},$n),{index:Bn}));if(Pn.push(deepCloneElement(Hn,{key:"original"+getKey$1(Hn,Bn),tabindex:"-1","data-index":Bn,"aria-hidden":!Gn["slick-active"],class:classNames(Gn,Yn),style:_extends$1(_extends$1({outline:"none"},Hn.props.style||{}),Wn),onClick:()=>{$n.focusOnSelect&&$n.focusOnSelect(zn)}})),$n.infinite&&$n.fade===!1){const Go=Rn-Bn;Go<=getPreClones($n)&&Rn!==$n.slidesToShow&&(_n=-Go,_n>=Dn&&(Hn=Fn),Gn=getSlideClasses(_extends$1(_extends$1({},$n),{index:_n})),In.push(deepCloneElement(Hn,{key:"precloned"+getKey$1(Hn,_n),class:classNames(Gn,Yn),tabindex:"-1","data-index":_n,"aria-hidden":!Gn["slick-active"],style:_extends$1(_extends$1({},Hn.props.style||{}),Wn),onClick:()=>{$n.focusOnSelect&&$n.focusOnSelect(zn)}}))),Rn!==$n.slidesToShow&&(_n=Rn+Bn,_n{$n.focusOnSelect&&$n.focusOnSelect(zn)}})))}}),$n.rtl?In.concat(Pn,Nn).reverse():In.concat(Pn,Nn)},Track$2=($n,Cn)=>{let{attrs:_n,slots:Pn}=Cn;const In=renderSlides(_n,flattenChildren(Pn==null?void 0:Pn.default())),{onMouseenter:Nn,onMouseover:Rn,onMouseleave:Dn}=_n,Ln={onMouseenter:Nn,onMouseover:Rn,onMouseleave:Dn},Fn=_extends$1({class:"slick-track",style:_n.trackStyle},Ln);return createVNode("div",Fn,[In])};Track$2.inheritAttrs=!1;const Track$3=Track$2,getDotCount=function($n){let Cn;return $n.infinite?Cn=Math.ceil($n.slideCount/$n.slidesToScroll):Cn=Math.ceil(($n.slideCount-$n.slidesToShow)/$n.slidesToScroll)+1,Cn},Dots=($n,Cn)=>{let{attrs:_n}=Cn;const{slideCount:Pn,slidesToScroll:In,slidesToShow:Nn,infinite:Rn,currentSlide:Dn,appendDots:Ln,customPaging:Fn,clickHandler:Bn,dotsClass:Hn,onMouseenter:zn,onMouseover:Wn,onMouseleave:Yn}=_n,Gn=getDotCount({slideCount:Pn,slidesToScroll:In,slidesToShow:Nn,infinite:Rn}),Go={onMouseenter:zn,onMouseover:Wn,onMouseleave:Yn};let Xn=[];for(let Yo=0;Yo=rr&&Dn<=Jo:Dn===rr}),ta={message:"dots",index:Yo,slidesToScroll:In,currentSlide:Dn};Xn=Xn.concat(createVNode("li",{key:Yo,class:nr},[cloneElement(Fn({i:Yo}),{onClick:oa})]))}return cloneElement(Ln({dots:Xn}),_extends$1({class:Hn},Go))};Dots.inheritAttrs=!1;const Dots$1=Dots;function noop$a(){}function handler($n,Cn,_n){_n&&_n.preventDefault(),Cn($n,_n)}const PrevArrow=($n,Cn)=>{let{attrs:_n}=Cn;const{clickHandler:Pn,infinite:In,currentSlide:Nn,slideCount:Rn,slidesToShow:Dn}=_n,Ln={"slick-arrow":!0,"slick-prev":!0};let Fn=function(Wn){handler({message:"previous"},Pn,Wn)};!In&&(Nn===0||Rn<=Dn)&&(Ln["slick-disabled"]=!0,Fn=noop$a);const Bn={key:"0","data-role":"none",class:Ln,style:{display:"block"},onClick:Fn},Hn={currentSlide:Nn,slideCount:Rn};let zn;return _n.prevArrow?zn=cloneElement(_n.prevArrow(_extends$1(_extends$1({},Bn),Hn)),{key:"0",class:Ln,style:{display:"block"},onClick:Fn},!1):zn=createVNode("button",_objectSpread2$1({key:"0",type:"button"},Bn),[" ",createTextVNode("Previous")]),zn};PrevArrow.inheritAttrs=!1;const NextArrow=($n,Cn)=>{let{attrs:_n}=Cn;const{clickHandler:Pn,currentSlide:In,slideCount:Nn}=_n,Rn={"slick-arrow":!0,"slick-next":!0};let Dn=function(Hn){handler({message:"next"},Pn,Hn)};canGoNext(_n)||(Rn["slick-disabled"]=!0,Dn=noop$a);const Ln={key:"1","data-role":"none",class:classNames(Rn),style:{display:"block"},onClick:Dn},Fn={currentSlide:In,slideCount:Nn};let Bn;return _n.nextArrow?Bn=cloneElement(_n.nextArrow(_extends$1(_extends$1({},Ln),Fn)),{key:"1",class:classNames(Rn),style:{display:"block"},onClick:Dn},!1):Bn=createVNode("button",_objectSpread2$1({key:"1",type:"button"},Ln),[" ",createTextVNode("Next")]),Bn};NextArrow.inheritAttrs=!1;var __rest$W=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{this.currentSlide>=$n.children.length&&this.changeSlide({message:"index",index:$n.children.length-$n.slidesToShow,currentSlide:this.currentSlide}),!this.preProps.autoplay&&$n.autoplay?this.handleAutoPlay("playing"):$n.autoplay?this.handleAutoPlay("update"):this.pause("paused")}),this.preProps=_extends$1({},$n)}},mounted(){if(this.__emit("init"),this.lazyLoad){const $n=getOnDemandLazySlides(_extends$1(_extends$1({},this.$props),this.$data));$n.length>0&&(this.setState(Cn=>({lazyLoadedList:Cn.lazyLoadedList.concat($n)})),this.__emit("lazyLoad",$n))}this.$nextTick(()=>{const $n=_extends$1({listRef:this.list,trackRef:this.track,children:this.children},this.$props);this.updateState($n,!0,()=>{this.adaptHeight(),this.autoplay&&this.handleAutoPlay("playing")}),this.lazyLoad==="progressive"&&(this.lazyLoadTimer=setInterval(this.progressiveLazyLoad,1e3)),this.ro=new ResizeObserver$3(()=>{this.animating?(this.onWindowResized(!1),this.callbackTimers.push(setTimeout(()=>this.onWindowResized(),this.speed))):this.onWindowResized()}),this.ro.observe(this.list),document.querySelectorAll&&Array.prototype.forEach.call(document.querySelectorAll(".slick-slide"),Cn=>{Cn.onfocus=this.$props.pauseOnFocus?this.onSlideFocus:null,Cn.onblur=this.$props.pauseOnFocus?this.onSlideBlur:null}),window.addEventListener?window.addEventListener("resize",this.onWindowResized):window.attachEvent("onresize",this.onWindowResized)})},beforeUnmount(){var $n;this.animationEndCallback&&clearTimeout(this.animationEndCallback),this.lazyLoadTimer&&clearInterval(this.lazyLoadTimer),this.callbackTimers.length&&(this.callbackTimers.forEach(Cn=>clearTimeout(Cn)),this.callbackTimers=[]),window.addEventListener?window.removeEventListener("resize",this.onWindowResized):window.detachEvent("onresize",this.onWindowResized),this.autoplayTimer&&clearInterval(this.autoplayTimer),($n=this.ro)===null||$n===void 0||$n.disconnect()},updated(){if(this.checkImagesLoad(),this.__emit("reInit"),this.lazyLoad){const $n=getOnDemandLazySlides(_extends$1(_extends$1({},this.$props),this.$data));$n.length>0&&(this.setState(Cn=>({lazyLoadedList:Cn.lazyLoadedList.concat($n)})),this.__emit("lazyLoad"))}this.adaptHeight()},methods:{listRefHandler($n){this.list=$n},trackRefHandler($n){this.track=$n},adaptHeight(){if(this.adaptiveHeight&&this.list){const $n=this.list.querySelector(`[data-index="${this.currentSlide}"]`);this.list.style.height=getHeight($n)+"px"}},onWindowResized($n){this.debouncedResize&&this.debouncedResize.cancel(),this.debouncedResize=debounce$2(()=>this.resizeWindow($n),50),this.debouncedResize()},resizeWindow(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;if(!!!this.track)return;const _n=_extends$1(_extends$1({listRef:this.list,trackRef:this.track,children:this.children},this.$props),this.$data);this.updateState(_n,$n,()=>{this.autoplay?this.handleAutoPlay("update"):this.pause("paused")}),this.setState({animating:!1}),clearTimeout(this.animationEndCallback),delete this.animationEndCallback},updateState($n,Cn,_n){const Pn=initializedState($n);$n=_extends$1(_extends$1(_extends$1({},$n),Pn),{slideIndex:Pn.currentSlide});const In=getTrackLeft($n);$n=_extends$1(_extends$1({},$n),{left:In});const Nn=getTrackCSS($n);(Cn||this.children.length!==$n.children.length)&&(Pn.trackStyle=Nn),this.setState(Pn,_n)},ssrInit(){const $n=this.children;if(this.variableWidth){let Ln=0,Fn=0;const Bn=[],Hn=getPreClones(_extends$1(_extends$1(_extends$1({},this.$props),this.$data),{slideCount:$n.length})),zn=getPostClones(_extends$1(_extends$1(_extends$1({},this.$props),this.$data),{slideCount:$n.length}));$n.forEach(Yn=>{var Gn,Go;const Xn=((Go=(Gn=Yn.props.style)===null||Gn===void 0?void 0:Gn.width)===null||Go===void 0?void 0:Go.split("px")[0])||0;Bn.push(Xn),Ln+=Xn});for(let Yn=0;Yn{const In=()=>++_n&&_n>=Cn&&this.onWindowResized();if(!Pn.onclick)Pn.onclick=()=>Pn.parentNode.focus();else{const Nn=Pn.onclick;Pn.onclick=()=>{Nn(),Pn.parentNode.focus()}}Pn.onload||(this.$props.lazyLoad?Pn.onload=()=>{this.adaptHeight(),this.callbackTimers.push(setTimeout(this.onWindowResized,this.speed))}:(Pn.onload=In,Pn.onerror=()=>{In(),this.__emit("lazyLoadError")}))})},progressiveLazyLoad(){const $n=[],Cn=_extends$1(_extends$1({},this.$props),this.$data);for(let _n=this.currentSlide;_n=-getPreClones(Cn);_n--)if(this.lazyLoadedList.indexOf(_n)<0){$n.push(_n);break}$n.length>0?(this.setState(_n=>({lazyLoadedList:_n.lazyLoadedList.concat($n)})),this.__emit("lazyLoad",$n)):this.lazyLoadTimer&&(clearInterval(this.lazyLoadTimer),delete this.lazyLoadTimer)},slideHandler($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const{asNavFor:_n,currentSlide:Pn,beforeChange:In,speed:Nn,afterChange:Rn}=this.$props,{state:Dn,nextState:Ln}=slideHandler(_extends$1(_extends$1(_extends$1({index:$n},this.$props),this.$data),{trackRef:this.track,useCSS:this.useCSS&&!Cn}));if(!Dn)return;In&&In(Pn,Dn.currentSlide);const Fn=Dn.lazyLoadedList.filter(Bn=>this.lazyLoadedList.indexOf(Bn)<0);this.$attrs.onLazyLoad&&Fn.length>0&&this.__emit("lazyLoad",Fn),!this.$props.waitForAnimate&&this.animationEndCallback&&(clearTimeout(this.animationEndCallback),Rn&&Rn(Pn),delete this.animationEndCallback),this.setState(Dn,()=>{_n&&this.asNavForIndex!==$n&&(this.asNavForIndex=$n,_n.innerSlider.slideHandler($n)),Ln&&(this.animationEndCallback=setTimeout(()=>{const{animating:Bn}=Ln,Hn=__rest$W(Ln,["animating"]);this.setState(Hn,()=>{this.callbackTimers.push(setTimeout(()=>this.setState({animating:Bn}),10)),Rn&&Rn(Dn.currentSlide),delete this.animationEndCallback})},Nn))})},changeSlide($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const _n=_extends$1(_extends$1({},this.$props),this.$data),Pn=changeSlide(_n,$n);if(!(Pn!==0&&!Pn)&&(Cn===!0?this.slideHandler(Pn,Cn):this.slideHandler(Pn),this.$props.autoplay&&this.handleAutoPlay("update"),this.$props.focusOnSelect)){const In=this.list.querySelectorAll(".slick-current");In[0]&&In[0].focus()}},clickHandler($n){this.clickable===!1&&($n.stopPropagation(),$n.preventDefault()),this.clickable=!0},keyHandler($n){const Cn=keyHandler($n,this.accessibility,this.rtl);Cn!==""&&this.changeSlide({message:Cn})},selectHandler($n){this.changeSlide($n)},disableBodyScroll(){const $n=Cn=>{Cn=Cn||window.event,Cn.preventDefault&&Cn.preventDefault(),Cn.returnValue=!1};window.ontouchmove=$n},enableBodyScroll(){window.ontouchmove=null},swipeStart($n){this.verticalSwiping&&this.disableBodyScroll();const Cn=swipeStart($n,this.swipe,this.draggable);Cn!==""&&this.setState(Cn)},swipeMove($n){const Cn=swipeMove($n,_extends$1(_extends$1(_extends$1({},this.$props),this.$data),{trackRef:this.track,listRef:this.list,slideIndex:this.currentSlide}));Cn&&(Cn.swiping&&(this.clickable=!1),this.setState(Cn))},swipeEnd($n){const Cn=swipeEnd($n,_extends$1(_extends$1(_extends$1({},this.$props),this.$data),{trackRef:this.track,listRef:this.list,slideIndex:this.currentSlide}));if(!Cn)return;const _n=Cn.triggerSlideHandler;delete Cn.triggerSlideHandler,this.setState(Cn),_n!==void 0&&(this.slideHandler(_n),this.$props.verticalSwiping&&this.enableBodyScroll())},touchEnd($n){this.swipeEnd($n),this.clickable=!0},slickPrev(){this.callbackTimers.push(setTimeout(()=>this.changeSlide({message:"previous"}),0))},slickNext(){this.callbackTimers.push(setTimeout(()=>this.changeSlide({message:"next"}),0))},slickGoTo($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if($n=Number($n),isNaN($n))return"";this.callbackTimers.push(setTimeout(()=>this.changeSlide({message:"index",index:$n,currentSlide:this.currentSlide},Cn),0))},play(){let $n;if(this.rtl)$n=this.currentSlide-this.slidesToScroll;else if(canGoNext(_extends$1(_extends$1({},this.$props),this.$data)))$n=this.currentSlide+this.slidesToScroll;else return!1;this.slideHandler($n)},handleAutoPlay($n){this.autoplayTimer&&clearInterval(this.autoplayTimer);const Cn=this.autoplaying;if($n==="update"){if(Cn==="hovered"||Cn==="focused"||Cn==="paused")return}else if($n==="leave"){if(Cn==="paused"||Cn==="focused")return}else if($n==="blur"&&(Cn==="paused"||Cn==="hovered"))return;this.autoplayTimer=setInterval(this.play,this.autoplaySpeed+50),this.setState({autoplaying:"playing"})},pause($n){this.autoplayTimer&&(clearInterval(this.autoplayTimer),this.autoplayTimer=null);const Cn=this.autoplaying;$n==="paused"?this.setState({autoplaying:"paused"}):$n==="focused"?(Cn==="hovered"||Cn==="playing")&&this.setState({autoplaying:"focused"}):Cn==="playing"&&this.setState({autoplaying:"hovered"})},onDotsOver(){this.autoplay&&this.pause("hovered")},onDotsLeave(){this.autoplay&&this.autoplaying==="hovered"&&this.handleAutoPlay("leave")},onTrackOver(){this.autoplay&&this.pause("hovered")},onTrackLeave(){this.autoplay&&this.autoplaying==="hovered"&&this.handleAutoPlay("leave")},onSlideFocus(){this.autoplay&&this.pause("focused")},onSlideBlur(){this.autoplay&&this.autoplaying==="focused"&&this.handleAutoPlay("blur")},customPaging($n){let{i:Cn}=$n;return createVNode("button",null,[Cn+1])},appendDots($n){let{dots:Cn}=$n;return createVNode("ul",{style:{display:"block"}},[Cn])}},render(){const $n=classNames("slick-slider",this.$attrs.class,{"slick-vertical":this.vertical,"slick-initialized":!0}),Cn=_extends$1(_extends$1({},this.$props),this.$data);let _n=extractObject(Cn,["fade","cssEase","speed","infinite","centerMode","focusOnSelect","currentSlide","lazyLoad","lazyLoadedList","rtl","slideWidth","slideHeight","listHeight","vertical","slidesToShow","slidesToScroll","slideCount","trackStyle","variableWidth","unslick","centerPadding","targetSlide","useCSS"]);const{pauseOnHover:Pn}=this.$props;_n=_extends$1(_extends$1({},_n),{focusOnSelect:this.focusOnSelect&&this.clickable?this.selectHandler:null,ref:this.trackRefHandler,onMouseleave:Pn?this.onTrackLeave:noop$9,onMouseover:Pn?this.onTrackOver:noop$9});let In;if(this.dots===!0&&this.slideCount>=this.slidesToShow){let Go=extractObject(Cn,["dotsClass","slideCount","slidesToShow","currentSlide","slidesToScroll","clickHandler","children","infinite","appendDots"]);Go.customPaging=this.customPaging,Go.appendDots=this.appendDots;const{customPaging:Xn,appendDots:Yo}=this.$slots;Xn&&(Go.customPaging=Xn),Yo&&(Go.appendDots=Yo);const{pauseOnDotsHover:qo}=this.$props;Go=_extends$1(_extends$1({},Go),{clickHandler:this.changeSlide,onMouseover:qo?this.onDotsOver:noop$9,onMouseleave:qo?this.onDotsLeave:noop$9}),In=createVNode(Dots$1,Go,null)}let Nn,Rn;const Dn=extractObject(Cn,["infinite","centerMode","currentSlide","slideCount","slidesToShow"]);Dn.clickHandler=this.changeSlide;const{prevArrow:Ln,nextArrow:Fn}=this.$slots;Ln&&(Dn.prevArrow=Ln),Fn&&(Dn.nextArrow=Fn),this.arrows&&(Nn=createVNode(PrevArrow,Dn,null),Rn=createVNode(NextArrow,Dn,null));let Bn=null;this.vertical&&(Bn={height:typeof this.listHeight=="number"?`${this.listHeight}px`:this.listHeight});let Hn=null;this.vertical===!1?this.centerMode===!0&&(Hn={padding:"0px "+this.centerPadding}):this.centerMode===!0&&(Hn={padding:this.centerPadding+" 0px"});const zn=_extends$1(_extends$1({},Bn),Hn),Wn=this.touchMove;let Yn={ref:this.listRefHandler,class:"slick-list",style:zn,onClick:this.clickHandler,onMousedown:Wn?this.swipeStart:noop$9,onMousemove:this.dragging&&Wn?this.swipeMove:noop$9,onMouseup:Wn?this.swipeEnd:noop$9,onMouseleave:this.dragging&&Wn?this.swipeEnd:noop$9,[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]:Wn?this.swipeStart:noop$9,[supportsPassive$1?"onTouchmovePassive":"onTouchmove"]:this.dragging&&Wn?this.swipeMove:noop$9,onTouchend:Wn?this.touchEnd:noop$9,onTouchcancel:this.dragging&&Wn?this.swipeEnd:noop$9,onKeydown:this.accessibility?this.keyHandler:noop$9},Gn={class:$n,dir:"ltr",style:this.$attrs.style};return this.unslick&&(Yn={class:"slick-list",ref:this.listRefHandler},Gn={class:$n}),createVNode("div",Gn,[this.unslick?"":Nn,createVNode("div",Yn,[createVNode(Track$3,_n,{default:()=>[this.children]})]),this.unslick?"":Rn,this.unslick?"":In])}},Slider$2=defineComponent({name:"Slider",mixins:[BaseMixin],inheritAttrs:!1,props:_extends$1({},defaultProps$3),data(){return this._responsiveMediaHandlers=[],{breakpoint:null}},mounted(){if(this.responsive){const $n=this.responsive.map(_n=>_n.breakpoint);$n.sort((_n,Pn)=>_n-Pn),$n.forEach((_n,Pn)=>{let In;Pn===0?In=json2mq({minWidth:0,maxWidth:_n}):In=json2mq({minWidth:$n[Pn-1]+1,maxWidth:_n}),canUseDOM()&&this.media(In,()=>{this.setState({breakpoint:_n})})});const Cn=json2mq({minWidth:$n.slice(-1)[0]});canUseDOM()&&this.media(Cn,()=>{this.setState({breakpoint:null})})}},beforeUnmount(){this._responsiveMediaHandlers.forEach(function($n){$n.mql.removeListener($n.listener)})},methods:{innerSliderRefHandler($n){this.innerSlider=$n},media($n,Cn){const _n=window.matchMedia($n),Pn=In=>{let{matches:Nn}=In;Nn&&Cn()};_n.addListener(Pn),Pn(_n),this._responsiveMediaHandlers.push({mql:_n,query:$n,listener:Pn})},slickPrev(){var $n;($n=this.innerSlider)===null||$n===void 0||$n.slickPrev()},slickNext(){var $n;($n=this.innerSlider)===null||$n===void 0||$n.slickNext()},slickGoTo($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;var _n;(_n=this.innerSlider)===null||_n===void 0||_n.slickGoTo($n,Cn)},slickPause(){var $n;($n=this.innerSlider)===null||$n===void 0||$n.pause("paused")},slickPlay(){var $n;($n=this.innerSlider)===null||$n===void 0||$n.handleAutoPlay("play")}},render(){var $n;let Cn,_n;this.breakpoint?(_n=this.responsive.filter(Dn=>Dn.breakpoint===this.breakpoint),Cn=_n[0].settings==="unslick"?"unslick":_extends$1(_extends$1({},this.$props),_n[0].settings)):Cn=_extends$1({},this.$props),Cn.centerMode&&(Cn.slidesToScroll>1,Cn.slidesToScroll=1),Cn.fade&&(Cn.slidesToShow>1,Cn.slidesToScroll>1,Cn.slidesToShow=1,Cn.slidesToScroll=1);let Pn=getSlot(this)||[];Pn=Pn.filter(Dn=>typeof Dn=="string"?!!Dn.trim():!!Dn),Cn.variableWidth&&(Cn.rows>1||Cn.slidesPerRow>1)&&(console.warn("variableWidth is not supported in case of rows > 1 or slidesPerRow > 1"),Cn.variableWidth=!1);const In=[];let Nn=null;for(let Dn=0;Dn=Pn.length));Hn+=1)Bn.push(cloneElement(Pn[Hn],{key:100*Dn+10*Fn+Hn,tabindex:-1,style:{width:`${100/Cn.slidesPerRow}%`,display:"inline-block"}}));Ln.push(createVNode("div",{key:10*Dn+Fn},[Bn]))}Cn.variableWidth?In.push(createVNode("div",{key:Dn,style:{width:Nn}},[Ln])):In.push(createVNode("div",{key:Dn},[Ln]))}if(Cn==="unslick"){const Dn="regular slider "+(this.className||"");return createVNode("div",{class:Dn},[Pn])}else In.length<=Cn.slidesToShow&&(Cn.unslick=!0);const Rn=_extends$1(_extends$1(_extends$1({},this.$attrs),Cn),{children:In,ref:this.innerSliderRefHandler});return createVNode(InnerSlider,_objectSpread2$1(_objectSpread2$1({},Rn),{},{__propsSymbol__:[]}),this.$slots)}}),genCarouselStyle=$n=>{const{componentCls:Cn,antCls:_n,carouselArrowSize:Pn,carouselDotOffset:In,marginXXS:Nn}=$n,Rn=-Pn*1.25,Dn=Nn;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{".slick-slider":{position:"relative",display:"block",boxSizing:"border-box",touchAction:"pan-y",WebkitTouchCallout:"none",WebkitTapHighlightColor:"transparent",".slick-track, .slick-list":{transform:"translate3d(0, 0, 0)",touchAction:"pan-y"}},".slick-list":{position:"relative",display:"block",margin:0,padding:0,overflow:"hidden","&:focus":{outline:"none"},"&.dragging":{cursor:"pointer"},".slick-slide":{pointerEvents:"none",[`input${_n}-radio-input, input${_n}-checkbox-input`]:{visibility:"hidden"},"&.slick-active":{pointerEvents:"auto",[`input${_n}-radio-input, input${_n}-checkbox-input`]:{visibility:"visible"}},"> div > div":{verticalAlign:"bottom"}}},".slick-track":{position:"relative",top:0,insetInlineStart:0,display:"block","&::before, &::after":{display:"table",content:'""'},"&::after":{clear:"both"}},".slick-slide":{display:"none",float:"left",height:"100%",minHeight:1,img:{display:"block"},"&.dragging img":{pointerEvents:"none"}},".slick-initialized .slick-slide":{display:"block"},".slick-vertical .slick-slide":{display:"block",height:"auto"},".slick-arrow.slick-hidden":{display:"none"},".slick-prev, .slick-next":{position:"absolute",top:"50%",display:"block",width:Pn,height:Pn,marginTop:-Pn/2,padding:0,color:"transparent",fontSize:0,lineHeight:0,background:"transparent",border:0,outline:"none",cursor:"pointer","&:hover, &:focus":{color:"transparent",background:"transparent",outline:"none","&::before":{opacity:1}},"&.slick-disabled::before":{opacity:.25}},".slick-prev":{insetInlineStart:Rn,"&::before":{content:'"←"'}},".slick-next":{insetInlineEnd:Rn,"&::before":{content:'"→"'}},".slick-dots":{position:"absolute",insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:15,display:"flex !important",justifyContent:"center",paddingInlineStart:0,listStyle:"none","&-bottom":{bottom:In},"&-top":{top:In,bottom:"auto"},li:{position:"relative",display:"inline-block",flex:"0 1 auto",boxSizing:"content-box",width:$n.dotWidth,height:$n.dotHeight,marginInline:Dn,padding:0,textAlign:"center",textIndent:-999,verticalAlign:"top",transition:`all ${$n.motionDurationSlow}`,button:{position:"relative",display:"block",width:"100%",height:$n.dotHeight,padding:0,color:"transparent",fontSize:0,background:$n.colorBgContainer,border:0,borderRadius:1,outline:"none",cursor:"pointer",opacity:.3,transition:`all ${$n.motionDurationSlow}`,"&: hover, &:focus":{opacity:.75},"&::after":{position:"absolute",inset:-Dn,content:'""'}},"&.slick-active":{width:$n.dotWidthActive,"& button":{background:$n.colorBgContainer,opacity:1},"&: hover, &:focus":{opacity:1}}}}})}},genCarouselVerticalStyle=$n=>{const{componentCls:Cn,carouselDotOffset:_n,marginXXS:Pn}=$n,In={width:$n.dotHeight,height:$n.dotWidth};return{[`${Cn}-vertical`]:{".slick-dots":{top:"50%",bottom:"auto",flexDirection:"column",width:$n.dotHeight,height:"auto",margin:0,transform:"translateY(-50%)","&-left":{insetInlineEnd:"auto",insetInlineStart:_n},"&-right":{insetInlineEnd:_n,insetInlineStart:"auto"},li:_extends$1(_extends$1({},In),{margin:`${Pn}px 0`,verticalAlign:"baseline",button:In,"&.slick-active":_extends$1(_extends$1({},In),{button:In})})}}}},genCarouselRtlStyle=$n=>{const{componentCls:Cn}=$n;return[{[`${Cn}-rtl`]:{direction:"rtl",".slick-dots":{[`${Cn}-rtl&`]:{flexDirection:"row-reverse"}}}},{[`${Cn}-vertical`]:{".slick-dots":{[`${Cn}-rtl&`]:{flexDirection:"column"}}}}]},useStyle$D=genComponentStyleHook("Carousel",$n=>{const{controlHeightLG:Cn,controlHeightSM:_n}=$n,Pn=merge$1($n,{carouselArrowSize:Cn/2,carouselDotOffset:_n/2});return[genCarouselStyle(Pn),genCarouselVerticalStyle(Pn),genCarouselRtlStyle(Pn)]},{dotWidth:16,dotHeight:3,dotWidthActive:24});var __rest$V=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({effect:stringType(),dots:booleanType(!0),vertical:booleanType(),autoplay:booleanType(),easing:String,beforeChange:functionType(),afterChange:functionType(),prefixCls:String,accessibility:booleanType(),nextArrow:PropTypes.any,prevArrow:PropTypes.any,pauseOnHover:booleanType(),adaptiveHeight:booleanType(),arrows:booleanType(!1),autoplaySpeed:Number,centerMode:booleanType(),centerPadding:String,cssEase:String,dotsClass:String,draggable:booleanType(!1),fade:booleanType(),focusOnSelect:booleanType(),infinite:booleanType(),initialSlide:Number,lazyLoad:stringType(),rtl:booleanType(),slide:String,slidesToShow:Number,slidesToScroll:Number,speed:Number,swipe:booleanType(),swipeToSlide:booleanType(),swipeEvent:functionType(),touchMove:booleanType(),touchThreshold:Number,variableWidth:booleanType(),useCSS:booleanType(),slickGoTo:Number,responsive:Array,dotPosition:stringType(),verticalSwiping:booleanType(!1)}),Carousel=defineComponent({compatConfig:{MODE:3},name:"ACarousel",inheritAttrs:!1,props:carouselProps(),setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;const Nn=ref();In({goTo:function(Yn){let Gn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;var Go;(Go=Nn.value)===null||Go===void 0||Go.slickGoTo(Yn,Gn)},autoplay:Yn=>{var Gn,Go;(Go=(Gn=Nn.value)===null||Gn===void 0?void 0:Gn.innerSlider)===null||Go===void 0||Go.handleAutoPlay(Yn)},prev:()=>{var Yn;(Yn=Nn.value)===null||Yn===void 0||Yn.slickPrev()},next:()=>{var Yn;(Yn=Nn.value)===null||Yn===void 0||Yn.slickNext()},innerSlider:computed(()=>{var Yn;return(Yn=Nn.value)===null||Yn===void 0?void 0:Yn.innerSlider})}),watchEffect(()=>{warning$3($n.vertical===void 0)});const{prefixCls:Dn,direction:Ln}=useConfigInject("carousel",$n),[Fn,Bn]=useStyle$D(Dn),Hn=computed(()=>$n.dotPosition?$n.dotPosition:$n.vertical!==void 0&&$n.vertical?"right":"bottom"),zn=computed(()=>Hn.value==="left"||Hn.value==="right"),Wn=computed(()=>{const Yn="slick-dots";return classNames({[Yn]:!0,[`${Yn}-${Hn.value}`]:!0,[`${$n.dotsClass}`]:!!$n.dotsClass})});return()=>{const{dots:Yn,arrows:Gn,draggable:Go,effect:Xn}=$n,{class:Yo,style:qo}=Pn,Jo=__rest$V(Pn,["class","style"]),Zo=Xn==="fade"?!0:$n.fade,rr=classNames(Dn.value,{[`${Dn.value}-rtl`]:Ln.value==="rtl",[`${Dn.value}-vertical`]:zn.value,[`${Yo}`]:!!Yo},Bn.value);return Fn(createVNode("div",{class:rr,style:qo},[createVNode(Slider$2,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Nn},$n),Jo),{},{dots:!!Yn,dotsClass:Wn.value,arrows:Gn,draggable:Go,fade:Zo,vertical:zn.value}),_n)]))}}}),index$q=withInstall(Carousel),VALUE_SPLIT="__RC_CASCADER_SPLIT__",SHOW_PARENT$1="SHOW_PARENT",SHOW_CHILD$1="SHOW_CHILD";function toPathKey($n){return $n.join(VALUE_SPLIT)}function toPathKeys($n){return $n.map(toPathKey)}function toPathValueStr($n){return $n.split(VALUE_SPLIT)}function fillFieldNames$2($n){const{label:Cn,value:_n,children:Pn}=$n||{},In=_n||"value";return{label:Cn||"label",value:In,key:In,children:Pn||"children"}}function isLeaf($n,Cn){var _n,Pn;return(_n=$n.isLeaf)!==null&&_n!==void 0?_n:!(!((Pn=$n[Cn.children])===null||Pn===void 0)&&Pn.length)}function scrollIntoParentView($n){const Cn=$n.parentElement;if(!Cn)return;const _n=$n.offsetTop-Cn.offsetTop;_n-Cn.scrollTop<0?Cn.scrollTo({top:_n}):_n+$n.offsetHeight-Cn.scrollTop>Cn.offsetHeight&&Cn.scrollTo({top:_n+$n.offsetHeight-Cn.offsetHeight})}const TreeContextKey=Symbol("TreeContextKey"),TreeContext=defineComponent({compatConfig:{MODE:3},name:"TreeContext",props:{value:{type:Object}},setup($n,Cn){let{slots:_n}=Cn;return provide(TreeContextKey,computed(()=>$n.value)),()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),useInjectTreeContext=()=>inject(TreeContextKey,computed(()=>({}))),KeysStateKey=Symbol("KeysStateKey"),useProvideKeysState=$n=>{provide(KeysStateKey,$n)},useInjectKeysState=()=>inject(KeysStateKey,{expandedKeys:shallowRef([]),selectedKeys:shallowRef([]),loadedKeys:shallowRef([]),loadingKeys:shallowRef([]),checkedKeys:shallowRef([]),halfCheckedKeys:shallowRef([]),expandedKeysSet:computed(()=>new Set),selectedKeysSet:computed(()=>new Set),loadedKeysSet:computed(()=>new Set),loadingKeysSet:computed(()=>new Set),checkedKeysSet:computed(()=>new Set),halfCheckedKeysSet:computed(()=>new Set),flattenNodes:shallowRef([])}),Indent=$n=>{let{prefixCls:Cn,level:_n,isStart:Pn,isEnd:In}=$n;const Nn=`${Cn}-indent-unit`,Rn=[];for(let Dn=0;Dn<_n;Dn+=1)Rn.push(createVNode("span",{key:Dn,class:{[Nn]:!0,[`${Nn}-start`]:Pn[Dn],[`${Nn}-end`]:In[Dn]}},null));return createVNode("span",{"aria-hidden":"true",class:`${Cn}-indent`},[Rn])},Indent$1=Indent,treeNodeProps={eventKey:[String,Number],prefixCls:String,title:PropTypes.any,data:{type:Object,default:void 0},parent:{type:Object,default:void 0},isStart:{type:Array},isEnd:{type:Array},active:{type:Boolean,default:void 0},onMousemove:{type:Function},isLeaf:{type:Boolean,default:void 0},checkable:{type:Boolean,default:void 0},selectable:{type:Boolean,default:void 0},disabled:{type:Boolean,default:void 0},disableCheckbox:{type:Boolean,default:void 0},icon:PropTypes.any,switcherIcon:PropTypes.any,domRef:{type:Function}},nodeListProps={prefixCls:{type:String},motion:{type:Object},focusable:{type:Boolean},activeItem:{type:Object},focused:{type:Boolean},tabindex:{type:Number},checkable:{type:Boolean},selectable:{type:Boolean},disabled:{type:Boolean},height:{type:Number},itemHeight:{type:Number},virtual:{type:Boolean},onScroll:{type:Function},onKeydown:{type:Function},onFocus:{type:Function},onBlur:{type:Function},onActiveChange:{type:Function},onContextmenu:{type:Function},onListChangeStart:{type:Function},onListChangeEnd:{type:Function}},treeProps$1=()=>({prefixCls:String,focusable:{type:Boolean,default:void 0},activeKey:[Number,String],tabindex:Number,children:PropTypes.any,treeData:{type:Array},fieldNames:{type:Object},showLine:{type:[Boolean,Object],default:void 0},showIcon:{type:Boolean,default:void 0},icon:PropTypes.any,selectable:{type:Boolean,default:void 0},expandAction:[String,Boolean],disabled:{type:Boolean,default:void 0},multiple:{type:Boolean,default:void 0},checkable:{type:Boolean,default:void 0},checkStrictly:{type:Boolean,default:void 0},draggable:{type:[Function,Boolean]},defaultExpandParent:{type:Boolean,default:void 0},autoExpandParent:{type:Boolean,default:void 0},defaultExpandAll:{type:Boolean,default:void 0},defaultExpandedKeys:{type:Array},expandedKeys:{type:Array},defaultCheckedKeys:{type:Array},checkedKeys:{type:[Object,Array]},defaultSelectedKeys:{type:Array},selectedKeys:{type:Array},allowDrop:{type:Function},dropIndicatorRender:{type:Function},onFocus:{type:Function},onBlur:{type:Function},onKeydown:{type:Function},onContextmenu:{type:Function},onClick:{type:Function},onDblclick:{type:Function},onScroll:{type:Function},onExpand:{type:Function},onCheck:{type:Function},onSelect:{type:Function},onLoad:{type:Function},loadData:{type:Function},loadedKeys:{type:Array},onMouseenter:{type:Function},onMouseleave:{type:Function},onRightClick:{type:Function},onDragstart:{type:Function},onDragenter:{type:Function},onDragover:{type:Function},onDragleave:{type:Function},onDragend:{type:Function},onDrop:{type:Function},onActiveChange:{type:Function},filterTreeNode:{type:Function},motion:PropTypes.any,switcherIcon:PropTypes.any,height:Number,itemHeight:Number,virtual:{type:Boolean,default:void 0},direction:{type:String},rootClassName:String,rootStyle:Object});var __rest$U=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In"`v-slot:"+Oa+"` ")}`;const Nn=shallowRef(!1),Rn=useInjectTreeContext(),{expandedKeysSet:Dn,selectedKeysSet:Ln,loadedKeysSet:Fn,loadingKeysSet:Bn,checkedKeysSet:Hn,halfCheckedKeysSet:zn}=useInjectKeysState(),{dragOverNodeKey:Wn,dropPosition:Yn,keyEntities:Gn}=Rn.value,Go=computed(()=>getTreeNodeProps($n.eventKey,{expandedKeysSet:Dn.value,selectedKeysSet:Ln.value,loadedKeysSet:Fn.value,loadingKeysSet:Bn.value,checkedKeysSet:Hn.value,halfCheckedKeysSet:zn.value,dragOverNodeKey:Wn,dropPosition:Yn,keyEntities:Gn})),Xn=eagerComputed(()=>Go.value.expanded),Yo=eagerComputed(()=>Go.value.selected),qo=eagerComputed(()=>Go.value.checked),Jo=eagerComputed(()=>Go.value.loaded),Zo=eagerComputed(()=>Go.value.loading),rr=eagerComputed(()=>Go.value.halfChecked),nr=eagerComputed(()=>Go.value.dragOver),ta=eagerComputed(()=>Go.value.dragOverGapTop),oa=eagerComputed(()=>Go.value.dragOverGapBottom),ra=eagerComputed(()=>Go.value.pos),ea=shallowRef(),la=computed(()=>{const{eventKey:Oa}=$n,{keyEntities:Ma}=Rn.value,{children:Ua}=Ma[Oa]||{};return!!(Ua||[]).length}),ua=computed(()=>{const{isLeaf:Oa}=$n,{loadData:Ma}=Rn.value,Ua=la.value;return Oa===!1?!1:Oa||!Ma&&!Ua||Ma&&Jo.value&&!Ua}),ga=computed(()=>ua.value?null:Xn.value?ICON_OPEN:ICON_CLOSE),aa=computed(()=>{const{disabled:Oa}=$n,{disabled:Ma}=Rn.value;return!!(Ma||Oa)}),ca=computed(()=>{const{checkable:Oa}=$n,{checkable:Ma}=Rn.value;return!Ma||Oa===!1?!1:Ma}),sa=computed(()=>{const{selectable:Oa}=$n,{selectable:Ma}=Rn.value;return typeof Oa=="boolean"?Oa:Ma}),ia=computed(()=>{const{data:Oa,active:Ma,checkable:Ua,disableCheckbox:Qa,disabled:ri,selectable:fi}=$n;return _extends$1(_extends$1({active:Ma,checkable:Ua,disableCheckbox:Qa,disabled:ri,selectable:fi},Oa),{dataRef:Oa,data:Oa,isLeaf:ua.value,checked:qo.value,expanded:Xn.value,loading:Zo.value,selected:Yo.value,halfChecked:rr.value})}),fa=getCurrentInstance(),ma=computed(()=>{const{eventKey:Oa}=$n,{keyEntities:Ma}=Rn.value,{parent:Ua}=Ma[Oa]||{};return _extends$1(_extends$1({},convertNodePropsToEventData(_extends$1({},$n,Go.value))),{parent:Ua})}),ya=reactive({eventData:ma,eventKey:computed(()=>$n.eventKey),selectHandle:ea,pos:ra,key:fa.vnode.key});In(ya);const ba=Oa=>{const{onNodeDoubleClick:Ma}=Rn.value;Ma(Oa,ma.value)},Ia=Oa=>{if(aa.value)return;const{onNodeSelect:Ma}=Rn.value;Oa.preventDefault(),Ma(Oa,ma.value)},Ea=Oa=>{if(aa.value)return;const{disableCheckbox:Ma}=$n,{onNodeCheck:Ua}=Rn.value;if(!ca.value||Ma)return;Oa.preventDefault();const Qa=!qo.value;Ua(Oa,ma.value,Qa)},xa=Oa=>{const{onNodeClick:Ma}=Rn.value;Ma(Oa,ma.value),sa.value?Ia(Oa):Ea(Oa)},Ta=Oa=>{const{onNodeMouseEnter:Ma}=Rn.value;Ma(Oa,ma.value)},wa=Oa=>{const{onNodeMouseLeave:Ma}=Rn.value;Ma(Oa,ma.value)},La=Oa=>{const{onNodeContextMenu:Ma}=Rn.value;Ma(Oa,ma.value)},Na=Oa=>{const{onNodeDragStart:Ma}=Rn.value;Oa.stopPropagation(),Nn.value=!0,Ma(Oa,ya);try{Oa.dataTransfer.setData("text/plain","")}catch{}},$a=Oa=>{const{onNodeDragEnter:Ma}=Rn.value;Oa.preventDefault(),Oa.stopPropagation(),Ma(Oa,ya)},ka=Oa=>{const{onNodeDragOver:Ma}=Rn.value;Oa.preventDefault(),Oa.stopPropagation(),Ma(Oa,ya)},Ha=Oa=>{const{onNodeDragLeave:Ma}=Rn.value;Oa.stopPropagation(),Ma(Oa,ya)},da=Oa=>{const{onNodeDragEnd:Ma}=Rn.value;Oa.stopPropagation(),Nn.value=!1,Ma(Oa,ya)},pa=Oa=>{const{onNodeDrop:Ma}=Rn.value;Oa.preventDefault(),Oa.stopPropagation(),Nn.value=!1,Ma(Oa,ya)},Sa=Oa=>{const{onNodeExpand:Ma}=Rn.value;Zo.value||Ma(Oa,ma.value)},Aa=()=>{const{data:Oa}=$n,{draggable:Ma}=Rn.value;return!!(Ma&&(!Ma.nodeDraggable||Ma.nodeDraggable(Oa)))},Ra=()=>{const{draggable:Oa,prefixCls:Ma}=Rn.value;return Oa&&(Oa!=null&&Oa.icon)?createVNode("span",{class:`${Ma}-draggable-icon`},[Oa.icon]):null},Fa=()=>{var Oa,Ma,Ua;const{switcherIcon:Qa=Pn.switcherIcon||((Oa=Rn.value.slots)===null||Oa===void 0?void 0:Oa[(Ua=(Ma=$n.data)===null||Ma===void 0?void 0:Ma.slots)===null||Ua===void 0?void 0:Ua.switcherIcon])}=$n,{switcherIcon:ri}=Rn.value,fi=Qa||ri;return typeof fi=="function"?fi(ia.value):fi},za=()=>{const{loadData:Oa,onNodeLoad:Ma}=Rn.value;Zo.value||Oa&&Xn.value&&!ua.value&&!la.value&&!Jo.value&&Ma(ma.value)};onMounted(()=>{za()}),onUpdated(()=>{za()});const Wa=()=>{const{prefixCls:Oa}=Rn.value,Ma=Fa();if(ua.value)return Ma!==!1?createVNode("span",{class:classNames(`${Oa}-switcher`,`${Oa}-switcher-noop`)},[Ma]):null;const Ua=classNames(`${Oa}-switcher`,`${Oa}-switcher_${Xn.value?ICON_OPEN:ICON_CLOSE}`);return Ma!==!1?createVNode("span",{onClick:Sa,class:Ua},[Ma]):null},Ya=()=>{var Oa,Ma;const{disableCheckbox:Ua}=$n,{prefixCls:Qa}=Rn.value,ri=aa.value;return ca.value?createVNode("span",{class:classNames(`${Qa}-checkbox`,qo.value&&`${Qa}-checkbox-checked`,!qo.value&&rr.value&&`${Qa}-checkbox-indeterminate`,(ri||Ua)&&`${Qa}-checkbox-disabled`),onClick:Ea},[(Ma=(Oa=Rn.value).customCheckable)===null||Ma===void 0?void 0:Ma.call(Oa)]):null},ja=()=>{const{prefixCls:Oa}=Rn.value;return createVNode("span",{class:classNames(`${Oa}-iconEle`,`${Oa}-icon__${ga.value||"docu"}`,Zo.value&&`${Oa}-icon_loading`)},null)},qa=()=>{const{disabled:Oa,eventKey:Ma}=$n,{draggable:Ua,dropLevelOffset:Qa,dropPosition:ri,prefixCls:fi,indent:ei,dropIndicatorRender:ti,dragOverNodeKey:ni,direction:ui}=Rn.value;return!Oa&&Ua!==!1&&ni===Ma?ti({dropPosition:ri,dropLevelOffset:Qa,indent:ei,prefixCls:fi,direction:ui}):null},Xa=()=>{var Oa,Ma,Ua,Qa,ri,fi;const{icon:ei=Pn.icon,data:ti}=$n,ni=Pn.title||((Oa=Rn.value.slots)===null||Oa===void 0?void 0:Oa[(Ua=(Ma=$n.data)===null||Ma===void 0?void 0:Ma.slots)===null||Ua===void 0?void 0:Ua.title])||((Qa=Rn.value.slots)===null||Qa===void 0?void 0:Qa.title)||$n.title,{prefixCls:ui,showIcon:mi,icon:di,loadData:gi}=Rn.value,wi=aa.value,Ti=`${ui}-node-content-wrapper`;let Ei;if(mi){const Zi=ei||((ri=Rn.value.slots)===null||ri===void 0?void 0:ri[(fi=ti==null?void 0:ti.slots)===null||fi===void 0?void 0:fi.icon])||di;Ei=Zi?createVNode("span",{class:classNames(`${ui}-iconEle`,`${ui}-icon__customize`)},[typeof Zi=="function"?Zi(ia.value):Zi]):ja()}else gi&&Zo.value&&(Ei=ja());let Ni;typeof ni=="function"?Ni=ni(ia.value):Ni=ni,Ni=Ni===void 0?defaultTitle:Ni;const Ri=createVNode("span",{class:`${ui}-title`},[Ni]);return createVNode("span",{ref:ea,title:typeof ni=="string"?ni:"",class:classNames(`${Ti}`,`${Ti}-${ga.value||"normal"}`,!wi&&(Yo.value||Nn.value)&&`${ui}-node-selected`),onMouseenter:Ta,onMouseleave:wa,onContextmenu:La,onClick:xa,onDblclick:ba},[Ei,Ri,qa()])};return()=>{const Oa=_extends$1(_extends$1({},$n),_n),{eventKey:Ma,isLeaf:Ua,isStart:Qa,isEnd:ri,domRef:fi,active:ei,data:ti,onMousemove:ni,selectable:ui}=Oa,mi=__rest$U(Oa,["eventKey","isLeaf","isStart","isEnd","domRef","active","data","onMousemove","selectable"]),{prefixCls:di,filterTreeNode:gi,keyEntities:wi,dropContainerKey:Ti,dropTargetKey:Ei,draggingNodeKey:Ni}=Rn.value,Ri=aa.value,Zi=pickAttrs(mi,{aria:!0,data:!0}),{level:Qi}=wi[Ma]||{},Ji=ri[ri.length-1],Yi=Aa(),rl=!Ri&&Yi,yi=Ni===Ma,il=ui!==void 0?{"aria-selected":!!ui}:void 0;return createVNode("div",_objectSpread2$1(_objectSpread2$1({ref:fi,class:classNames(_n.class,`${di}-treenode`,{[`${di}-treenode-disabled`]:Ri,[`${di}-treenode-switcher-${Xn.value?"open":"close"}`]:!Ua,[`${di}-treenode-checkbox-checked`]:qo.value,[`${di}-treenode-checkbox-indeterminate`]:rr.value,[`${di}-treenode-selected`]:Yo.value,[`${di}-treenode-loading`]:Zo.value,[`${di}-treenode-active`]:ei,[`${di}-treenode-leaf-last`]:Ji,[`${di}-treenode-draggable`]:rl,dragging:yi,"drop-target":Ei===Ma,"drop-container":Ti===Ma,"drag-over":!Ri&&nr.value,"drag-over-gap-top":!Ri&&ta.value,"drag-over-gap-bottom":!Ri&&oa.value,"filter-node":gi&&gi(ma.value)}),style:_n.style,draggable:rl,"aria-grabbed":yi,onDragstart:rl?Na:void 0,onDragenter:Yi?$a:void 0,onDragover:Yi?ka:void 0,onDragleave:Yi?Ha:void 0,onDrop:Yi?pa:void 0,onDragend:Yi?da:void 0,onMousemove:ni},il),Zi),[createVNode(Indent$1,{prefixCls:di,level:Qi,isStart:Qa,isEnd:ri},null),Ra(),Wa(),Ya(),Xa()])}}});function arrDel($n,Cn){if(!$n)return[];const _n=$n.slice(),Pn=_n.indexOf(Cn);return Pn>=0&&_n.splice(Pn,1),_n}function arrAdd($n,Cn){const _n=($n||[]).slice();return _n.indexOf(Cn)===-1&&_n.push(Cn),_n}function posToArr($n){return $n.split("-")}function getPosition($n,Cn){return`${$n}-${Cn}`}function isTreeNode($n){return $n&&$n.type&&$n.type.isTreeNode}function getDragChildrenKeys($n,Cn){const _n=[],Pn=Cn[$n];function In(){(arguments.length>0&&arguments[0]!==void 0?arguments[0]:[]).forEach(Rn=>{let{key:Dn,children:Ln}=Rn;_n.push(Dn),In(Ln)})}return In(Pn.children),_n}function isLastChild($n){if($n.parent){const Cn=posToArr($n.pos);return Number(Cn[Cn.length-1])===$n.parent.children.length-1}return!1}function isFirstChild($n){const Cn=posToArr($n.pos);return Number(Cn[Cn.length-1])===0}function calcDropPosition($n,Cn,_n,Pn,In,Nn,Rn,Dn,Ln,Fn){var Bn;const{clientX:Hn,clientY:zn}=$n,{top:Wn,height:Yn}=$n.target.getBoundingClientRect(),Go=((Fn==="rtl"?-1:1)*(((In==null?void 0:In.x)||0)-Hn)-12)/Pn;let Xn=Dn[_n.eventKey];if(znua.key===Xn.key),ea=ra<=0?0:ra-1,la=Rn[ea].key;Xn=Dn[la]}const Yo=Xn.key,qo=Xn,Jo=Xn.key;let Zo=0,rr=0;if(!Ln.has(Yo))for(let ra=0;ra-1.5?Nn({dragNode:nr,dropNode:ta,dropPosition:1})?Zo=1:oa=!1:Nn({dragNode:nr,dropNode:ta,dropPosition:0})?Zo=0:Nn({dragNode:nr,dropNode:ta,dropPosition:1})?Zo=1:oa=!1:Nn({dragNode:nr,dropNode:ta,dropPosition:1})?Zo=1:oa=!1,{dropPosition:Zo,dropLevelOffset:rr,dropTargetKey:Xn.key,dropTargetPos:Xn.pos,dragOverNodeKey:Jo,dropContainerKey:Zo===0?null:((Bn=Xn.parent)===null||Bn===void 0?void 0:Bn.key)||null,dropAllowed:oa}}function calcSelectedKeys($n,Cn){if(!$n)return;const{multiple:_n}=Cn;return _n?$n.slice():$n.length?[$n[0]]:$n}function parseCheckedKeys($n){if(!$n)return null;let Cn;if(Array.isArray($n))Cn={checkedKeys:$n,halfCheckedKeys:void 0};else if(typeof $n=="object")Cn={checkedKeys:$n.checked||void 0,halfCheckedKeys:$n.halfChecked||void 0};else return null;return Cn}function conductExpandParent($n,Cn){const _n=new Set;function Pn(In){if(_n.has(In))return;const Nn=Cn[In];if(!Nn)return;_n.add(In);const{parent:Rn,node:Dn}=Nn;Dn.disabled||Rn&&Pn(Rn.key)}return($n||[]).forEach(In=>{Pn(In)}),[..._n]}var __rest$T=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In0&&arguments[0]!==void 0?arguments[0]:[];return filterEmpty(_n).map(In=>{var Nn,Rn,Dn,Ln;if(!isTreeNode(In))return null;const Fn=In.children||{},Bn=In.key,Hn={};for(const[ra,ea]of Object.entries(In.props))Hn[camelize(ra)]=ea;const{isLeaf:zn,checkable:Wn,selectable:Yn,disabled:Gn,disableCheckbox:Go}=Hn,Xn={isLeaf:zn||zn===""||void 0,checkable:Wn||Wn===""||void 0,selectable:Yn||Yn===""||void 0,disabled:Gn||Gn===""||void 0,disableCheckbox:Go||Go===""||void 0},Yo=_extends$1(_extends$1({},Hn),Xn),{title:qo=(Nn=Fn.title)===null||Nn===void 0?void 0:Nn.call(Fn,Yo),icon:Jo=(Rn=Fn.icon)===null||Rn===void 0?void 0:Rn.call(Fn,Yo),switcherIcon:Zo=(Dn=Fn.switcherIcon)===null||Dn===void 0?void 0:Dn.call(Fn,Yo)}=Hn,rr=__rest$T(Hn,["title","icon","switcherIcon"]),nr=(Ln=Fn.default)===null||Ln===void 0?void 0:Ln.call(Fn),ta=_extends$1(_extends$1(_extends$1({},rr),{title:qo,icon:Jo,switcherIcon:Zo,key:Bn,isLeaf:zn}),Xn),oa=Cn(nr);return oa.length&&(ta.children=oa),ta})}return Cn($n)}function flattenTreeData($n,Cn,_n){const{_title:Pn,key:In,children:Nn}=fillFieldNames$1(_n),Rn=new Set(Cn===!0?[]:Cn),Dn=[];function Ln(Fn){let Bn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;return Fn.map((Hn,zn)=>{const Wn=getPosition(Bn?Bn.pos:"0",zn),Yn=getKey(Hn[In],Wn);let Gn;for(let Xn=0;Xnzn[Nn]:typeof Nn=="function"&&(Bn=zn=>Nn(zn)):Bn=(zn,Wn)=>getKey(zn[Dn],Wn);function Hn(zn,Wn,Yn,Gn){const Go=zn?zn[Fn]:$n,Xn=zn?getPosition(Yn.pos,Wn):"0",Yo=zn?[...Gn,zn]:[];if(zn){const qo=Bn(zn,Xn),Jo={node:zn,index:Wn,pos:Xn,key:qo,parentPos:Yn.node?Yn.pos:null,level:Yn.level+1,nodes:Yo};Cn(Jo)}Go&&Go.forEach((qo,Jo)=>{Hn(qo,Jo,{node:zn,pos:Xn,level:Yn?Yn.level+1:-1},Yo)})}Hn(null)}function convertDataToEntities($n){let{initWrapper:Cn,processEntity:_n,onProcessFinished:Pn,externalGetKey:In,childrenPropName:Nn,fieldNames:Rn}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},Dn=arguments.length>2?arguments[2]:void 0;const Ln=In||Dn,Fn={},Bn={};let Hn={posEntities:Fn,keyEntities:Bn};return Cn&&(Hn=Cn(Hn)||Hn),traverseDataNodes($n,zn=>{const{node:Wn,index:Yn,pos:Gn,key:Go,parentPos:Xn,level:Yo,nodes:qo}=zn,Jo={node:Wn,nodes:qo,index:Yn,key:Go,pos:Gn,level:Yo},Zo=getKey(Go,Gn);Fn[Gn]=Jo,Bn[Zo]=Jo,Jo.parent=Fn[Xn],Jo.parent&&(Jo.parent.children=Jo.parent.children||[],Jo.parent.children.push(Jo)),_n&&_n(Jo,Hn)},{externalGetKey:Ln,childrenPropName:Nn,fieldNames:Rn}),Pn&&Pn(Hn),Hn}function getTreeNodeProps($n,Cn){let{expandedKeysSet:_n,selectedKeysSet:Pn,loadedKeysSet:In,loadingKeysSet:Nn,checkedKeysSet:Rn,halfCheckedKeysSet:Dn,dragOverNodeKey:Ln,dropPosition:Fn,keyEntities:Bn}=Cn;const Hn=Bn[$n];return{eventKey:$n,expanded:_n.has($n),selected:Pn.has($n),loaded:In.has($n),loading:Nn.has($n),checked:Rn.has($n),halfChecked:Dn.has($n),pos:String(Hn?Hn.pos:""),parent:Hn.parent,dragOver:Ln===$n&&Fn===0,dragOverGapTop:Ln===$n&&Fn===-1,dragOverGapBottom:Ln===$n&&Fn===1}}function convertNodePropsToEventData($n){const{data:Cn,expanded:_n,selected:Pn,checked:In,loaded:Nn,loading:Rn,halfChecked:Dn,dragOver:Ln,dragOverGapTop:Fn,dragOverGapBottom:Bn,pos:Hn,active:zn,eventKey:Wn}=$n,Yn=_extends$1(_extends$1({dataRef:Cn},Cn),{expanded:_n,selected:Pn,checked:In,loaded:Nn,loading:Rn,halfChecked:Dn,dragOver:Ln,dragOverGapTop:Fn,dragOverGapBottom:Bn,pos:Hn,active:zn,eventKey:Wn,key:Wn});return"props"in Yn||Object.defineProperty(Yn,"props",{get(){return $n}}),Yn}const useEntities=($n,Cn)=>computed(()=>convertDataToEntities($n.value,{fieldNames:Cn.value,initWrapper:Pn=>_extends$1(_extends$1({},Pn),{pathKeyEntities:{}}),processEntity:(Pn,In)=>{const Nn=Pn.nodes.map(Rn=>Rn[Cn.value.value]).join(VALUE_SPLIT);In.pathKeyEntities[Nn]=Pn,Pn.key=Nn}}).pathKeyEntities);function useSearchConfig($n){const Cn=shallowRef(!1),_n=ref({});return watchEffect(()=>{if(!$n.value){Cn.value=!1,_n.value={};return}let Pn={matchInputWidth:!0,limit:50};$n.value&&typeof $n.value=="object"&&(Pn=_extends$1(_extends$1({},Pn),$n.value)),Pn.limit<=0&&delete Pn.limit,Cn.value=!0,_n.value=Pn}),{showSearch:Cn,searchConfig:_n}}const SEARCH_MARK="__rc_cascader_search_mark__",defaultFilter=($n,Cn,_n)=>{let{label:Pn}=_n;return Cn.some(In=>String(In[Pn]).toLowerCase().includes($n.toLowerCase()))},defaultRender$1=$n=>{let{path:Cn,fieldNames:_n}=$n;return Cn.map(Pn=>Pn[_n.label]).join(" / ")},useSearchOptions=($n,Cn,_n,Pn,In,Nn)=>computed(()=>{const{filter:Rn=defaultFilter,render:Dn=defaultRender$1,limit:Ln=50,sort:Fn}=In.value,Bn=[];if(!$n.value)return[];function Hn(zn,Wn){zn.forEach(Yn=>{if(!Fn&&Ln>0&&Bn.length>=Ln)return;const Gn=[...Wn,Yn],Go=Yn[_n.value.children];(!Go||Go.length===0||Nn.value)&&Rn($n.value,Gn,{label:_n.value.label})&&Bn.push(_extends$1(_extends$1({},Yn),{[_n.value.label]:Dn({inputValue:$n.value,path:Gn,prefixCls:Pn.value,fieldNames:_n.value}),[SEARCH_MARK]:Gn})),Go&&Hn(Yn[_n.value.children],Gn)})}return Hn(Cn.value,[]),Fn&&Bn.sort((zn,Wn)=>Fn(zn[SEARCH_MARK],Wn[SEARCH_MARK],$n.value,_n.value)),Ln>0?Bn.slice(0,Ln):Bn});function formatStrategyValues$1($n,Cn,_n){const Pn=new Set($n);return $n.filter(In=>{const Nn=Cn[In],Rn=Nn?Nn.parent:null,Dn=Nn?Nn.children:null;return _n===SHOW_CHILD$1?!(Dn&&Dn.some(Ln=>Ln.key&&Pn.has(Ln.key))):!(Rn&&!Rn.node.disabled&&Pn.has(Rn.key))})}function toPathOptions($n,Cn,_n){let Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;var In;let Nn=Cn;const Rn=[];for(let Dn=0;Dn<$n.length;Dn+=1){const Ln=$n[Dn],Fn=Nn==null?void 0:Nn.findIndex(Hn=>{const zn=Hn[_n.value];return Pn?String(zn)===String(Ln):zn===Ln}),Bn=Fn!==-1?Nn==null?void 0:Nn[Fn]:null;Rn.push({value:(In=Bn==null?void 0:Bn[_n.value])!==null&&In!==void 0?In:Ln,index:Fn,option:Bn}),Nn=Bn==null?void 0:Bn[_n.children]}return Rn}const useMissingValues=($n,Cn,_n)=>computed(()=>{const Pn=[],In=[];return _n.value.forEach(Nn=>{toPathOptions(Nn,$n.value,Cn.value).every(Dn=>Dn.option)?In.push(Nn):Pn.push(Nn)}),[In,Pn]});function removeFromCheckedKeys($n,Cn){const _n=new Set;return $n.forEach(Pn=>{Cn.has(Pn)||_n.add(Pn)}),_n}function isCheckDisabled$1($n){const{disabled:Cn,disableCheckbox:_n,checkable:Pn}=$n||{};return!!(Cn||_n)||Pn===!1}function fillConductCheck($n,Cn,_n,Pn){const In=new Set($n),Nn=new Set;for(let Dn=0;Dn<=_n;Dn+=1)(Cn.get(Dn)||new Set).forEach(Fn=>{const{key:Bn,node:Hn,children:zn=[]}=Fn;In.has(Bn)&&!Pn(Hn)&&zn.filter(Wn=>!Pn(Wn.node)).forEach(Wn=>{In.add(Wn.key)})});const Rn=new Set;for(let Dn=_n;Dn>=0;Dn-=1)(Cn.get(Dn)||new Set).forEach(Fn=>{const{parent:Bn,node:Hn}=Fn;if(Pn(Hn)||!Fn.parent||Rn.has(Fn.parent.key))return;if(Pn(Fn.parent.node)){Rn.add(Bn.key);return}let zn=!0,Wn=!1;(Bn.children||[]).filter(Yn=>!Pn(Yn.node)).forEach(Yn=>{let{key:Gn}=Yn;const Go=In.has(Gn);zn&&!Go&&(zn=!1),!Wn&&(Go||Nn.has(Gn))&&(Wn=!0)}),zn&&In.add(Bn.key),Wn&&Nn.add(Bn.key),Rn.add(Bn.key)});return{checkedKeys:Array.from(In),halfCheckedKeys:Array.from(removeFromCheckedKeys(Nn,In))}}function cleanConductCheck($n,Cn,_n,Pn,In){const Nn=new Set($n);let Rn=new Set(Cn);for(let Ln=0;Ln<=Pn;Ln+=1)(_n.get(Ln)||new Set).forEach(Bn=>{const{key:Hn,node:zn,children:Wn=[]}=Bn;!Nn.has(Hn)&&!Rn.has(Hn)&&!In(zn)&&Wn.filter(Yn=>!In(Yn.node)).forEach(Yn=>{Nn.delete(Yn.key)})});Rn=new Set;const Dn=new Set;for(let Ln=Pn;Ln>=0;Ln-=1)(_n.get(Ln)||new Set).forEach(Bn=>{const{parent:Hn,node:zn}=Bn;if(In(zn)||!Bn.parent||Dn.has(Bn.parent.key))return;if(In(Bn.parent.node)){Dn.add(Hn.key);return}let Wn=!0,Yn=!1;(Hn.children||[]).filter(Gn=>!In(Gn.node)).forEach(Gn=>{let{key:Go}=Gn;const Xn=Nn.has(Go);Wn&&!Xn&&(Wn=!1),!Yn&&(Xn||Rn.has(Go))&&(Yn=!0)}),Wn||Nn.delete(Hn.key),Yn&&Rn.add(Hn.key),Dn.add(Hn.key)});return{checkedKeys:Array.from(Nn),halfCheckedKeys:Array.from(removeFromCheckedKeys(Rn,Nn))}}function conductCheck($n,Cn,_n,Pn,In,Nn){let Rn;Nn?Rn=Nn:Rn=isCheckDisabled$1;const Dn=new Set($n.filter(Fn=>!!_n[Fn]));let Ln;return Cn===!0?Ln=fillConductCheck(Dn,In,Pn,Rn):Ln=cleanConductCheck(Dn,Cn.halfCheckedKeys,In,Pn,Rn),Ln}const useDisplayValues=($n,Cn,_n,Pn,In)=>computed(()=>{const Nn=In.value||(Rn=>{let{labels:Dn}=Rn;const Ln=Pn.value?Dn.slice(-1):Dn,Fn=" / ";return Ln.every(Bn=>["string","number"].includes(typeof Bn))?Ln.join(Fn):Ln.reduce((Bn,Hn,zn)=>{const Wn=isValidElement(Hn)?cloneElement(Hn,{key:zn}):Hn;return zn===0?[Wn]:[...Bn,Fn,Wn]},[])});return $n.value.map(Rn=>{const Dn=toPathOptions(Rn,Cn.value,_n.value),Ln=Nn({labels:Dn.map(Bn=>{let{option:Hn,value:zn}=Bn;var Wn;return(Wn=Hn==null?void 0:Hn[_n.value.label])!==null&&Wn!==void 0?Wn:zn}),selectedOptions:Dn.map(Bn=>{let{option:Hn}=Bn;return Hn})}),Fn=toPathKey(Rn);return{label:Ln,value:Fn,key:Fn,valueCells:Rn}})}),CascaderContextKey=Symbol("CascaderContextKey"),useProvideCascader=$n=>{provide(CascaderContextKey,$n)},useInjectCascader=()=>inject(CascaderContextKey),useActive=()=>{const $n=useBaseProps(),{values:Cn}=useInjectCascader(),[_n,Pn]=useState([]);return watch(()=>$n.open,()=>{if($n.open&&!$n.multiple){const In=Cn.value[0];Pn(In||[])}},{immediate:!0}),[_n,Pn]},useKeyboard=($n,Cn,_n,Pn,In,Nn)=>{const Rn=useBaseProps(),Dn=computed(()=>Rn.direction==="rtl"),[Ln,Fn,Bn]=[ref([]),ref(),ref([])];watchEffect(()=>{let Gn=-1,Go=Cn.value;const Xn=[],Yo=[],qo=Pn.value.length;for(let Zo=0;Zonr[_n.value.value]===Pn.value[Zo]);if(rr===-1)break;Gn=rr,Xn.push(Gn),Yo.push(Pn.value[Zo]),Go=Go[Gn][_n.value.children]}let Jo=Cn.value;for(let Zo=0;Zo{In(Gn)},zn=Gn=>{const Go=Bn.value.length;let Xn=Fn.value;Xn===-1&&Gn<0&&(Xn=Go);for(let Yo=0;Yo{if(Ln.value.length>1){const Gn=Ln.value.slice(0,-1);Hn(Gn)}else Rn.toggleOpen(!1)},Yn=()=>{var Gn;const Xn=(((Gn=Bn.value[Fn.value])===null||Gn===void 0?void 0:Gn[_n.value.children])||[]).find(Yo=>!Yo.disabled);if(Xn){const Yo=[...Ln.value,Xn[_n.value.value]];Hn(Yo)}};$n.expose({onKeydown:Gn=>{const{which:Go}=Gn;switch(Go){case KeyCode$1.UP:case KeyCode$1.DOWN:{let Xn=0;Go===KeyCode$1.UP?Xn=-1:Go===KeyCode$1.DOWN&&(Xn=1),Xn!==0&&zn(Xn);break}case KeyCode$1.LEFT:{Dn.value?Yn():Wn();break}case KeyCode$1.RIGHT:{Dn.value?Wn():Yn();break}case KeyCode$1.BACKSPACE:{Rn.searchValue||Wn();break}case KeyCode$1.ENTER:{if(Ln.value.length){const Xn=Bn.value[Fn.value],Yo=(Xn==null?void 0:Xn[SEARCH_MARK])||[];Yo.length?Nn(Yo.map(qo=>qo[_n.value.value]),Yo[Yo.length-1]):Nn(Ln.value,Xn)}break}case KeyCode$1.ESC:Rn.toggleOpen(!1),open&&Gn.stopPropagation()}},onKeyup:()=>{}})};function Checkbox$1($n){let{prefixCls:Cn,checked:_n,halfChecked:Pn,disabled:In,onClick:Nn}=$n;const{customSlots:Rn,checkable:Dn}=useInjectCascader(),Ln=Dn.value!==!1?Rn.value.checkable:Dn.value,Fn=typeof Ln=="function"?Ln():typeof Ln=="boolean"?null:Ln;return createVNode("span",{class:{[Cn]:!0,[`${Cn}-checked`]:_n,[`${Cn}-indeterminate`]:!_n&&Pn,[`${Cn}-disabled`]:In},onClick:Nn},[Fn])}Checkbox$1.props=["prefixCls","checked","halfChecked","disabled","onClick"];Checkbox$1.displayName="Checkbox";Checkbox$1.inheritAttrs=!1;const FIX_LABEL="__cascader_fix_label__";function Column$1($n){let{prefixCls:Cn,multiple:_n,options:Pn,activeValue:In,prevValuePath:Nn,onToggleOpen:Rn,onSelect:Dn,onActive:Ln,checkedSet:Fn,halfCheckedSet:Bn,loadingKeys:Hn,isSelectable:zn}=$n;var Wn,Yn,Gn,Go,Xn,Yo;const qo=`${Cn}-menu`,Jo=`${Cn}-menu-item`,{fieldNames:Zo,changeOnSelect:rr,expandTrigger:nr,expandIcon:ta,loadingIcon:oa,dropdownMenuColumnStyle:ra,customSlots:ea}=useInjectCascader(),la=(Wn=ta.value)!==null&&Wn!==void 0?Wn:(Gn=(Yn=ea.value).expandIcon)===null||Gn===void 0?void 0:Gn.call(Yn),ua=(Go=oa.value)!==null&&Go!==void 0?Go:(Yo=(Xn=ea.value).loadingIcon)===null||Yo===void 0?void 0:Yo.call(Xn),ga=nr.value==="hover";return createVNode("ul",{class:qo,role:"menu"},[Pn.map(aa=>{var ca;const{disabled:sa}=aa,ia=aa[SEARCH_MARK],fa=(ca=aa[FIX_LABEL])!==null&&ca!==void 0?ca:aa[Zo.value.label],ma=aa[Zo.value.value],ya=isLeaf(aa,Zo.value),ba=ia?ia.map($a=>$a[Zo.value.value]):[...Nn,ma],Ia=toPathKey(ba),Ea=Hn.includes(Ia),xa=Fn.has(Ia),Ta=Bn.has(Ia),wa=()=>{!sa&&(!ga||!ya)&&Ln(ba)},La=()=>{zn(aa)&&Dn(ba,ya)};let Na;return typeof aa.title=="string"?Na=aa.title:typeof fa=="string"&&(Na=fa),createVNode("li",{key:Ia,class:[Jo,{[`${Jo}-expand`]:!ya,[`${Jo}-active`]:In===ma,[`${Jo}-disabled`]:sa,[`${Jo}-loading`]:Ea}],style:ra.value,role:"menuitemcheckbox",title:Na,"aria-checked":xa,"data-path-key":Ia,onClick:()=>{wa(),(!_n||ya)&&La()},onDblclick:()=>{rr.value&&Rn(!1)},onMouseenter:()=>{ga&&wa()},onMousedown:$a=>{$a.preventDefault()}},[_n&&createVNode(Checkbox$1,{prefixCls:`${Cn}-checkbox`,checked:xa,halfChecked:Ta,disabled:sa,onClick:$a=>{$a.stopPropagation(),La()}},null),createVNode("div",{class:`${Jo}-content`},[fa]),!Ea&&la&&!ya&&createVNode("div",{class:`${Jo}-expand-icon`},[la]),Ea&&ua&&createVNode("div",{class:`${Jo}-loading-icon`},[ua])])})])}Column$1.props=["prefixCls","multiple","options","activeValue","prevValuePath","onToggleOpen","onSelect","onActive","checkedSet","halfCheckedSet","loadingKeys","isSelectable"];Column$1.displayName="Column";Column$1.inheritAttrs=!1;const OptionList$1=defineComponent({compatConfig:{MODE:3},name:"OptionList",inheritAttrs:!1,setup($n,Cn){const{attrs:_n,slots:Pn}=Cn,In=useBaseProps(),Nn=ref(),Rn=computed(()=>In.direction==="rtl"),{options:Dn,values:Ln,halfValues:Fn,fieldNames:Bn,changeOnSelect:Hn,onSelect:zn,searchOptions:Wn,dropdownPrefixCls:Yn,loadData:Gn,expandTrigger:Go,customSlots:Xn}=useInjectCascader(),Yo=computed(()=>Yn.value||In.prefixCls),qo=shallowRef([]),Jo=ca=>{if(!Gn.value||In.searchValue)return;const ia=toPathOptions(ca,Dn.value,Bn.value).map(ma=>{let{option:ya}=ma;return ya}),fa=ia[ia.length-1];if(fa&&!isLeaf(fa,Bn.value)){const ma=toPathKey(ca);qo.value=[...qo.value,ma],Gn.value(ia)}};watchEffect(()=>{qo.value.length&&qo.value.forEach(ca=>{const sa=toPathValueStr(ca),ia=toPathOptions(sa,Dn.value,Bn.value,!0).map(ma=>{let{option:ya}=ma;return ya}),fa=ia[ia.length-1];(!fa||fa[Bn.value.children]||isLeaf(fa,Bn.value))&&(qo.value=qo.value.filter(ma=>ma!==ca))})});const Zo=computed(()=>new Set(toPathKeys(Ln.value))),rr=computed(()=>new Set(toPathKeys(Fn.value))),[nr,ta]=useActive(),oa=ca=>{ta(ca),Jo(ca)},ra=ca=>{const{disabled:sa}=ca,ia=isLeaf(ca,Bn.value);return!sa&&(ia||Hn.value||In.multiple)},ea=function(ca,sa){let ia=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;zn(ca),!In.multiple&&(sa||Hn.value&&(Go.value==="hover"||ia))&&In.toggleOpen(!1)},la=computed(()=>In.searchValue?Wn.value:Dn.value),ua=computed(()=>{const ca=[{options:la.value}];let sa=la.value;for(let ia=0;iaba[Bn.value.value]===fa),ya=ma==null?void 0:ma[Bn.value.children];if(!(ya!=null&&ya.length))break;sa=ya,ca.push({options:ya})}return ca});useKeyboard(Cn,la,Bn,nr,oa,(ca,sa)=>{ra(sa)&&ea(ca,isLeaf(sa,Bn.value),!0)});const aa=ca=>{ca.preventDefault()};return onMounted(()=>{watch(nr,ca=>{var sa;for(let ia=0;ia{var ca,sa,ia,fa,ma;const{notFoundContent:ya=((ca=Pn.notFoundContent)===null||ca===void 0?void 0:ca.call(Pn))||((ia=(sa=Xn.value).notFoundContent)===null||ia===void 0?void 0:ia.call(sa)),multiple:ba,toggleOpen:Ia}=In,Ea=!(!((ma=(fa=ua.value[0])===null||fa===void 0?void 0:fa.options)===null||ma===void 0)&&ma.length),xa=[{[Bn.value.value]:"__EMPTY__",[FIX_LABEL]:ya,disabled:!0}],Ta=_extends$1(_extends$1({},_n),{multiple:!Ea&&ba,onSelect:ea,onActive:oa,onToggleOpen:Ia,checkedSet:Zo.value,halfCheckedSet:rr.value,loadingKeys:qo.value,isSelectable:ra}),La=(Ea?[{options:xa}]:ua.value).map((Na,$a)=>{const ka=nr.value.slice(0,$a),Ha=nr.value[$a];return createVNode(Column$1,_objectSpread2$1(_objectSpread2$1({key:$a},Ta),{},{prefixCls:Yo.value,options:Na.options,prevValuePath:ka,activeValue:Ha}),null)});return createVNode("div",{class:[`${Yo.value}-menus`,{[`${Yo.value}-menu-empty`]:Ea,[`${Yo.value}-rtl`]:Rn.value}],onMousedown:aa,ref:Nn},[La])}}});function useMaxLevel($n){const Cn=ref(0),_n=shallowRef();return watchEffect(()=>{const Pn=new Map;let In=0;const Nn=$n.value||{};for(const Rn in Nn)if(Object.prototype.hasOwnProperty.call(Nn,Rn)){const Dn=Nn[Rn],{level:Ln}=Dn;let Fn=Pn.get(Ln);Fn||(Fn=new Set,Pn.set(Ln,Fn)),Fn.add(Dn),In=Math.max(In,Ln)}Cn.value=In,_n.value=Pn}),{maxLevel:Cn,levelEntities:_n}}function baseCascaderProps(){return _extends$1(_extends$1({},omit$1(baseSelectPropsWithoutPrivate(),["tokenSeparators","mode","showSearch"])),{id:String,prefixCls:String,fieldNames:objectType(),children:Array,value:{type:[String,Number,Array]},defaultValue:{type:[String,Number,Array]},changeOnSelect:{type:Boolean,default:void 0},displayRender:Function,checkable:{type:Boolean,default:void 0},showCheckedStrategy:{type:String,default:SHOW_PARENT$1},showSearch:{type:[Boolean,Object],default:void 0},searchValue:String,onSearch:Function,expandTrigger:String,options:Array,dropdownPrefixCls:String,loadData:Function,popupVisible:{type:Boolean,default:void 0},popupClassName:String,dropdownClassName:String,dropdownMenuColumnStyle:{type:Object,default:void 0},popupStyle:{type:Object,default:void 0},dropdownStyle:{type:Object,default:void 0},popupPlacement:String,placement:String,onPopupVisibleChange:Function,onDropdownVisibleChange:Function,expandIcon:PropTypes.any,loadingIcon:PropTypes.any})}function internalCascaderProps(){return _extends$1(_extends$1({},baseCascaderProps()),{onChange:Function,customSlots:Object})}function isMultipleValue($n){return Array.isArray($n)&&Array.isArray($n[0])}function toRawValues($n){return $n?isMultipleValue($n)?$n:($n.length===0?[]:[$n]).map(Cn=>Array.isArray(Cn)?Cn:[Cn]):[]}const Cascader$1=defineComponent({compatConfig:{MODE:3},name:"Cascader",inheritAttrs:!1,props:initDefaultProps(internalCascaderProps(),{}),setup($n,Cn){let{attrs:_n,expose:Pn,slots:In}=Cn;const Nn=useId$1(toRef($n,"id")),Rn=computed(()=>!!$n.checkable),[Dn,Ln]=useMergedState($n.defaultValue,{value:computed(()=>$n.value),postState:toRawValues}),Fn=computed(()=>fillFieldNames$2($n.fieldNames)),Bn=computed(()=>$n.options||[]),Hn=useEntities(Bn,Fn),zn=$a=>{const ka=Hn.value;return $a.map(Ha=>{const{nodes:da}=ka[Ha];return da.map(pa=>pa[Fn.value.value])})},[Wn,Yn]=useMergedState("",{value:computed(()=>$n.searchValue),postState:$a=>$a||""}),Gn=($a,ka)=>{Yn($a),ka.source!=="blur"&&$n.onSearch&&$n.onSearch($a)},{showSearch:Go,searchConfig:Xn}=useSearchConfig(toRef($n,"showSearch")),Yo=useSearchOptions(Wn,Bn,Fn,computed(()=>$n.dropdownPrefixCls||$n.prefixCls),Xn,toRef($n,"changeOnSelect")),qo=useMissingValues(Bn,Fn,Dn),[Jo,Zo,rr]=[ref([]),ref([]),ref([])],{maxLevel:nr,levelEntities:ta}=useMaxLevel(Hn);watchEffect(()=>{const[$a,ka]=qo.value;if(!Rn.value||!Dn.value.length){[Jo.value,Zo.value,rr.value]=[$a,[],ka];return}const Ha=toPathKeys($a),da=Hn.value,{checkedKeys:pa,halfCheckedKeys:Sa}=conductCheck(Ha,!0,da,nr.value,ta.value);[Jo.value,Zo.value,rr.value]=[zn(pa),zn(Sa),ka]});const oa=computed(()=>{const $a=toPathKeys(Jo.value),ka=formatStrategyValues$1($a,Hn.value,$n.showCheckedStrategy);return[...rr.value,...zn(ka)]}),ra=useDisplayValues(oa,Bn,Fn,Rn,toRef($n,"displayRender")),ea=$a=>{if(Ln($a),$n.onChange){const ka=toRawValues($a),Ha=ka.map(Sa=>toPathOptions(Sa,Bn.value,Fn.value).map(Aa=>Aa.option)),da=Rn.value?ka:ka[0],pa=Rn.value?Ha:Ha[0];$n.onChange(da,pa)}},la=$a=>{if(Yn(""),!Rn.value)ea($a);else{const ka=toPathKey($a),Ha=toPathKeys(Jo.value),da=toPathKeys(Zo.value),pa=Ha.includes(ka),Sa=rr.value.some(Fa=>toPathKey(Fa)===ka);let Aa=Jo.value,Ra=rr.value;if(Sa&&!pa)Ra=rr.value.filter(Fa=>toPathKey(Fa)!==ka);else{const Fa=pa?Ha.filter(Ya=>Ya!==ka):[...Ha,ka];let za;pa?{checkedKeys:za}=conductCheck(Fa,{checked:!1,halfCheckedKeys:da},Hn.value,nr.value,ta.value):{checkedKeys:za}=conductCheck(Fa,!0,Hn.value,nr.value,ta.value);const Wa=formatStrategyValues$1(za,Hn.value,$n.showCheckedStrategy);Aa=zn(Wa)}ea([...Ra,...Aa])}},ua=($a,ka)=>{if(ka.type==="clear"){ea([]);return}const{valueCells:Ha}=ka.values[0];la(Ha)},ga=computed(()=>$n.open!==void 0?$n.open:$n.popupVisible),aa=computed(()=>$n.dropdownClassName||$n.popupClassName),ca=computed(()=>$n.dropdownStyle||$n.popupStyle||{}),sa=computed(()=>$n.placement||$n.popupPlacement),ia=$a=>{var ka,Ha;(ka=$n.onDropdownVisibleChange)===null||ka===void 0||ka.call($n,$a),(Ha=$n.onPopupVisibleChange)===null||Ha===void 0||Ha.call($n,$a)},{changeOnSelect:fa,checkable:ma,dropdownPrefixCls:ya,loadData:ba,expandTrigger:Ia,expandIcon:Ea,loadingIcon:xa,dropdownMenuColumnStyle:Ta,customSlots:wa}=toRefs($n);useProvideCascader({options:Bn,fieldNames:Fn,values:Jo,halfValues:Zo,changeOnSelect:fa,onSelect:la,checkable:ma,searchOptions:Yo,dropdownPrefixCls:ya,loadData:ba,expandTrigger:Ia,expandIcon:Ea,loadingIcon:xa,dropdownMenuColumnStyle:Ta,customSlots:wa});const La=ref();Pn({focus(){var $a;($a=La.value)===null||$a===void 0||$a.focus()},blur(){var $a;($a=La.value)===null||$a===void 0||$a.blur()},scrollTo($a){var ka;(ka=La.value)===null||ka===void 0||ka.scrollTo($a)}});const Na=computed(()=>omit$1($n,["id","prefixCls","fieldNames","defaultValue","value","changeOnSelect","onChange","displayRender","checkable","searchValue","onSearch","showSearch","expandTrigger","options","dropdownPrefixCls","loadData","popupVisible","open","popupClassName","dropdownClassName","dropdownMenuColumnStyle","popupPlacement","placement","onDropdownVisibleChange","onPopupVisibleChange","expandIcon","loadingIcon","customSlots","showCheckedStrategy","children"]));return()=>{const $a=!(Wn.value?Yo.value:Bn.value).length,{dropdownMatchSelectWidth:ka=!1}=$n,Ha=Wn.value&&Xn.value.matchInputWidth||$a?{}:{minWidth:"auto"};return createVNode(BaseSelect,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Na.value),_n),{},{ref:La,id:Nn,prefixCls:$n.prefixCls,dropdownMatchSelectWidth:ka,dropdownStyle:_extends$1(_extends$1({},ca.value),Ha),displayValues:ra.value,onDisplayValuesChange:ua,mode:Rn.value?"multiple":void 0,searchValue:Wn.value,onSearch:Gn,showSearch:Go.value,OptionList:OptionList$1,emptyOptions:$a,open:ga.value,dropdownClassName:aa.value,placement:sa.value,onDropdownVisibleChange:ia,getRawInputElement:()=>{var da;return(da=In.default)===null||da===void 0?void 0:da.call(In)}}),In)}}});var LeftOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"}}]},name:"left",theme:"outlined"};const LeftOutlinedSvg=LeftOutlined$2;function _objectSpread$D($n){for(var Cn=1;CncanUseDom$1()&&window.document.documentElement,isStyleNameSupport=$n=>{if(canUseDom$1()&&window.document.documentElement){const Cn=Array.isArray($n)?$n:[$n],{documentElement:_n}=window.document;return Cn.some(Pn=>Pn in _n.style)}return!1},isStyleValueSupport=($n,Cn)=>{if(!isStyleNameSupport($n))return!1;const _n=document.createElement("div"),Pn=_n.style[$n];return _n.style[$n]=Cn,_n.style[$n]!==Pn};function isStyleSupport($n,Cn){return!Array.isArray($n)&&Cn!==void 0?isStyleValueSupport($n,Cn):isStyleNameSupport($n)}let flexGapSupported;const detectFlexGapSupported=()=>{if(!canUseDocElement())return!1;if(flexGapSupported!==void 0)return flexGapSupported;const $n=document.createElement("div");return $n.style.display="flex",$n.style.flexDirection="column",$n.style.rowGap="1px",$n.appendChild(document.createElement("div")),$n.appendChild(document.createElement("div")),document.body.appendChild($n),flexGapSupported=$n.scrollHeight===1,document.body.removeChild($n),flexGapSupported},useFlexGapSupport=()=>{const $n=shallowRef(!1);return onMounted(()=>{$n.value=detectFlexGapSupported()}),$n},RowContextKey=Symbol("rowContextKey"),useProvideRow=$n=>{provide(RowContextKey,$n)},useInjectRow=()=>inject(RowContextKey,{gutter:computed(()=>{}),wrap:computed(()=>{}),supportFlexGap:computed(()=>{})}),genGridRowStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{display:"flex",flexFlow:"row wrap",minWidth:0,"&::before, &::after":{display:"flex"},"&-no-wrap":{flexWrap:"nowrap"},"&-start":{justifyContent:"flex-start"},"&-center":{justifyContent:"center"},"&-end":{justifyContent:"flex-end"},"&-space-between":{justifyContent:"space-between"},"&-space-around ":{justifyContent:"space-around"},"&-top":{alignItems:"flex-start"},"&-middle":{alignItems:"center"},"&-bottom":{alignItems:"flex-end"}}}},genGridColStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{position:"relative",maxWidth:"100%",minHeight:1}}},genLoopGridColumnsStyle=($n,Cn)=>{const{componentCls:_n,gridColumns:Pn}=$n,In={};for(let Nn=Pn;Nn>=0;Nn--)Nn===0?(In[`${_n}${Cn}-${Nn}`]={display:"none"},In[`${_n}-push-${Nn}`]={insetInlineStart:"auto"},In[`${_n}-pull-${Nn}`]={insetInlineEnd:"auto"},In[`${_n}${Cn}-push-${Nn}`]={insetInlineStart:"auto"},In[`${_n}${Cn}-pull-${Nn}`]={insetInlineEnd:"auto"},In[`${_n}${Cn}-offset-${Nn}`]={marginInlineEnd:0},In[`${_n}${Cn}-order-${Nn}`]={order:0}):(In[`${_n}${Cn}-${Nn}`]={display:"block",flex:`0 0 ${Nn/Pn*100}%`,maxWidth:`${Nn/Pn*100}%`},In[`${_n}${Cn}-push-${Nn}`]={insetInlineStart:`${Nn/Pn*100}%`},In[`${_n}${Cn}-pull-${Nn}`]={insetInlineEnd:`${Nn/Pn*100}%`},In[`${_n}${Cn}-offset-${Nn}`]={marginInlineStart:`${Nn/Pn*100}%`},In[`${_n}${Cn}-order-${Nn}`]={order:Nn});return In},genGridStyle=($n,Cn)=>genLoopGridColumnsStyle($n,Cn),genGridMediaStyle=($n,Cn,_n)=>({[`@media (min-width: ${Cn}px)`]:_extends$1({},genGridStyle($n,_n))}),useRowStyle=genComponentStyleHook("Grid",$n=>[genGridRowStyle($n)]),useColStyle=genComponentStyleHook("Grid",$n=>{const Cn=merge$1($n,{gridColumns:24}),_n={"-sm":Cn.screenSMMin,"-md":Cn.screenMDMin,"-lg":Cn.screenLGMin,"-xl":Cn.screenXLMin,"-xxl":Cn.screenXXLMin};return[genGridColStyle(Cn),genGridStyle(Cn,""),genGridStyle(Cn,"-xs"),Object.keys(_n).map(Pn=>genGridMediaStyle(Cn,_n[Pn],Pn)).reduce((Pn,In)=>_extends$1(_extends$1({},Pn),In),{})]}),rowProps=()=>({align:someType([String,Object]),justify:someType([String,Object]),prefixCls:String,gutter:someType([Number,Array,Object],0),wrap:{type:Boolean,default:void 0}}),ARow=defineComponent({compatConfig:{MODE:3},name:"ARow",inheritAttrs:!1,props:rowProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("row",$n),[Rn,Dn]=useRowStyle(In);let Ln;const Fn=useResponsiveObserver(),Bn=ref({xs:!0,sm:!0,md:!0,lg:!0,xl:!0,xxl:!0}),Hn=ref({xs:!1,sm:!1,md:!1,lg:!1,xl:!1,xxl:!1}),zn=qo=>computed(()=>{if(typeof $n[qo]=="string")return $n[qo];if(typeof $n[qo]!="object")return"";for(let Jo=0;Jo{Ln=Fn.value.subscribe(qo=>{Hn.value=qo;const Jo=$n.gutter||0;(!Array.isArray(Jo)&&typeof Jo=="object"||Array.isArray(Jo)&&(typeof Jo[0]=="object"||typeof Jo[1]=="object"))&&(Bn.value=qo)})}),onBeforeUnmount(()=>{Fn.value.unsubscribe(Ln)});const Go=computed(()=>{const qo=[void 0,void 0],{gutter:Jo=0}=$n;return(Array.isArray(Jo)?Jo:[Jo,void 0]).forEach((rr,nr)=>{if(typeof rr=="object")for(let ta=0;ta$n.wrap)});const Xn=computed(()=>classNames(In.value,{[`${In.value}-no-wrap`]:$n.wrap===!1,[`${In.value}-${Yn.value}`]:Yn.value,[`${In.value}-${Wn.value}`]:Wn.value,[`${In.value}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value)),Yo=computed(()=>{const qo=Go.value,Jo={},Zo=qo[0]!=null&&qo[0]>0?`${qo[0]/-2}px`:void 0,rr=qo[1]!=null&&qo[1]>0?`${qo[1]/-2}px`:void 0;return Zo&&(Jo.marginLeft=Zo,Jo.marginRight=Zo),Gn.value?Jo.rowGap=`${qo[1]}px`:rr&&(Jo.marginTop=rr,Jo.marginBottom=rr),Jo});return()=>{var qo;return Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Xn.value,style:_extends$1(_extends$1({},Yo.value),Pn.style)}),[(qo=_n.default)===null||qo===void 0?void 0:qo.call(_n)]))}}}),Row$2=ARow;var define_process_env_default={};function _extends(){return _extends=Object.assign?Object.assign.bind():function($n){for(var Cn=1;Cn"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function _construct($n,Cn,_n){return _isNativeReflectConstruct()?_construct=Reflect.construct.bind():_construct=function(In,Nn,Rn){var Dn=[null];Dn.push.apply(Dn,Nn);var Ln=Function.bind.apply(In,Dn),Fn=new Ln;return Rn&&_setPrototypeOf(Fn,Rn.prototype),Fn},_construct.apply(null,arguments)}function _isNativeFunction($n){return Function.toString.call($n).indexOf("[native code]")!==-1}function _wrapNativeSuper($n){var Cn=typeof Map=="function"?new Map:void 0;return _wrapNativeSuper=function(Pn){if(Pn===null||!_isNativeFunction(Pn))return Pn;if(typeof Pn!="function")throw new TypeError("Super expression must either be null or a function");if(typeof Cn<"u"){if(Cn.has(Pn))return Cn.get(Pn);Cn.set(Pn,In)}function In(){return _construct(Pn,arguments,_getPrototypeOf(this).constructor)}return In.prototype=Object.create(Pn.prototype,{constructor:{value:In,enumerable:!1,writable:!0,configurable:!0}}),_setPrototypeOf(In,Pn)},_wrapNativeSuper($n)}var formatRegExp=/%[sdj%]/g,warning=function(){};typeof process<"u";function convertFieldsError($n){if(!$n||!$n.length)return null;var Cn={};return $n.forEach(function(_n){var Pn=_n.field;Cn[Pn]=Cn[Pn]||[],Cn[Pn].push(_n)}),Cn}function format$3($n){for(var Cn=arguments.length,_n=new Array(Cn>1?Cn-1:0),Pn=1;Pn=Nn)return Dn;switch(Dn){case"%s":return String(_n[In++]);case"%d":return Number(_n[In++]);case"%j":try{return JSON.stringify(_n[In++])}catch{return"[Circular]"}break;default:return Dn}});return Rn}return $n}function isNativeStringType($n){return $n==="string"||$n==="url"||$n==="hex"||$n==="email"||$n==="date"||$n==="pattern"}function isEmptyValue($n,Cn){return!!($n==null||Cn==="array"&&Array.isArray($n)&&!$n.length||isNativeStringType(Cn)&&typeof $n=="string"&&!$n)}function asyncParallelArray($n,Cn,_n){var Pn=[],In=0,Nn=$n.length;function Rn(Dn){Pn.push.apply(Pn,Dn||[]),In++,In===Nn&&_n(Pn)}$n.forEach(function(Dn){Cn(Dn,Rn)})}function asyncSerialArray($n,Cn,_n){var Pn=0,In=$n.length;function Nn(Rn){if(Rn&&Rn.length){_n(Rn);return}var Dn=Pn;Pn=Pn+1,Dn()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/,hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},types={integer:function(Cn){return types.number(Cn)&&parseInt(Cn,10)===Cn},float:function(Cn){return types.number(Cn)&&!types.integer(Cn)},array:function(Cn){return Array.isArray(Cn)},regexp:function(Cn){if(Cn instanceof RegExp)return!0;try{return!!new RegExp(Cn)}catch{return!1}},date:function(Cn){return typeof Cn.getTime=="function"&&typeof Cn.getMonth=="function"&&typeof Cn.getYear=="function"&&!isNaN(Cn.getTime())},number:function(Cn){return isNaN(Cn)?!1:typeof Cn=="number"},object:function(Cn){return typeof Cn=="object"&&!types.array(Cn)},method:function(Cn){return typeof Cn=="function"},email:function(Cn){return typeof Cn=="string"&&Cn.length<=320&&!!Cn.match(pattern$2.email)},url:function(Cn){return typeof Cn=="string"&&Cn.length<=2048&&!!Cn.match(getUrlRegex())},hex:function(Cn){return typeof Cn=="string"&&!!Cn.match(pattern$2.hex)}},type$1=function(Cn,_n,Pn,In,Nn){if(Cn.required&&_n===void 0){required$1(Cn,_n,Pn,In,Nn);return}var Rn=["integer","float","array","regexp","object","method","email","number","date","url","hex"],Dn=Cn.type;Rn.indexOf(Dn)>-1?types[Dn](_n)||In.push(format$3(Nn.messages.types[Dn],Cn.fullField,Cn.type)):Dn&&typeof _n!==Cn.type&&In.push(format$3(Nn.messages.types[Dn],Cn.fullField,Cn.type))},range=function(Cn,_n,Pn,In,Nn){var Rn=typeof Cn.len=="number",Dn=typeof Cn.min=="number",Ln=typeof Cn.max=="number",Fn=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,Bn=_n,Hn=null,zn=typeof _n=="number",Wn=typeof _n=="string",Yn=Array.isArray(_n);if(zn?Hn="number":Wn?Hn="string":Yn&&(Hn="array"),!Hn)return!1;Yn&&(Bn=_n.length),Wn&&(Bn=_n.replace(Fn,"_").length),Rn?Bn!==Cn.len&&In.push(format$3(Nn.messages[Hn].len,Cn.fullField,Cn.len)):Dn&&!Ln&&BnCn.max?In.push(format$3(Nn.messages[Hn].max,Cn.fullField,Cn.max)):Dn&&Ln&&(BnCn.max)&&In.push(format$3(Nn.messages[Hn].range,Cn.fullField,Cn.min,Cn.max))},ENUM$1="enum",enumerable$1=function(Cn,_n,Pn,In,Nn){Cn[ENUM$1]=Array.isArray(Cn[ENUM$1])?Cn[ENUM$1]:[],Cn[ENUM$1].indexOf(_n)===-1&&In.push(format$3(Nn.messages[ENUM$1],Cn.fullField,Cn[ENUM$1].join(", ")))},pattern$1=function(Cn,_n,Pn,In,Nn){if(Cn.pattern){if(Cn.pattern instanceof RegExp)Cn.pattern.lastIndex=0,Cn.pattern.test(_n)||In.push(format$3(Nn.messages.pattern.mismatch,Cn.fullField,_n,Cn.pattern));else if(typeof Cn.pattern=="string"){var Rn=new RegExp(Cn.pattern);Rn.test(_n)||In.push(format$3(Nn.messages.pattern.mismatch,Cn.fullField,_n,Cn.pattern))}}},rules={required:required$1,whitespace,type:type$1,range,enum:enumerable$1,pattern:pattern$1},string=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n,"string")&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn,"string"),isEmptyValue(_n,"string")||(rules.type(Cn,_n,In,Rn,Nn),rules.range(Cn,_n,In,Rn,Nn),rules.pattern(Cn,_n,In,Rn,Nn),Cn.whitespace===!0&&rules.whitespace(Cn,_n,In,Rn,Nn))}Pn(Rn)},method2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&rules.type(Cn,_n,In,Rn,Nn)}Pn(Rn)},number2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(_n===""&&(_n=void 0),isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&(rules.type(Cn,_n,In,Rn,Nn),rules.range(Cn,_n,In,Rn,Nn))}Pn(Rn)},_boolean=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&rules.type(Cn,_n,In,Rn,Nn)}Pn(Rn)},regexp2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),isEmptyValue(_n)||rules.type(Cn,_n,In,Rn,Nn)}Pn(Rn)},integer2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&(rules.type(Cn,_n,In,Rn,Nn),rules.range(Cn,_n,In,Rn,Nn))}Pn(Rn)},floatFn=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&(rules.type(Cn,_n,In,Rn,Nn),rules.range(Cn,_n,In,Rn,Nn))}Pn(Rn)},array2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(_n==null&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn,"array"),_n!=null&&(rules.type(Cn,_n,In,Rn,Nn),rules.range(Cn,_n,In,Rn,Nn))}Pn(Rn)},object2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&rules.type(Cn,_n,In,Rn,Nn)}Pn(Rn)},ENUM="enum",enumerable2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),_n!==void 0&&rules[ENUM](Cn,_n,In,Rn,Nn)}Pn(Rn)},pattern2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n,"string")&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn),isEmptyValue(_n,"string")||rules.pattern(Cn,_n,In,Rn,Nn)}Pn(Rn)},date2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n,"date")&&!Cn.required)return Pn();if(rules.required(Cn,_n,In,Rn,Nn),!isEmptyValue(_n,"date")){var Ln;_n instanceof Date?Ln=_n:Ln=new Date(_n),rules.type(Cn,Ln,In,Rn,Nn),Ln&&rules.range(Cn,Ln.getTime(),In,Rn,Nn)}}Pn(Rn)},required2=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Array.isArray(_n)?"array":typeof _n;rules.required(Cn,_n,In,Rn,Nn,Dn),Pn(Rn)},type2=function(Cn,_n,Pn,In,Nn){var Rn=Cn.type,Dn=[],Ln=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Ln){if(isEmptyValue(_n,Rn)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Dn,Nn,Rn),isEmptyValue(_n,Rn)||rules.type(Cn,_n,In,Dn,Nn)}Pn(Dn)},any=function(Cn,_n,Pn,In,Nn){var Rn=[],Dn=Cn.required||!Cn.required&&In.hasOwnProperty(Cn.field);if(Dn){if(isEmptyValue(_n)&&!Cn.required)return Pn();rules.required(Cn,_n,In,Rn,Nn)}Pn(Rn)},validators={string,method:method2,number:number2,boolean:_boolean,regexp:regexp2,integer:integer2,float:floatFn,array:array2,object:object2,enum:enumerable2,pattern:pattern2,date:date2,url:type2,hex:type2,email:type2,required:required2,any};function newMessages(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var Cn=JSON.parse(JSON.stringify(this));return Cn.clone=this.clone,Cn}}}var messages$1=newMessages(),Schema=function(){function $n(_n){this.rules=null,this._messages=messages$1,this.define(_n)}var Cn=$n.prototype;return Cn.define=function(Pn){var In=this;if(!Pn)throw new Error("Cannot configure a schema with no rules");if(typeof Pn!="object"||Array.isArray(Pn))throw new Error("Rules must be an object");this.rules={},Object.keys(Pn).forEach(function(Nn){var Rn=Pn[Nn];In.rules[Nn]=Array.isArray(Rn)?Rn:[Rn]})},Cn.messages=function(Pn){return Pn&&(this._messages=deepMerge(newMessages(),Pn)),this._messages},Cn.validate=function(Pn,In,Nn){var Rn=this;In===void 0&&(In={}),Nn===void 0&&(Nn=function(){});var Dn=Pn,Ln=In,Fn=Nn;if(typeof Ln=="function"&&(Fn=Ln,Ln={}),!this.rules||Object.keys(this.rules).length===0)return Fn&&Fn(null,Dn),Promise.resolve(Dn);function Bn(Gn){var Go=[],Xn={};function Yo(Jo){if(Array.isArray(Jo)){var Zo;Go=(Zo=Go).concat.apply(Zo,Jo)}else Go.push(Jo)}for(var qo=0;qo3&&arguments[3]!==void 0?arguments[3]:!1;return Cn.length&&Pn&&_n===void 0&&!get($n,Cn.slice(0,-1))?$n:internalSet($n,Cn,_n,Pn)}function getNamePath($n){return toArray$5($n)}function getValue($n,Cn){return get($n,Cn)}function setValue($n,Cn,_n){let Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;return set($n,Cn,_n,Pn)}function containsNamePath($n,Cn){return $n&&$n.some(_n=>matchNamePath(_n,Cn))}function isObject$4($n){return typeof $n=="object"&&$n!==null&&Object.getPrototypeOf($n)===Object.prototype}function internalSetValues($n,Cn){const _n=Array.isArray($n)?[...$n]:_extends$1({},$n);return Cn&&Object.keys(Cn).forEach(Pn=>{const In=_n[Pn],Nn=Cn[Pn],Rn=isObject$4(In)&&isObject$4(Nn);_n[Pn]=Rn?internalSetValues(In,Nn||{}):Nn}),_n}function setValues($n){for(var Cn=arguments.length,_n=new Array(Cn>1?Cn-1:0),Pn=1;PninternalSetValues(In,Nn),$n)}function cloneByNamePathList($n,Cn){let _n={};return Cn.forEach(Pn=>{const In=getValue($n,Pn);_n=setValue(_n,Pn,In)}),_n}function matchNamePath($n,Cn){return!$n||!Cn||$n.length!==Cn.length?!1:$n.every((_n,Pn)=>Cn[Pn]===_n)}const typeTemplate$1="'${name}' is not a valid ${type}",defaultValidateMessages={default:"Validation error on field '${name}'",required:"'${name}' is required",enum:"'${name}' must be one of [${enum}]",whitespace:"'${name}' cannot be empty",date:{format:"'${name}' is invalid for format date",parse:"'${name}' could not be parsed as date",invalid:"'${name}' is invalid date"},types:{string:typeTemplate$1,method:typeTemplate$1,array:typeTemplate$1,object:typeTemplate$1,number:typeTemplate$1,date:typeTemplate$1,boolean:typeTemplate$1,integer:typeTemplate$1,float:typeTemplate$1,regexp:typeTemplate$1,email:typeTemplate$1,url:typeTemplate$1,hex:typeTemplate$1},string:{len:"'${name}' must be exactly ${len} characters",min:"'${name}' must be at least ${min} characters",max:"'${name}' cannot be longer than ${max} characters",range:"'${name}' must be between ${min} and ${max} characters"},number:{len:"'${name}' must equal ${len}",min:"'${name}' cannot be less than ${min}",max:"'${name}' cannot be greater than ${max}",range:"'${name}' must be between ${min} and ${max}"},array:{len:"'${name}' must be exactly ${len} in length",min:"'${name}' cannot be less than ${min} in length",max:"'${name}' cannot be greater than ${max} in length",range:"'${name}' must be between ${min} and ${max} in length"},pattern:{mismatch:"'${name}' does not match pattern ${pattern}"}};var __awaiter$2=function($n,Cn,_n,Pn){function In(Nn){return Nn instanceof _n?Nn:new _n(function(Rn){Rn(Nn)})}return new(_n||(_n=Promise))(function(Nn,Rn){function Dn(Bn){try{Fn(Pn.next(Bn))}catch(Hn){Rn(Hn)}}function Ln(Bn){try{Fn(Pn.throw(Bn))}catch(Hn){Rn(Hn)}}function Fn(Bn){Bn.done?Nn(Bn.value):In(Bn.value).then(Dn,Ln)}Fn((Pn=Pn.apply($n,Cn||[])).next())})};const AsyncValidator=Schema;function replaceMessage($n,Cn){return $n.replace(/\$\{\w+\}/g,_n=>{const Pn=_n.slice(2,-1);return Cn[Pn]})}function validateRule($n,Cn,_n,Pn,In){return __awaiter$2(this,void 0,void 0,function*(){const Nn=_extends$1({},_n);delete Nn.ruleIndex,delete Nn.trigger;let Rn=null;Nn&&Nn.type==="array"&&Nn.defaultField&&(Rn=Nn.defaultField,delete Nn.defaultField);const Dn=new AsyncValidator({[$n]:[Nn]}),Ln=setValues({},defaultValidateMessages,Pn.validateMessages);Dn.messages(Ln);let Fn=[];try{yield Promise.resolve(Dn.validate({[$n]:Cn},_extends$1({},Pn)))}catch(zn){zn.errors?Fn=zn.errors.map((Wn,Yn)=>{let{message:Gn}=Wn;return isValidElement(Gn)?cloneVNode(Gn,{key:`error_${Yn}`}):Gn}):(console.error(zn),Fn=[Ln.default()])}if(!Fn.length&&Rn)return(yield Promise.all(Cn.map((Wn,Yn)=>validateRule(`${$n}.${Yn}`,Wn,Rn,Pn,In)))).reduce((Wn,Yn)=>[...Wn,...Yn],[]);const Bn=_extends$1(_extends$1(_extends$1({},_n),{name:$n,enum:(_n.enum||[]).join(", ")}),In);return Fn.map(zn=>typeof zn=="string"?replaceMessage(zn,Bn):zn)})}function validateRules($n,Cn,_n,Pn,In,Nn){const Rn=$n.join("."),Dn=_n.map((Fn,Bn)=>{const Hn=Fn.validator,zn=_extends$1(_extends$1({},Fn),{ruleIndex:Bn});return Hn&&(zn.validator=(Wn,Yn,Gn)=>{let Go=!1;const Yo=Hn(Wn,Yn,function(){for(var qo=arguments.length,Jo=new Array(qo),Zo=0;Zo{Go||Gn(...Jo)})});Go=Yo&&typeof Yo.then=="function"&&typeof Yo.catch=="function",Go&&Yo.then(()=>{Gn()}).catch(qo=>{Gn(qo||" ")})}),zn}).sort((Fn,Bn)=>{let{warningOnly:Hn,ruleIndex:zn}=Fn,{warningOnly:Wn,ruleIndex:Yn}=Bn;return!!Hn==!!Wn?zn-Yn:Hn?1:-1});let Ln;if(In===!0)Ln=new Promise((Fn,Bn)=>__awaiter$2(this,void 0,void 0,function*(){for(let Hn=0;HnvalidateRule(Rn,Cn,Bn,Pn,Nn).then(Hn=>({errors:Hn,rule:Bn})));Ln=(In?finishOnFirstFailed(Fn):finishOnAllFailed(Fn)).then(Bn=>Promise.reject(Bn))}return Ln.catch(Fn=>Fn),Ln}function finishOnAllFailed($n){return __awaiter$2(this,void 0,void 0,function*(){return Promise.all($n).then(Cn=>[].concat(...Cn))})}function finishOnFirstFailed($n){return __awaiter$2(this,void 0,void 0,function*(){let Cn=0;return new Promise(_n=>{$n.forEach(Pn=>{Pn.then(In=>{In.errors.length&&_n([In]),Cn+=1,Cn===$n.length&&_n([])})})})})}const FormContextKey=Symbol("formContextKey"),useProvideForm=$n=>{provide(FormContextKey,$n)},useInjectForm=()=>inject(FormContextKey,{name:computed(()=>{}),labelAlign:computed(()=>"right"),vertical:computed(()=>!1),addField:($n,Cn)=>{},removeField:$n=>{},model:computed(()=>{}),rules:computed(()=>{}),colon:computed(()=>{}),labelWrap:computed(()=>{}),labelCol:computed(()=>{}),requiredMark:computed(()=>!1),validateTrigger:computed(()=>{}),onValidate:()=>{},validateMessages:computed(()=>defaultValidateMessages)}),FormItemPrefixContextKey=Symbol("formItemPrefixContextKey"),useProvideFormItemPrefix=$n=>{provide(FormItemPrefixContextKey,$n)},useInjectFormItemPrefix=()=>inject(FormItemPrefixContextKey,{prefixCls:computed(()=>"")});function parseFlex($n){return typeof $n=="number"?`${$n} ${$n} auto`:/^\d+(\.\d+)?(px|em|rem|%)$/.test($n)?`0 0 ${$n}`:$n}const colProps=()=>({span:[String,Number],order:[String,Number],offset:[String,Number],push:[String,Number],pull:[String,Number],xs:{type:[String,Number,Object],default:void 0},sm:{type:[String,Number,Object],default:void 0},md:{type:[String,Number,Object],default:void 0},lg:{type:[String,Number,Object],default:void 0},xl:{type:[String,Number,Object],default:void 0},xxl:{type:[String,Number,Object],default:void 0},prefixCls:String,flex:[String,Number]}),sizes=["xs","sm","md","lg","xl","xxl"],Col=defineComponent({compatConfig:{MODE:3},name:"ACol",inheritAttrs:!1,props:colProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{gutter:In,supportFlexGap:Nn,wrap:Rn}=useInjectRow(),{prefixCls:Dn,direction:Ln}=useConfigInject("col",$n),[Fn,Bn]=useColStyle(Dn),Hn=computed(()=>{const{span:Wn,order:Yn,offset:Gn,push:Go,pull:Xn}=$n,Yo=Dn.value;let qo={};return sizes.forEach(Jo=>{let Zo={};const rr=$n[Jo];typeof rr=="number"?Zo.span=rr:typeof rr=="object"&&(Zo=rr||{}),qo=_extends$1(_extends$1({},qo),{[`${Yo}-${Jo}-${Zo.span}`]:Zo.span!==void 0,[`${Yo}-${Jo}-order-${Zo.order}`]:Zo.order||Zo.order===0,[`${Yo}-${Jo}-offset-${Zo.offset}`]:Zo.offset||Zo.offset===0,[`${Yo}-${Jo}-push-${Zo.push}`]:Zo.push||Zo.push===0,[`${Yo}-${Jo}-pull-${Zo.pull}`]:Zo.pull||Zo.pull===0,[`${Yo}-rtl`]:Ln.value==="rtl"})}),classNames(Yo,{[`${Yo}-${Wn}`]:Wn!==void 0,[`${Yo}-order-${Yn}`]:Yn,[`${Yo}-offset-${Gn}`]:Gn,[`${Yo}-push-${Go}`]:Go,[`${Yo}-pull-${Xn}`]:Xn},qo,Pn.class,Bn.value)}),zn=computed(()=>{const{flex:Wn}=$n,Yn=In.value,Gn={};if(Yn&&Yn[0]>0){const Go=`${Yn[0]/2}px`;Gn.paddingLeft=Go,Gn.paddingRight=Go}if(Yn&&Yn[1]>0&&!Nn.value){const Go=`${Yn[1]/2}px`;Gn.paddingTop=Go,Gn.paddingBottom=Go}return Wn&&(Gn.flex=parseFlex(Wn),Rn.value===!1&&!Gn.minWidth&&(Gn.minWidth=0)),Gn});return()=>{var Wn;return Fn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Hn.value,style:[zn.value,Pn.style]}),[(Wn=_n.default)===null||Wn===void 0?void 0:Wn.call(_n)]))}}});var QuestionCircleOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"}}]},name:"question-circle",theme:"outlined"};const QuestionCircleOutlinedSvg=QuestionCircleOutlined$2;function _objectSpread$C($n){for(var Cn=1;Cn{let{slots:_n,emit:Pn,attrs:In}=Cn;var Nn,Rn,Dn,Ln,Fn;const{prefixCls:Bn,htmlFor:Hn,labelCol:zn,labelAlign:Wn,colon:Yn,required:Gn,requiredMark:Go}=_extends$1(_extends$1({},$n),In),[Xn]=useLocaleReceiver("Form"),Yo=(Nn=$n.label)!==null&&Nn!==void 0?Nn:(Rn=_n.label)===null||Rn===void 0?void 0:Rn.call(_n);if(!Yo)return null;const{vertical:qo,labelAlign:Jo,labelCol:Zo,labelWrap:rr,colon:nr}=useInjectForm(),ta=zn||(Zo==null?void 0:Zo.value)||{},oa=Wn||(Jo==null?void 0:Jo.value),ra=`${Bn}-item-label`,ea=classNames(ra,oa==="left"&&`${ra}-left`,ta.class,{[`${ra}-wrap`]:!!rr.value});let la=Yo;const ua=Yn===!0||(nr==null?void 0:nr.value)!==!1&&Yn!==!1;if(ua&&!qo.value&&typeof Yo=="string"&&Yo.trim()!==""&&(la=Yo.replace(/[:|:]\s*$/,"")),$n.tooltip||_n.tooltip){const ca=createVNode("span",{class:`${Bn}-item-tooltip`},[createVNode(Tooltip,{title:$n.tooltip},{default:()=>[createVNode(QuestionCircleOutlined$1,null,null)]})]);la=createVNode(Fragment,null,[la,_n.tooltip?(Dn=_n.tooltip)===null||Dn===void 0?void 0:Dn.call(_n,{class:`${Bn}-item-tooltip`}):ca])}Go==="optional"&&!Gn&&(la=createVNode(Fragment,null,[la,createVNode("span",{class:`${Bn}-item-optional`},[((Ln=Xn.value)===null||Ln===void 0?void 0:Ln.optional)||((Fn=localeValues$1.Form)===null||Fn===void 0?void 0:Fn.optional)])]));const aa=classNames({[`${Bn}-item-required`]:Gn,[`${Bn}-item-required-mark-optional`]:Go==="optional",[`${Bn}-item-no-colon`]:!ua});return createVNode(Col,_objectSpread2$1(_objectSpread2$1({},ta),{},{class:ea}),{default:()=>[createVNode("label",{for:Hn,class:aa,title:typeof Yo=="string"?Yo:"",onClick:ca=>Pn("click",ca)},[la])]})};FormItemLabel.displayName="FormItemLabel";FormItemLabel.inheritAttrs=!1;const FormItemLabel$1=FormItemLabel,genFormValidateMotionStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-show-help`,Pn=`${Cn}-show-help-item`;return{[_n]:{transition:`opacity ${$n.motionDurationSlow} ${$n.motionEaseInOut}`,"&-appear, &-enter":{opacity:0,"&-active":{opacity:1}},"&-leave":{opacity:1,"&-active":{opacity:0}},[Pn]:{overflow:"hidden",transition:`height ${$n.motionDurationSlow} ${$n.motionEaseInOut}, - opacity ${$n.motionDurationSlow} ${$n.motionEaseInOut}, - transform ${$n.motionDurationSlow} ${$n.motionEaseInOut} !important`,[`&${Pn}-appear, &${Pn}-enter`]:{transform:"translateY(-5px)",opacity:0,"&-active":{transform:"translateY(0)",opacity:1}},[`&${Pn}-leave-active`]:{transform:"translateY(-5px)"}}}}},genFormValidateMotionStyle$1=genFormValidateMotionStyle,resetForm=$n=>({legend:{display:"block",width:"100%",marginBottom:$n.marginLG,padding:0,color:$n.colorTextDescription,fontSize:$n.fontSizeLG,lineHeight:"inherit",border:0,borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`},label:{fontSize:$n.fontSize},'input[type="search"]':{boxSizing:"border-box"},'input[type="radio"], input[type="checkbox"]':{lineHeight:"normal"},'input[type="file"]':{display:"block"},'input[type="range"]':{display:"block",width:"100%"},"select[multiple], select[size]":{height:"auto"},"input[type='file']:focus,\n input[type='radio']:focus,\n input[type='checkbox']:focus":{outline:0,boxShadow:`0 0 0 ${$n.controlOutlineWidth}px ${$n.controlOutline}`},output:{display:"block",paddingTop:15,color:$n.colorText,fontSize:$n.fontSize,lineHeight:$n.lineHeight}}),genFormSize=($n,Cn)=>{const{formItemCls:_n}=$n;return{[_n]:{[`${_n}-label > label`]:{height:Cn},[`${_n}-control-input`]:{minHeight:Cn}}}},genFormStyle=$n=>{const{componentCls:Cn}=$n;return{[$n.componentCls]:_extends$1(_extends$1(_extends$1({},resetComponent($n)),resetForm($n)),{[`${Cn}-text`]:{display:"inline-block",paddingInlineEnd:$n.paddingSM},"&-small":_extends$1({},genFormSize($n,$n.controlHeightSM)),"&-large":_extends$1({},genFormSize($n,$n.controlHeightLG))})}},genFormItemStyle=$n=>{const{formItemCls:Cn,iconCls:_n,componentCls:Pn,rootPrefixCls:In}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{marginBottom:$n.marginLG,verticalAlign:"top","&-with-help":{transition:"none"},[`&-hidden, - &-hidden.${In}-row`]:{display:"none"},"&-has-warning":{[`${Cn}-split`]:{color:$n.colorError}},"&-has-error":{[`${Cn}-split`]:{color:$n.colorWarning}},[`${Cn}-label`]:{display:"inline-block",flexGrow:0,overflow:"hidden",whiteSpace:"nowrap",textAlign:"end",verticalAlign:"middle","&-left":{textAlign:"start"},"&-wrap":{overflow:"unset",lineHeight:`${$n.lineHeight} - 0.25em`,whiteSpace:"unset"},"> label":{position:"relative",display:"inline-flex",alignItems:"center",maxWidth:"100%",height:$n.controlHeight,color:$n.colorTextHeading,fontSize:$n.fontSize,[`> ${_n}`]:{fontSize:$n.fontSize,verticalAlign:"top"},[`&${Cn}-required:not(${Cn}-required-mark-optional)::before`]:{display:"inline-block",marginInlineEnd:$n.marginXXS,color:$n.colorError,fontSize:$n.fontSize,fontFamily:"SimSun, sans-serif",lineHeight:1,content:'"*"',[`${Pn}-hide-required-mark &`]:{display:"none"}},[`${Cn}-optional`]:{display:"inline-block",marginInlineStart:$n.marginXXS,color:$n.colorTextDescription,[`${Pn}-hide-required-mark &`]:{display:"none"}},[`${Cn}-tooltip`]:{color:$n.colorTextDescription,cursor:"help",writingMode:"horizontal-tb",marginInlineStart:$n.marginXXS},"&::after":{content:'":"',position:"relative",marginBlock:0,marginInlineStart:$n.marginXXS/2,marginInlineEnd:$n.marginXS},[`&${Cn}-no-colon::after`]:{content:'" "'}}},[`${Cn}-control`]:{display:"flex",flexDirection:"column",flexGrow:1,[`&:first-child:not([class^="'${In}-col-'"]):not([class*="' ${In}-col-'"])`]:{width:"100%"},"&-input":{position:"relative",display:"flex",alignItems:"center",minHeight:$n.controlHeight,"&-content":{flex:"auto",maxWidth:"100%"}}},[Cn]:{"&-explain, &-extra":{clear:"both",color:$n.colorTextDescription,fontSize:$n.fontSize,lineHeight:$n.lineHeight},"&-explain-connected":{width:"100%"},"&-extra":{minHeight:$n.controlHeightSM,transition:`color ${$n.motionDurationMid} ${$n.motionEaseOut}`},"&-explain":{"&-error":{color:$n.colorError},"&-warning":{color:$n.colorWarning}}},[`&-with-help ${Cn}-explain`]:{height:"auto",opacity:1},[`${Cn}-feedback-icon`]:{fontSize:$n.fontSize,textAlign:"center",visibility:"visible",animationName:zoomIn,animationDuration:$n.motionDurationMid,animationTimingFunction:$n.motionEaseOutBack,pointerEvents:"none","&-success":{color:$n.colorSuccess},"&-error":{color:$n.colorError},"&-warning":{color:$n.colorWarning},"&-validating":{color:$n.colorPrimary}}})}},genHorizontalStyle$1=$n=>{const{componentCls:Cn,formItemCls:_n,rootPrefixCls:Pn}=$n;return{[`${Cn}-horizontal`]:{[`${_n}-label`]:{flexGrow:0},[`${_n}-control`]:{flex:"1 1 0",minWidth:0},[`${_n}-label.${Pn}-col-24 + ${_n}-control`]:{minWidth:"unset"}}}},genInlineStyle=$n=>{const{componentCls:Cn,formItemCls:_n}=$n;return{[`${Cn}-inline`]:{display:"flex",flexWrap:"wrap",[_n]:{flex:"none",flexWrap:"nowrap",marginInlineEnd:$n.margin,marginBottom:0,"&-with-help":{marginBottom:$n.marginLG},[`> ${_n}-label, - > ${_n}-control`]:{display:"inline-block",verticalAlign:"top"},[`> ${_n}-label`]:{flex:"none"},[`${Cn}-text`]:{display:"inline-block"},[`${_n}-has-feedback`]:{display:"inline-block"}}}}},makeVerticalLayoutLabel=$n=>({margin:0,padding:`0 0 ${$n.paddingXS}px`,whiteSpace:"initial",textAlign:"start","> label":{margin:0,"&::after":{display:"none"}}}),makeVerticalLayout=$n=>{const{componentCls:Cn,formItemCls:_n}=$n;return{[`${_n} ${_n}-label`]:makeVerticalLayoutLabel($n),[Cn]:{[_n]:{flexWrap:"wrap",[`${_n}-label, - ${_n}-control`]:{flex:"0 0 100%",maxWidth:"100%"}}}}},genVerticalStyle$1=$n=>{const{componentCls:Cn,formItemCls:_n,rootPrefixCls:Pn}=$n;return{[`${Cn}-vertical`]:{[_n]:{"&-row":{flexDirection:"column"},"&-label > label":{height:"auto"},[`${Cn}-item-control`]:{width:"100%"}}},[`${Cn}-vertical ${_n}-label, - .${Pn}-col-24${_n}-label, - .${Pn}-col-xl-24${_n}-label`]:makeVerticalLayoutLabel($n),[`@media (max-width: ${$n.screenXSMax}px)`]:[makeVerticalLayout($n),{[Cn]:{[`.${Pn}-col-xs-24${_n}-label`]:makeVerticalLayoutLabel($n)}}],[`@media (max-width: ${$n.screenSMMax}px)`]:{[Cn]:{[`.${Pn}-col-sm-24${_n}-label`]:makeVerticalLayoutLabel($n)}},[`@media (max-width: ${$n.screenMDMax}px)`]:{[Cn]:{[`.${Pn}-col-md-24${_n}-label`]:makeVerticalLayoutLabel($n)}},[`@media (max-width: ${$n.screenLGMax}px)`]:{[Cn]:{[`.${Pn}-col-lg-24${_n}-label`]:makeVerticalLayoutLabel($n)}}}},useStyle$C=genComponentStyleHook("Form",($n,Cn)=>{let{rootPrefixCls:_n}=Cn;const Pn=merge$1($n,{formItemCls:`${$n.componentCls}-item`,rootPrefixCls:_n});return[genFormStyle(Pn),genFormItemStyle(Pn),genFormValidateMotionStyle$1(Pn),genHorizontalStyle$1(Pn),genInlineStyle(Pn),genVerticalStyle$1(Pn),genCollapseMotion$1(Pn),zoomIn]}),ErrorList=defineComponent({compatConfig:{MODE:3},name:"ErrorList",inheritAttrs:!1,props:["errors","help","onErrorVisibleChanged","helpStatus","warnings"],setup($n,Cn){let{attrs:_n}=Cn;const{prefixCls:Pn,status:In}=useInjectFormItemPrefix(),Nn=computed(()=>`${Pn.value}-item-explain`),Rn=computed(()=>!!($n.errors&&$n.errors.length)),Dn=ref(In.value),[,Ln]=useStyle$C(Pn);return watch([Rn,In],()=>{Rn.value&&(Dn.value=In.value)}),()=>{var Fn,Bn;const Hn=collapseMotion$1(`${Pn.value}-show-help-item`),zn=getTransitionGroupProps(`${Pn.value}-show-help-item`,Hn);return zn.role="alert",zn.class=[Ln.value,Nn.value,_n.class,`${Pn.value}-show-help`],createVNode(Transition,_objectSpread2$1(_objectSpread2$1({},getTransitionProps(`${Pn.value}-show-help`)),{},{onAfterEnter:()=>$n.onErrorVisibleChanged(!0),onAfterLeave:()=>$n.onErrorVisibleChanged(!1)}),{default:()=>[withDirectives(createVNode(TransitionGroup,_objectSpread2$1(_objectSpread2$1({},zn),{},{tag:"div"}),{default:()=>[(Bn=$n.errors)===null||Bn===void 0?void 0:Bn.map((Wn,Yn)=>createVNode("div",{key:Yn,class:Dn.value?`${Nn.value}-${Dn.value}`:""},[Wn]))]}),[[vShow,!!(!((Fn=$n.errors)===null||Fn===void 0)&&Fn.length)]])]})}}}),FormItemInput=defineComponent({compatConfig:{MODE:3},slots:Object,inheritAttrs:!1,props:["prefixCls","errors","hasFeedback","onDomErrorVisibleChange","wrapperCol","help","extra","status","marginBottom","onErrorVisibleChanged"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectForm(),{wrapperCol:In}=Pn,Nn=_extends$1({},Pn);return delete Nn.labelCol,delete Nn.wrapperCol,useProvideForm(Nn),useProvideFormItemPrefix({prefixCls:computed(()=>$n.prefixCls),status:computed(()=>$n.status)}),()=>{var Rn,Dn,Ln;const{prefixCls:Fn,wrapperCol:Bn,marginBottom:Hn,onErrorVisibleChanged:zn,help:Wn=(Rn=_n.help)===null||Rn===void 0?void 0:Rn.call(_n),errors:Yn=filterEmpty((Dn=_n.errors)===null||Dn===void 0?void 0:Dn.call(_n)),extra:Gn=(Ln=_n.extra)===null||Ln===void 0?void 0:Ln.call(_n)}=$n,Go=`${Fn}-item`,Xn=Bn||(In==null?void 0:In.value)||{},Yo=classNames(`${Go}-control`,Xn.class);return createVNode(Col,_objectSpread2$1(_objectSpread2$1({},Xn),{},{class:Yo}),{default:()=>{var qo;return createVNode(Fragment,null,[createVNode("div",{class:`${Go}-control-input`},[createVNode("div",{class:`${Go}-control-input-content`},[(qo=_n.default)===null||qo===void 0?void 0:qo.call(_n)])]),Hn!==null||Yn.length?createVNode("div",{style:{display:"flex",flexWrap:"nowrap"}},[createVNode(ErrorList,{errors:Yn,help:Wn,class:`${Go}-explain-connected`,onErrorVisibleChanged:zn},null),!!Hn&&createVNode("div",{style:{width:0,height:`${Hn}px`}},null)]):null,Gn?createVNode("div",{class:`${Go}-extra`},[Gn]):null])}})}}}),FormItemInput$1=FormItemInput;function useDebounce($n){const Cn=shallowRef($n.value.slice());let _n=null;return watchEffect(()=>{clearTimeout(_n),_n=setTimeout(()=>{Cn.value=$n.value},$n.value.length?0:10)}),Cn}tuple$1("success","warning","error","validating","");const iconMap={success:CheckCircleFilled$1,warning:ExclamationCircleFilled$1,error:CloseCircleFilled$1,validating:LoadingOutlined$1};function getPropByPath$1($n,Cn,_n){let Pn=$n;const In=Cn;let Nn=0;try{for(let Rn=In.length;Nn({htmlFor:String,prefixCls:String,label:PropTypes.any,help:PropTypes.any,extra:PropTypes.any,labelCol:{type:Object},wrapperCol:{type:Object},hasFeedback:{type:Boolean,default:!1},colon:{type:Boolean,default:void 0},labelAlign:String,prop:{type:[String,Number,Array]},name:{type:[String,Number,Array]},rules:[Array,Object],autoLink:{type:Boolean,default:!0},required:{type:Boolean,default:void 0},validateFirst:{type:Boolean,default:void 0},validateStatus:PropTypes.oneOf(tuple$1("","success","warning","error","validating")),validateTrigger:{type:[String,Array]},messageVariables:{type:Object},hidden:Boolean,noStyle:Boolean,tooltip:String});let indexGuid$1=0;const defaultItemNamePrefixCls="form_item",FormItem=defineComponent({compatConfig:{MODE:3},name:"AFormItem",inheritAttrs:!1,__ANT_NEW_FORM_ITEM:!0,props:formItemProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;$n.prop;const Nn=`form-item-${++indexGuid$1}`,{prefixCls:Rn}=useConfigInject("form",$n),[Dn,Ln]=useStyle$C(Rn),Fn=shallowRef(),Bn=useInjectForm(),Hn=computed(()=>$n.name||$n.prop),zn=shallowRef([]),Wn=shallowRef(!1),Yn=shallowRef(),Gn=computed(()=>{const xa=Hn.value;return getNamePath(xa)}),Go=computed(()=>{if(Gn.value.length){const xa=Bn.name.value,Ta=Gn.value.join("_");return xa?`${xa}_${Ta}`:`${defaultItemNamePrefixCls}_${Ta}`}else return}),Xn=()=>{const xa=Bn.model.value;if(!(!xa||!Hn.value))return getPropByPath$1(xa,Gn.value,!0).v},Yo=computed(()=>Xn()),qo=shallowRef(cloneDeep(Yo.value)),Jo=computed(()=>{let xa=$n.validateTrigger!==void 0?$n.validateTrigger:Bn.validateTrigger.value;return xa=xa===void 0?"change":xa,toArray$5(xa)}),Zo=computed(()=>{let xa=Bn.rules.value;const Ta=$n.rules,wa=$n.required!==void 0?{required:!!$n.required,trigger:Jo.value}:[],La=getPropByPath$1(xa,Gn.value);xa=xa?La.o[La.k]||La.v:[];const Na=[].concat(Ta||xa||[]);return find(Na,$a=>$a.required)?Na:Na.concat(wa)}),rr=computed(()=>{const xa=Zo.value;let Ta=!1;return xa&&xa.length&&xa.every(wa=>wa.required?(Ta=!0,!1):!0),Ta||$n.required}),nr=shallowRef();watchEffect(()=>{nr.value=$n.validateStatus});const ta=computed(()=>{let xa={};return typeof $n.label=="string"?xa.label=$n.label:$n.name&&(xa.label=String($n.name)),$n.messageVariables&&(xa=_extends$1(_extends$1({},xa),$n.messageVariables)),xa}),oa=xa=>{if(Gn.value.length===0)return;const{validateFirst:Ta=!1}=$n,{triggerName:wa}=xa||{};let La=Zo.value;if(wa&&(La=La.filter($a=>{const{trigger:ka}=$a;return!ka&&!Jo.value.length?!0:toArray$5(ka||Jo.value).includes(wa)})),!La.length)return Promise.resolve();const Na=validateRules(Gn.value,Yo.value,La,_extends$1({validateMessages:Bn.validateMessages.value},xa),Ta,ta.value);return nr.value="validating",zn.value=[],Na.catch($a=>$a).then(function(){let $a=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];if(nr.value==="validating"){const ka=$a.filter(Ha=>Ha&&Ha.errors.length);nr.value=ka.length?"error":"success",zn.value=ka.map(Ha=>Ha.errors),Bn.onValidate(Hn.value,!zn.value.length,zn.value.length?toRaw(zn.value[0]):null)}}),Na},ra=()=>{oa({triggerName:"blur"})},ea=()=>{if(Wn.value){Wn.value=!1;return}oa({triggerName:"change"})},la=()=>{nr.value=$n.validateStatus,Wn.value=!1,zn.value=[]},ua=()=>{var xa;nr.value=$n.validateStatus,Wn.value=!0,zn.value=[];const Ta=Bn.model.value||{},wa=Yo.value,La=getPropByPath$1(Ta,Gn.value,!0);Array.isArray(wa)?La.o[La.k]=[].concat((xa=qo.value)!==null&&xa!==void 0?xa:[]):La.o[La.k]=qo.value,nextTick(()=>{Wn.value=!1})},ga=computed(()=>$n.htmlFor===void 0?Go.value:$n.htmlFor),aa=()=>{const xa=ga.value;if(!xa||!Yn.value)return;const Ta=Yn.value.$el.querySelector(`[id="${xa}"]`);Ta&&Ta.focus&&Ta.focus()};In({onFieldBlur:ra,onFieldChange:ea,clearValidate:la,resetField:ua}),useProvideFormItemContext({id:Go,onFieldBlur:()=>{$n.autoLink&&ra()},onFieldChange:()=>{$n.autoLink&&ea()},clearValidate:la},computed(()=>!!($n.autoLink&&Bn.model.value&&Hn.value)));let ca=!1;watch(Hn,xa=>{xa?ca||(ca=!0,Bn.addField(Nn,{fieldValue:Yo,fieldId:Go,fieldName:Hn,resetField:ua,clearValidate:la,namePath:Gn,validateRules:oa,rules:Zo})):(ca=!1,Bn.removeField(Nn))},{immediate:!0}),onBeforeUnmount(()=>{Bn.removeField(Nn)});const sa=useDebounce(zn),ia=computed(()=>$n.validateStatus!==void 0?$n.validateStatus:sa.value.length?"error":nr.value),fa=computed(()=>({[`${Rn.value}-item`]:!0,[Ln.value]:!0,[`${Rn.value}-item-has-feedback`]:ia.value&&$n.hasFeedback,[`${Rn.value}-item-has-success`]:ia.value==="success",[`${Rn.value}-item-has-warning`]:ia.value==="warning",[`${Rn.value}-item-has-error`]:ia.value==="error",[`${Rn.value}-item-is-validating`]:ia.value==="validating",[`${Rn.value}-item-hidden`]:$n.hidden})),ma=reactive({});FormItemInputContext.useProvide(ma),watchEffect(()=>{let xa;if($n.hasFeedback){const Ta=ia.value&&iconMap[ia.value];xa=Ta?createVNode("span",{class:classNames(`${Rn.value}-item-feedback-icon`,`${Rn.value}-item-feedback-icon-${ia.value}`)},[createVNode(Ta,null,null)]):null}_extends$1(ma,{status:ia.value,hasFeedback:$n.hasFeedback,feedbackIcon:xa,isFormItemInput:!0})});const ya=shallowRef(null),ba=shallowRef(!1),Ia=()=>{if(Fn.value){const xa=getComputedStyle(Fn.value);ya.value=parseInt(xa.marginBottom,10)}};onMounted(()=>{watch(ba,()=>{ba.value&&Ia()},{flush:"post",immediate:!0})});const Ea=xa=>{xa||(ya.value=null)};return()=>{var xa,Ta;if($n.noStyle)return(xa=_n.default)===null||xa===void 0?void 0:xa.call(_n);const wa=(Ta=$n.help)!==null&&Ta!==void 0?Ta:_n.help?filterEmpty(_n.help()):null,La=!!(wa!=null&&Array.isArray(wa)&&wa.length||sa.value.length);return ba.value=La,Dn(createVNode("div",{class:[fa.value,La?`${Rn.value}-item-with-help`:"",Pn.class],ref:Fn},[createVNode(Row$2,_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:`${Rn.value}-row`,key:"row"}),{default:()=>{var Na,$a;return createVNode(Fragment,null,[createVNode(FormItemLabel$1,_objectSpread2$1(_objectSpread2$1({},$n),{},{htmlFor:ga.value,required:rr.value,requiredMark:Bn.requiredMark.value,prefixCls:Rn.value,onClick:aa,label:$n.label}),{label:_n.label,tooltip:_n.tooltip}),createVNode(FormItemInput$1,_objectSpread2$1(_objectSpread2$1({},$n),{},{errors:wa!=null?toArray$5(wa):sa.value,marginBottom:ya.value,prefixCls:Rn.value,status:ia.value,ref:Yn,help:wa,extra:(Na=$n.extra)!==null&&Na!==void 0?Na:($a=_n.extra)===null||$a===void 0?void 0:$a.call(_n),onErrorVisibleChanged:Ea}),{default:_n.default})])}}),!!ya.value&&createVNode("div",{class:`${Rn.value}-margin-offset`,style:{marginBottom:`-${ya.value}px`}},null)]))}}});function allPromiseFinish($n){let Cn=!1,_n=$n.length;const Pn=[];return $n.length?new Promise((In,Nn)=>{$n.forEach((Rn,Dn)=>{Rn.catch(Ln=>(Cn=!0,Ln)).then(Ln=>{_n-=1,Pn[Dn]=Ln,!(_n>0)&&(Cn&&Nn(Pn),In(Pn))})})}):Promise.resolve([])}function isRequired($n){let Cn=!1;return $n&&$n.length&&$n.every(_n=>_n.required?(Cn=!0,!1):!0),Cn}function toArray$4($n){return $n==null?[]:Array.isArray($n)?$n:[$n]}function getPropByPath($n,Cn,_n){let Pn=$n;Cn=Cn.replace(/\[(\w+)\]/g,".$1"),Cn=Cn.replace(/^\./,"");const In=Cn.split(".");let Nn=0;for(let Rn=In.length;Nn1&&arguments[1]!==void 0?arguments[1]:ref({}),_n=arguments.length>2?arguments[2]:void 0;const Pn=cloneDeep(unref($n)),In=reactive({}),Nn=shallowRef([]),Rn=qo=>{_extends$1(unref($n),_extends$1(_extends$1({},cloneDeep(Pn)),qo)),nextTick(()=>{Object.keys(In).forEach(Jo=>{In[Jo]={autoLink:!1,required:isRequired(unref(Cn)[Jo])}})})},Dn=function(){let qo=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],Jo=arguments.length>1?arguments[1]:void 0;return Jo.length?qo.filter(Zo=>{const rr=toArray$4(Zo.trigger||"change");return intersection(rr,Jo).length}):qo};let Ln=null;const Fn=function(qo){let Jo=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},Zo=arguments.length>2?arguments[2]:void 0;const rr=[],nr={};for(let ra=0;ra({name:ea,errors:[],warnings:[]})).catch(ga=>{const aa=[],ca=[];return ga.forEach(sa=>{let{rule:{warningOnly:ia},errors:fa}=sa;ia?ca.push(...fa):aa.push(...fa)}),aa.length?Promise.reject({name:ea,errors:aa,warnings:ca}):{name:ea,errors:aa,warnings:ca}}))}const ta=allPromiseFinish(rr);Ln=ta;const oa=ta.then(()=>Ln===ta?Promise.resolve(nr):Promise.reject([])).catch(ra=>{const ea=ra.filter(la=>la&&la.errors.length);return Promise.reject({values:nr,errorFields:ea,outOfDate:Ln!==ta})});return oa.catch(ra=>ra),oa},Bn=function(qo,Jo,Zo){let rr=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};const nr=validateRules([qo],Jo,Zo,_extends$1({validateMessages:defaultValidateMessages},rr),!!rr.validateFirst);return In[qo]?(In[qo].validateStatus="validating",nr.catch(ta=>ta).then(function(){let ta=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];var oa;if(In[qo].validateStatus==="validating"){const ra=ta.filter(ea=>ea&&ea.errors.length);In[qo].validateStatus=ra.length?"error":"success",In[qo].help=ra.length?ra.map(ea=>ea.errors):null,(oa=_n==null?void 0:_n.onValidate)===null||oa===void 0||oa.call(_n,qo,!ra.length,ra.length?toRaw(In[qo].help[0]):null)}}),nr):nr.catch(ta=>ta)},Hn=(qo,Jo)=>{let Zo=[],rr=!0;qo?Array.isArray(qo)?Zo=qo:Zo=[qo]:(rr=!1,Zo=Nn.value);const nr=Fn(Zo,Jo||{},rr);return nr.catch(ta=>ta),nr},zn=qo=>{let Jo=[];qo?Array.isArray(qo)?Jo=qo:Jo=[qo]:Jo=Nn.value,Jo.forEach(Zo=>{In[Zo]&&_extends$1(In[Zo],{validateStatus:"",help:null})})},Wn=qo=>{const Jo={autoLink:!1},Zo=[],rr=Array.isArray(qo)?qo:[qo];for(let nr=0;nr{const Jo=[];Nn.value.forEach(Zo=>{const rr=getPropByPath(qo,Zo,!1),nr=getPropByPath(Yn,Zo,!1);(Gn&&(_n==null?void 0:_n.immediate)&&rr.isValid||!isEqual$2(rr.v,nr.v))&&Jo.push(Zo)}),Hn(Jo,{trigger:"change"}),Gn=!1,Yn=cloneDeep(toRaw(qo))},Xn=_n==null?void 0:_n.debounce;let Yo=!0;return watch(Cn,()=>{Nn.value=Cn?Object.keys(unref(Cn)):[],!Yo&&_n&&_n.validateOnRuleChange&&Hn(),Yo=!1},{deep:!0,immediate:!0}),watch(Nn,()=>{const qo={};Nn.value.forEach(Jo=>{qo[Jo]=_extends$1({},In[Jo],{autoLink:!1,required:isRequired(unref(Cn)[Jo])}),delete In[Jo]});for(const Jo in In)Object.prototype.hasOwnProperty.call(In,Jo)&&delete In[Jo];_extends$1(In,qo)},{immediate:!0}),watch($n,Xn&&Xn.wait?debounce$2(Go,Xn.wait,omit(Xn,["wait"])):Go,{immediate:_n&&!!_n.immediate,deep:!0}),{modelRef:$n,rulesRef:Cn,initialModel:Pn,validateInfos:In,resetFields:Rn,validate:Hn,validateField:Bn,mergeValidateInfo:Wn,clearValidate:zn}}const formProps=()=>({layout:PropTypes.oneOf(tuple$1("horizontal","inline","vertical")),labelCol:objectType(),wrapperCol:objectType(),colon:booleanType(),labelAlign:stringType(),labelWrap:booleanType(),prefixCls:String,requiredMark:someType([String,Boolean]),hideRequiredMark:booleanType(),model:PropTypes.object,rules:objectType(),validateMessages:objectType(),validateOnRuleChange:booleanType(),scrollToFirstError:anyType(),onSubmit:functionType(),name:String,validateTrigger:someType([String,Array]),size:stringType(),disabled:booleanType(),onValuesChange:functionType(),onFieldsChange:functionType(),onFinish:functionType(),onFinishFailed:functionType(),onValidate:functionType()});function isEqualName($n,Cn){return isEqual$2(toArray$5($n),toArray$5(Cn))}const Form=defineComponent({compatConfig:{MODE:3},name:"AForm",inheritAttrs:!1,props:initDefaultProps(formProps(),{layout:"horizontal",hideRequiredMark:!1,colon:!0}),Item:FormItem,useForm,setup($n,Cn){let{emit:_n,slots:Pn,expose:In,attrs:Nn}=Cn;const{prefixCls:Rn,direction:Dn,form:Ln,size:Fn,disabled:Bn}=useConfigInject("form",$n),Hn=computed(()=>$n.requiredMark===""||$n.requiredMark),zn=computed(()=>{var sa;return Hn.value!==void 0?Hn.value:Ln&&((sa=Ln.value)===null||sa===void 0?void 0:sa.requiredMark)!==void 0?Ln.value.requiredMark:!$n.hideRequiredMark});useProviderSize(Fn),useProviderDisabled(Bn);const Wn=computed(()=>{var sa,ia;return(sa=$n.colon)!==null&&sa!==void 0?sa:(ia=Ln.value)===null||ia===void 0?void 0:ia.colon}),{validateMessages:Yn}=useInjectGlobalForm(),Gn=computed(()=>_extends$1(_extends$1(_extends$1({},defaultValidateMessages),Yn.value),$n.validateMessages)),[Go,Xn]=useStyle$C(Rn),Yo=computed(()=>classNames(Rn.value,{[`${Rn.value}-${$n.layout}`]:!0,[`${Rn.value}-hide-required-mark`]:zn.value===!1,[`${Rn.value}-rtl`]:Dn.value==="rtl",[`${Rn.value}-${Fn.value}`]:Fn.value},Xn.value)),qo=ref(),Jo={},Zo=(sa,ia)=>{Jo[sa]=ia},rr=sa=>{delete Jo[sa]},nr=sa=>{const ia=!!sa,fa=ia?toArray$5(sa).map(getNamePath):[];return ia?Object.values(Jo).filter(ma=>fa.findIndex(ya=>isEqualName(ya,ma.fieldName.value))>-1):Object.values(Jo)},ta=sa=>{if(!$n.model){warning$3();return}nr(sa).forEach(ia=>{ia.resetField()})},oa=sa=>{nr(sa).forEach(ia=>{ia.clearValidate()})},ra=sa=>{const{scrollToFirstError:ia}=$n;if(_n("finishFailed",sa),ia&&sa.errorFields.length){let fa={};typeof ia=="object"&&(fa=ia),la(sa.errorFields[0].name,fa)}},ea=function(){return aa(...arguments)},la=function(sa){let ia=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const fa=nr(sa?[sa]:void 0);if(fa.length){const ma=fa[0].fieldId.value,ya=ma?document.getElementById(ma):null;ya&&scrollIntoView(ya,_extends$1({scrollMode:"if-needed",block:"nearest"},ia))}},ua=function(){let sa=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;if(sa===!0){const ia=[];return Object.values(Jo).forEach(fa=>{let{namePath:ma}=fa;ia.push(ma.value)}),cloneByNamePathList($n.model,ia)}else return cloneByNamePathList($n.model,sa)},ga=(sa,ia)=>{if(warning$3(),!$n.model)return warning$3(),Promise.reject("Form `model` is required for validateFields to work.");const fa=!!sa,ma=fa?toArray$5(sa).map(getNamePath):[],ya=[];Object.values(Jo).forEach(Ea=>{var xa;if(fa||ma.push(Ea.namePath.value),!(!((xa=Ea.rules)===null||xa===void 0)&&xa.value.length))return;const Ta=Ea.namePath.value;if(!fa||containsNamePath(ma,Ta)){const wa=Ea.validateRules(_extends$1({validateMessages:Gn.value},ia));ya.push(wa.then(()=>({name:Ta,errors:[],warnings:[]})).catch(La=>{const Na=[],$a=[];return La.forEach(ka=>{let{rule:{warningOnly:Ha},errors:da}=ka;Ha?$a.push(...da):Na.push(...da)}),Na.length?Promise.reject({name:Ta,errors:Na,warnings:$a}):{name:Ta,errors:Na,warnings:$a}}))}});const ba=allPromiseFinish(ya);qo.value=ba;const Ia=ba.then(()=>qo.value===ba?Promise.resolve(ua(ma)):Promise.reject([])).catch(Ea=>{const xa=Ea.filter(Ta=>Ta&&Ta.errors.length);return Promise.reject({values:ua(ma),errorFields:xa,outOfDate:qo.value!==ba})});return Ia.catch(Ea=>Ea),Ia},aa=function(){return ga(...arguments)},ca=sa=>{sa.preventDefault(),sa.stopPropagation(),_n("submit",sa),$n.model&&ga().then(fa=>{_n("finish",fa)}).catch(fa=>{ra(fa)})};return In({resetFields:ta,clearValidate:oa,validateFields:ga,getFieldsValue:ua,validate:ea,scrollToField:la}),useProvideForm({model:computed(()=>$n.model),name:computed(()=>$n.name),labelAlign:computed(()=>$n.labelAlign),labelCol:computed(()=>$n.labelCol),labelWrap:computed(()=>$n.labelWrap),wrapperCol:computed(()=>$n.wrapperCol),vertical:computed(()=>$n.layout==="vertical"),colon:Wn,requiredMark:zn,validateTrigger:computed(()=>$n.validateTrigger),rules:computed(()=>$n.rules),addField:Zo,removeField:rr,onValidate:(sa,ia,fa)=>{_n("validate",sa,ia,fa)},validateMessages:Gn}),watch(()=>$n.rules,()=>{$n.validateOnRuleChange&&ga()}),()=>{var sa;return Go(createVNode("form",_objectSpread2$1(_objectSpread2$1({},Nn),{},{onSubmit:ca,class:[Yo.value,Nn.class]}),[(sa=Pn.default)===null||sa===void 0?void 0:sa.call(Pn)]))}}}),Form$1=Form;Form$1.useInjectFormItemContext=useInjectFormItemContext;Form$1.ItemRest=FormItemRest;Form$1.install=function($n){return $n.component(Form$1.name,Form$1),$n.component(Form$1.Item.name,Form$1.Item),$n.component(FormItemRest.name,FormItemRest),$n};const antCheckboxEffect=new Keyframes("antCheckboxEffect",{"0%":{transform:"scale(1)",opacity:.5},"100%":{transform:"scale(1.6)",opacity:0}}),genCheckboxStyle=$n=>{const{checkboxCls:Cn}=$n,_n=`${Cn}-wrapper`;return[{[`${Cn}-group`]:_extends$1(_extends$1({},resetComponent($n)),{display:"inline-flex",flexWrap:"wrap",columnGap:$n.marginXS,[`> ${$n.antCls}-row`]:{flex:1}}),[_n]:_extends$1(_extends$1({},resetComponent($n)),{display:"inline-flex",alignItems:"baseline",cursor:"pointer","&:after":{display:"inline-block",width:0,overflow:"hidden",content:"'\\a0'"},[`& + ${_n}`]:{marginInlineStart:0},[`&${_n}-in-form-item`]:{'input[type="checkbox"]':{width:14,height:14}}}),[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",whiteSpace:"nowrap",lineHeight:1,cursor:"pointer",alignSelf:"center",[`${Cn}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0,margin:0,[`&:focus-visible + ${Cn}-inner`]:_extends$1({},genFocusOutline($n))},[`${Cn}-inner`]:{boxSizing:"border-box",position:"relative",top:0,insetInlineStart:0,display:"block",width:$n.checkboxSize,height:$n.checkboxSize,direction:"ltr",backgroundColor:$n.colorBgContainer,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:$n.borderRadiusSM,borderCollapse:"separate",transition:`all ${$n.motionDurationSlow}`,"&:after":{boxSizing:"border-box",position:"absolute",top:"50%",insetInlineStart:"21.5%",display:"table",width:$n.checkboxSize/14*5,height:$n.checkboxSize/14*8,border:`${$n.lineWidthBold}px solid ${$n.colorWhite}`,borderTop:0,borderInlineStart:0,transform:"rotate(45deg) scale(0) translate(-50%,-50%)",opacity:0,content:'""',transition:`all ${$n.motionDurationFast} ${$n.motionEaseInBack}, opacity ${$n.motionDurationFast}`}},"& + span":{paddingInlineStart:$n.paddingXS,paddingInlineEnd:$n.paddingXS}})},{[Cn]:{"&-indeterminate":{[`${Cn}-inner`]:{"&:after":{top:"50%",insetInlineStart:"50%",width:$n.fontSizeLG/2,height:$n.fontSizeLG/2,backgroundColor:$n.colorPrimary,border:0,transform:"translate(-50%, -50%) scale(1)",opacity:1,content:'""'}}}}},{[`${_n}:hover ${Cn}:after`]:{visibility:"visible"},[` - ${_n}:not(${_n}-disabled), - ${Cn}:not(${Cn}-disabled) - `]:{[`&:hover ${Cn}-inner`]:{borderColor:$n.colorPrimary}},[`${_n}:not(${_n}-disabled)`]:{[`&:hover ${Cn}-checked:not(${Cn}-disabled) ${Cn}-inner`]:{backgroundColor:$n.colorPrimaryHover,borderColor:"transparent"},[`&:hover ${Cn}-checked:not(${Cn}-disabled):after`]:{borderColor:$n.colorPrimaryHover}}},{[`${Cn}-checked`]:{[`${Cn}-inner`]:{backgroundColor:$n.colorPrimary,borderColor:$n.colorPrimary,"&:after":{opacity:1,transform:"rotate(45deg) scale(1) translate(-50%,-50%)",transition:`all ${$n.motionDurationMid} ${$n.motionEaseOutBack} ${$n.motionDurationFast}`}},"&:after":{position:"absolute",top:0,insetInlineStart:0,width:"100%",height:"100%",borderRadius:$n.borderRadiusSM,visibility:"hidden",border:`${$n.lineWidthBold}px solid ${$n.colorPrimary}`,animationName:antCheckboxEffect,animationDuration:$n.motionDurationSlow,animationTimingFunction:"ease-in-out",animationFillMode:"backwards",content:'""',transition:`all ${$n.motionDurationSlow}`}},[` - ${_n}-checked:not(${_n}-disabled), - ${Cn}-checked:not(${Cn}-disabled) - `]:{[`&:hover ${Cn}-inner`]:{backgroundColor:$n.colorPrimaryHover,borderColor:"transparent"},[`&:hover ${Cn}:after`]:{borderColor:$n.colorPrimaryHover}}},{[`${_n}-disabled`]:{cursor:"not-allowed"},[`${Cn}-disabled`]:{[`&, ${Cn}-input`]:{cursor:"not-allowed",pointerEvents:"none"},[`${Cn}-inner`]:{background:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,"&:after":{borderColor:$n.colorTextDisabled}},"&:after":{display:"none"},"& + span":{color:$n.colorTextDisabled},[`&${Cn}-indeterminate ${Cn}-inner::after`]:{background:$n.colorTextDisabled}}}]};function getStyle$2($n,Cn){const _n=merge$1(Cn,{checkboxCls:`.${$n}`,checkboxSize:Cn.controlInteractiveSize});return[genCheckboxStyle(_n)]}const useStyle$B=genComponentStyleHook("Checkbox",($n,Cn)=>{let{prefixCls:_n}=Cn;return[getStyle$2(_n,$n)]}),genBaseStyle$c=$n=>{const{prefixCls:Cn,componentCls:_n,antCls:Pn}=$n,In=`${_n}-menu-item`,Nn=` - &${In}-expand ${In}-expand-icon, - ${In}-loading-icon - `,Rn=Math.round(($n.controlHeight-$n.fontSize*$n.lineHeight)/2);return[{[_n]:{width:$n.controlWidth}},{[`${_n}-dropdown`]:[getStyle$2(`${Cn}-checkbox`,$n),{[`&${Pn}-select-dropdown`]:{padding:0}},{[_n]:{"&-checkbox":{top:0,marginInlineEnd:$n.paddingXS},"&-menus":{display:"flex",flexWrap:"nowrap",alignItems:"flex-start",[`&${_n}-menu-empty`]:{[`${_n}-menu`]:{width:"100%",height:"auto",[In]:{color:$n.colorTextDisabled}}}},"&-menu":{flexGrow:1,minWidth:$n.controlItemWidth,height:$n.dropdownHeight,margin:0,padding:$n.paddingXXS,overflow:"auto",verticalAlign:"top",listStyle:"none","-ms-overflow-style":"-ms-autohiding-scrollbar","&:not(:last-child)":{borderInlineEnd:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},"&-item":_extends$1(_extends$1({},textEllipsis),{display:"flex",flexWrap:"nowrap",alignItems:"center",padding:`${Rn}px ${$n.paddingSM}px`,lineHeight:$n.lineHeight,cursor:"pointer",transition:`all ${$n.motionDurationMid}`,borderRadius:$n.borderRadiusSM,"&:hover":{background:$n.controlItemBgHover},"&-disabled":{color:$n.colorTextDisabled,cursor:"not-allowed","&:hover":{background:"transparent"},[Nn]:{color:$n.colorTextDisabled}},[`&-active:not(${In}-disabled)`]:{"&, &:hover":{fontWeight:$n.fontWeightStrong,backgroundColor:$n.controlItemBgActive}},"&-content":{flex:"auto"},[Nn]:{marginInlineStart:$n.paddingXXS,color:$n.colorTextDescription,fontSize:$n.fontSizeIcon},"&-keyword":{color:$n.colorHighlight}})}}}]},{[`${_n}-dropdown-rtl`]:{direction:"rtl"}},genCompactItemStyle($n)]},useStyle$A=genComponentStyleHook("Cascader",$n=>[genBaseStyle$c($n)],{controlWidth:184,controlItemWidth:111,dropdownHeight:180});var __rest$S=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);InLn===0?[Dn]:[...Rn,Cn,Dn],[]),In=[];let Nn=0;return Pn.forEach((Rn,Dn)=>{const Ln=Nn+Rn.length;let Fn=$n.slice(Nn,Ln);Nn=Ln,Dn%2===1&&(Fn=createVNode("span",{class:`${_n}-menu-item-keyword`,key:"seperator"},[Fn])),In.push(Fn)}),In}const defaultSearchRender=$n=>{let{inputValue:Cn,path:_n,prefixCls:Pn,fieldNames:In}=$n;const Nn=[],Rn=Cn.toLowerCase();return _n.forEach((Dn,Ln)=>{Ln!==0&&Nn.push(" / ");let Fn=Dn[In.label];const Bn=typeof Fn;(Bn==="string"||Bn==="number")&&(Fn=highlightKeyword(String(Fn),Rn,Pn)),Nn.push(Fn)}),Nn};function cascaderProps(){return _extends$1(_extends$1({},omit$1(internalCascaderProps(),["customSlots","checkable","options"])),{multiple:{type:Boolean,default:void 0},size:String,bordered:{type:Boolean,default:void 0},placement:{type:String},suffixIcon:PropTypes.any,status:String,options:Array,popupClassName:String,dropdownClassName:String,"onUpdate:value":Function})}const Cascader=defineComponent({compatConfig:{MODE:3},name:"ACascader",inheritAttrs:!1,props:initDefaultProps(cascaderProps(),{bordered:!0,choiceTransitionName:"",allowClear:!0}),setup($n,Cn){let{attrs:_n,expose:Pn,slots:In,emit:Nn}=Cn;const Rn=useInjectFormItemContext(),Dn=FormItemInputContext.useInject(),Ln=computed(()=>getMergedStatus(Dn.status,$n.status)),{prefixCls:Fn,rootPrefixCls:Bn,getPrefixCls:Hn,direction:zn,getPopupContainer:Wn,renderEmpty:Yn,size:Gn,disabled:Go}=useConfigInject("cascader",$n),Xn=computed(()=>Hn("select",$n.prefixCls)),{compactSize:Yo,compactItemClassnames:qo}=useCompactItemContext(Xn,zn),Jo=computed(()=>Yo.value||Gn.value),Zo=useInjectDisabled(),rr=computed(()=>{var ia;return(ia=Go.value)!==null&&ia!==void 0?ia:Zo.value}),[nr,ta]=useSelectStyle(Xn),[oa]=useStyle$A(Fn),ra=computed(()=>zn.value==="rtl"),ea=computed(()=>{if(!$n.showSearch)return $n.showSearch;let ia={render:defaultSearchRender};return typeof $n.showSearch=="object"&&(ia=_extends$1(_extends$1({},ia),$n.showSearch)),ia}),la=computed(()=>classNames($n.popupClassName||$n.dropdownClassName,`${Fn.value}-dropdown`,{[`${Fn.value}-dropdown-rtl`]:ra.value},ta.value)),ua=ref();Pn({focus(){var ia;(ia=ua.value)===null||ia===void 0||ia.focus()},blur(){var ia;(ia=ua.value)===null||ia===void 0||ia.blur()}});const ga=function(){for(var ia=arguments.length,fa=new Array(ia),ma=0;ma$n.showArrow!==void 0?$n.showArrow:$n.loading||!$n.multiple),sa=computed(()=>$n.placement!==void 0?$n.placement:zn.value==="rtl"?"bottomRight":"bottomLeft");return()=>{var ia,fa;const{notFoundContent:ma=(ia=In.notFoundContent)===null||ia===void 0?void 0:ia.call(In),expandIcon:ya=(fa=In.expandIcon)===null||fa===void 0?void 0:fa.call(In),multiple:ba,bordered:Ia,allowClear:Ea,choiceTransitionName:xa,transitionName:Ta,id:wa=Rn.id.value}=$n,La=__rest$S($n,["notFoundContent","expandIcon","multiple","bordered","allowClear","choiceTransitionName","transitionName","id"]),Na=ma||Yn("Cascader");let $a=ya;ya||($a=ra.value?createVNode(LeftOutlined$1,null,null):createVNode(RightOutlined$1,null,null));const ka=createVNode("span",{class:`${Xn.value}-menu-item-loading-icon`},[createVNode(LoadingOutlined$1,{spin:!0},null)]),{suffixIcon:Ha,removeIcon:da,clearIcon:pa}=getIcons(_extends$1(_extends$1({},$n),{hasFeedback:Dn.hasFeedback,feedbackIcon:Dn.feedbackIcon,multiple:ba,prefixCls:Xn.value,showArrow:ca.value}),In);return oa(nr(createVNode(Cascader$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},La),_n),{},{id:wa,prefixCls:Xn.value,class:[Fn.value,{[`${Xn.value}-lg`]:Jo.value==="large",[`${Xn.value}-sm`]:Jo.value==="small",[`${Xn.value}-rtl`]:ra.value,[`${Xn.value}-borderless`]:!Ia,[`${Xn.value}-in-form-item`]:Dn.isFormItemInput},getStatusClassNames(Xn.value,Ln.value,Dn.hasFeedback),qo.value,_n.class,ta.value],disabled:rr.value,direction:zn.value,placement:sa.value,notFoundContent:Na,allowClear:Ea,showSearch:ea.value,expandIcon:$a,inputIcon:Ha,removeIcon:da,clearIcon:pa,loadingIcon:ka,checkable:!!ba,dropdownClassName:la.value,dropdownPrefixCls:Fn.value,choiceTransitionName:getTransitionName$1(Bn.value,"",xa),transitionName:getTransitionName$1(Bn.value,getTransitionDirection(sa.value),Ta),getPopupContainer:Wn==null?void 0:Wn.value,customSlots:_extends$1(_extends$1({},In),{checkable:()=>createVNode("span",{class:`${Fn.value}-checkbox-inner`},null)}),tagRender:$n.tagRender||In.tagRender,displayRender:$n.displayRender||In.displayRender,maxTagPlaceholder:$n.maxTagPlaceholder||In.maxTagPlaceholder,showArrow:Dn.hasFeedback||$n.showArrow,onChange:ga,onBlur:aa,ref:ua}),In)))}}}),index$p=withInstall(_extends$1(Cascader,{SHOW_CHILD:SHOW_CHILD$1,SHOW_PARENT:SHOW_PARENT$1})),abstractCheckboxGroupProps=()=>({name:String,prefixCls:String,options:arrayType([]),disabled:Boolean,id:String}),checkboxGroupProps=()=>_extends$1(_extends$1({},abstractCheckboxGroupProps()),{defaultValue:arrayType(),value:arrayType(),onChange:functionType(),"onUpdate:value":functionType()}),abstractCheckboxProps=()=>({prefixCls:String,defaultChecked:booleanType(),checked:booleanType(),disabled:booleanType(),isGroup:booleanType(),value:PropTypes.any,name:String,id:String,indeterminate:booleanType(),type:stringType("checkbox"),autofocus:booleanType(),onChange:functionType(),"onUpdate:checked":functionType(),onClick:functionType(),skipGroup:booleanType(!1)}),checkboxProps=()=>_extends$1(_extends$1({},abstractCheckboxProps()),{indeterminate:booleanType(!1)}),CheckboxGroupContextKey=Symbol("CheckboxGroupContext");var __rest$R=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In(Yn==null?void 0:Yn.disabled.value)||Bn.value);watchEffect(()=>{!$n.skipGroup&&Yn&&Yn.registerValue(Gn,$n.value)}),onBeforeUnmount(()=>{Yn&&Yn.cancelValue(Gn)}),onMounted(()=>{warning$3(!!($n.checked!==void 0||Yn||$n.value===void 0))});const Xn=Zo=>{const rr=Zo.target.checked;_n("update:checked",rr),_n("change",Zo),Rn.onFieldChange()},Yo=ref();return Nn({focus:()=>{var Zo;(Zo=Yo.value)===null||Zo===void 0||Zo.focus()},blur:()=>{var Zo;(Zo=Yo.value)===null||Zo===void 0||Zo.blur()}}),()=>{var Zo;const rr=flattenChildren((Zo=In.default)===null||Zo===void 0?void 0:Zo.call(In)),{indeterminate:nr,skipGroup:ta,id:oa=Rn.id.value}=$n,ra=__rest$R($n,["indeterminate","skipGroup","id"]),{onMouseenter:ea,onMouseleave:la,onInput:ua,class:ga,style:aa}=Pn,ca=__rest$R(Pn,["onMouseenter","onMouseleave","onInput","class","style"]),sa=_extends$1(_extends$1(_extends$1(_extends$1({},ra),{id:oa,prefixCls:Ln.value}),ca),{disabled:Go.value});Yn&&!ta?(sa.onChange=function(){for(var ya=arguments.length,ba=new Array(ya),Ia=0;Ia`${Dn.value}-group`),[Bn,Hn]=useStyle$B(Fn),zn=ref(($n.value===void 0?$n.defaultValue:$n.value)||[]);watch(()=>$n.value,()=>{zn.value=$n.value||[]});const Wn=computed(()=>$n.options.map(Jo=>typeof Jo=="string"||typeof Jo=="number"?{label:Jo,value:Jo}:Jo)),Yn=ref(Symbol()),Gn=ref(new Map),Go=Jo=>{Gn.value.delete(Jo),Yn.value=Symbol()},Xn=(Jo,Zo)=>{Gn.value.set(Jo,Zo),Yn.value=Symbol()},Yo=ref(new Map);return watch(Yn,()=>{const Jo=new Map;for(const Zo of Gn.value.values())Jo.set(Zo,!0);Yo.value=Jo}),provide(CheckboxGroupContextKey,{cancelValue:Go,registerValue:Xn,toggleOption:Jo=>{const Zo=zn.value.indexOf(Jo.value),rr=[...zn.value];Zo===-1?rr.push(Jo.value):rr.splice(Zo,1),$n.value===void 0&&(zn.value=rr);const nr=rr.filter(ta=>Yo.value.has(ta)).sort((ta,oa)=>{const ra=Wn.value.findIndex(la=>la.value===ta),ea=Wn.value.findIndex(la=>la.value===oa);return ra-ea});In("update:value",nr),In("change",nr),Rn.onFieldChange()},mergedValue:zn,name:computed(()=>$n.name),disabled:computed(()=>$n.disabled)}),Nn({mergedValue:zn}),()=>{var Jo;const{id:Zo=Rn.id.value}=$n;let rr=null;return Wn.value&&Wn.value.length>0&&(rr=Wn.value.map(nr=>{var ta;return createVNode(Checkbox,{prefixCls:Dn.value,key:nr.value.toString(),disabled:"disabled"in nr?nr.disabled:$n.disabled,indeterminate:nr.indeterminate,value:nr.value,checked:zn.value.indexOf(nr.value)!==-1,onChange:nr.onChange,class:`${Fn.value}-item`},{default:()=>[_n.label!==void 0?(ta=_n.label)===null||ta===void 0?void 0:ta.call(_n,nr):nr.label]})})),Bn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Fn.value,{[`${Fn.value}-rtl`]:Ln.value==="rtl"},Pn.class,Hn.value],id:Zo}),[rr||((Jo=_n.default)===null||Jo===void 0?void 0:Jo.call(_n))]))}}});Checkbox.Group=CheckboxGroup;Checkbox.install=function($n){return $n.component(Checkbox.name,Checkbox),$n.component(CheckboxGroup.name,CheckboxGroup),$n};const index$o={useBreakpoint},index$n=withInstall(Col),genBaseStyle$b=$n=>{const{componentCls:Cn,commentBg:_n,commentPaddingBase:Pn,commentNestIndent:In,commentFontSizeBase:Nn,commentFontSizeSm:Rn,commentAuthorNameColor:Dn,commentAuthorTimeColor:Ln,commentActionColor:Fn,commentActionHoverColor:Bn,commentActionsMarginBottom:Hn,commentActionsMarginTop:zn,commentContentDetailPMarginBottom:Wn}=$n;return{[Cn]:{position:"relative",backgroundColor:_n,[`${Cn}-inner`]:{display:"flex",padding:Pn},[`${Cn}-avatar`]:{position:"relative",flexShrink:0,marginRight:$n.marginSM,cursor:"pointer",img:{width:"32px",height:"32px",borderRadius:"50%"}},[`${Cn}-content`]:{position:"relative",flex:"1 1 auto",minWidth:"1px",fontSize:Nn,wordWrap:"break-word","&-author":{display:"flex",flexWrap:"wrap",justifyContent:"flex-start",marginBottom:$n.marginXXS,fontSize:Nn,"& > a,& > span":{paddingRight:$n.paddingXS,fontSize:Rn,lineHeight:"18px"},"&-name":{color:Dn,fontSize:Nn,transition:`color ${$n.motionDurationSlow}`,"> *":{color:Dn,"&:hover":{color:Dn}}},"&-time":{color:Ln,whiteSpace:"nowrap",cursor:"auto"}},"&-detail p":{marginBottom:Wn,whiteSpace:"pre-wrap"}},[`${Cn}-actions`]:{marginTop:zn,marginBottom:Hn,paddingLeft:0,"> li":{display:"inline-block",color:Fn,"> span":{marginRight:"10px",color:Fn,fontSize:Rn,cursor:"pointer",transition:`color ${$n.motionDurationSlow}`,userSelect:"none","&:hover":{color:Bn}}}},[`${Cn}-nested`]:{marginLeft:In},"&-rtl":{direction:"rtl"}}}},useStyle$z=genComponentStyleHook("Comment",$n=>{const Cn=merge$1($n,{commentBg:"inherit",commentPaddingBase:`${$n.paddingMD}px 0`,commentNestIndent:"44px",commentFontSizeBase:$n.fontSize,commentFontSizeSm:$n.fontSizeSM,commentAuthorNameColor:$n.colorTextTertiary,commentAuthorTimeColor:$n.colorTextPlaceholder,commentActionColor:$n.colorTextTertiary,commentActionHoverColor:$n.colorTextSecondary,commentActionsMarginBottom:"inherit",commentActionsMarginTop:$n.marginSM,commentContentDetailPMarginBottom:"inherit"});return[genBaseStyle$b(Cn)]}),commentProps=()=>({actions:Array,author:PropTypes.any,avatar:PropTypes.any,content:PropTypes.any,prefixCls:String,datetime:PropTypes.any}),Comment=defineComponent({compatConfig:{MODE:3},name:"AComment",inheritAttrs:!1,props:commentProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("comment",$n),[Rn,Dn]=useStyle$z(In),Ln=(Bn,Hn)=>createVNode("div",{class:`${Bn}-nested`},[Hn]),Fn=Bn=>!Bn||!Bn.length?null:Bn.map((zn,Wn)=>createVNode("li",{key:`action-${Wn}`},[zn]));return()=>{var Bn,Hn,zn,Wn,Yn,Gn,Go,Xn,Yo,qo,Jo;const Zo=In.value,rr=(Bn=$n.actions)!==null&&Bn!==void 0?Bn:(Hn=_n.actions)===null||Hn===void 0?void 0:Hn.call(_n),nr=(zn=$n.author)!==null&&zn!==void 0?zn:(Wn=_n.author)===null||Wn===void 0?void 0:Wn.call(_n),ta=(Yn=$n.avatar)!==null&&Yn!==void 0?Yn:(Gn=_n.avatar)===null||Gn===void 0?void 0:Gn.call(_n),oa=(Go=$n.content)!==null&&Go!==void 0?Go:(Xn=_n.content)===null||Xn===void 0?void 0:Xn.call(_n),ra=(Yo=$n.datetime)!==null&&Yo!==void 0?Yo:(qo=_n.datetime)===null||qo===void 0?void 0:qo.call(_n),ea=createVNode("div",{class:`${Zo}-avatar`},[typeof ta=="string"?createVNode("img",{src:ta,alt:"comment-avatar"},null):ta]),la=rr?createVNode("ul",{class:`${Zo}-actions`},[Fn(Array.isArray(rr)?rr:[rr])]):null,ua=createVNode("div",{class:`${Zo}-content-author`},[nr&&createVNode("span",{class:`${Zo}-content-author-name`},[nr]),ra&&createVNode("span",{class:`${Zo}-content-author-time`},[ra])]),ga=createVNode("div",{class:`${Zo}-content`},[ua,createVNode("div",{class:`${Zo}-content-detail`},[oa]),la]),aa=createVNode("div",{class:`${Zo}-inner`},[ea,ga]),ca=flattenChildren((Jo=_n.default)===null||Jo===void 0?void 0:Jo.call(_n));return Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Zo,{[`${Zo}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value]}),[aa,ca&&ca.length?Ln(Zo,ca):null]))}}}),index$m=withInstall(Comment);let runtimeLocale=_extends$1({},localeValues$1.Modal);function changeConfirmLocale($n){$n?runtimeLocale=_extends$1(_extends$1({},runtimeLocale),$n):runtimeLocale=_extends$1({},localeValues$1.Modal)}function getConfirmLocale(){return runtimeLocale}const ANT_MARK="internalMark",LocaleProvider=defineComponent({compatConfig:{MODE:3},name:"ALocaleProvider",props:{locale:{type:Object},ANT_MARK__:String},setup($n,Cn){let{slots:_n}=Cn;warning$3($n.ANT_MARK__===ANT_MARK);const Pn=reactive({antLocale:_extends$1(_extends$1({},$n.locale),{exist:!0}),ANT_MARK__:ANT_MARK});return provide("localeData",Pn),watch(()=>$n.locale,In=>{changeConfirmLocale(In&&In.Modal),Pn.antLocale=_extends$1(_extends$1({},In),{exist:!0})},{immediate:!0}),()=>{var In;return(In=_n.default)===null||In===void 0?void 0:In.call(_n)}}});LocaleProvider.install=function($n){return $n.component(LocaleProvider.name,LocaleProvider),$n};const locale$3=withInstall(LocaleProvider),Notice=defineComponent({name:"Notice",inheritAttrs:!1,props:["prefixCls","duration","updateMark","noticeKey","closeIcon","closable","props","onClick","onClose","holder","visible"],setup($n,Cn){let{attrs:_n,slots:Pn}=Cn,In,Nn=!1;const Rn=computed(()=>$n.duration===void 0?4.5:$n.duration),Dn=()=>{Rn.value&&!Nn&&(In=setTimeout(()=>{Fn()},Rn.value*1e3))},Ln=()=>{In&&(clearTimeout(In),In=null)},Fn=Hn=>{Hn&&Hn.stopPropagation(),Ln();const{onClose:zn,noticeKey:Wn}=$n;zn&&zn(Wn)},Bn=()=>{Ln(),Dn()};return onMounted(()=>{Dn()}),onUnmounted(()=>{Nn=!0,Ln()}),watch([Rn,()=>$n.updateMark,()=>$n.visible],(Hn,zn)=>{let[Wn,Yn,Gn]=Hn,[Go,Xn,Yo]=zn;(Wn!==Go||Yn!==Xn||Gn!==Yo&&Yo)&&Bn()},{flush:"post"}),()=>{var Hn,zn;const{prefixCls:Wn,closable:Yn,closeIcon:Gn=(Hn=Pn.closeIcon)===null||Hn===void 0?void 0:Hn.call(Pn),onClick:Go,holder:Xn}=$n,{class:Yo,style:qo}=_n,Jo=`${Wn}-notice`,Zo=Object.keys(_n).reduce((nr,ta)=>((ta.startsWith("data-")||ta.startsWith("aria-")||ta==="role")&&(nr[ta]=_n[ta]),nr),{}),rr=createVNode("div",_objectSpread2$1({class:classNames(Jo,Yo,{[`${Jo}-closable`]:Yn}),style:qo,onMouseenter:Ln,onMouseleave:Dn,onClick:Go},Zo),[createVNode("div",{class:`${Jo}-content`},[(zn=Pn.default)===null||zn===void 0?void 0:zn.call(Pn)]),Yn?createVNode("a",{tabindex:0,onClick:Fn,class:`${Jo}-close`},[Gn||createVNode("span",{class:`${Jo}-close-x`},null)]):null]);return Xn?createVNode(Teleport,{to:Xn},{default:()=>rr}):rr}}});var __rest$Q=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const{prefixCls:Bn,animation:Hn="fade"}=$n;let zn=$n.transitionName;return!zn&&Hn&&(zn=`${Bn}-${Hn}`),getTransitionGroupProps(zn)}),Ln=(Bn,Hn)=>{const zn=Bn.key||getUuid$1(),Wn=_extends$1(_extends$1({},Bn),{key:zn}),{maxCount:Yn}=$n,Gn=Rn.value.map(Xn=>Xn.notice.key).indexOf(zn),Go=Rn.value.concat();Gn!==-1?Go.splice(Gn,1,{notice:Wn,holderCallback:Hn}):(Yn&&Rn.value.length>=Yn&&(Wn.key=Go[0].notice.key,Wn.updateMark=getUuid$1(),Wn.userPassKey=zn,Go.shift()),Go.push({notice:Wn,holderCallback:Hn})),Rn.value=Go},Fn=Bn=>{Rn.value=Rn.value.filter(Hn=>{let{notice:{key:zn,userPassKey:Wn}}=Hn;return(Wn||zn)!==Bn})};return Pn({add:Ln,remove:Fn,notices:Rn}),()=>{var Bn;const{prefixCls:Hn,closeIcon:zn=(Bn=In.closeIcon)===null||Bn===void 0?void 0:Bn.call(In,{prefixCls:Hn})}=$n,Wn=Rn.value.map((Gn,Go)=>{let{notice:Xn,holderCallback:Yo}=Gn;const qo=Go===Rn.value.length-1?Xn.updateMark:void 0,{key:Jo,userPassKey:Zo}=Xn,{content:rr}=Xn,nr=_extends$1(_extends$1(_extends$1({prefixCls:Hn,closeIcon:typeof zn=="function"?zn({prefixCls:Hn}):zn},Xn),Xn.props),{key:Jo,noticeKey:Zo||Jo,updateMark:qo,onClose:ta=>{var oa;Fn(ta),(oa=Xn.onClose)===null||oa===void 0||oa.call(Xn)},onClick:Xn.onClick});return Yo?createVNode("div",{key:Jo,class:`${Hn}-hook-holder`,ref:ta=>{typeof Jo>"u"||(ta?(Nn.set(Jo,ta),Yo(ta,nr)):Nn.delete(Jo))}},null):createVNode(Notice,_objectSpread2$1(_objectSpread2$1({},nr),{},{class:classNames(nr.class,$n.hashId)}),{default:()=>[typeof rr=="function"?rr({prefixCls:Hn}):rr]})}),Yn={[Hn]:1,[_n.class]:!!_n.class,[$n.hashId]:!0};return createVNode("div",{class:Yn,style:_n.style||{top:"65px",left:"50%"}},[createVNode(TransitionGroup,_objectSpread2$1({tag:"div"},Dn.value),{default:()=>[Wn]})])}}});Notification$1.newInstance=function(Cn,_n){const Pn=Cn||{},{name:In="notification",getContainer:Nn,appContext:Rn,prefixCls:Dn,rootPrefixCls:Ln,transitionName:Fn,hasTransitionName:Bn,useStyle:Hn}=Pn,zn=__rest$Q(Pn,["name","getContainer","appContext","prefixCls","rootPrefixCls","transitionName","hasTransitionName","useStyle"]),Wn=document.createElement("div");Nn?Nn().appendChild(Wn):document.body.appendChild(Wn);const Gn=createVNode(defineComponent({compatConfig:{MODE:3},name:"NotificationWrapper",setup(Go,Xn){let{attrs:Yo}=Xn;const qo=shallowRef(),Jo=computed(()=>globalConfigForApi.getPrefixCls(In,Dn)),[,Zo]=Hn(Jo);return onMounted(()=>{_n({notice(rr){var nr;(nr=qo.value)===null||nr===void 0||nr.add(rr)},removeNotice(rr){var nr;(nr=qo.value)===null||nr===void 0||nr.remove(rr)},destroy(){render$1(null,Wn),Wn.parentNode&&Wn.parentNode.removeChild(Wn)},component:qo})}),()=>{const rr=globalConfigForApi,nr=rr.getRootPrefixCls(Ln,Jo.value),ta=Bn?Fn:`${Jo.value}-${Fn}`;return createVNode(ConfigProvider$1,_objectSpread2$1(_objectSpread2$1({},rr),{},{prefixCls:nr}),{default:()=>[createVNode(Notification$1,_objectSpread2$1(_objectSpread2$1({ref:qo},Yo),{},{prefixCls:Jo.value,transitionName:ta,hashId:Zo.value}),null)]})}}}),zn);Gn.appContext=Rn||Gn.appContext,render$1(Gn,Wn)};const Notification$2=Notification$1;let seed=0;const now$1=Date.now();function getUuid(){const $n=seed;return seed+=1,`rcNotification_${now$1}_${$n}`}const Notification=defineComponent({name:"HookNotification",inheritAttrs:!1,props:["prefixCls","transitionName","animation","maxCount","closeIcon","hashId","remove","notices","getStyles","getClassName","onAllRemoved","getContainer"],setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=new Map,Nn=computed(()=>$n.notices),Rn=computed(()=>{let Bn=$n.transitionName;if(!Bn&&$n.animation)switch(typeof $n.animation){case"string":Bn=$n.animation;break;case"function":Bn=$n.animation().name;break;case"object":Bn=$n.animation.name;break;default:Bn=`${$n.prefixCls}-fade`;break}return getTransitionGroupProps(Bn)}),Dn=Bn=>$n.remove(Bn),Ln=ref({});watch(Nn,()=>{const Bn={};Object.keys(Ln.value).forEach(Hn=>{Bn[Hn]=[]}),$n.notices.forEach(Hn=>{const{placement:zn="topRight"}=Hn.notice;zn&&(Bn[zn]=Bn[zn]||[],Bn[zn].push(Hn))}),Ln.value=Bn});const Fn=computed(()=>Object.keys(Ln.value));return()=>{var Bn;const{prefixCls:Hn,closeIcon:zn=(Bn=Pn.closeIcon)===null||Bn===void 0?void 0:Bn.call(Pn,{prefixCls:Hn})}=$n,Wn=Fn.value.map(Yn=>{var Gn,Go;const Xn=Ln.value[Yn],Yo=(Gn=$n.getClassName)===null||Gn===void 0?void 0:Gn.call($n,Yn),qo=(Go=$n.getStyles)===null||Go===void 0?void 0:Go.call($n,Yn),Jo=Xn.map((nr,ta)=>{let{notice:oa,holderCallback:ra}=nr;const ea=ta===Nn.value.length-1?oa.updateMark:void 0,{key:la,userPassKey:ua}=oa,{content:ga}=oa,aa=_extends$1(_extends$1(_extends$1({prefixCls:Hn,closeIcon:typeof zn=="function"?zn({prefixCls:Hn}):zn},oa),oa.props),{key:la,noticeKey:ua||la,updateMark:ea,onClose:ca=>{var sa;Dn(ca),(sa=oa.onClose)===null||sa===void 0||sa.call(oa)},onClick:oa.onClick});return ra?createVNode("div",{key:la,class:`${Hn}-hook-holder`,ref:ca=>{typeof la>"u"||(ca?(In.set(la,ca),ra(ca,aa)):In.delete(la))}},null):createVNode(Notice,_objectSpread2$1(_objectSpread2$1({},aa),{},{class:classNames(aa.class,$n.hashId)}),{default:()=>[typeof ga=="function"?ga({prefixCls:Hn}):ga]})}),Zo={[Hn]:1,[`${Hn}-${Yn}`]:1,[_n.class]:!!_n.class,[$n.hashId]:!0,[Yo]:!!Yo};function rr(){var nr;Xn.length>0||(Reflect.deleteProperty(Ln.value,Yn),(nr=$n.onAllRemoved)===null||nr===void 0||nr.call($n))}return createVNode("div",{key:Yn,class:Zo,style:_n.style||qo||{top:"65px",left:"50%"}},[createVNode(TransitionGroup,_objectSpread2$1(_objectSpread2$1({tag:"div"},Rn.value),{},{onAfterLeave:rr}),{default:()=>[Jo]})])});return createVNode(Portal$1,{getContainer:$n.getContainer},{default:()=>[Wn]})}}}),HookNotification=Notification;var __rest$P=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);Indocument.body;let uniqueKey=0;function mergeConfig(){const $n={};for(var Cn=arguments.length,_n=new Array(Cn),Pn=0;Pn{In&&Object.keys(In).forEach(Nn=>{const Rn=In[Nn];Rn!==void 0&&($n[Nn]=Rn)})}),$n}function useNotification$1(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};const{getContainer:Cn=defaultGetContainer$1,motion:_n,prefixCls:Pn,maxCount:In,getClassName:Nn,getStyles:Rn,onAllRemoved:Dn}=$n,Ln=__rest$P($n,["getContainer","motion","prefixCls","maxCount","getClassName","getStyles","onAllRemoved"]),Fn=shallowRef([]),Bn=shallowRef(),Hn=(Xn,Yo)=>{const qo=Xn.key||getUuid(),Jo=_extends$1(_extends$1({},Xn),{key:qo}),Zo=Fn.value.map(nr=>nr.notice.key).indexOf(qo),rr=Fn.value.concat();Zo!==-1?rr.splice(Zo,1,{notice:Jo,holderCallback:Yo}):(In&&Fn.value.length>=In&&(Jo.key=rr[0].notice.key,Jo.updateMark=getUuid(),Jo.userPassKey=qo,rr.shift()),rr.push({notice:Jo,holderCallback:Yo})),Fn.value=rr},zn=Xn=>{Fn.value=Fn.value.filter(Yo=>{let{notice:{key:qo,userPassKey:Jo}}=Yo;return(Jo||qo)!==Xn})},Wn=()=>{Fn.value=[]},Yn=()=>createVNode(HookNotification,{ref:Bn,prefixCls:Pn,maxCount:In,notices:Fn.value,remove:zn,getClassName:Nn,getStyles:Rn,animation:_n,hashId:$n.hashId,onAllRemoved:Dn,getContainer:Cn},null),Gn=shallowRef([]),Go={open:Xn=>{const Yo=mergeConfig(Ln,Xn);(Yo.key===null||Yo.key===void 0)&&(Yo.key=`vc-notification-${uniqueKey}`,uniqueKey+=1),Gn.value=[...Gn.value,{type:"open",config:Yo}]},close:Xn=>{Gn.value=[...Gn.value,{type:"close",key:Xn}]},destroy:()=>{Gn.value=[...Gn.value,{type:"destroy"}]}};return watch(Gn,()=>{Gn.value.length&&(Gn.value.forEach(Xn=>{switch(Xn.type){case"open":Hn(Xn.config);break;case"close":zn(Xn.key);break;case"destroy":Wn();break}}),Gn.value=[])}),[Go,Yn]}const genMessageStyle=$n=>{const{componentCls:Cn,iconCls:_n,boxShadowSecondary:Pn,colorBgElevated:In,colorSuccess:Nn,colorError:Rn,colorWarning:Dn,colorInfo:Ln,fontSizeLG:Fn,motionEaseInOutCirc:Bn,motionDurationSlow:Hn,marginXS:zn,paddingXS:Wn,borderRadiusLG:Yn,zIndexPopup:Gn,messageNoticeContentPadding:Go}=$n,Xn=new Keyframes("MessageMoveIn",{"0%":{padding:0,transform:"translateY(-100%)",opacity:0},"100%":{padding:Wn,transform:"translateY(0)",opacity:1}}),Yo=new Keyframes("MessageMoveOut",{"0%":{maxHeight:$n.height,padding:Wn,opacity:1},"100%":{maxHeight:0,padding:0,opacity:0}});return[{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"fixed",top:zn,left:"50%",transform:"translateX(-50%)",width:"100%",pointerEvents:"none",zIndex:Gn,[`${Cn}-move-up`]:{animationFillMode:"forwards"},[` - ${Cn}-move-up-appear, - ${Cn}-move-up-enter - `]:{animationName:Xn,animationDuration:Hn,animationPlayState:"paused",animationTimingFunction:Bn},[` - ${Cn}-move-up-appear${Cn}-move-up-appear-active, - ${Cn}-move-up-enter${Cn}-move-up-enter-active - `]:{animationPlayState:"running"},[`${Cn}-move-up-leave`]:{animationName:Yo,animationDuration:Hn,animationPlayState:"paused",animationTimingFunction:Bn},[`${Cn}-move-up-leave${Cn}-move-up-leave-active`]:{animationPlayState:"running"},"&-rtl":{direction:"rtl",span:{direction:"rtl"}}})},{[`${Cn}-notice`]:{padding:Wn,textAlign:"center",[_n]:{verticalAlign:"text-bottom",marginInlineEnd:zn,fontSize:Fn},[`${Cn}-notice-content`]:{display:"inline-block",padding:Go,background:In,borderRadius:Yn,boxShadow:Pn,pointerEvents:"all"},[`${Cn}-success ${_n}`]:{color:Nn},[`${Cn}-error ${_n}`]:{color:Rn},[`${Cn}-warning ${_n}`]:{color:Dn},[` - ${Cn}-info ${_n}, - ${Cn}-loading ${_n}`]:{color:Ln}}},{[`${Cn}-notice-pure-panel`]:{padding:0,textAlign:"start"}}]},useStyle$y=genComponentStyleHook("Message",$n=>{const Cn=merge$1($n,{messageNoticeContentPadding:`${($n.controlHeightLG-$n.fontSize*$n.lineHeight)/2}px ${$n.paddingSM}px`});return[genMessageStyle(Cn)]},$n=>({height:150,zIndexPopup:$n.zIndexPopupBase+10})),TypeIcon={info:createVNode(InfoCircleFilled$1,null,null),success:createVNode(CheckCircleFilled$1,null,null),error:createVNode(CloseCircleFilled$1,null,null),warning:createVNode(ExclamationCircleFilled$1,null,null),loading:createVNode(LoadingOutlined$1,null,null)},PureContent$1=defineComponent({name:"PureContent",inheritAttrs:!1,props:["prefixCls","type","icon"],setup($n,Cn){let{slots:_n}=Cn;return()=>{var Pn;return createVNode("div",{class:classNames(`${$n.prefixCls}-custom-content`,`${$n.prefixCls}-${$n.type}`)},[$n.icon||TypeIcon[$n.type],createVNode("span",null,[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)])])}}});var __rest$O=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);InNn("message",$n.prefixCls)),[,Ln]=useStyle$y(Dn),Fn=()=>{var Gn;const Go=(Gn=$n.top)!==null&&Gn!==void 0?Gn:DEFAULT_OFFSET$1;return{left:"50%",transform:"translateX(-50%)",top:typeof Go=="number"?`${Go}px`:Go}},Bn=()=>classNames(Ln.value,$n.rtl?`${Dn.value}-rtl`:""),Hn=()=>{var Gn;return getMotion$1({prefixCls:Dn.value,animation:(Gn=$n.animation)!==null&&Gn!==void 0?Gn:"move-up",transitionName:$n.transitionName})},zn=createVNode("span",{class:`${Dn.value}-close-x`},[createVNode(CloseOutlined$1,{class:`${Dn.value}-close-icon`},null)]),[Wn,Yn]=useNotification$1({getStyles:Fn,prefixCls:Dn.value,getClassName:Bn,motion:Hn,closable:!1,closeIcon:zn,duration:(Pn=$n.duration)!==null&&Pn!==void 0?Pn:DEFAULT_DURATION$1,getContainer:(In=$n.staticGetContainer)!==null&&In!==void 0?In:Rn.value,maxCount:$n.maxCount,onAllRemoved:$n.onAllRemoved});return _n(_extends$1(_extends$1({},Wn),{prefixCls:Dn,hashId:Ln})),Yn}});let keyIndex=0;function useInternalMessage($n){const Cn=shallowRef(null),_n=Symbol("messageHolderKey"),Pn=Ln=>{var Fn;(Fn=Cn.value)===null||Fn===void 0||Fn.close(Ln)},In=Ln=>{if(!Cn.value){const Zo=()=>{};return Zo.then=()=>{},Zo}const{open:Fn,prefixCls:Bn,hashId:Hn}=Cn.value,zn=`${Bn}-notice`,{content:Wn,icon:Yn,type:Gn,key:Go,class:Xn,onClose:Yo}=Ln,qo=__rest$O(Ln,["content","icon","type","key","class","onClose"]);let Jo=Go;return Jo==null&&(keyIndex+=1,Jo=`antd-message-${keyIndex}`),wrapPromiseFn(Zo=>(Fn(_extends$1(_extends$1({},qo),{key:Jo,content:()=>createVNode(PureContent$1,{prefixCls:Bn,type:Gn,icon:typeof Yn=="function"?Yn():Yn},{default:()=>[typeof Wn=="function"?Wn():Wn]}),placement:"top",class:classNames(Gn&&`${zn}-${Gn}`,Hn,Xn),onClose:()=>{Yo==null||Yo(),Zo()}})),()=>{Pn(Jo)}))},Rn={open:In,destroy:Ln=>{var Fn;Ln!==void 0?Pn(Ln):(Fn=Cn.value)===null||Fn===void 0||Fn.destroy()}};return["info","success","warning","error","loading"].forEach(Ln=>{const Fn=(Bn,Hn,zn)=>{let Wn;Bn&&typeof Bn=="object"&&"content"in Bn?Wn=Bn:Wn={content:Bn};let Yn,Gn;typeof Hn=="function"?Gn=Hn:(Yn=Hn,Gn=zn);const Go=_extends$1(_extends$1({onClose:Gn,duration:Yn},Wn),{type:Ln});return In(Go)};Rn[Ln]=Fn}),[Rn,()=>createVNode(Holder$1,_objectSpread2$1(_objectSpread2$1({key:_n},$n),{},{ref:Cn}),null)]}function useMessage($n){return useInternalMessage($n)}let defaultDuration$1=3,defaultTop$1,messageInstance,key=1,localPrefixCls="",transitionName="move-up",hasTransitionName=!1,getContainer=()=>document.body,maxCount$1,rtl$1=!1;function getKeyThenIncreaseKey(){return key++}function setMessageConfig($n){$n.top!==void 0&&(defaultTop$1=$n.top,messageInstance=null),$n.duration!==void 0&&(defaultDuration$1=$n.duration),$n.prefixCls!==void 0&&(localPrefixCls=$n.prefixCls),$n.getContainer!==void 0&&(getContainer=$n.getContainer,messageInstance=null),$n.transitionName!==void 0&&(transitionName=$n.transitionName,messageInstance=null,hasTransitionName=!0),$n.maxCount!==void 0&&(maxCount$1=$n.maxCount,messageInstance=null),$n.rtl!==void 0&&(rtl$1=$n.rtl)}function getMessageInstance($n,Cn){if(messageInstance){Cn(messageInstance);return}Notification$2.newInstance({appContext:$n.appContext,prefixCls:$n.prefixCls||localPrefixCls,rootPrefixCls:$n.rootPrefixCls,transitionName,hasTransitionName,style:{top:defaultTop$1},getContainer:getContainer||$n.getPopupContainer,maxCount:maxCount$1,name:"message",useStyle:useStyle$y},_n=>{if(messageInstance){Cn(messageInstance);return}messageInstance=_n,Cn(_n)})}const typeToIcon$2={info:InfoCircleFilled$1,success:CheckCircleFilled$1,error:CloseCircleFilled$1,warning:ExclamationCircleFilled$1,loading:LoadingOutlined$1},typeList=Object.keys(typeToIcon$2);function notice$1($n){const Cn=$n.duration!==void 0?$n.duration:defaultDuration$1,_n=$n.key||getKeyThenIncreaseKey(),Pn=new Promise(Nn=>{const Rn=()=>(typeof $n.onClose=="function"&&$n.onClose(),Nn(!0));getMessageInstance($n,Dn=>{Dn.notice({key:_n,duration:Cn,style:$n.style||{},class:$n.class,content:Ln=>{let{prefixCls:Fn}=Ln;const Bn=typeToIcon$2[$n.type],Hn=Bn?createVNode(Bn,null,null):"",zn=classNames(`${Fn}-custom-content`,{[`${Fn}-${$n.type}`]:$n.type,[`${Fn}-rtl`]:rtl$1===!0});return createVNode("div",{class:zn},[typeof $n.icon=="function"?$n.icon():$n.icon||Hn,createVNode("span",null,[typeof $n.content=="function"?$n.content():$n.content])])},onClose:Rn,onClick:$n.onClick})})}),In=()=>{messageInstance&&messageInstance.removeNotice(_n)};return In.then=(Nn,Rn)=>Pn.then(Nn,Rn),In.promise=Pn,In}function isArgsProps($n){return Object.prototype.toString.call($n)==="[object Object]"&&!!$n.content}const api$2={open:notice$1,config:setMessageConfig,destroy($n){if(messageInstance)if($n){const{removeNotice:Cn}=messageInstance;Cn($n)}else{const{destroy:Cn}=messageInstance;Cn(),messageInstance=null}}};function attachTypeApi($n,Cn){$n[Cn]=(_n,Pn,In)=>isArgsProps(_n)?$n.open(_extends$1(_extends$1({},_n),{type:Cn})):(typeof Pn=="function"&&(In=Pn,Pn=void 0),$n.open({content:_n,duration:Pn,type:Cn,onClose:In}))}typeList.forEach($n=>attachTypeApi(api$2,$n));api$2.warn=api$2.warning;api$2.useMessage=useMessage;const message=api$2,genNotificationPlacementStyle=$n=>{const{componentCls:Cn,width:_n,notificationMarginEdge:Pn}=$n,In=new Keyframes("antNotificationTopFadeIn",{"0%":{marginTop:"-100%",opacity:0},"100%":{marginTop:0,opacity:1}}),Nn=new Keyframes("antNotificationBottomFadeIn",{"0%":{marginBottom:"-100%",opacity:0},"100%":{marginBottom:0,opacity:1}}),Rn=new Keyframes("antNotificationLeftFadeIn",{"0%":{right:{_skip_check_:!0,value:_n},opacity:0},"100%":{right:{_skip_check_:!0,value:0},opacity:1}});return{[`&${Cn}-top, &${Cn}-bottom`]:{marginInline:0},[`&${Cn}-top`]:{[`${Cn}-fade-enter${Cn}-fade-enter-active, ${Cn}-fade-appear${Cn}-fade-appear-active`]:{animationName:In}},[`&${Cn}-bottom`]:{[`${Cn}-fade-enter${Cn}-fade-enter-active, ${Cn}-fade-appear${Cn}-fade-appear-active`]:{animationName:Nn}},[`&${Cn}-topLeft, &${Cn}-bottomLeft`]:{marginInlineEnd:0,marginInlineStart:Pn,[`${Cn}-fade-enter${Cn}-fade-enter-active, ${Cn}-fade-appear${Cn}-fade-appear-active`]:{animationName:Rn}}}},genNotificationStyle=$n=>{const{iconCls:Cn,componentCls:_n,boxShadowSecondary:Pn,fontSizeLG:In,notificationMarginBottom:Nn,borderRadiusLG:Rn,colorSuccess:Dn,colorInfo:Ln,colorWarning:Fn,colorError:Bn,colorTextHeading:Hn,notificationBg:zn,notificationPadding:Wn,notificationMarginEdge:Yn,motionDurationMid:Gn,motionEaseInOut:Go,fontSize:Xn,lineHeight:Yo,width:qo,notificationIconSize:Jo}=$n,Zo=`${_n}-notice`,rr=new Keyframes("antNotificationFadeIn",{"0%":{left:{_skip_check_:!0,value:qo},opacity:0},"100%":{left:{_skip_check_:!0,value:0},opacity:1}}),nr=new Keyframes("antNotificationFadeOut",{"0%":{maxHeight:$n.animationMaxHeight,marginBottom:Nn,opacity:1},"100%":{maxHeight:0,marginBottom:0,paddingTop:0,paddingBottom:0,opacity:0}});return[{[_n]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"fixed",zIndex:$n.zIndexPopup,marginInlineEnd:Yn,[`${_n}-hook-holder`]:{position:"relative"},[`&${_n}-top, &${_n}-bottom`]:{[`${_n}-notice`]:{marginInline:"auto auto"}},[`&${_n}-topLeft, &${_n}-bottomLeft`]:{[`${_n}-notice`]:{marginInlineEnd:"auto",marginInlineStart:0}},[`${_n}-fade-enter, ${_n}-fade-appear`]:{animationDuration:$n.motionDurationMid,animationTimingFunction:Go,animationFillMode:"both",opacity:0,animationPlayState:"paused"},[`${_n}-fade-leave`]:{animationTimingFunction:Go,animationFillMode:"both",animationDuration:Gn,animationPlayState:"paused"},[`${_n}-fade-enter${_n}-fade-enter-active, ${_n}-fade-appear${_n}-fade-appear-active`]:{animationName:rr,animationPlayState:"running"},[`${_n}-fade-leave${_n}-fade-leave-active`]:{animationName:nr,animationPlayState:"running"}}),genNotificationPlacementStyle($n)),{"&-rtl":{direction:"rtl",[`${_n}-notice-btn`]:{float:"left"}}})},{[Zo]:{position:"relative",width:qo,maxWidth:`calc(100vw - ${Yn*2}px)`,marginBottom:Nn,marginInlineStart:"auto",padding:Wn,overflow:"hidden",lineHeight:Yo,wordWrap:"break-word",background:zn,borderRadius:Rn,boxShadow:Pn,[`${_n}-close-icon`]:{fontSize:Xn,cursor:"pointer"},[`${Zo}-message`]:{marginBottom:$n.marginXS,color:Hn,fontSize:In,lineHeight:$n.lineHeightLG},[`${Zo}-description`]:{fontSize:Xn},[`&${Zo}-closable ${Zo}-message`]:{paddingInlineEnd:$n.paddingLG},[`${Zo}-with-icon ${Zo}-message`]:{marginBottom:$n.marginXS,marginInlineStart:$n.marginSM+Jo,fontSize:In},[`${Zo}-with-icon ${Zo}-description`]:{marginInlineStart:$n.marginSM+Jo,fontSize:Xn},[`${Zo}-icon`]:{position:"absolute",fontSize:Jo,lineHeight:0,[`&-success${Cn}`]:{color:Dn},[`&-info${Cn}`]:{color:Ln},[`&-warning${Cn}`]:{color:Fn},[`&-error${Cn}`]:{color:Bn}},[`${Zo}-close`]:{position:"absolute",top:$n.notificationPaddingVertical,insetInlineEnd:$n.notificationPaddingHorizontal,color:$n.colorIcon,outline:"none",width:$n.notificationCloseButtonSize,height:$n.notificationCloseButtonSize,borderRadius:$n.borderRadiusSM,transition:`background-color ${$n.motionDurationMid}, color ${$n.motionDurationMid}`,display:"flex",alignItems:"center",justifyContent:"center","&:hover":{color:$n.colorIconHover,backgroundColor:$n.wireframe?"transparent":$n.colorFillContent}},[`${Zo}-btn`]:{float:"right",marginTop:$n.marginSM}}},{[`${Zo}-pure-panel`]:{margin:0}}]},useStyle$x=genComponentStyleHook("Notification",$n=>{const Cn=$n.paddingMD,_n=$n.paddingLG,Pn=merge$1($n,{notificationBg:$n.colorBgElevated,notificationPaddingVertical:Cn,notificationPaddingHorizontal:_n,notificationPadding:`${$n.paddingMD}px ${$n.paddingContentHorizontalLG}px`,notificationMarginBottom:$n.margin,notificationMarginEdge:$n.marginLG,animationMaxHeight:150,notificationIconSize:$n.fontSizeLG*$n.lineHeightLG,notificationCloseButtonSize:$n.controlHeightLG*.55});return[genNotificationStyle(Pn)]},$n=>({zIndexPopup:$n.zIndexPopupBase+50,width:384}));function getCloseIcon($n,Cn){return Cn||createVNode("span",{class:`${$n}-close-x`},[createVNode(CloseOutlined$1,{class:`${$n}-close-icon`},null)])}createVNode(InfoCircleFilled$1,null,null),createVNode(CheckCircleFilled$1,null,null),createVNode(CloseCircleFilled$1,null,null),createVNode(ExclamationCircleFilled$1,null,null),createVNode(LoadingOutlined$1,null,null);const typeToIcon$1={success:CheckCircleFilled$1,info:InfoCircleFilled$1,error:CloseCircleFilled$1,warning:ExclamationCircleFilled$1};function PureContent($n){let{prefixCls:Cn,icon:_n,type:Pn,message:In,description:Nn,btn:Rn}=$n,Dn=null;if(_n)Dn=createVNode("span",{class:`${Cn}-icon`},[renderHelper(_n)]);else if(Pn){const Ln=typeToIcon$1[Pn];Dn=createVNode(Ln,{class:`${Cn}-icon ${Cn}-icon-${Pn}`},null)}return createVNode("div",{class:classNames({[`${Cn}-with-icon`]:Dn}),role:"alert"},[Dn,createVNode("div",{class:`${Cn}-message`},[In]),createVNode("div",{class:`${Cn}-description`},[Nn]),Rn&&createVNode("div",{class:`${Cn}-btn`},[Rn])])}function getPlacementStyle($n,Cn,_n){let Pn;switch(Cn=typeof Cn=="number"?`${Cn}px`:Cn,_n=typeof _n=="number"?`${_n}px`:_n,$n){case"top":Pn={left:"50%",transform:"translateX(-50%)",right:"auto",top:Cn,bottom:"auto"};break;case"topLeft":Pn={left:0,top:Cn,bottom:"auto"};break;case"topRight":Pn={right:0,top:Cn,bottom:"auto"};break;case"bottom":Pn={left:"50%",transform:"translateX(-50%)",right:"auto",top:"auto",bottom:_n};break;case"bottomLeft":Pn={left:0,top:"auto",bottom:_n};break;default:Pn={right:0,top:"auto",bottom:_n};break}return Pn}function getMotion($n){return{name:`${$n}-fade`}}var __rest$N=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.prefixCls||Pn("notification")),Rn=zn=>{var Wn,Yn;return getPlacementStyle(zn,(Wn=$n.top)!==null&&Wn!==void 0?Wn:DEFAULT_OFFSET,(Yn=$n.bottom)!==null&&Yn!==void 0?Yn:DEFAULT_OFFSET)},[,Dn]=useStyle$x(Nn),Ln=()=>classNames(Dn.value,{[`${Nn.value}-rtl`]:$n.rtl}),Fn=()=>getMotion(Nn.value),[Bn,Hn]=useNotification$1({prefixCls:Nn.value,getStyles:Rn,getClassName:Ln,motion:Fn,closable:!0,closeIcon:getCloseIcon(Nn.value),duration:DEFAULT_DURATION,getContainer:()=>{var zn,Wn;return((zn=$n.getPopupContainer)===null||zn===void 0?void 0:zn.call($n))||((Wn=In.value)===null||Wn===void 0?void 0:Wn.call(In))||document.body},maxCount:$n.maxCount,hashId:Dn.value,onAllRemoved:$n.onAllRemoved});return _n(_extends$1(_extends$1({},Bn),{prefixCls:Nn.value,hashId:Dn})),Hn}});function useInternalNotification($n){const Cn=shallowRef(null),_n=Symbol("notificationHolderKey"),Pn=Dn=>{if(!Cn.value)return;const{open:Ln,prefixCls:Fn,hashId:Bn}=Cn.value,Hn=`${Fn}-notice`,{message:zn,description:Wn,icon:Yn,type:Gn,btn:Go,class:Xn}=Dn,Yo=__rest$N(Dn,["message","description","icon","type","btn","class"]);return Ln(_extends$1(_extends$1({placement:"topRight"},Yo),{content:()=>createVNode(PureContent,{prefixCls:Hn,icon:typeof Yn=="function"?Yn():Yn,type:Gn,message:typeof zn=="function"?zn():zn,description:typeof Wn=="function"?Wn():Wn,btn:typeof Go=="function"?Go():Go},null),class:classNames(Gn&&`${Hn}-${Gn}`,Bn,Xn)}))},Nn={open:Pn,destroy:Dn=>{var Ln,Fn;Dn!==void 0?(Ln=Cn.value)===null||Ln===void 0||Ln.close(Dn):(Fn=Cn.value)===null||Fn===void 0||Fn.destroy()}};return["success","info","warning","error"].forEach(Dn=>{Nn[Dn]=Ln=>Pn(_extends$1(_extends$1({},Ln),{type:Dn}))}),[Nn,()=>createVNode(Holder,_objectSpread2$1(_objectSpread2$1({key:_n},$n),{},{ref:Cn}),null)]}function useNotification($n){return useInternalNotification($n)}const notificationInstance={};let defaultDuration=4.5,defaultTop="24px",defaultBottom="24px",defaultPrefixCls$1="",defaultPlacement="topRight",defaultGetContainer=()=>document.body,defaultCloseIcon=null,rtl=!1,maxCount;function setNotificationConfig($n){const{duration:Cn,placement:_n,bottom:Pn,top:In,getContainer:Nn,closeIcon:Rn,prefixCls:Dn}=$n;Dn!==void 0&&(defaultPrefixCls$1=Dn),Cn!==void 0&&(defaultDuration=Cn),_n!==void 0&&(defaultPlacement=_n),Pn!==void 0&&(defaultBottom=typeof Pn=="number"?`${Pn}px`:Pn),In!==void 0&&(defaultTop=typeof In=="number"?`${In}px`:In),Nn!==void 0&&(defaultGetContainer=Nn),Rn!==void 0&&(defaultCloseIcon=Rn),$n.rtl!==void 0&&(rtl=$n.rtl),$n.maxCount!==void 0&&(maxCount=$n.maxCount)}function getNotificationInstance($n,Cn){let{prefixCls:_n,placement:Pn=defaultPlacement,getContainer:In=defaultGetContainer,top:Nn,bottom:Rn,closeIcon:Dn=defaultCloseIcon,appContext:Ln}=$n;const{getPrefixCls:Fn}=globalConfig(),Bn=Fn("notification",_n||defaultPrefixCls$1),Hn=`${Bn}-${Pn}-${rtl}`,zn=notificationInstance[Hn];if(zn){Promise.resolve(zn).then(Yn=>{Cn(Yn)});return}const Wn=classNames(`${Bn}-${Pn}`,{[`${Bn}-rtl`]:rtl===!0});Notification$2.newInstance({name:"notification",prefixCls:_n||defaultPrefixCls$1,useStyle:useStyle$x,class:Wn,style:getPlacementStyle(Pn,Nn??defaultTop,Rn??defaultBottom),appContext:Ln,getContainer:In,closeIcon:Yn=>{let{prefixCls:Gn}=Yn;return createVNode("span",{class:`${Gn}-close-x`},[renderHelper(Dn,{},createVNode(CloseOutlined$1,{class:`${Gn}-close-icon`},null))])},maxCount,hasTransitionName:!0},Yn=>{notificationInstance[Hn]=Yn,Cn(Yn)})}const typeToIcon={success:CheckCircleOutlined$1,info:InfoCircleOutlined$1,error:CloseCircleOutlined$1,warning:ExclamationCircleOutlined$1};function notice($n){const{icon:Cn,type:_n,description:Pn,message:In,btn:Nn}=$n,Rn=$n.duration===void 0?defaultDuration:$n.duration;getNotificationInstance($n,Dn=>{Dn.notice({content:Ln=>{let{prefixCls:Fn}=Ln;const Bn=`${Fn}-notice`;let Hn=null;if(Cn)Hn=()=>createVNode("span",{class:`${Bn}-icon`},[renderHelper(Cn)]);else if(_n){const zn=typeToIcon[_n];Hn=()=>createVNode(zn,{class:`${Bn}-icon ${Bn}-icon-${_n}`},null)}return createVNode("div",{class:Hn?`${Bn}-with-icon`:""},[Hn&&Hn(),createVNode("div",{class:`${Bn}-message`},[!Pn&&Hn?createVNode("span",{class:`${Bn}-message-single-line-auto-margin`},null):null,renderHelper(In)]),createVNode("div",{class:`${Bn}-description`},[renderHelper(Pn)]),Nn?createVNode("span",{class:`${Bn}-btn`},[renderHelper(Nn)]):null])},duration:Rn,closable:!0,onClose:$n.onClose,onClick:$n.onClick,key:$n.key,style:$n.style||{},class:$n.class})})}const api$1={open:notice,close($n){Object.keys(notificationInstance).forEach(Cn=>Promise.resolve(notificationInstance[Cn]).then(_n=>{_n.removeNotice($n)}))},config:setNotificationConfig,destroy(){Object.keys(notificationInstance).forEach($n=>{Promise.resolve(notificationInstance[$n]).then(Cn=>{Cn.destroy()}),delete notificationInstance[$n]})}},iconTypes=["success","info","warning","error"];iconTypes.forEach($n=>{api$1[$n]=Cn=>api$1.open(_extends$1(_extends$1({},Cn),{type:$n}))});api$1.warn=api$1.warning;api$1.useNotification=useNotification;const notification=api$1,dynamicStyleMark=`-ant-${Date.now()}-${Math.random()}`;function getStyle$1($n,Cn){const _n={},Pn=(Rn,Dn)=>{let Ln=Rn.clone();return Ln=(Dn==null?void 0:Dn(Ln))||Ln,Ln.toRgbString()},In=(Rn,Dn)=>{const Ln=new TinyColor(Rn),Fn=generate$2(Ln.toRgbString());_n[`${Dn}-color`]=Pn(Ln),_n[`${Dn}-color-disabled`]=Fn[1],_n[`${Dn}-color-hover`]=Fn[4],_n[`${Dn}-color-active`]=Fn[6],_n[`${Dn}-color-outline`]=Ln.clone().setAlpha(.2).toRgbString(),_n[`${Dn}-color-deprecated-bg`]=Fn[0],_n[`${Dn}-color-deprecated-border`]=Fn[2]};if(Cn.primaryColor){In(Cn.primaryColor,"primary");const Rn=new TinyColor(Cn.primaryColor),Dn=generate$2(Rn.toRgbString());Dn.forEach((Fn,Bn)=>{_n[`primary-${Bn+1}`]=Fn}),_n["primary-color-deprecated-l-35"]=Pn(Rn,Fn=>Fn.lighten(35)),_n["primary-color-deprecated-l-20"]=Pn(Rn,Fn=>Fn.lighten(20)),_n["primary-color-deprecated-t-20"]=Pn(Rn,Fn=>Fn.tint(20)),_n["primary-color-deprecated-t-50"]=Pn(Rn,Fn=>Fn.tint(50)),_n["primary-color-deprecated-f-12"]=Pn(Rn,Fn=>Fn.setAlpha(Fn.getAlpha()*.12));const Ln=new TinyColor(Dn[0]);_n["primary-color-active-deprecated-f-30"]=Pn(Ln,Fn=>Fn.setAlpha(Fn.getAlpha()*.3)),_n["primary-color-active-deprecated-d-02"]=Pn(Ln,Fn=>Fn.darken(2))}return Cn.successColor&&In(Cn.successColor,"success"),Cn.warningColor&&In(Cn.warningColor,"warning"),Cn.errorColor&&In(Cn.errorColor,"error"),Cn.infoColor&&In(Cn.infoColor,"info"),` - :root { - ${Object.keys(_n).map(Rn=>`--${$n}-${Rn}: ${_n[Rn]};`).join(` -`)} - } - `.trim()}function registerTheme($n,Cn){const _n=getStyle$1($n,Cn);canUseDom$1()?updateCSS$1(_n,`${dynamicStyleMark}-dynamic-theme`):warning$3()}const useStyle$w=$n=>{const[Cn,_n]=useToken();return useStyleRegister(computed(()=>({theme:Cn.value,token:_n.value,hashId:"",path:["ant-design-icons",$n.value]})),()=>[{[`.${$n.value}`]:_extends$1(_extends$1({},resetIcon()),{[`.${$n.value} .${$n.value}-icon`]:{display:"block"}})}])};function useTheme($n,Cn){const _n=computed(()=>($n==null?void 0:$n.value)||{}),Pn=computed(()=>_n.value.inherit===!1||!(Cn!=null&&Cn.value)?defaultConfig$1:Cn.value);return computed(()=>{if(!($n!=null&&$n.value))return Cn==null?void 0:Cn.value;const Nn=_extends$1({},Pn.value.components);return Object.keys($n.value.components||{}).forEach(Rn=>{Nn[Rn]=_extends$1(_extends$1({},Nn[Rn]),$n.value.components[Rn])}),_extends$1(_extends$1(_extends$1({},Pn.value),_n.value),{token:_extends$1(_extends$1({},Pn.value.token),_n.value.token),components:Nn})})}var __rest$M=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{_extends$1(globalConfigForApi,globalConfigBySet),globalConfigForApi.prefixCls=getGlobalPrefixCls(),globalConfigForApi.iconPrefixCls=getGlobalIconPrefixCls(),globalConfigForApi.getPrefixCls=($n,Cn)=>Cn||($n?`${globalConfigForApi.prefixCls}-${$n}`:globalConfigForApi.prefixCls),globalConfigForApi.getRootPrefixCls=()=>globalConfigForApi.prefixCls?globalConfigForApi.prefixCls:getGlobalPrefixCls()});let stopWatchEffect;const setGlobalConfig=$n=>{stopWatchEffect&&stopWatchEffect(),stopWatchEffect=watchEffect(()=>{_extends$1(globalConfigBySet,reactive($n)),_extends$1(globalConfigForApi,reactive($n))}),$n.theme&®isterTheme(getGlobalPrefixCls(),$n.theme)},globalConfig=()=>({getPrefixCls:($n,Cn)=>Cn||($n?`${getGlobalPrefixCls()}-${$n}`:getGlobalPrefixCls()),getIconPrefixCls:getGlobalIconPrefixCls,getRootPrefixCls:()=>globalConfigForApi.prefixCls?globalConfigForApi.prefixCls:getGlobalPrefixCls()}),ConfigProvider=defineComponent({compatConfig:{MODE:3},name:"AConfigProvider",inheritAttrs:!1,props:configProviderProps(),setup($n,Cn){let{slots:_n}=Cn;const Pn=useConfigContextInject(),In=(aa,ca)=>{const{prefixCls:sa="ant"}=$n;if(ca)return ca;const ia=sa||Pn.getPrefixCls("");return aa?`${ia}-${aa}`:ia},Nn=computed(()=>$n.iconPrefixCls||Pn.iconPrefixCls.value||defaultIconPrefixCls),Rn=computed(()=>Nn.value!==Pn.iconPrefixCls.value),Dn=computed(()=>{var aa;return $n.csp||((aa=Pn.csp)===null||aa===void 0?void 0:aa.value)}),Ln=useStyle$w(Nn),Fn=useTheme(computed(()=>$n.theme),computed(()=>{var aa;return(aa=Pn.theme)===null||aa===void 0?void 0:aa.value})),Bn=aa=>($n.renderEmpty||_n.renderEmpty||Pn.renderEmpty||renderEmpty)(aa),Hn=computed(()=>{var aa,ca;return(aa=$n.autoInsertSpaceInButton)!==null&&aa!==void 0?aa:(ca=Pn.autoInsertSpaceInButton)===null||ca===void 0?void 0:ca.value}),zn=computed(()=>{var aa;return $n.locale||((aa=Pn.locale)===null||aa===void 0?void 0:aa.value)});watch(zn,()=>{globalConfigBySet.locale=zn.value},{immediate:!0});const Wn=computed(()=>{var aa;return $n.direction||((aa=Pn.direction)===null||aa===void 0?void 0:aa.value)}),Yn=computed(()=>{var aa,ca;return(aa=$n.space)!==null&&aa!==void 0?aa:(ca=Pn.space)===null||ca===void 0?void 0:ca.value}),Gn=computed(()=>{var aa,ca;return(aa=$n.virtual)!==null&&aa!==void 0?aa:(ca=Pn.virtual)===null||ca===void 0?void 0:ca.value}),Go=computed(()=>{var aa,ca;return(aa=$n.dropdownMatchSelectWidth)!==null&&aa!==void 0?aa:(ca=Pn.dropdownMatchSelectWidth)===null||ca===void 0?void 0:ca.value}),Xn=computed(()=>{var aa;return $n.getTargetContainer!==void 0?$n.getTargetContainer:(aa=Pn.getTargetContainer)===null||aa===void 0?void 0:aa.value}),Yo=computed(()=>{var aa;return $n.getPopupContainer!==void 0?$n.getPopupContainer:(aa=Pn.getPopupContainer)===null||aa===void 0?void 0:aa.value}),qo=computed(()=>{var aa;return $n.pageHeader!==void 0?$n.pageHeader:(aa=Pn.pageHeader)===null||aa===void 0?void 0:aa.value}),Jo=computed(()=>{var aa;return $n.input!==void 0?$n.input:(aa=Pn.input)===null||aa===void 0?void 0:aa.value}),Zo=computed(()=>{var aa;return $n.pagination!==void 0?$n.pagination:(aa=Pn.pagination)===null||aa===void 0?void 0:aa.value}),rr=computed(()=>{var aa;return $n.form!==void 0?$n.form:(aa=Pn.form)===null||aa===void 0?void 0:aa.value}),nr=computed(()=>{var aa;return $n.select!==void 0?$n.select:(aa=Pn.select)===null||aa===void 0?void 0:aa.value}),ta=computed(()=>$n.componentSize),oa=computed(()=>$n.componentDisabled),ra=computed(()=>{var aa,ca;return(aa=$n.wave)!==null&&aa!==void 0?aa:(ca=Pn.wave)===null||ca===void 0?void 0:ca.value}),ea={csp:Dn,autoInsertSpaceInButton:Hn,locale:zn,direction:Wn,space:Yn,virtual:Gn,dropdownMatchSelectWidth:Go,getPrefixCls:In,iconPrefixCls:Nn,theme:computed(()=>{var aa,ca;return(aa=Fn.value)!==null&&aa!==void 0?aa:(ca=Pn.theme)===null||ca===void 0?void 0:ca.value}),renderEmpty:Bn,getTargetContainer:Xn,getPopupContainer:Yo,pageHeader:qo,input:Jo,pagination:Zo,form:rr,select:nr,componentSize:ta,componentDisabled:oa,transformCellText:computed(()=>$n.transformCellText),wave:ra},la=computed(()=>{const aa=Fn.value||{},{algorithm:ca,token:sa}=aa,ia=__rest$M(aa,["algorithm","token"]),fa=ca&&(!Array.isArray(ca)||ca.length>0)?createTheme(ca):void 0;return _extends$1(_extends$1({},ia),{theme:fa,token:_extends$1(_extends$1({},defaultSeedToken),sa)})}),ua=computed(()=>{var aa,ca;let sa={};return zn.value&&(sa=((aa=zn.value.Form)===null||aa===void 0?void 0:aa.defaultValidateMessages)||((ca=localeValues$1.Form)===null||ca===void 0?void 0:ca.defaultValidateMessages)||{}),$n.form&&$n.form.validateMessages&&(sa=_extends$1(_extends$1({},sa),$n.form.validateMessages)),sa});useConfigContextProvider(ea),useProvideGlobalForm({validateMessages:ua}),useProviderSize(ta),useProviderDisabled(oa);const ga=aa=>{var ca,sa;let ia=Rn.value?Ln((ca=_n.default)===null||ca===void 0?void 0:ca.call(_n)):(sa=_n.default)===null||sa===void 0?void 0:sa.call(_n);if($n.theme){const fa=function(){return ia}();ia=createVNode(DesignTokenProvider,{value:la.value},{default:()=>[fa]})}return createVNode(locale$3,{locale:zn.value||aa,ANT_MARK__:ANT_MARK},{default:()=>[ia]})};return watchEffect(()=>{Wn.value&&(message.config({rtl:Wn.value==="rtl"}),notification.config({rtl:Wn.value==="rtl"}))}),()=>createVNode(LocaleReceiver,{children:(aa,ca,sa)=>ga(sa)},null)}});ConfigProvider.config=setGlobalConfig;ConfigProvider.install=function($n){$n.component(ConfigProvider.name,ConfigProvider)};const ConfigProvider$1=ConfigProvider,PickerButton=($n,Cn)=>{let{attrs:_n,slots:Pn}=Cn;return createVNode(Button$1,_objectSpread2$1(_objectSpread2$1({size:"small",type:"primary"},$n),_n),Pn)},PickerButton$1=PickerButton,genTagStatusStyle=($n,Cn,_n)=>{const Pn=capitalize$1(_n);return{[`${$n.componentCls}-${Cn}`]:{color:$n[`color${_n}`],background:$n[`color${Pn}Bg`],borderColor:$n[`color${Pn}Border`],[`&${$n.componentCls}-borderless`]:{borderColor:"transparent"}}}},genPresetStyle=$n=>genPresetColor($n,(Cn,_n)=>{let{textColor:Pn,lightBorderColor:In,lightColor:Nn,darkColor:Rn}=_n;return{[`${$n.componentCls}-${Cn}`]:{color:Pn,background:Nn,borderColor:In,"&-inverse":{color:$n.colorTextLightSolid,background:Rn,borderColor:Rn},[`&${$n.componentCls}-borderless`]:{borderColor:"transparent"}}}}),genBaseStyle$a=$n=>{const{paddingXXS:Cn,lineWidth:_n,tagPaddingHorizontal:Pn,componentCls:In}=$n,Nn=Pn-_n,Rn=Cn-_n;return{[In]:_extends$1(_extends$1({},resetComponent($n)),{display:"inline-block",height:"auto",marginInlineEnd:$n.marginXS,paddingInline:Nn,fontSize:$n.tagFontSize,lineHeight:`${$n.tagLineHeight}px`,whiteSpace:"nowrap",background:$n.tagDefaultBg,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:$n.borderRadiusSM,opacity:1,transition:`all ${$n.motionDurationMid}`,textAlign:"start",[`&${In}-rtl`]:{direction:"rtl"},"&, a, a:hover":{color:$n.tagDefaultColor},[`${In}-close-icon`]:{marginInlineStart:Rn,color:$n.colorTextDescription,fontSize:$n.tagIconSize,cursor:"pointer",transition:`all ${$n.motionDurationMid}`,"&:hover":{color:$n.colorTextHeading}},[`&${In}-has-color`]:{borderColor:"transparent",[`&, a, a:hover, ${$n.iconCls}-close, ${$n.iconCls}-close:hover`]:{color:$n.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",[`&:not(${In}-checkable-checked):hover`]:{color:$n.colorPrimary,backgroundColor:$n.colorFillSecondary},"&:active, &-checked":{color:$n.colorTextLightSolid},"&-checked":{backgroundColor:$n.colorPrimary,"&:hover":{backgroundColor:$n.colorPrimaryHover}},"&:active":{backgroundColor:$n.colorPrimaryActive}},"&-hidden":{display:"none"},[`> ${$n.iconCls} + span, > span + ${$n.iconCls}`]:{marginInlineStart:Nn}}),[`${In}-borderless`]:{borderColor:"transparent",background:$n.tagBorderlessBg}}},useStyle$v=genComponentStyleHook("Tag",$n=>{const{fontSize:Cn,lineHeight:_n,lineWidth:Pn,fontSizeIcon:In}=$n,Nn=Math.round(Cn*_n),Rn=$n.fontSizeSM,Dn=Nn-Pn*2,Ln=$n.colorFillAlter,Fn=$n.colorText,Bn=merge$1($n,{tagFontSize:Rn,tagLineHeight:Dn,tagDefaultBg:Ln,tagDefaultColor:Fn,tagIconSize:In-2*Pn,tagPaddingHorizontal:8,tagBorderlessBg:$n.colorFillTertiary});return[genBaseStyle$a(Bn),genPresetStyle(Bn),genTagStatusStyle(Bn,"success","Success"),genTagStatusStyle(Bn,"processing","Info"),genTagStatusStyle(Bn,"error","Error"),genTagStatusStyle(Bn,"warning","Warning")]}),checkableTagProps=()=>({prefixCls:String,checked:{type:Boolean,default:void 0},onChange:{type:Function},onClick:{type:Function},"onUpdate:checked":Function}),CheckableTag=defineComponent({compatConfig:{MODE:3},name:"ACheckableTag",inheritAttrs:!1,props:checkableTagProps(),setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const{prefixCls:Nn}=useConfigInject("tag",$n),[Rn,Dn]=useStyle$v(Nn),Ln=Bn=>{const{checked:Hn}=$n;Pn("update:checked",!Hn),Pn("change",!Hn),Pn("click",Bn)},Fn=computed(()=>classNames(Nn.value,Dn.value,{[`${Nn.value}-checkable`]:!0,[`${Nn.value}-checkable-checked`]:$n.checked}));return()=>{var Bn;return Rn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},In),{},{class:[Fn.value,In.class],onClick:Ln}),[(Bn=_n.default)===null||Bn===void 0?void 0:Bn.call(_n)]))}}}),CheckableTag$1=CheckableTag,tagProps=()=>({prefixCls:String,color:{type:String},closable:{type:Boolean,default:!1},closeIcon:PropTypes.any,visible:{type:Boolean,default:void 0},onClose:{type:Function},onClick:eventType(),"onUpdate:visible":Function,icon:PropTypes.any,bordered:{type:Boolean,default:!0}}),Tag=defineComponent({compatConfig:{MODE:3},name:"ATag",inheritAttrs:!1,props:tagProps(),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const{prefixCls:Nn,direction:Rn}=useConfigInject("tag",$n),[Dn,Ln]=useStyle$v(Nn),Fn=shallowRef(!0);watchEffect(()=>{$n.visible!==void 0&&(Fn.value=$n.visible)});const Bn=Yn=>{Yn.stopPropagation(),Pn("update:visible",!1),Pn("close",Yn),!Yn.defaultPrevented&&$n.visible===void 0&&(Fn.value=!1)},Hn=computed(()=>isPresetColor($n.color)||isPresetStatusColor($n.color)),zn=computed(()=>classNames(Nn.value,Ln.value,{[`${Nn.value}-${$n.color}`]:Hn.value,[`${Nn.value}-has-color`]:$n.color&&!Hn.value,[`${Nn.value}-hidden`]:!Fn.value,[`${Nn.value}-rtl`]:Rn.value==="rtl",[`${Nn.value}-borderless`]:!$n.bordered})),Wn=Yn=>{Pn("click",Yn)};return()=>{var Yn,Gn,Go;const{icon:Xn=(Yn=_n.icon)===null||Yn===void 0?void 0:Yn.call(_n),color:Yo,closeIcon:qo=(Gn=_n.closeIcon)===null||Gn===void 0?void 0:Gn.call(_n),closable:Jo=!1}=$n,Zo=()=>Jo?qo?createVNode("span",{class:`${Nn.value}-close-icon`,onClick:Bn},[qo]):createVNode(CloseOutlined$1,{class:`${Nn.value}-close-icon`,onClick:Bn},null):null,rr={backgroundColor:Yo&&!Hn.value?Yo:void 0},nr=Xn||null,ta=(Go=_n.default)===null||Go===void 0?void 0:Go.call(_n),oa=nr?createVNode(Fragment,null,[nr,createVNode("span",null,[ta])]):ta,ra=$n.onClick!==void 0,ea=createVNode("span",_objectSpread2$1(_objectSpread2$1({},In),{},{onClick:Wn,class:[zn.value,In.class],style:[rr,In.style]}),[oa,Zo()]);return Dn(ra?createVNode(Wave,null,{default:()=>[ea]}):ea)}}});Tag.CheckableTag=CheckableTag$1;Tag.install=function($n){return $n.component(Tag.name,Tag),$n.component(CheckableTag$1.name,CheckableTag$1),$n};const Tag$1=Tag;function PickerTag($n,Cn){let{slots:_n,attrs:Pn}=Cn;return createVNode(Tag$1,_objectSpread2$1(_objectSpread2$1({color:"blue"},$n),Pn),_n)}var CalendarOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"}}]},name:"calendar",theme:"outlined"};const CalendarOutlinedSvg=CalendarOutlined$2;function _objectSpread$B($n){for(var Cn=1;Cnea.value||ta.value),[ga,aa]=useStyle$J(Zo),ca=ref();Gn({focus:()=>{var La;(La=ca.value)===null||La===void 0||La.focus()},blur:()=>{var La;(La=ca.value)===null||La===void 0||La.blur()}});const sa=La=>Yo.valueFormat?$n.toString(La,Yo.valueFormat):La,ia=(La,Na)=>{const $a=sa(La);Xn("update:value",$a),Xn("change",$a,Na),qo.onFieldChange()},fa=La=>{Xn("update:open",La),Xn("openChange",La)},ma=La=>{Xn("focus",La)},ya=La=>{Xn("blur",La),qo.onFieldBlur()},ba=(La,Na)=>{const $a=sa(La);Xn("panelChange",$a,Na)},Ia=La=>{const Na=sa(La);Xn("ok",Na)},[Ea]=useLocaleReceiver("DatePicker",enUS),xa=computed(()=>Yo.value?Yo.valueFormat?$n.toDate(Yo.value,Yo.valueFormat):Yo.value:Yo.value===""?void 0:Yo.value),Ta=computed(()=>Yo.defaultValue?Yo.valueFormat?$n.toDate(Yo.defaultValue,Yo.valueFormat):Yo.defaultValue:Yo.defaultValue===""?void 0:Yo.defaultValue),wa=computed(()=>Yo.defaultPickerValue?Yo.valueFormat?$n.toDate(Yo.defaultPickerValue,Yo.valueFormat):Yo.defaultPickerValue:Yo.defaultPickerValue===""?void 0:Yo.defaultPickerValue);return()=>{var La,Na,$a,ka,Ha,da;const pa=_extends$1(_extends$1({},Ea.value),Yo.locale),Sa=_extends$1(_extends$1({},Yo),Go),{bordered:Aa=!0,placeholder:Ra,suffixIcon:Fa=(La=Yn.suffixIcon)===null||La===void 0?void 0:La.call(Yn),showToday:za=!0,transitionName:Wa,allowClear:Ya=!0,dateRender:ja=Yn.dateRender,renderExtraFooter:qa=Yn.renderExtraFooter,monthCellRender:Xa=Yn.monthCellRender||Yo.monthCellContentRender||Yn.monthCellContentRender,clearIcon:Oa=(Na=Yn.clearIcon)===null||Na===void 0?void 0:Na.call(Yn),id:Ma=qo.id.value}=Sa,Ua=__rest$L(Sa,["bordered","placeholder","suffixIcon","showToday","transitionName","allowClear","dateRender","renderExtraFooter","monthCellRender","clearIcon","id"]),Qa=Sa.showTime===""?!0:Sa.showTime,{format:ri}=Sa;let fi={};Fn&&(fi.picker=Fn);const ei=Fn||Sa.picker||"date";fi=_extends$1(_extends$1(_extends$1({},fi),Qa?getTimeProps(_extends$1({format:ri,picker:ei},typeof Qa=="object"?Qa:{})):{}),ei==="time"?getTimeProps(_extends$1(_extends$1({format:ri},Ua),{picker:ei})):{});const ti=Zo.value,ni=createVNode(Fragment,null,[Fa||createVNode(Fn==="time"?ClockCircleOutlined$1:CalendarOutlined$1,null,null),Jo.hasFeedback&&Jo.feedbackIcon]);return ga(createVNode(Picker$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({monthCellRender:Xa,dateRender:ja,renderExtraFooter:qa,ref:ca,placeholder:getPlaceholder(pa,ei,Ra),suffixIcon:ni,dropdownAlign:transPlacement2DropdownAlign(rr.value,Yo.placement),clearIcon:Oa||createVNode(CloseCircleFilled$1,null,null),allowClear:Ya,transitionName:Wa||`${oa.value}-slide-up`},Ua),fi),{},{id:Ma,picker:ei,value:xa.value,defaultValue:Ta.value,defaultPickerValue:wa.value,showToday:za,locale:pa.lang,class:classNames({[`${ti}-${ua.value}`]:ua.value,[`${ti}-borderless`]:!Aa},getStatusClassNames(ti,getMergedStatus(Jo.status,Yo.status),Jo.hasFeedback),Go.class,aa.value,la.value),disabled:ra.value,prefixCls:ti,getPopupContainer:Go.getCalendarContainer||nr.value,generateConfig:$n,prevIcon:(($a=Yn.prevIcon)===null||$a===void 0?void 0:$a.call(Yn))||createVNode("span",{class:`${ti}-prev-icon`},null),nextIcon:((ka=Yn.nextIcon)===null||ka===void 0?void 0:ka.call(Yn))||createVNode("span",{class:`${ti}-next-icon`},null),superPrevIcon:((Ha=Yn.superPrevIcon)===null||Ha===void 0?void 0:Ha.call(Yn))||createVNode("span",{class:`${ti}-super-prev-icon`},null),superNextIcon:((da=Yn.superNextIcon)===null||da===void 0?void 0:da.call(Yn))||createVNode("span",{class:`${ti}-super-next-icon`},null),components:Components,direction:rr.value,dropdownClassName:classNames(aa.value,Yo.popupClassName,Yo.dropdownClassName),onChange:ia,onOpenChange:fa,onFocus:ma,onBlur:ya,onPanelChange:ba,onOk:Ia}),null))}}})}const Pn=_n(void 0,"ADatePicker"),In=_n("week","AWeekPicker"),Nn=_n("month","AMonthPicker"),Rn=_n("year","AYearPicker"),Dn=_n("time","TimePicker"),Ln=_n("quarter","AQuarterPicker");return{DatePicker:Pn,WeekPicker:In,MonthPicker:Nn,YearPicker:Rn,TimePicker:Dn,QuarterPicker:Ln}}var SwapRightOutlined$2={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"}}]},name:"swap-right",theme:"outlined"};const SwapRightOutlinedSvg=SwapRightOutlined$2;function _objectSpread$z($n){for(var Cn=1;CnYo.value||Gn.value),[Zo,rr]=useStyle$J(zn),nr=ref();Nn({focus:()=>{var ma;(ma=nr.value)===null||ma===void 0||ma.focus()},blur:()=>{var ma;(ma=nr.value)===null||ma===void 0||ma.blur()}});const ta=ma=>Fn.valueFormat?$n.toString(ma,Fn.valueFormat):ma,oa=(ma,ya)=>{const ba=ta(ma);Ln("update:value",ba),Ln("change",ba,ya),Bn.onFieldChange()},ra=ma=>{Ln("update:open",ma),Ln("openChange",ma)},ea=ma=>{Ln("focus",ma)},la=ma=>{Ln("blur",ma),Bn.onFieldBlur()},ua=(ma,ya)=>{const ba=ta(ma);Ln("panelChange",ba,ya)},ga=ma=>{const ya=ta(ma);Ln("ok",ya)},aa=(ma,ya,ba)=>{const Ia=ta(ma);Ln("calendarChange",Ia,ya,ba)},[ca]=useLocaleReceiver("DatePicker",enUS),sa=computed(()=>Fn.value&&Fn.valueFormat?$n.toDate(Fn.value,Fn.valueFormat):Fn.value),ia=computed(()=>Fn.defaultValue&&Fn.valueFormat?$n.toDate(Fn.defaultValue,Fn.valueFormat):Fn.defaultValue),fa=computed(()=>Fn.defaultPickerValue&&Fn.valueFormat?$n.toDate(Fn.defaultPickerValue,Fn.valueFormat):Fn.defaultPickerValue);return()=>{var ma,ya,ba,Ia,Ea,xa,Ta;const wa=_extends$1(_extends$1({},ca.value),Fn.locale),La=_extends$1(_extends$1({},Fn),Dn),{prefixCls:Na,bordered:$a=!0,placeholder:ka,suffixIcon:Ha=(ma=Rn.suffixIcon)===null||ma===void 0?void 0:ma.call(Rn),picker:da="date",transitionName:pa,allowClear:Sa=!0,dateRender:Aa=Rn.dateRender,renderExtraFooter:Ra=Rn.renderExtraFooter,separator:Fa=(ya=Rn.separator)===null||ya===void 0?void 0:ya.call(Rn),clearIcon:za=(ba=Rn.clearIcon)===null||ba===void 0?void 0:ba.call(Rn),id:Wa=Bn.id.value}=La,Ya=__rest$K(La,["prefixCls","bordered","placeholder","suffixIcon","picker","transitionName","allowClear","dateRender","renderExtraFooter","separator","clearIcon","id"]);delete Ya["onUpdate:value"],delete Ya["onUpdate:open"];const{format:ja,showTime:qa}=La;let Xa={};Xa=_extends$1(_extends$1(_extends$1({},Xa),qa?getTimeProps(_extends$1({format:ja,picker:da},qa)):{}),da==="time"?getTimeProps(_extends$1(_extends$1({format:ja},omit$1(Ya,["disabledTime"])),{picker:da})):{});const Oa=zn.value,Ma=createVNode(Fragment,null,[Ha||createVNode(da==="time"?ClockCircleOutlined$1:CalendarOutlined$1,null,null),Hn.hasFeedback&&Hn.feedbackIcon]);return Zo(createVNode(VCRangePicker,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({dateRender:Aa,renderExtraFooter:Ra,separator:Fa||createVNode("span",{"aria-label":"to",class:`${Oa}-separator`},[createVNode(SwapRightOutlined$1,null,null)]),ref:nr,dropdownAlign:transPlacement2DropdownAlign(Wn.value,Fn.placement),placeholder:getRangePlaceholder(wa,da,ka),suffixIcon:Ma,clearIcon:za||createVNode(CloseCircleFilled$1,null,null),allowClear:Sa,transitionName:pa||`${Go.value}-slide-up`},Ya),Xa),{},{disabled:Xn.value,id:Wa,value:sa.value,defaultValue:ia.value,defaultPickerValue:fa.value,picker:da,class:classNames({[`${Oa}-${Jo.value}`]:Jo.value,[`${Oa}-borderless`]:!$a},getStatusClassNames(Oa,getMergedStatus(Hn.status,Fn.status),Hn.hasFeedback),Dn.class,rr.value,qo.value),locale:wa.lang,prefixCls:Oa,getPopupContainer:Dn.getCalendarContainer||Yn.value,generateConfig:$n,prevIcon:((Ia=Rn.prevIcon)===null||Ia===void 0?void 0:Ia.call(Rn))||createVNode("span",{class:`${Oa}-prev-icon`},null),nextIcon:((Ea=Rn.nextIcon)===null||Ea===void 0?void 0:Ea.call(Rn))||createVNode("span",{class:`${Oa}-next-icon`},null),superPrevIcon:((xa=Rn.superPrevIcon)===null||xa===void 0?void 0:xa.call(Rn))||createVNode("span",{class:`${Oa}-super-prev-icon`},null),superNextIcon:((Ta=Rn.superNextIcon)===null||Ta===void 0?void 0:Ta.call(Rn))||createVNode("span",{class:`${Oa}-super-next-icon`},null),components:Components,direction:Wn.value,dropdownClassName:classNames(rr.value,Fn.popupClassName,Fn.dropdownClassName),onChange:oa,onOpenChange:ra,onFocus:ea,onBlur:la,onPanelChange:ua,onOk:ga,onCalendarChange:aa}),null))}}})}const Components={button:PickerButton$1,rangeItem:PickerTag};function toArray$3($n){return $n?Array.isArray($n)?$n:[$n]:[]}function getTimeProps($n){const{format:Cn,picker:_n,showHour:Pn,showMinute:In,showSecond:Nn,use12Hours:Rn}=$n,Dn=toArray$3(Cn)[0],Ln=_extends$1({},$n);return Dn&&typeof Dn=="string"&&(!Dn.includes("s")&&Nn===void 0&&(Ln.showSecond=!1),!Dn.includes("m")&&In===void 0&&(Ln.showMinute=!1),!Dn.includes("H")&&!Dn.includes("h")&&Pn===void 0&&(Ln.showHour=!1),(Dn.includes("a")||Dn.includes("A"))&&Rn===void 0&&(Ln.use12Hours=!0)),_n==="time"?Ln:(typeof Dn=="function"&&delete Ln.format,{showTime:Ln})}function generatePicker($n,Cn){const{DatePicker:_n,WeekPicker:Pn,MonthPicker:In,YearPicker:Nn,TimePicker:Rn,QuarterPicker:Dn}=generateSinglePicker($n,Cn),Ln=generateRangePicker($n,Cn);return{DatePicker:_n,WeekPicker:Pn,MonthPicker:In,YearPicker:Nn,TimePicker:Rn,QuarterPicker:Dn,RangePicker:Ln}}const{DatePicker:DatePicker$1,WeekPicker,MonthPicker,YearPicker,TimePicker:TimePicker$3,QuarterPicker,RangePicker}=generatePicker(dayjsGenerateConfig),DatePicker$2=_extends$1(DatePicker$1,{WeekPicker,MonthPicker,YearPicker,RangePicker,TimePicker:TimePicker$3,QuarterPicker,install:$n=>($n.component(DatePicker$1.name,DatePicker$1),$n.component(RangePicker.name,RangePicker),$n.component(MonthPicker.name,MonthPicker),$n.component(WeekPicker.name,WeekPicker),$n.component(QuarterPicker.name,QuarterPicker),$n)});function notEmpty($n){return $n!=null}const Cell$1=$n=>{const{itemPrefixCls:Cn,component:_n,span:Pn,labelStyle:In,contentStyle:Nn,bordered:Rn,label:Dn,content:Ln,colon:Fn}=$n,Bn=_n;return Rn?createVNode(Bn,{class:[{[`${Cn}-item-label`]:notEmpty(Dn),[`${Cn}-item-content`]:notEmpty(Ln)}],colSpan:Pn},{default:()=>[notEmpty(Dn)&&createVNode("span",{style:In},[Dn]),notEmpty(Ln)&&createVNode("span",{style:Nn},[Ln])]}):createVNode(Bn,{class:[`${Cn}-item`],colSpan:Pn},{default:()=>[createVNode("div",{class:`${Cn}-item-container`},[(Dn||Dn===0)&&createVNode("span",{class:[`${Cn}-item-label`,{[`${Cn}-item-no-colon`]:!Fn}],style:In},[Dn]),(Ln||Ln===0)&&createVNode("span",{class:`${Cn}-item-content`,style:Nn},[Ln])])]})},Cell$2=Cell$1,Row=$n=>{const Cn=(Fn,Bn,Hn)=>{let{colon:zn,prefixCls:Wn,bordered:Yn}=Bn,{component:Gn,type:Go,showLabel:Xn,showContent:Yo,labelStyle:qo,contentStyle:Jo}=Hn;return Fn.map((Zo,rr)=>{var nr,ta;const oa=Zo.props||{},{prefixCls:ra=Wn,span:ea=1,labelStyle:la=oa["label-style"],contentStyle:ua=oa["content-style"],label:ga=(ta=(nr=Zo.children)===null||nr===void 0?void 0:nr.label)===null||ta===void 0?void 0:ta.call(nr)}=oa,aa=getSlot(Zo),ca=getClass(Zo),sa=getStyle$3(Zo),{key:ia}=Zo;return typeof Gn=="string"?createVNode(Cell$2,{key:`${Go}-${String(ia)||rr}`,class:ca,style:sa,labelStyle:_extends$1(_extends$1({},qo),la),contentStyle:_extends$1(_extends$1({},Jo),ua),span:ea,colon:zn,component:Gn,itemPrefixCls:ra,bordered:Yn,label:Xn?ga:null,content:Yo?aa:null},null):[createVNode(Cell$2,{key:`label-${String(ia)||rr}`,class:ca,style:_extends$1(_extends$1(_extends$1({},qo),sa),la),span:1,colon:zn,component:Gn[0],itemPrefixCls:ra,bordered:Yn,label:ga},null),createVNode(Cell$2,{key:`content-${String(ia)||rr}`,class:ca,style:_extends$1(_extends$1(_extends$1({},Jo),sa),ua),span:ea*2-1,component:Gn[1],itemPrefixCls:ra,bordered:Yn,content:aa},null)]})},{prefixCls:_n,vertical:Pn,row:In,index:Nn,bordered:Rn}=$n,{labelStyle:Dn,contentStyle:Ln}=inject(descriptionsContext,{labelStyle:ref({}),contentStyle:ref({})});return Pn?createVNode(Fragment,null,[createVNode("tr",{key:`label-${Nn}`,class:`${_n}-row`},[Cn(In,$n,{component:"th",type:"label",showLabel:!0,labelStyle:Dn.value,contentStyle:Ln.value})]),createVNode("tr",{key:`content-${Nn}`,class:`${_n}-row`},[Cn(In,$n,{component:"td",type:"content",showContent:!0,labelStyle:Dn.value,contentStyle:Ln.value})])]):createVNode("tr",{key:Nn,class:`${_n}-row`},[Cn(In,$n,{component:Rn?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0,labelStyle:Dn.value,contentStyle:Ln.value})])},Row$1=Row,genBorderedStyle$4=$n=>{const{componentCls:Cn,descriptionsSmallPadding:_n,descriptionsDefaultPadding:Pn,descriptionsMiddlePadding:In,descriptionsBg:Nn}=$n;return{[`&${Cn}-bordered`]:{[`${Cn}-view`]:{border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,"> table":{tableLayout:"auto",borderCollapse:"collapse"}},[`${Cn}-item-label, ${Cn}-item-content`]:{padding:Pn,borderInlineEnd:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`${Cn}-item-label`]:{backgroundColor:Nn,"&::after":{display:"none"}},[`${Cn}-row`]:{borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,"&:last-child":{borderBottom:"none"}},[`&${Cn}-middle`]:{[`${Cn}-item-label, ${Cn}-item-content`]:{padding:In}},[`&${Cn}-small`]:{[`${Cn}-item-label, ${Cn}-item-content`]:{padding:_n}}}}},genDescriptionStyles=$n=>{const{componentCls:Cn,descriptionsExtraColor:_n,descriptionItemPaddingBottom:Pn,descriptionsItemLabelColonMarginRight:In,descriptionsItemLabelColonMarginLeft:Nn,descriptionsTitleMarginBottom:Rn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1({},resetComponent($n)),genBorderedStyle$4($n)),{"&-rtl":{direction:"rtl"},[`${Cn}-header`]:{display:"flex",alignItems:"center",marginBottom:Rn},[`${Cn}-title`]:_extends$1(_extends$1({},textEllipsis),{flex:"auto",color:$n.colorText,fontWeight:$n.fontWeightStrong,fontSize:$n.fontSizeLG,lineHeight:$n.lineHeightLG}),[`${Cn}-extra`]:{marginInlineStart:"auto",color:_n,fontSize:$n.fontSize},[`${Cn}-view`]:{width:"100%",borderRadius:$n.borderRadiusLG,table:{width:"100%",tableLayout:"fixed"}},[`${Cn}-row`]:{"> th, > td":{paddingBottom:Pn},"&:last-child":{borderBottom:"none"}},[`${Cn}-item-label`]:{color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize,lineHeight:$n.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${Nn}px ${In}px`},[`&${Cn}-item-no-colon::after`]:{content:'""'}},[`${Cn}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${Cn}-item-content`]:{display:"table-cell",flex:1,color:$n.colorText,fontSize:$n.fontSize,lineHeight:$n.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${Cn}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${Cn}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${Cn}-item-content`]:{display:"inline-flex",alignItems:"baseline"}}},"&-middle":{[`${Cn}-row`]:{"> th, > td":{paddingBottom:$n.paddingSM}}},"&-small":{[`${Cn}-row`]:{"> th, > td":{paddingBottom:$n.paddingXS}}}})}},useStyle$u=genComponentStyleHook("Descriptions",$n=>{const Cn=$n.colorFillAlter,_n=$n.fontSizeSM*$n.lineHeightSM,Pn=$n.colorText,In=`${$n.paddingXS}px ${$n.padding}px`,Nn=`${$n.padding}px ${$n.paddingLG}px`,Rn=`${$n.paddingSM}px ${$n.paddingLG}px`,Dn=$n.padding,Ln=$n.marginXS,Fn=$n.marginXXS/2,Bn=merge$1($n,{descriptionsBg:Cn,descriptionsTitleMarginBottom:_n,descriptionsExtraColor:Pn,descriptionItemPaddingBottom:Dn,descriptionsSmallPadding:In,descriptionsDefaultPadding:Nn,descriptionsMiddlePadding:Rn,descriptionsItemLabelColonMarginRight:Ln,descriptionsItemLabelColonMarginLeft:Fn});return[genDescriptionStyles(Bn)]});PropTypes.any;const descriptionsItemProp=()=>({prefixCls:String,label:PropTypes.any,labelStyle:{type:Object,default:void 0},contentStyle:{type:Object,default:void 0},span:{type:Number,default:1}}),DescriptionsItem=defineComponent({compatConfig:{MODE:3},name:"ADescriptionsItem",props:descriptionsItemProp(),setup($n,Cn){let{slots:_n}=Cn;return()=>{var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}}}),DEFAULT_COLUMN_MAP={xxxl:3,xxl:3,xl:3,lg:3,md:3,sm:2,xs:1};function getColumn($n,Cn){if(typeof $n=="number")return $n;if(typeof $n=="object")for(let _n=0;_nCn)&&(Pn=cloneElement($n,{span:Cn}),warning$3()),Pn}function getRows($n,Cn){const _n=flattenChildren($n),Pn=[];let In=[],Nn=Cn;return _n.forEach((Rn,Dn)=>{var Ln;const Fn=(Ln=Rn.props)===null||Ln===void 0?void 0:Ln.span,Bn=Fn||1;if(Dn===_n.length-1){In.push(getFilledItem(Rn,Nn,Fn)),Pn.push(In);return}Bn({prefixCls:String,bordered:{type:Boolean,default:void 0},size:{type:String,default:"default"},title:PropTypes.any,extra:PropTypes.any,column:{type:[Number,Object],default:()=>DEFAULT_COLUMN_MAP},layout:String,colon:{type:Boolean,default:void 0},labelStyle:{type:Object,default:void 0},contentStyle:{type:Object,default:void 0}}),descriptionsContext=Symbol("descriptionsContext"),Descriptions=defineComponent({compatConfig:{MODE:3},name:"ADescriptions",inheritAttrs:!1,props:descriptionsProps(),slots:Object,Item:DescriptionsItem,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("descriptions",$n);let Rn;const Dn=ref({}),[Ln,Fn]=useStyle$u(In),Bn=useResponsiveObserver();onBeforeMount(()=>{Rn=Bn.value.subscribe(zn=>{typeof $n.column=="object"&&(Dn.value=zn)})}),onBeforeUnmount(()=>{Bn.value.unsubscribe(Rn)}),provide(descriptionsContext,{labelStyle:toRef($n,"labelStyle"),contentStyle:toRef($n,"contentStyle")});const Hn=computed(()=>getColumn($n.column,Dn.value));return()=>{var zn,Wn,Yn;const{size:Gn,bordered:Go=!1,layout:Xn="horizontal",colon:Yo=!0,title:qo=(zn=_n.title)===null||zn===void 0?void 0:zn.call(_n),extra:Jo=(Wn=_n.extra)===null||Wn===void 0?void 0:Wn.call(_n)}=$n,Zo=(Yn=_n.default)===null||Yn===void 0?void 0:Yn.call(_n),rr=getRows(Zo,Hn.value);return Ln(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[In.value,{[`${In.value}-${Gn}`]:Gn!=="default",[`${In.value}-bordered`]:!!Go,[`${In.value}-rtl`]:Nn.value==="rtl"},Pn.class,Fn.value]}),[(qo||Jo)&&createVNode("div",{class:`${In.value}-header`},[qo&&createVNode("div",{class:`${In.value}-title`},[qo]),Jo&&createVNode("div",{class:`${In.value}-extra`},[Jo])]),createVNode("div",{class:`${In.value}-view`},[createVNode("table",null,[createVNode("tbody",null,[rr.map((nr,ta)=>createVNode(Row$1,{key:ta,index:ta,colon:Yo,prefixCls:In.value,vertical:Xn==="vertical",bordered:Go,row:nr},null))])])])]))}}});Descriptions.install=function($n){return $n.component(Descriptions.name,Descriptions),$n.component(Descriptions.Item.name,Descriptions.Item),$n};const Descriptions$1=Descriptions,genSharedDividerStyle=$n=>{const{componentCls:Cn,sizePaddingEdgeHorizontal:_n,colorSplit:Pn,lineWidth:In}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{borderBlockStart:`${In}px solid ${Pn}`,"&-vertical":{position:"relative",top:"-0.06em",display:"inline-block",height:"0.9em",margin:`0 ${$n.dividerVerticalGutterMargin}px`,verticalAlign:"middle",borderTop:0,borderInlineStart:`${In}px solid ${Pn}`},"&-horizontal":{display:"flex",clear:"both",width:"100%",minWidth:"100%",margin:`${$n.dividerHorizontalGutterMargin}px 0`},[`&-horizontal${Cn}-with-text`]:{display:"flex",alignItems:"center",margin:`${$n.dividerHorizontalWithTextGutterMargin}px 0`,color:$n.colorTextHeading,fontWeight:500,fontSize:$n.fontSizeLG,whiteSpace:"nowrap",textAlign:"center",borderBlockStart:`0 ${Pn}`,"&::before, &::after":{position:"relative",width:"50%",borderBlockStart:`${In}px solid transparent`,borderBlockStartColor:"inherit",borderBlockEnd:0,transform:"translateY(50%)",content:"''"}},[`&-horizontal${Cn}-with-text-left`]:{"&::before":{width:"5%"},"&::after":{width:"95%"}},[`&-horizontal${Cn}-with-text-right`]:{"&::before":{width:"95%"},"&::after":{width:"5%"}},[`${Cn}-inner-text`]:{display:"inline-block",padding:"0 1em"},"&-dashed":{background:"none",borderColor:Pn,borderStyle:"dashed",borderWidth:`${In}px 0 0`},[`&-horizontal${Cn}-with-text${Cn}-dashed`]:{"&::before, &::after":{borderStyle:"dashed none none"}},[`&-vertical${Cn}-dashed`]:{borderInlineStartWidth:In,borderInlineEnd:0,borderBlockStart:0,borderBlockEnd:0},[`&-plain${Cn}-with-text`]:{color:$n.colorText,fontWeight:"normal",fontSize:$n.fontSize},[`&-horizontal${Cn}-with-text-left${Cn}-no-default-orientation-margin-left`]:{"&::before":{width:0},"&::after":{width:"100%"},[`${Cn}-inner-text`]:{paddingInlineStart:_n}},[`&-horizontal${Cn}-with-text-right${Cn}-no-default-orientation-margin-right`]:{"&::before":{width:"100%"},"&::after":{width:0},[`${Cn}-inner-text`]:{paddingInlineEnd:_n}}})}},useStyle$t=genComponentStyleHook("Divider",$n=>{const Cn=merge$1($n,{dividerVerticalGutterMargin:$n.marginXS,dividerHorizontalWithTextGutterMargin:$n.margin,dividerHorizontalGutterMargin:$n.marginLG});return[genSharedDividerStyle(Cn)]},{sizePaddingEdgeHorizontal:0}),dividerProps=()=>({prefixCls:String,type:{type:String,default:"horizontal"},dashed:{type:Boolean,default:!1},orientation:{type:String,default:"center"},plain:{type:Boolean,default:!1},orientationMargin:[String,Number]}),Divider=defineComponent({name:"ADivider",inheritAttrs:!1,compatConfig:{MODE:3},props:dividerProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("divider",$n),[Rn,Dn]=useStyle$t(In),Ln=computed(()=>$n.orientation==="left"&&$n.orientationMargin!=null),Fn=computed(()=>$n.orientation==="right"&&$n.orientationMargin!=null),Bn=computed(()=>{const{type:Wn,dashed:Yn,plain:Gn}=$n,Go=In.value;return{[Go]:!0,[Dn.value]:!!Dn.value,[`${Go}-${Wn}`]:!0,[`${Go}-dashed`]:!!Yn,[`${Go}-plain`]:!!Gn,[`${Go}-rtl`]:Nn.value==="rtl",[`${Go}-no-default-orientation-margin-left`]:Ln.value,[`${Go}-no-default-orientation-margin-right`]:Fn.value}}),Hn=computed(()=>{const Wn=typeof $n.orientationMargin=="number"?`${$n.orientationMargin}px`:$n.orientationMargin;return _extends$1(_extends$1({},Ln.value&&{marginLeft:Wn}),Fn.value&&{marginRight:Wn})}),zn=computed(()=>$n.orientation.length>0?"-"+$n.orientation:$n.orientation);return()=>{var Wn;const Yn=flattenChildren((Wn=_n.default)===null||Wn===void 0?void 0:Wn.call(_n));return Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Bn.value,Yn.length?`${In.value}-with-text ${In.value}-with-text${zn.value}`:"",Pn.class],role:"separator"}),[Yn.length?createVNode("span",{class:`${In.value}-inner-text`,style:Hn.value},[Yn]):null]))}}}),index$l=withInstall(Divider);Dropdown$1.Button=DropdownButton;Dropdown$1.install=function($n){return $n.component(Dropdown$1.name,Dropdown$1),$n.component(DropdownButton.name,DropdownButton),$n};const props=()=>({prefixCls:String,width:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),height:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),style:{type:Object,default:void 0},class:String,rootClassName:String,rootStyle:objectType(),placement:{type:String},wrapperClassName:String,level:{type:[String,Array]},levelMove:{type:[Number,Function,Array]},duration:String,ease:String,showMask:{type:Boolean,default:void 0},maskClosable:{type:Boolean,default:void 0},maskStyle:{type:Object,default:void 0},afterVisibleChange:Function,keyboard:{type:Boolean,default:void 0},contentWrapperStyle:arrayType(),autofocus:{type:Boolean,default:void 0},open:{type:Boolean,default:void 0},motion:functionType(),maskMotion:objectType()}),drawerProps$1=()=>_extends$1(_extends$1({},props()),{forceRender:{type:Boolean,default:void 0},getContainer:PropTypes.oneOfType([PropTypes.string,PropTypes.func,PropTypes.object,PropTypes.looseBool])}),drawerChildProps=()=>_extends$1(_extends$1({},props()),{getContainer:Function,getOpenCount:Function,scrollLocker:PropTypes.any,inline:Boolean});function dataToArray($n){return Array.isArray($n)?$n:[$n]}const transitionEndObject={transition:"transitionend",WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend"};Object.keys(transitionEndObject).filter($n=>{if(typeof document>"u")return!1;const Cn=document.getElementsByTagName("html")[0];return $n in(Cn?Cn.style:{})})[0];const windowIsUndefined=!(typeof window<"u"&&window.document&&window.document.createElement);var __rest$J=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{nextTick(()=>{var Xn;const{open:Yo,getContainer:qo,showMask:Jo,autofocus:Zo}=$n,rr=qo==null?void 0:qo();Yn($n),Yo&&(rr&&(rr.parentNode,document.body),nextTick(()=>{Zo&&Bn()}),Jo&&((Xn=$n.scrollLocker)===null||Xn===void 0||Xn.lock()))})}),watch(()=>$n.level,()=>{Yn($n)},{flush:"post"}),watch(()=>$n.open,()=>{const{open:Xn,getContainer:Yo,scrollLocker:qo,showMask:Jo,autofocus:Zo}=$n,rr=Yo==null?void 0:Yo();rr&&(rr.parentNode,document.body),Xn?(Zo&&Bn(),Jo&&(qo==null||qo.lock())):qo==null||qo.unLock()},{flush:"post"}),onUnmounted(()=>{var Xn;const{open:Yo}=$n;Yo&&(document.body.style.touchAction=""),(Xn=$n.scrollLocker)===null||Xn===void 0||Xn.unLock()}),watch(()=>$n.placement,Xn=>{Xn&&(Ln.value=null)});const Bn=()=>{var Xn,Yo;(Yo=(Xn=Nn.value)===null||Xn===void 0?void 0:Xn.focus)===null||Yo===void 0||Yo.call(Xn)},Hn=Xn=>{_n("close",Xn)},zn=Xn=>{Xn.keyCode===KeyCode$1.ESC&&(Xn.stopPropagation(),Hn(Xn))},Wn=()=>{const{open:Xn,afterVisibleChange:Yo}=$n;Yo&&Yo(!!Xn)},Yn=Xn=>{let{level:Yo,getContainer:qo}=Xn;if(windowIsUndefined)return;const Jo=qo==null?void 0:qo(),Zo=Jo?Jo.parentNode:null;Fn=[],Yo==="all"?(Zo?Array.prototype.slice.call(Zo.children):[]).forEach(nr=>{nr.nodeName!=="SCRIPT"&&nr.nodeName!=="STYLE"&&nr.nodeName!=="LINK"&&nr!==Jo&&Fn.push(nr)}):Yo&&dataToArray(Yo).forEach(rr=>{document.querySelectorAll(rr).forEach(nr=>{Fn.push(nr)})})},Gn=Xn=>{_n("handleClick",Xn)},Go=shallowRef(!1);return watch(Nn,()=>{nextTick(()=>{Go.value=!0})}),()=>{var Xn,Yo;const{width:qo,height:Jo,open:Zo,prefixCls:rr,placement:nr,level:ta,levelMove:oa,ease:ra,duration:ea,getContainer:la,onChange:ua,afterVisibleChange:ga,showMask:aa,maskClosable:ca,maskStyle:sa,keyboard:ia,getOpenCount:fa,scrollLocker:ma,contentWrapperStyle:ya,style:ba,class:Ia,rootClassName:Ea,rootStyle:xa,maskMotion:Ta,motion:wa,inline:La}=$n,Na=__rest$J($n,["width","height","open","prefixCls","placement","level","levelMove","ease","duration","getContainer","onChange","afterVisibleChange","showMask","maskClosable","maskStyle","keyboard","getOpenCount","scrollLocker","contentWrapperStyle","style","class","rootClassName","rootStyle","maskMotion","motion","inline"]),$a=Zo&&Go.value,ka=classNames(rr,{[`${rr}-${nr}`]:!0,[`${rr}-open`]:$a,[`${rr}-inline`]:La,"no-mask":!aa,[Ea]:!0}),Ha=typeof wa=="function"?wa(nr):wa;return createVNode("div",_objectSpread2$1(_objectSpread2$1({},omit$1(Na,["autofocus"])),{},{tabindex:-1,class:ka,style:xa,ref:Nn,onKeydown:$a&&ia?zn:void 0}),[createVNode(Transition,Ta,{default:()=>[aa&&withDirectives(createVNode("div",{class:`${rr}-mask`,onClick:ca?Hn:void 0,style:sa,ref:Rn},null),[[vShow,$a]])]}),createVNode(Transition,_objectSpread2$1(_objectSpread2$1({},Ha),{},{onAfterEnter:Wn,onAfterLeave:Wn}),{default:()=>[withDirectives(createVNode("div",{class:`${rr}-content-wrapper`,style:[ya],ref:In},[createVNode("div",{class:[`${rr}-content`,Ia],style:ba,ref:Ln},[(Xn=Pn.default)===null||Xn===void 0?void 0:Xn.call(Pn)]),Pn.handler?createVNode("div",{onClick:Gn,ref:Dn},[(Yo=Pn.handler)===null||Yo===void 0?void 0:Yo.call(Pn)]):null]),[[vShow,$a]])]})])}}}),Child=DrawerChild;var __rest$I=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{},showMask:!0,maskClosable:!0,maskStyle:{},wrapperClassName:"",keyboard:!0,forceRender:!1,autofocus:!0}),emits:["handleClick","close"],setup($n,Cn){let{emit:_n,slots:Pn}=Cn;const In=ref(null),Nn=Dn=>{_n("handleClick",Dn)},Rn=Dn=>{_n("close",Dn)};return()=>{const{getContainer:Dn,wrapperClassName:Ln,rootClassName:Fn,rootStyle:Bn,forceRender:Hn}=$n,zn=__rest$I($n,["getContainer","wrapperClassName","rootClassName","rootStyle","forceRender"]);let Wn=null;if(!Dn)return createVNode(Child,_objectSpread2$1(_objectSpread2$1({},zn),{},{rootClassName:Fn,rootStyle:Bn,open:$n.open,onClose:Rn,onHandleClick:Nn,inline:!0}),Pn);const Yn=!!Pn.handler||Hn;return(Yn||$n.open||In.value)&&(Wn=createVNode(Portal,{autoLock:!0,visible:$n.open,forceRender:Yn,getContainer:Dn,wrapperClassName:Ln},{default:Gn=>{var{visible:Go,afterClose:Xn}=Gn,Yo=__rest$I(Gn,["visible","afterClose"]);return createVNode(Child,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:In},zn),Yo),{},{rootClassName:Fn,rootStyle:Bn,open:Go!==void 0?Go:$n.open,afterVisibleChange:Xn!==void 0?Xn:$n.afterVisibleChange,onClose:Rn,onHandleClick:Nn}),Pn)}})),Wn}}}),Drawer$1=DrawerWrapper,genMotionStyle$2=$n=>{const{componentCls:Cn,motionDurationSlow:_n}=$n,Pn={"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${_n}`}}};return{[Cn]:{[`${Cn}-mask-motion`]:{"&-enter, &-appear, &-leave":{"&-active":{transition:`all ${_n}`}},"&-enter, &-appear":{opacity:0,"&-active":{opacity:1}},"&-leave":{opacity:1,"&-active":{opacity:0}}},[`${Cn}-panel-motion`]:{"&-left":[Pn,{"&-enter, &-appear":{"&-start":{transform:"translateX(-100%) !important"},"&-active":{transform:"translateX(0)"}},"&-leave":{transform:"translateX(0)","&-active":{transform:"translateX(-100%)"}}}],"&-right":[Pn,{"&-enter, &-appear":{"&-start":{transform:"translateX(100%) !important"},"&-active":{transform:"translateX(0)"}},"&-leave":{transform:"translateX(0)","&-active":{transform:"translateX(100%)"}}}],"&-top":[Pn,{"&-enter, &-appear":{"&-start":{transform:"translateY(-100%) !important"},"&-active":{transform:"translateY(0)"}},"&-leave":{transform:"translateY(0)","&-active":{transform:"translateY(-100%)"}}}],"&-bottom":[Pn,{"&-enter, &-appear":{"&-start":{transform:"translateY(100%) !important"},"&-active":{transform:"translateY(0)"}},"&-leave":{transform:"translateY(0)","&-active":{transform:"translateY(100%)"}}}]}}}},genMotionStyle$3=genMotionStyle$2,genDrawerStyle=$n=>{const{componentCls:Cn,zIndexPopup:_n,colorBgMask:Pn,colorBgElevated:In,motionDurationSlow:Nn,motionDurationMid:Rn,padding:Dn,paddingLG:Ln,fontSizeLG:Fn,lineHeightLG:Bn,lineWidth:Hn,lineType:zn,colorSplit:Wn,marginSM:Yn,colorIcon:Gn,colorIconHover:Go,colorText:Xn,fontWeightStrong:Yo,drawerFooterPaddingVertical:qo,drawerFooterPaddingHorizontal:Jo}=$n,Zo=`${Cn}-content-wrapper`;return{[Cn]:{position:"fixed",inset:0,zIndex:_n,pointerEvents:"none","&-pure":{position:"relative",background:In,[`&${Cn}-left`]:{boxShadow:$n.boxShadowDrawerLeft},[`&${Cn}-right`]:{boxShadow:$n.boxShadowDrawerRight},[`&${Cn}-top`]:{boxShadow:$n.boxShadowDrawerUp},[`&${Cn}-bottom`]:{boxShadow:$n.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${Cn}-mask`]:{position:"absolute",inset:0,zIndex:_n,background:Pn,pointerEvents:"auto"},[Zo]:{position:"absolute",zIndex:_n,transition:`all ${Nn}`,"&-hidden":{display:"none"}},[`&-left > ${Zo}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:$n.boxShadowDrawerLeft},[`&-right > ${Zo}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:$n.boxShadowDrawerRight},[`&-top > ${Zo}`]:{top:0,insetInline:0,boxShadow:$n.boxShadowDrawerUp},[`&-bottom > ${Zo}`]:{bottom:0,insetInline:0,boxShadow:$n.boxShadowDrawerDown},[`${Cn}-content`]:{width:"100%",height:"100%",overflow:"auto",background:In,pointerEvents:"auto"},[`${Cn}-wrapper-body`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%"},[`${Cn}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${Dn}px ${Ln}px`,fontSize:Fn,lineHeight:Bn,borderBottom:`${Hn}px ${zn} ${Wn}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${Cn}-extra`]:{flex:"none"},[`${Cn}-close`]:{display:"inline-block",marginInlineEnd:Yn,color:Gn,fontWeight:Yo,fontSize:Fn,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,outline:0,cursor:"pointer",transition:`color ${Rn}`,textRendering:"auto","&:focus, &:hover":{color:Go,textDecoration:"none"}},[`${Cn}-title`]:{flex:1,margin:0,color:Xn,fontWeight:$n.fontWeightStrong,fontSize:Fn,lineHeight:Bn},[`${Cn}-body`]:{flex:1,minWidth:0,minHeight:0,padding:Ln,overflow:"auto"},[`${Cn}-footer`]:{flexShrink:0,padding:`${qo}px ${Jo}px`,borderTop:`${Hn}px ${zn} ${Wn}`},"&-rtl":{direction:"rtl"}}}},useStyle$s=genComponentStyleHook("Drawer",$n=>{const Cn=merge$1($n,{drawerFooterPaddingVertical:$n.paddingXS,drawerFooterPaddingHorizontal:$n.padding});return[genDrawerStyle(Cn),genMotionStyle$3(Cn)]},$n=>({zIndexPopup:$n.zIndexPopupBase}));var __rest$H=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({autofocus:{type:Boolean,default:void 0},closable:{type:Boolean,default:void 0},closeIcon:PropTypes.any,destroyOnClose:{type:Boolean,default:void 0},forceRender:{type:Boolean,default:void 0},getContainer:{type:[String,Function,Boolean,Object],default:void 0},maskClosable:{type:Boolean,default:void 0},mask:{type:Boolean,default:void 0},maskStyle:objectType(),rootClassName:String,rootStyle:objectType(),size:{type:String},drawerStyle:objectType(),headerStyle:objectType(),bodyStyle:objectType(),contentWrapperStyle:{type:Object,default:void 0},title:PropTypes.any,visible:{type:Boolean,default:void 0},open:{type:Boolean,default:void 0},width:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),height:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),zIndex:Number,prefixCls:String,push:PropTypes.oneOfType([PropTypes.looseBool,{type:Object}]),placement:PropTypes.oneOf(PlacementTypes),keyboard:{type:Boolean,default:void 0},extra:PropTypes.any,footer:PropTypes.any,footerStyle:objectType(),level:PropTypes.any,levelMove:{type:[Number,Array,Function]},handle:PropTypes.any,afterVisibleChange:Function,onAfterVisibleChange:Function,onAfterOpenChange:Function,"onUpdate:visible":Function,"onUpdate:open":Function,onClose:Function}),Drawer=defineComponent({compatConfig:{MODE:3},name:"ADrawer",inheritAttrs:!1,props:initDefaultProps(drawerProps(),{closable:!0,placement:"right",maskClosable:!0,mask:!0,level:null,keyboard:!0,push:defaultPushState}),slots:Object,setup($n,Cn){let{emit:_n,slots:Pn,attrs:In}=Cn;const Nn=shallowRef(!1),Rn=shallowRef(!1),Dn=shallowRef(null),Ln=shallowRef(!1),Fn=shallowRef(!1),Bn=computed(()=>{var fa;return(fa=$n.open)!==null&&fa!==void 0?fa:$n.visible});watch(Bn,()=>{Bn.value?Ln.value=!0:Fn.value=!1},{immediate:!0}),watch([Bn,Ln],()=>{Bn.value&&Ln.value&&(Fn.value=!0)},{immediate:!0});const Hn=inject("parentDrawerOpts",null),{prefixCls:zn,getPopupContainer:Wn,direction:Yn}=useConfigInject("drawer",$n),[Gn,Go]=useStyle$s(zn),Xn=computed(()=>$n.getContainer===void 0&&(Wn!=null&&Wn.value)?()=>Wn.value(document.body):$n.getContainer);devWarning(!$n.afterVisibleChange,"Drawer","`afterVisibleChange` prop is deprecated, please use `@afterVisibleChange` event instead"),provide("parentDrawerOpts",{setPush:()=>{Nn.value=!0},setPull:()=>{Nn.value=!1,nextTick(()=>{Jo()})}}),onMounted(()=>{Bn.value&&Hn&&Hn.setPush()}),onUnmounted(()=>{Hn&&Hn.setPull()}),watch(Fn,()=>{Hn&&(Fn.value?Hn.setPush():Hn.setPull())},{flush:"post"});const Jo=()=>{var fa,ma;(ma=(fa=Dn.value)===null||fa===void 0?void 0:fa.domFocus)===null||ma===void 0||ma.call(fa)},Zo=fa=>{_n("update:visible",!1),_n("update:open",!1),_n("close",fa)},rr=fa=>{var ma;fa||(Rn.value===!1&&(Rn.value=!0),$n.destroyOnClose&&(Ln.value=!1)),(ma=$n.afterVisibleChange)===null||ma===void 0||ma.call($n,fa),_n("afterVisibleChange",fa),_n("afterOpenChange",fa)},nr=computed(()=>{const{push:fa,placement:ma}=$n;let ya;return typeof fa=="boolean"?ya=fa?defaultPushState.distance:0:ya=fa.distance,ya=parseFloat(String(ya||0)),ma==="left"||ma==="right"?`translateX(${ma==="left"?ya:-ya}px)`:ma==="top"||ma==="bottom"?`translateY(${ma==="top"?ya:-ya}px)`:null}),ta=computed(()=>{var fa;return(fa=$n.width)!==null&&fa!==void 0?fa:$n.size==="large"?736:378}),oa=computed(()=>{var fa;return(fa=$n.height)!==null&&fa!==void 0?fa:$n.size==="large"?736:378}),ra=computed(()=>{const{mask:fa,placement:ma}=$n;if(!Fn.value&&!fa)return{};const ya={};return ma==="left"||ma==="right"?ya.width=isNumeric(ta.value)?`${ta.value}px`:ta.value:ya.height=isNumeric(oa.value)?`${oa.value}px`:oa.value,ya}),ea=computed(()=>{const{zIndex:fa,contentWrapperStyle:ma}=$n,ya=ra.value;return[{zIndex:fa,transform:Nn.value?nr.value:void 0},_extends$1({},ma),ya]}),la=fa=>{const{closable:ma,headerStyle:ya}=$n,ba=getPropsSlot(Pn,$n,"extra"),Ia=getPropsSlot(Pn,$n,"title");return!Ia&&!ma?null:createVNode("div",{class:classNames(`${fa}-header`,{[`${fa}-header-close-only`]:ma&&!Ia&&!ba}),style:ya},[createVNode("div",{class:`${fa}-header-title`},[ua(fa),Ia&&createVNode("div",{class:`${fa}-title`},[Ia])]),ba&&createVNode("div",{class:`${fa}-extra`},[ba])])},ua=fa=>{var ma;const{closable:ya}=$n,ba=Pn.closeIcon?(ma=Pn.closeIcon)===null||ma===void 0?void 0:ma.call(Pn):$n.closeIcon;return ya&&createVNode("button",{key:"closer",onClick:Zo,"aria-label":"Close",class:`${fa}-close`},[ba===void 0?createVNode(CloseOutlined$1,null,null):ba])},ga=fa=>{var ma;if(Rn.value&&!$n.forceRender&&!Ln.value)return null;const{bodyStyle:ya,drawerStyle:ba}=$n;return createVNode("div",{class:`${fa}-wrapper-body`,style:ba},[la(fa),createVNode("div",{key:"body",class:`${fa}-body`,style:ya},[(ma=Pn.default)===null||ma===void 0?void 0:ma.call(Pn)]),aa(fa)])},aa=fa=>{const ma=getPropsSlot(Pn,$n,"footer");if(!ma)return null;const ya=`${fa}-footer`;return createVNode("div",{class:ya,style:$n.footerStyle},[ma])},ca=computed(()=>classNames({"no-mask":!$n.mask,[`${zn.value}-rtl`]:Yn.value==="rtl"},$n.rootClassName,Go.value)),sa=computed(()=>getTransitionProps(getTransitionName$1(zn.value,"mask-motion"))),ia=fa=>getTransitionProps(getTransitionName$1(zn.value,`panel-motion-${fa}`));return()=>{const{width:fa,height:ma,placement:ya,mask:ba,forceRender:Ia}=$n,Ea=__rest$H($n,["width","height","placement","mask","forceRender"]),xa=_extends$1(_extends$1(_extends$1({},In),omit$1(Ea,["size","closeIcon","closable","destroyOnClose","drawerStyle","headerStyle","bodyStyle","title","push","onAfterVisibleChange","onClose","onUpdate:visible","onUpdate:open","visible"])),{forceRender:Ia,onClose:Zo,afterVisibleChange:rr,handler:!1,prefixCls:zn.value,open:Fn.value,showMask:ba,placement:ya,ref:Dn});return Gn(createVNode(NoCompactStyle,null,{default:()=>[createVNode(Drawer$1,_objectSpread2$1(_objectSpread2$1({},xa),{},{maskMotion:sa.value,motion:ia,width:ta.value,height:oa.value,getContainer:Xn.value,rootClassName:ca.value,rootStyle:$n.rootStyle,contentWrapperStyle:ea.value}),{handler:$n.handle?()=>$n.handle:Pn.handle,default:()=>ga(zn.value)})]}))}}}),index$k=withInstall(Drawer);var FileTextOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"}}]},name:"file-text",theme:"outlined"};const FileTextOutlinedSvg=FileTextOutlined$2;function _objectSpread$y($n){for(var Cn=1;Cn({prefixCls:String,description:PropTypes.any,type:stringType("default"),shape:stringType("circle"),tooltip:PropTypes.any,href:String,target:functionType(),badge:objectType(),onClick:functionType()}),floatButtonContentProps=()=>({prefixCls:stringType()}),floatButtonGroupProps=()=>_extends$1(_extends$1({},floatButtonProps()),{trigger:stringType(),open:booleanType(),onOpenChange:functionType(),"onUpdate:open":functionType()}),backTopProps=()=>_extends$1(_extends$1({},floatButtonProps()),{prefixCls:String,duration:Number,target:functionType(),visibilityHeight:Number,onClick:functionType()}),FloatButtonContent=defineComponent({compatConfig:{MODE:3},name:"AFloatButtonContent",inheritAttrs:!1,props:floatButtonContentProps(),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;return()=>{var In;const{prefixCls:Nn}=$n,Rn=filterEmpty((In=Pn.description)===null||In===void 0?void 0:In.call(Pn));return createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{class:[_n.class,`${Nn}-content`]}),[Pn.icon||Rn.length?createVNode(Fragment,null,[Pn.icon&&createVNode("div",{class:`${Nn}-icon`},[Pn.icon()]),Rn.length?createVNode("div",{class:`${Nn}-description`},[Rn]):null]):createVNode("div",{class:`${Nn}-icon`},[createVNode(FileTextOutlined$1,null,null)])])}}}),Content$2=FloatButtonContent,contextKey=Symbol("floatButtonGroupContext"),useProvideFloatButtonGroupContext=$n=>(provide(contextKey,$n),$n),useInjectFloatButtonGroupContext=()=>inject(contextKey,{shape:ref()}),getOffset$1=$n=>$n===0?0:$n-Math.sqrt(Math.pow($n,2)/2),initFloatButtonGroupMotion=$n=>{const{componentCls:Cn,floatButtonSize:_n,motionDurationSlow:Pn,motionEaseInOutCirc:In}=$n,Nn=`${Cn}-group`,Rn=new Keyframes("antFloatButtonMoveDownIn",{"0%":{transform:`translate3d(0, ${_n}px, 0)`,transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),Dn=new Keyframes("antFloatButtonMoveDownOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:`translate3d(0, ${_n}px, 0)`,transformOrigin:"0 0",opacity:0}});return[{[`${Nn}-wrap`]:_extends$1({},initMotion(`${Nn}-wrap`,Rn,Dn,Pn,!0))},{[`${Nn}-wrap`]:{[` - &${Nn}-wrap-enter, - &${Nn}-wrap-appear - `]:{opacity:0,animationTimingFunction:In},[`&${Nn}-wrap-leave`]:{animationTimingFunction:In}}}]},floatButtonGroupStyle=$n=>{const{antCls:Cn,componentCls:_n,floatButtonSize:Pn,margin:In,borderRadiusLG:Nn,borderRadiusSM:Rn,badgeOffset:Dn,floatButtonBodyPadding:Ln}=$n,Fn=`${_n}-group`;return{[Fn]:_extends$1(_extends$1({},resetComponent($n)),{zIndex:99,display:"block",border:"none",position:"fixed",width:Pn,height:"auto",boxShadow:"none",minHeight:Pn,insetInlineEnd:$n.floatButtonInsetInlineEnd,insetBlockEnd:$n.floatButtonInsetBlockEnd,borderRadius:Nn,[`${Fn}-wrap`]:{zIndex:-1,display:"block",position:"relative",marginBottom:In},[`&${Fn}-rtl`]:{direction:"rtl"},[_n]:{position:"static"}}),[`${Fn}-circle`]:{[`${_n}-circle:not(:last-child)`]:{marginBottom:$n.margin,[`${_n}-body`]:{width:Pn,height:Pn,borderRadius:"50%"}}},[`${Fn}-square`]:{[`${_n}-square`]:{borderRadius:0,padding:0,"&:first-child":{borderStartStartRadius:Nn,borderStartEndRadius:Nn},"&:last-child":{borderEndStartRadius:Nn,borderEndEndRadius:Nn},"&:not(:last-child)":{borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},[`${Cn}-badge`]:{[`${Cn}-badge-count`]:{top:-(Ln+Dn),insetInlineEnd:-(Ln+Dn)}}},[`${Fn}-wrap`]:{display:"block",borderRadius:Nn,boxShadow:$n.boxShadowSecondary,[`${_n}-square`]:{boxShadow:"none",marginTop:0,borderRadius:0,padding:Ln,"&:first-child":{borderStartStartRadius:Nn,borderStartEndRadius:Nn},"&:last-child":{borderEndStartRadius:Nn,borderEndEndRadius:Nn},"&:not(:last-child)":{borderBottom:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},[`${_n}-body`]:{width:$n.floatButtonBodySize,height:$n.floatButtonBodySize}}}},[`${Fn}-circle-shadow`]:{boxShadow:"none"},[`${Fn}-square-shadow`]:{boxShadow:$n.boxShadowSecondary,[`${_n}-square`]:{boxShadow:"none",padding:Ln,[`${_n}-body`]:{width:$n.floatButtonBodySize,height:$n.floatButtonBodySize,borderRadius:Rn}}}}},sharedFloatButtonStyle=$n=>{const{antCls:Cn,componentCls:_n,floatButtonBodyPadding:Pn,floatButtonIconSize:In,floatButtonSize:Nn,borderRadiusLG:Rn,badgeOffset:Dn,dotOffsetInSquare:Ln,dotOffsetInCircle:Fn}=$n;return{[_n]:_extends$1(_extends$1({},resetComponent($n)),{border:"none",position:"fixed",cursor:"pointer",zIndex:99,display:"block",justifyContent:"center",alignItems:"center",width:Nn,height:Nn,insetInlineEnd:$n.floatButtonInsetInlineEnd,insetBlockEnd:$n.floatButtonInsetBlockEnd,boxShadow:$n.boxShadowSecondary,"&-pure":{position:"relative",inset:"auto"},"&:empty":{display:"none"},[`${Cn}-badge`]:{width:"100%",height:"100%",[`${Cn}-badge-count`]:{transform:"translate(0, 0)",transformOrigin:"center",top:-Dn,insetInlineEnd:-Dn}},[`${_n}-body`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center",transition:`all ${$n.motionDurationMid}`,[`${_n}-content`]:{overflow:"hidden",textAlign:"center",minHeight:Nn,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",padding:`${Pn/2}px ${Pn}px`,[`${_n}-icon`]:{textAlign:"center",margin:"auto",width:In,fontSize:In,lineHeight:1}}}}),[`${_n}-rtl`]:{direction:"rtl"},[`${_n}-circle`]:{height:Nn,borderRadius:"50%",[`${Cn}-badge`]:{[`${Cn}-badge-dot`]:{top:Fn,insetInlineEnd:Fn}},[`${_n}-body`]:{borderRadius:"50%"}},[`${_n}-square`]:{height:"auto",minHeight:Nn,borderRadius:Rn,[`${Cn}-badge`]:{[`${Cn}-badge-dot`]:{top:Ln,insetInlineEnd:Ln}},[`${_n}-body`]:{height:"auto",borderRadius:Rn}},[`${_n}-default`]:{backgroundColor:$n.floatButtonBackgroundColor,transition:`background-color ${$n.motionDurationMid}`,[`${_n}-body`]:{backgroundColor:$n.floatButtonBackgroundColor,transition:`background-color ${$n.motionDurationMid}`,"&:hover":{backgroundColor:$n.colorFillContent},[`${_n}-content`]:{[`${_n}-icon`]:{color:$n.colorText},[`${_n}-description`]:{display:"flex",alignItems:"center",lineHeight:`${$n.fontSizeLG}px`,color:$n.colorText,fontSize:$n.fontSizeSM}}}},[`${_n}-primary`]:{backgroundColor:$n.colorPrimary,[`${_n}-body`]:{backgroundColor:$n.colorPrimary,transition:`background-color ${$n.motionDurationMid}`,"&:hover":{backgroundColor:$n.colorPrimaryHover},[`${_n}-content`]:{[`${_n}-icon`]:{color:$n.colorTextLightSolid},[`${_n}-description`]:{display:"flex",alignItems:"center",lineHeight:`${$n.fontSizeLG}px`,color:$n.colorTextLightSolid,fontSize:$n.fontSizeSM}}}}}},useStyle$r=genComponentStyleHook("FloatButton",$n=>{const{colorTextLightSolid:Cn,colorBgElevated:_n,controlHeightLG:Pn,marginXXL:In,marginLG:Nn,fontSize:Rn,fontSizeIcon:Dn,controlItemBgHover:Ln,paddingXXS:Fn,borderRadiusLG:Bn}=$n,Hn=merge$1($n,{floatButtonBackgroundColor:_n,floatButtonColor:Cn,floatButtonHoverBackgroundColor:Ln,floatButtonFontSize:Rn,floatButtonIconSize:Dn*1.5,floatButtonSize:Pn,floatButtonInsetBlockEnd:In,floatButtonInsetInlineEnd:Nn,floatButtonBodySize:Pn-Fn*2,floatButtonBodyPadding:Fn,badgeOffset:Fn*1.5,dotOffsetInCircle:getOffset$1(Pn/2),dotOffsetInSquare:getOffset$1(Bn)});return[floatButtonGroupStyle(Hn),sharedFloatButtonStyle(Hn),initFadeMotion($n),initFloatButtonGroupMotion(Hn)]});var __rest$G=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In(Ln==null?void 0:Ln.value)||$n.shape);return()=>{var Hn;const{prefixCls:zn,type:Wn="default",shape:Yn="circle",description:Gn=(Hn=Pn.description)===null||Hn===void 0?void 0:Hn.call(Pn),tooltip:Go,badge:Xn={}}=$n,Yo=__rest$G($n,["prefixCls","type","shape","description","tooltip","badge"]),qo=classNames(In.value,`${In.value}-${Wn}`,`${In.value}-${Bn.value}`,{[`${In.value}-rtl`]:Nn.value==="rtl"},_n.class,Dn.value),Jo=createVNode(Tooltip,{placement:"left"},{title:Pn.tooltip||Go?()=>Pn.tooltip&&Pn.tooltip()||Go:void 0,default:()=>createVNode(Badge,Xn,{default:()=>[createVNode("div",{class:`${In.value}-body`},[createVNode(Content$2,{prefixCls:In.value},{icon:Pn.icon,description:()=>Gn})])]})});return Rn($n.href?createVNode("a",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Fn},_n),Yo),{},{class:qo}),[Jo]):createVNode("button",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Fn},_n),Yo),{},{class:qo,type:"button"}),[Jo]))}}}),FloatButton$1=FloatButton,FloatButtonGroup=defineComponent({compatConfig:{MODE:3},name:"AFloatButtonGroup",inheritAttrs:!1,props:initDefaultProps(floatButtonGroupProps(),{type:"default",shape:"circle"}),setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const{prefixCls:Nn,direction:Rn}=useConfigInject(floatButtonPrefixCls,$n),[Dn,Ln]=useStyle$r(Nn),[Fn,Bn]=useMergedState(!1,{value:computed(()=>$n.open)}),Hn=ref(null),zn=ref(null);useProvideFloatButtonGroupContext({shape:computed(()=>$n.shape)});const Wn={onMouseenter(){var Xn;Bn(!0),In("update:open",!0),(Xn=$n.onOpenChange)===null||Xn===void 0||Xn.call($n,!0)},onMouseleave(){var Xn;Bn(!1),In("update:open",!1),(Xn=$n.onOpenChange)===null||Xn===void 0||Xn.call($n,!1)}},Yn=computed(()=>$n.trigger==="hover"?Wn:{}),Gn=()=>{var Xn;const Yo=!Fn.value;In("update:open",Yo),(Xn=$n.onOpenChange)===null||Xn===void 0||Xn.call($n,Yo),Bn(Yo)},Go=Xn=>{var Yo,qo,Jo;if(!((Yo=Hn.value)===null||Yo===void 0)&&Yo.contains(Xn.target)){!((qo=findDOMNode(zn.value))===null||qo===void 0)&&qo.contains(Xn.target)&&Gn();return}Bn(!1),In("update:open",!1),(Jo=$n.onOpenChange)===null||Jo===void 0||Jo.call($n,!1)};return watch(computed(()=>$n.trigger),Xn=>{canUseDom$1()&&(document.removeEventListener("click",Go),Xn==="click"&&document.addEventListener("click",Go))},{immediate:!0}),onBeforeUnmount(()=>{document.removeEventListener("click",Go)}),()=>{var Xn;const{shape:Yo="circle",type:qo="default",tooltip:Jo,description:Zo,trigger:rr}=$n,nr=`${Nn.value}-group`,ta=classNames(nr,Ln.value,_n.class,{[`${nr}-rtl`]:Rn.value==="rtl",[`${nr}-${Yo}`]:Yo,[`${nr}-${Yo}-shadow`]:!rr}),oa=classNames(Ln.value,`${nr}-wrap`),ra=getTransitionProps(`${nr}-wrap`);return Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({ref:Hn},_n),{},{class:ta},Yn.value),[rr&&["click","hover"].includes(rr)?createVNode(Fragment,null,[createVNode(Transition,ra,{default:()=>[withDirectives(createVNode("div",{class:oa},[Pn.default&&Pn.default()]),[[vShow,Fn.value]])]}),createVNode(FloatButton$1,{ref:zn,type:qo,shape:Yo,tooltip:Jo,description:Zo},{icon:()=>{var ea,la;return Fn.value?((ea=Pn.closeIcon)===null||ea===void 0?void 0:ea.call(Pn))||createVNode(CloseOutlined$1,null,null):((la=Pn.icon)===null||la===void 0?void 0:la.call(Pn))||createVNode(FileTextOutlined$1,null,null)},tooltip:Pn.tooltip,description:Pn.description})]):(Xn=Pn.default)===null||Xn===void 0?void 0:Xn.call(Pn)]))}}}),FloatButtonGroup$1=FloatButtonGroup;var VerticalAlignTopOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M859.9 168H164.1c-4.5 0-8.1 3.6-8.1 8v60c0 4.4 3.6 8 8.1 8h695.8c4.5 0 8.1-3.6 8.1-8v-60c0-4.4-3.6-8-8.1-8zM518.3 355a8 8 0 00-12.6 0l-112 141.7a7.98 7.98 0 006.3 12.9h73.9V848c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V509.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 355z"}}]},name:"vertical-align-top",theme:"outlined"};const VerticalAlignTopOutlinedSvg=VerticalAlignTopOutlined$2;function _objectSpread$x($n){for(var Cn=1;Cnwindow,duration:450,type:"default",shape:"circle"}),setup($n,Cn){let{slots:_n,attrs:Pn,emit:In}=Cn;const{prefixCls:Nn,direction:Rn}=useConfigInject(floatButtonPrefixCls,$n),[Dn]=useStyle$r(Nn),Ln=ref(),Fn=reactive({visible:$n.visibilityHeight===0,scrollEvent:null}),Bn=()=>Ln.value&&Ln.value.ownerDocument?Ln.value.ownerDocument:window,Hn=Go=>{const{target:Xn=Bn,duration:Yo}=$n;scrollTo$1(0,{getContainer:Xn,duration:Yo}),In("click",Go)},zn=throttleByAnimationFrame(Go=>{const{visibilityHeight:Xn}=$n,Yo=getScroll$3(Go.target,!0);Fn.visible=Yo>=Xn}),Wn=()=>{const{target:Go}=$n,Yo=(Go||Bn)();zn({target:Yo}),Yo==null||Yo.addEventListener("scroll",zn)},Yn=()=>{const{target:Go}=$n,Yo=(Go||Bn)();zn.cancel(),Yo==null||Yo.removeEventListener("scroll",zn)};watch(()=>$n.target,()=>{Yn(),nextTick(()=>{Wn()})}),onMounted(()=>{nextTick(()=>{Wn()})}),onActivated(()=>{nextTick(()=>{Wn()})}),onDeactivated(()=>{Yn()}),onBeforeUnmount(()=>{Yn()});const Gn=useInjectFloatButtonGroupContext();return()=>{const{description:Go,type:Xn,shape:Yo,tooltip:qo,badge:Jo}=$n,Zo=_extends$1(_extends$1({},Pn),{shape:(Gn==null?void 0:Gn.shape.value)||Yo,onClick:Hn,class:{[`${Nn.value}`]:!0,[`${Pn.class}`]:Pn.class,[`${Nn.value}-rtl`]:Rn.value==="rtl"},description:Go,type:Xn,tooltip:qo,badge:Jo}),rr=getTransitionProps("fade");return Dn(createVNode(Transition,rr,{default:()=>[withDirectives(createVNode(FloatButton$1,_objectSpread2$1(_objectSpread2$1({},Zo),{},{ref:Ln}),{icon:()=>{var nr;return((nr=_n.icon)===null||nr===void 0?void 0:nr.call(_n))||createVNode(VerticalAlignTopOutlined$1,null,null)}}),[[vShow,Fn.visible]])]}))}}}),BackTop$1=BackTop;FloatButton$1.Group=FloatButtonGroup$1;FloatButton$1.BackTop=BackTop$1;FloatButton$1.install=function($n){return $n.component(FloatButton$1.name,FloatButton$1),$n.component(FloatButtonGroup$1.name,FloatButtonGroup$1),$n.component(BackTop$1.name,BackTop$1),$n};const isValid$1=$n=>$n!=null&&(Array.isArray($n)?filterEmpty($n).length:!0);function hasPrefixSuffix($n){return isValid$1($n.prefix)||isValid$1($n.suffix)||isValid$1($n.allowClear)}function hasAddon$1($n){return isValid$1($n.addonBefore)||isValid$1($n.addonAfter)}function fixControlledValue($n){return typeof $n>"u"||$n===null?"":String($n)}function resolveOnChange($n,Cn,_n,Pn){if(!_n)return;const In=Cn;if(Cn.type==="click"){Object.defineProperty(In,"target",{writable:!0}),Object.defineProperty(In,"currentTarget",{writable:!0});const Nn=$n.cloneNode(!0);In.target=Nn,In.currentTarget=Nn,Nn.value="",_n(In);return}if(Pn!==void 0){Object.defineProperty(In,"target",{writable:!0}),Object.defineProperty(In,"currentTarget",{writable:!0}),In.target=$n,In.currentTarget=$n,$n.value=Pn,_n(In);return}_n(In)}function triggerFocus($n,Cn){if(!$n)return;$n.focus(Cn);const{cursor:_n}=Cn||{};if(_n){const Pn=$n.value.length;switch(_n){case"start":$n.setSelectionRange(0,0);break;case"end":$n.setSelectionRange(Pn,Pn);break;default:$n.setSelectionRange(0,Pn)}}}const commonInputProps=()=>({addonBefore:PropTypes.any,addonAfter:PropTypes.any,prefix:PropTypes.any,suffix:PropTypes.any,clearIcon:PropTypes.any,affixWrapperClassName:String,groupClassName:String,wrapperClassName:String,inputClassName:String,allowClear:{type:Boolean,default:void 0}}),baseInputProps=()=>_extends$1(_extends$1({},commonInputProps()),{value:{type:[String,Number,Symbol],default:void 0},defaultValue:{type:[String,Number,Symbol],default:void 0},inputElement:PropTypes.any,prefixCls:String,disabled:{type:Boolean,default:void 0},focused:{type:Boolean,default:void 0},triggerFocus:Function,readonly:{type:Boolean,default:void 0},handleReset:Function,hidden:{type:Boolean,default:void 0}}),inputProps$1=()=>_extends$1(_extends$1({},baseInputProps()),{id:String,placeholder:{type:[String,Number]},autocomplete:String,type:stringType("text"),name:String,size:{type:String},autofocus:{type:Boolean,default:void 0},lazy:{type:Boolean,default:!0},maxlength:Number,loading:{type:Boolean,default:void 0},bordered:{type:Boolean,default:void 0},showCount:{type:[Boolean,Object]},htmlSize:Number,onPressEnter:Function,onKeydown:Function,onKeyup:Function,onFocus:Function,onBlur:Function,onChange:Function,onInput:Function,"onUpdate:value":Function,onCompositionstart:Function,onCompositionend:Function,valueModifiers:Object,hidden:{type:Boolean,default:void 0},status:String}),BaseInput=defineComponent({name:"BaseInput",inheritAttrs:!1,props:baseInputProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=ref(),Nn=Dn=>{var Ln;if(!((Ln=In.value)===null||Ln===void 0)&&Ln.contains(Dn.target)){const{triggerFocus:Fn}=$n;Fn==null||Fn()}},Rn=()=>{var Dn;const{allowClear:Ln,value:Fn,disabled:Bn,readonly:Hn,handleReset:zn,suffix:Wn=_n.suffix,prefixCls:Yn}=$n;if(!Ln)return null;const Gn=!Bn&&!Hn&&Fn,Go=`${Yn}-clear-icon`,Xn=((Dn=_n.clearIcon)===null||Dn===void 0?void 0:Dn.call(_n))||"*";return createVNode("span",{onClick:zn,onMousedown:Yo=>Yo.preventDefault(),class:classNames({[`${Go}-hidden`]:!Gn,[`${Go}-has-suffix`]:!!Wn},Go),role:"button",tabindex:-1},[Xn])};return()=>{var Dn,Ln;const{focused:Fn,value:Bn,disabled:Hn,allowClear:zn,readonly:Wn,hidden:Yn,prefixCls:Gn,prefix:Go=(Dn=_n.prefix)===null||Dn===void 0?void 0:Dn.call(_n),suffix:Xn=(Ln=_n.suffix)===null||Ln===void 0?void 0:Ln.call(_n),addonAfter:Yo=_n.addonAfter,addonBefore:qo=_n.addonBefore,inputElement:Jo,affixWrapperClassName:Zo,wrapperClassName:rr,groupClassName:nr}=$n;let ta=cloneElement(Jo,{value:Bn,hidden:Yn});if(hasPrefixSuffix({prefix:Go,suffix:Xn,allowClear:zn})){const oa=`${Gn}-affix-wrapper`,ra=classNames(oa,{[`${oa}-disabled`]:Hn,[`${oa}-focused`]:Fn,[`${oa}-readonly`]:Wn,[`${oa}-input-with-clear-btn`]:Xn&&zn&&Bn},!hasAddon$1({addonAfter:Yo,addonBefore:qo})&&Pn.class,Zo),ea=(Xn||zn)&&createVNode("span",{class:`${Gn}-suffix`},[Rn(),Xn]);ta=createVNode("span",{class:ra,style:Pn.style,hidden:!hasAddon$1({addonAfter:Yo,addonBefore:qo})&&Yn,onMousedown:Nn,ref:In},[Go&&createVNode("span",{class:`${Gn}-prefix`},[Go]),cloneElement(Jo,{style:null,value:Bn,hidden:null}),ea])}if(hasAddon$1({addonAfter:Yo,addonBefore:qo})){const oa=`${Gn}-group`,ra=`${oa}-addon`,ea=classNames(`${Gn}-wrapper`,oa,rr),la=classNames(`${Gn}-group-wrapper`,Pn.class,nr);return createVNode("span",{class:la,style:Pn.style,hidden:Yn},[createVNode("span",{class:ea},[qo&&createVNode("span",{class:ra},[qo]),cloneElement(ta,{style:null,hidden:null}),Yo&&createVNode("span",{class:ra},[Yo])])])}return ta}}});var __rest$F=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.value,()=>{Rn.value=$n.value}),watch(()=>$n.disabled,()=>{$n.disabled&&(Dn.value=!1)});const Bn=nr=>{Ln.value&&triggerFocus(Ln.value,nr)};In({focus:Bn,blur:()=>{var nr;(nr=Ln.value)===null||nr===void 0||nr.blur()},input:Ln,stateValue:Rn,setSelectionRange:(nr,ta,oa)=>{var ra;(ra=Ln.value)===null||ra===void 0||ra.setSelectionRange(nr,ta,oa)},select:()=>{var nr;(nr=Ln.value)===null||nr===void 0||nr.select()}});const Yn=nr=>{Nn("change",nr)},Gn=(nr,ta)=>{Rn.value!==nr&&($n.value===void 0?Rn.value=nr:nextTick(()=>{var oa;Ln.value.value!==Rn.value&&((oa=Fn.value)===null||oa===void 0||oa.$forceUpdate())}),nextTick(()=>{ta&&ta()}))},Go=nr=>{const{value:ta,composing:oa}=nr.target;if((nr.isComposing||oa)&&$n.lazy||Rn.value===ta)return;const ra=nr.target.value;resolveOnChange(Ln.value,nr,Yn),Gn(ra)},Xn=nr=>{nr.keyCode===13&&Nn("pressEnter",nr),Nn("keydown",nr)},Yo=nr=>{Dn.value=!0,Nn("focus",nr)},qo=nr=>{Dn.value=!1,Nn("blur",nr)},Jo=nr=>{resolveOnChange(Ln.value,nr,Yn),Gn("",()=>{Bn()})},Zo=()=>{var nr,ta;const{addonBefore:oa=_n.addonBefore,addonAfter:ra=_n.addonAfter,disabled:ea,valueModifiers:la={},htmlSize:ua,autocomplete:ga,prefixCls:aa,inputClassName:ca,prefix:sa=(nr=_n.prefix)===null||nr===void 0?void 0:nr.call(_n),suffix:ia=(ta=_n.suffix)===null||ta===void 0?void 0:ta.call(_n),allowClear:fa,type:ma="text"}=$n,ya=omit$1($n,["prefixCls","onPressEnter","addonBefore","addonAfter","prefix","suffix","allowClear","defaultValue","size","bordered","htmlSize","lazy","showCount","valueModifiers","showCount","affixWrapperClassName","groupClassName","inputClassName","wrapperClassName"]),ba=_extends$1(_extends$1(_extends$1({},ya),Pn),{autocomplete:ga,onChange:Go,onInput:Go,onFocus:Yo,onBlur:qo,onKeydown:Xn,class:classNames(aa,{[`${aa}-disabled`]:ea},ca,!hasAddon$1({addonAfter:ra,addonBefore:oa})&&!hasPrefixSuffix({prefix:sa,suffix:ia,allowClear:fa})&&Pn.class),ref:Ln,key:"ant-input",size:ua,type:ma});la.lazy&&delete ba.onInput,ba.autofocus||delete ba.autofocus;const Ia=createVNode("input",omit$1(ba,["size"]),null);return withDirectives(Ia,[[antInputDirective]])},rr=()=>{var nr;const{maxlength:ta,suffix:oa=(nr=_n.suffix)===null||nr===void 0?void 0:nr.call(_n),showCount:ra,prefixCls:ea}=$n,la=Number(ta)>0;if(oa||ra){const ua=[...fixControlledValue(Rn.value)].length,ga=typeof ra=="object"?ra.formatter({count:ua,maxlength:ta}):`${ua}${la?` / ${ta}`:""}`;return createVNode(Fragment,null,[!!ra&&createVNode("span",{class:classNames(`${ea}-show-count-suffix`,{[`${ea}-show-count-has-suffix`]:!!oa})},[ga]),oa])}return null};return onMounted(()=>{}),()=>{const{prefixCls:nr,disabled:ta}=$n,oa=__rest$F($n,["prefixCls","disabled"]);return createVNode(BaseInput,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},oa),Pn),{},{ref:Fn,prefixCls:nr,inputElement:Zo(),handleReset:Jo,value:fixControlledValue(Rn.value),focused:Dn.value,triggerFocus:Bn,suffix:rr(),disabled:ta}),_n)}}}),inputProps=()=>omit$1(inputProps$1(),["wrapperClassName","groupClassName","inputClassName","affixWrapperClassName"]),textAreaProps=()=>_extends$1(_extends$1({},omit$1(inputProps(),["prefix","addonBefore","addonAfter","suffix"])),{rows:Number,autosize:{type:[Boolean,Object],default:void 0},autoSize:{type:[Boolean,Object],default:void 0},onResize:{type:Function},onCompositionstart:eventType(),onCompositionend:eventType(),valueModifiers:Object});var __rest$E=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);IngetMergedStatus(Ln.status,$n.status)),{direction:Bn,prefixCls:Hn,size:zn,autocomplete:Wn}=useConfigInject("input",$n),{compactSize:Yn,compactItemClassnames:Gn}=useCompactItemContext(Hn,Bn),Go=computed(()=>Yn.value||zn.value),[Xn,Yo]=useStyle$K(Hn),qo=useInjectDisabled();In({focus:ua=>{var ga;(ga=Rn.value)===null||ga===void 0||ga.focus(ua)},blur:()=>{var ua;(ua=Rn.value)===null||ua===void 0||ua.blur()},input:Rn,setSelectionRange:(ua,ga,aa)=>{var ca;(ca=Rn.value)===null||ca===void 0||ca.setSelectionRange(ua,ga,aa)},select:()=>{var ua;(ua=Rn.value)===null||ua===void 0||ua.select()}});const ta=ref([]),oa=()=>{ta.value.push(setTimeout(()=>{var ua,ga,aa,ca;!((ua=Rn.value)===null||ua===void 0)&&ua.input&&((ga=Rn.value)===null||ga===void 0?void 0:ga.input.getAttribute("type"))==="password"&&(!((aa=Rn.value)===null||aa===void 0)&&aa.input.hasAttribute("value"))&&((ca=Rn.value)===null||ca===void 0||ca.input.removeAttribute("value"))}))};onMounted(()=>{oa()}),onBeforeUpdate(()=>{ta.value.forEach(ua=>clearTimeout(ua))}),onBeforeUnmount(()=>{ta.value.forEach(ua=>clearTimeout(ua))});const ra=ua=>{oa(),Nn("blur",ua),Dn.onFieldBlur()},ea=ua=>{oa(),Nn("focus",ua)},la=ua=>{Nn("update:value",ua.target.value),Nn("change",ua),Nn("input",ua),Dn.onFieldChange()};return()=>{var ua,ga,aa,ca,sa,ia;const{hasFeedback:fa,feedbackIcon:ma}=Ln,{allowClear:ya,bordered:ba=!0,prefix:Ia=(ua=_n.prefix)===null||ua===void 0?void 0:ua.call(_n),suffix:Ea=(ga=_n.suffix)===null||ga===void 0?void 0:ga.call(_n),addonAfter:xa=(aa=_n.addonAfter)===null||aa===void 0?void 0:aa.call(_n),addonBefore:Ta=(ca=_n.addonBefore)===null||ca===void 0?void 0:ca.call(_n),id:wa=(sa=Dn.id)===null||sa===void 0?void 0:sa.value}=$n,La=__rest$E($n,["allowClear","bordered","prefix","suffix","addonAfter","addonBefore","id"]),Na=(fa||Ea)&&createVNode(Fragment,null,[Ea,fa&&ma]),$a=Hn.value,ka=hasPrefixSuffix({prefix:Ia,suffix:Ea})||!!fa,Ha=_n.clearIcon||(()=>createVNode(CloseCircleFilled$1,null,null));return Xn(createVNode(VcInput,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Pn),omit$1(La,["onUpdate:value","onChange","onInput"])),{},{onChange:la,id:wa,disabled:(ia=$n.disabled)!==null&&ia!==void 0?ia:qo.value,ref:Rn,prefixCls:$a,autocomplete:Wn.value,onBlur:ra,onFocus:ea,prefix:Ia,suffix:Na,allowClear:ya,addonAfter:xa&&createVNode(NoCompactStyle,null,{default:()=>[createVNode(NoFormStatus,null,{default:()=>[xa]})]}),addonBefore:Ta&&createVNode(NoCompactStyle,null,{default:()=>[createVNode(NoFormStatus,null,{default:()=>[Ta]})]}),class:[Pn.class,Gn.value],inputClassName:classNames({[`${$a}-sm`]:Go.value==="small",[`${$a}-lg`]:Go.value==="large",[`${$a}-rtl`]:Bn.value==="rtl",[`${$a}-borderless`]:!ba},!ka&&getStatusClassNames($a,Fn.value),Yo.value),affixWrapperClassName:classNames({[`${$a}-affix-wrapper-sm`]:Go.value==="small",[`${$a}-affix-wrapper-lg`]:Go.value==="large",[`${$a}-affix-wrapper-rtl`]:Bn.value==="rtl",[`${$a}-affix-wrapper-borderless`]:!ba},getStatusClassNames(`${$a}-affix-wrapper`,Fn.value,fa),Yo.value),wrapperClassName:classNames({[`${$a}-group-rtl`]:Bn.value==="rtl"},Yo.value),groupClassName:classNames({[`${$a}-group-wrapper-sm`]:Go.value==="small",[`${$a}-group-wrapper-lg`]:Go.value==="large",[`${$a}-group-wrapper-rtl`]:Bn.value==="rtl"},getStatusClassNames(`${$a}-group-wrapper`,Fn.value,fa),Yo.value)}),_extends$1(_extends$1({},_n),{clearIcon:Ha})))}}}),Group$1=defineComponent({compatConfig:{MODE:3},name:"AInputGroup",inheritAttrs:!1,props:{prefixCls:String,size:{type:String},compact:{type:Boolean,default:void 0}},setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn,getPrefixCls:Rn}=useConfigInject("input-group",$n),Dn=FormItemInputContext.useInject();FormItemInputContext.useProvide(Dn,{isFormItemInput:!1});const Ln=computed(()=>Rn("input")),[Fn,Bn]=useStyle$K(Ln),Hn=computed(()=>{const zn=In.value;return{[`${zn}`]:!0,[Bn.value]:!0,[`${zn}-lg`]:$n.size==="large",[`${zn}-sm`]:$n.size==="small",[`${zn}-compact`]:$n.compact,[`${zn}-rtl`]:Nn.value==="rtl"}});return()=>{var zn;return Fn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:classNames(Hn.value,Pn.class)}),[(zn=_n.default)===null||zn===void 0?void 0:zn.call(_n)]))}}});var __rest$D=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{var Zo;(Zo=Rn.value)===null||Zo===void 0||Zo.focus()},blur:()=>{var Zo;(Zo=Rn.value)===null||Zo===void 0||Zo.blur()}});const Bn=Zo=>{Nn("update:value",Zo.target.value),Zo&&Zo.target&&Zo.type==="click"&&Nn("search",Zo.target.value,Zo),Nn("change",Zo)},Hn=Zo=>{var rr;document.activeElement===((rr=Rn.value)===null||rr===void 0?void 0:rr.input)&&Zo.preventDefault()},zn=Zo=>{var rr,nr;Nn("search",(nr=(rr=Rn.value)===null||rr===void 0?void 0:rr.input)===null||nr===void 0?void 0:nr.stateValue,Zo)},Wn=Zo=>{Dn.value||$n.loading||zn(Zo)},Yn=Zo=>{Dn.value=!0,Nn("compositionstart",Zo)},Gn=Zo=>{Dn.value=!1,Nn("compositionend",Zo)},{prefixCls:Go,getPrefixCls:Xn,direction:Yo,size:qo}=useConfigInject("input-search",$n),Jo=computed(()=>Xn("input",$n.inputPrefixCls));return()=>{var Zo,rr,nr,ta;const{disabled:oa,loading:ra,addonAfter:ea=(Zo=_n.addonAfter)===null||Zo===void 0?void 0:Zo.call(_n),suffix:la=(rr=_n.suffix)===null||rr===void 0?void 0:rr.call(_n)}=$n,ua=__rest$D($n,["disabled","loading","addonAfter","suffix"]);let{enterButton:ga=(ta=(nr=_n.enterButton)===null||nr===void 0?void 0:nr.call(_n))!==null&&ta!==void 0?ta:!1}=$n;ga=ga||ga==="";const aa=typeof ga=="boolean"?createVNode(SearchOutlined$1,null,null):null,ca=`${Go.value}-button`,sa=Array.isArray(ga)?ga[0]:ga;let ia;const fa=sa.type&&isPlainObject$2(sa.type)&&sa.type.__ANT_BUTTON;if(fa||sa.tagName==="button")ia=cloneElement(sa,_extends$1({onMousedown:Hn,onClick:zn,key:"enterButton"},fa?{class:ca,size:qo.value}:{}),!1);else{const ya=aa&&!ga;ia=createVNode(Button$1,{class:ca,type:ga?"primary":void 0,size:qo.value,disabled:oa,key:"enterButton",onMousedown:Hn,onClick:zn,loading:ra,icon:ya?aa:null},{default:()=>[ya?null:aa||ga]})}ea&&(ia=[ia,ea]);const ma=classNames(Go.value,{[`${Go.value}-rtl`]:Yo.value==="rtl",[`${Go.value}-${qo.value}`]:!!qo.value,[`${Go.value}-with-button`]:!!ga},Pn.class);return createVNode(Input,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Rn},omit$1(ua,["onUpdate:value","onSearch","enterButton"])),Pn),{},{onPressEnter:Wn,onCompositionstart:Yn,onCompositionend:Gn,size:qo.value,prefixCls:Jo.value,addonAfter:ia,suffix:la,onChange:Bn,class:ma,disabled:oa}),_n)}}}),isValid=$n=>$n!=null&&(Array.isArray($n)?filterEmpty($n).length:!0);function hasAddon($n){return isValid($n.addonBefore)||isValid($n.addonAfter)}const ClearableInputType=["text","input"],ClearableLabeledInput=defineComponent({compatConfig:{MODE:3},name:"ClearableLabeledInput",inheritAttrs:!1,props:{prefixCls:String,inputType:PropTypes.oneOf(tuple$1("text","input")),value:anyType(),defaultValue:anyType(),allowClear:{type:Boolean,default:void 0},element:anyType(),handleReset:Function,disabled:{type:Boolean,default:void 0},direction:{type:String},size:{type:String},suffix:anyType(),prefix:anyType(),addonBefore:anyType(),addonAfter:anyType(),readonly:{type:Boolean,default:void 0},focused:{type:Boolean,default:void 0},bordered:{type:Boolean,default:!0},triggerFocus:{type:Function},hidden:Boolean,status:String,hashId:String},setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=FormItemInputContext.useInject(),Nn=Dn=>{const{value:Ln,disabled:Fn,readonly:Bn,handleReset:Hn,suffix:zn=_n.suffix}=$n,Wn=!Fn&&!Bn&&Ln,Yn=`${Dn}-clear-icon`;return createVNode(CloseCircleFilled$1,{onClick:Hn,onMousedown:Gn=>Gn.preventDefault(),class:classNames({[`${Yn}-hidden`]:!Wn,[`${Yn}-has-suffix`]:!!zn},Yn),role:"button"},null)},Rn=(Dn,Ln)=>{const{value:Fn,allowClear:Bn,direction:Hn,bordered:zn,hidden:Wn,status:Yn,addonAfter:Gn=_n.addonAfter,addonBefore:Go=_n.addonBefore,hashId:Xn}=$n,{status:Yo,hasFeedback:qo}=In;if(!Bn)return cloneElement(Ln,{value:Fn,disabled:$n.disabled});const Jo=classNames(`${Dn}-affix-wrapper`,`${Dn}-affix-wrapper-textarea-with-clear-btn`,getStatusClassNames(`${Dn}-affix-wrapper`,getMergedStatus(Yo,Yn),qo),{[`${Dn}-affix-wrapper-rtl`]:Hn==="rtl",[`${Dn}-affix-wrapper-borderless`]:!zn,[`${Pn.class}`]:!hasAddon({addonAfter:Gn,addonBefore:Go})&&Pn.class},Xn);return createVNode("span",{class:Jo,style:Pn.style,hidden:Wn},[cloneElement(Ln,{style:null,value:Fn,disabled:$n.disabled}),Nn(Dn)])};return()=>{var Dn;const{prefixCls:Ln,inputType:Fn,element:Bn=(Dn=_n.element)===null||Dn===void 0?void 0:Dn.call(_n)}=$n;return Fn===ClearableInputType[0]?Rn(Ln,Bn):null}}}),HIDDEN_TEXTAREA_STYLE=` - min-height:0 !important; - max-height:none !important; - height:0 !important; - visibility:hidden !important; - overflow:hidden !important; - position:absolute !important; - z-index:-1000 !important; - top:0 !important; - right:0 !important; - pointer-events: none !important; -`,SIZING_STYLE=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","font-variant","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing","word-break","white-space"],computedStyleCache={};let hiddenTextarea;function calculateNodeStyling($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const _n=$n.getAttribute("id")||$n.getAttribute("data-reactid")||$n.getAttribute("name");if(Cn&&computedStyleCache[_n])return computedStyleCache[_n];const Pn=window.getComputedStyle($n),In=Pn.getPropertyValue("box-sizing")||Pn.getPropertyValue("-moz-box-sizing")||Pn.getPropertyValue("-webkit-box-sizing"),Nn=parseFloat(Pn.getPropertyValue("padding-bottom"))+parseFloat(Pn.getPropertyValue("padding-top")),Rn=parseFloat(Pn.getPropertyValue("border-bottom-width"))+parseFloat(Pn.getPropertyValue("border-top-width")),Ln={sizingStyle:SIZING_STYLE.map(Fn=>`${Fn}:${Pn.getPropertyValue(Fn)}`).join(";"),paddingSize:Nn,borderSize:Rn,boxSizing:In};return Cn&&_n&&(computedStyleCache[_n]=Ln),Ln}function calculateAutoSizeStyle($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,_n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:null,Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:null;hiddenTextarea||(hiddenTextarea=document.createElement("textarea"),hiddenTextarea.setAttribute("tab-index","-1"),hiddenTextarea.setAttribute("aria-hidden","true"),document.body.appendChild(hiddenTextarea)),$n.getAttribute("wrap")?hiddenTextarea.setAttribute("wrap",$n.getAttribute("wrap")):hiddenTextarea.removeAttribute("wrap");const{paddingSize:In,borderSize:Nn,boxSizing:Rn,sizingStyle:Dn}=calculateNodeStyling($n,Cn);hiddenTextarea.setAttribute("style",`${Dn};${HIDDEN_TEXTAREA_STYLE}`),hiddenTextarea.value=$n.value||$n.placeholder||"";let Ln,Fn,Bn,Hn=hiddenTextarea.scrollHeight;if(Rn==="border-box"?Hn+=Nn:Rn==="content-box"&&(Hn-=In),_n!==null||Pn!==null){hiddenTextarea.value=" ";const Wn=hiddenTextarea.scrollHeight-In;_n!==null&&(Ln=Wn*_n,Rn==="border-box"&&(Ln=Ln+In+Nn),Hn=Math.max(Ln,Hn)),Pn!==null&&(Fn=Wn*Pn,Rn==="border-box"&&(Fn=Fn+In+Nn),Bn=Hn>Fn?"":"hidden",Hn=Math.min(Fn,Hn))}const zn={height:`${Hn}px`,overflowY:Bn,resize:"none"};return Ln&&(zn.minHeight=`${Ln}px`),Fn&&(zn.maxHeight=`${Fn}px`),zn}const RESIZE_START=0,RESIZE_MEASURING=1,RESIZE_STABLE=2,ResizableTextArea=defineComponent({compatConfig:{MODE:3},name:"ResizableTextArea",inheritAttrs:!1,props:textAreaProps(),setup($n,Cn){let{attrs:_n,emit:Pn,expose:In}=Cn,Nn,Rn;const Dn=ref(),Ln=ref({}),Fn=ref(RESIZE_STABLE);onBeforeUnmount(()=>{wrapperRaf.cancel(Nn),wrapperRaf.cancel(Rn)});const Bn=()=>{try{if(document.activeElement===Dn.value){const rr=Dn.value.selectionStart,nr=Dn.value.selectionEnd,ta=Dn.value.scrollTop;Dn.value.setSelectionRange(rr,nr),Dn.value.scrollTop=ta}}catch{}},Hn=ref(),zn=ref();watchEffect(()=>{const rr=$n.autoSize||$n.autosize;rr?(Hn.value=rr.minRows,zn.value=rr.maxRows):(Hn.value=void 0,zn.value=void 0)});const Wn=computed(()=>!!($n.autoSize||$n.autosize)),Yn=()=>{Fn.value=RESIZE_START};watch([()=>$n.value,Hn,zn,Wn],()=>{Wn.value&&Yn()},{immediate:!0,flush:"post"});const Gn=ref();watch([Fn,Dn],()=>{if(Dn.value)if(Fn.value===RESIZE_START)Fn.value=RESIZE_MEASURING;else if(Fn.value===RESIZE_MEASURING){const rr=calculateAutoSizeStyle(Dn.value,!1,Hn.value,zn.value);Fn.value=RESIZE_STABLE,Gn.value=rr}else Bn()},{immediate:!0,flush:"post"});const Go=getCurrentInstance(),Xn=ref(),Yo=()=>{wrapperRaf.cancel(Xn.value)},qo=rr=>{Fn.value===RESIZE_STABLE&&(Pn("resize",rr),Wn.value&&(Yo(),Xn.value=wrapperRaf(()=>{Yn()})))};onBeforeUnmount(()=>{Yo()}),In({resizeTextarea:()=>{Yn()},textArea:Dn,instance:Go}),warning$3($n.autosize===void 0);const Zo=()=>{const{prefixCls:rr,disabled:nr}=$n,ta=omit$1($n,["prefixCls","onPressEnter","autoSize","autosize","defaultValue","allowClear","type","lazy","maxlength","valueModifiers"]),oa=classNames(rr,_n.class,{[`${rr}-disabled`]:nr}),ra=Wn.value?Gn.value:null,ea=[_n.style,Ln.value,ra],la=_extends$1(_extends$1(_extends$1({},ta),_n),{style:ea,class:oa});return(Fn.value===RESIZE_START||Fn.value===RESIZE_MEASURING)&&ea.push({overflowX:"hidden",overflowY:"hidden"}),la.autofocus||delete la.autofocus,la.rows===0&&delete la.rows,createVNode(ResizeObserver$1,{onResize:qo,disabled:!Wn.value},{default:()=>[withDirectives(createVNode("textarea",_objectSpread2$1(_objectSpread2$1({},la),{},{ref:Dn}),null),[[antInputDirective]])]})};return()=>Zo()}}),ResizableTextArea$1=ResizableTextArea;function fixEmojiLength($n,Cn){return[...$n||""].slice(0,Cn).join("")}function setTriggerValue($n,Cn,_n,Pn){let In=_n;return $n?In=fixEmojiLength(_n,Pn):[...Cn||""].length<_n.length&&[..._n||""].length>Pn&&(In=Cn),In}const TextArea=defineComponent({compatConfig:{MODE:3},name:"ATextarea",inheritAttrs:!1,props:textAreaProps(),setup($n,Cn){let{attrs:_n,expose:Pn,emit:In}=Cn;const Nn=useInjectFormItemContext(),Rn=FormItemInputContext.useInject(),Dn=computed(()=>getMergedStatus(Rn.status,$n.status)),Ln=shallowRef($n.value===void 0?$n.defaultValue:$n.value),Fn=shallowRef(),Bn=shallowRef(""),{prefixCls:Hn,size:zn,direction:Wn}=useConfigInject("input",$n),[Yn,Gn]=useStyle$K(Hn),Go=useInjectDisabled(),Xn=computed(()=>$n.showCount===""||$n.showCount||!1),Yo=computed(()=>Number($n.maxlength)>0),qo=shallowRef(!1),Jo=shallowRef(),Zo=shallowRef(0),rr=ia=>{qo.value=!0,Jo.value=Bn.value,Zo.value=ia.currentTarget.selectionStart,In("compositionstart",ia)},nr=ia=>{var fa;qo.value=!1;let ma=ia.currentTarget.value;if(Yo.value){const ya=Zo.value>=$n.maxlength+1||Zo.value===((fa=Jo.value)===null||fa===void 0?void 0:fa.length);ma=setTriggerValue(ya,Jo.value,ma,$n.maxlength)}ma!==Bn.value&&(ea(ma),resolveOnChange(ia.currentTarget,ia,ga,ma)),In("compositionend",ia)},ta=getCurrentInstance();watch(()=>$n.value,()=>{var ia;"value"in ta.vnode.props,Ln.value=(ia=$n.value)!==null&&ia!==void 0?ia:""});const oa=ia=>{var fa;triggerFocus((fa=Fn.value)===null||fa===void 0?void 0:fa.textArea,ia)},ra=()=>{var ia,fa;(fa=(ia=Fn.value)===null||ia===void 0?void 0:ia.textArea)===null||fa===void 0||fa.blur()},ea=(ia,fa)=>{Ln.value!==ia&&($n.value===void 0?Ln.value=ia:nextTick(()=>{var ma,ya,ba;Fn.value.textArea.value!==Bn.value&&((ba=(ma=Fn.value)===null||ma===void 0?void 0:(ya=ma.instance).update)===null||ba===void 0||ba.call(ya))}),nextTick(()=>{fa&&fa()}))},la=ia=>{ia.keyCode===13&&In("pressEnter",ia),In("keydown",ia)},ua=ia=>{const{onBlur:fa}=$n;fa==null||fa(ia),Nn.onFieldBlur()},ga=ia=>{In("update:value",ia.target.value),In("change",ia),In("input",ia),Nn.onFieldChange()},aa=ia=>{resolveOnChange(Fn.value.textArea,ia,ga),ea("",()=>{oa()})},ca=ia=>{const{composing:fa}=ia.target;let ma=ia.target.value;if(qo.value=!!(ia.isComposing||fa),!(qo.value&&$n.lazy||Ln.value===ma)){if(Yo.value){const ya=ia.target,ba=ya.selectionStart>=$n.maxlength+1||ya.selectionStart===ma.length||!ya.selectionStart;ma=setTriggerValue(ba,Bn.value,ma,$n.maxlength)}resolveOnChange(ia.currentTarget,ia,ga,ma),ea(ma)}},sa=()=>{var ia,fa;const{class:ma}=_n,{bordered:ya=!0}=$n,ba=_extends$1(_extends$1(_extends$1({},omit$1($n,["allowClear"])),_n),{class:[{[`${Hn.value}-borderless`]:!ya,[`${ma}`]:ma&&!Xn.value,[`${Hn.value}-sm`]:zn.value==="small",[`${Hn.value}-lg`]:zn.value==="large"},getStatusClassNames(Hn.value,Dn.value),Gn.value],disabled:Go.value,showCount:null,prefixCls:Hn.value,onInput:ca,onChange:ca,onBlur:ua,onKeydown:la,onCompositionstart:rr,onCompositionend:nr});return!((ia=$n.valueModifiers)===null||ia===void 0)&&ia.lazy&&delete ba.onInput,createVNode(ResizableTextArea$1,_objectSpread2$1(_objectSpread2$1({},ba),{},{id:(fa=ba==null?void 0:ba.id)!==null&&fa!==void 0?fa:Nn.id.value,ref:Fn,maxlength:$n.maxlength}),null)};return Pn({focus:oa,blur:ra,resizableTextArea:Fn}),watchEffect(()=>{let ia=fixControlledValue(Ln.value);!qo.value&&Yo.value&&($n.value===null||$n.value===void 0)&&(ia=fixEmojiLength(ia,$n.maxlength)),Bn.value=ia}),()=>{var ia;const{maxlength:fa,bordered:ma=!0,hidden:ya}=$n,{style:ba,class:Ia}=_n,Ea=_extends$1(_extends$1(_extends$1({},$n),_n),{prefixCls:Hn.value,inputType:"text",handleReset:aa,direction:Wn.value,bordered:ma,style:Xn.value?void 0:ba,hashId:Gn.value,disabled:(ia=$n.disabled)!==null&&ia!==void 0?ia:Go.value});let xa=createVNode(ClearableLabeledInput,_objectSpread2$1(_objectSpread2$1({},Ea),{},{value:Bn.value,status:$n.status}),{element:sa});if(Xn.value||Rn.hasFeedback){const Ta=[...Bn.value].length;let wa="";typeof Xn.value=="object"?wa=Xn.value.formatter({value:Bn.value,count:Ta,maxlength:fa}):wa=`${Ta}${Yo.value?` / ${fa}`:""}`,xa=createVNode("div",{hidden:ya,class:classNames(`${Hn.value}-textarea`,{[`${Hn.value}-textarea-rtl`]:Wn.value==="rtl",[`${Hn.value}-textarea-show-count`]:Xn.value,[`${Hn.value}-textarea-in-form-item`]:Rn.isFormItemInput},`${Hn.value}-textarea-show-count`,Ia,Gn.value),style:ba,"data-count":typeof wa!="object"?wa:void 0},[xa,Rn.hasFeedback&&createVNode("span",{class:`${Hn.value}-textarea-suffix`},[Rn.feedbackIcon])])}return Yn(xa)}}});var EyeOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"}}]},name:"eye",theme:"outlined"};const EyeOutlinedSvg=EyeOutlined$2;function _objectSpread$w($n){for(var Cn=1;CncreateVNode($n?EyeOutlined$1:EyeInvisibleOutlined$1,null,null),Password=defineComponent({compatConfig:{MODE:3},name:"AInputPassword",inheritAttrs:!1,props:_extends$1(_extends$1({},inputProps()),{prefixCls:String,inputPrefixCls:String,action:{type:String,default:"click"},visibilityToggle:{type:Boolean,default:!0},visible:{type:Boolean,default:void 0},"onUpdate:visible":Function,iconRender:Function}),setup($n,Cn){let{slots:_n,attrs:Pn,expose:In,emit:Nn}=Cn;const Rn=shallowRef(!1),Dn=()=>{const{disabled:Go}=$n;Go||(Rn.value=!Rn.value,Nn("update:visible",Rn.value))};watchEffect(()=>{$n.visible!==void 0&&(Rn.value=!!$n.visible)});const Ln=shallowRef();In({focus:()=>{var Go;(Go=Ln.value)===null||Go===void 0||Go.focus()},blur:()=>{var Go;(Go=Ln.value)===null||Go===void 0||Go.blur()}});const Hn=Go=>{const{action:Xn,iconRender:Yo=_n.iconRender||defaultIconRender}=$n,qo=ActionMap[Xn]||"",Jo=Yo(Rn.value),Zo={[qo]:Dn,class:`${Go}-icon`,key:"passwordIcon",onMousedown:rr=>{rr.preventDefault()},onMouseup:rr=>{rr.preventDefault()}};return cloneElement(isValidElement(Jo)?Jo:createVNode("span",null,[Jo]),Zo)},{prefixCls:zn,getPrefixCls:Wn}=useConfigInject("input-password",$n),Yn=computed(()=>Wn("input",$n.inputPrefixCls)),Gn=()=>{const{size:Go,visibilityToggle:Xn}=$n,Yo=__rest$C($n,["size","visibilityToggle"]),qo=Xn&&Hn(zn.value),Jo=classNames(zn.value,Pn.class,{[`${zn.value}-${Go}`]:!!Go}),Zo=_extends$1(_extends$1(_extends$1({},omit$1(Yo,["suffix","iconRender","action"])),Pn),{type:Rn.value?"text":"password",class:Jo,prefixCls:Yn.value,suffix:qo});return Go&&(Zo.size=Go),createVNode(Input,_objectSpread2$1({ref:Ln},Zo),_n)};return()=>Gn()}});Input.Group=Group$1;Input.Search=Search$1;Input.TextArea=TextArea;Input.Password=Password;Input.install=function($n){return $n.component(Input.name,Input),$n.component(Input.Group.name,Input.Group),$n.component(Input.Search.name,Input.Search),$n.component(Input.TextArea.name,Input.TextArea),$n.component(Input.Password.name,Input.Password),$n};function getClientSize(){const $n=document.documentElement.clientWidth,Cn=window.innerHeight||document.documentElement.clientHeight;return{width:$n,height:Cn}}function getOffset($n){const Cn=$n.getBoundingClientRect(),_n=document.documentElement;return{left:Cn.left+(window.pageXOffset||_n.scrollLeft)-(_n.clientLeft||document.body.clientLeft||0),top:Cn.top+(window.pageYOffset||_n.scrollTop)-(_n.clientTop||document.body.clientTop||0)}}function dialogPropTypes(){return{keyboard:{type:Boolean,default:void 0},mask:{type:Boolean,default:void 0},afterClose:Function,closable:{type:Boolean,default:void 0},maskClosable:{type:Boolean,default:void 0},visible:{type:Boolean,default:void 0},destroyOnClose:{type:Boolean,default:void 0},mousePosition:PropTypes.shape({x:Number,y:Number}).loose,title:PropTypes.any,footer:PropTypes.any,transitionName:String,maskTransitionName:String,animation:PropTypes.any,maskAnimation:PropTypes.any,wrapStyle:{type:Object,default:void 0},bodyStyle:{type:Object,default:void 0},maskStyle:{type:Object,default:void 0},prefixCls:String,wrapClassName:String,rootClassName:String,width:[String,Number],height:[String,Number],zIndex:Number,bodyProps:PropTypes.any,maskProps:PropTypes.any,wrapProps:PropTypes.any,getContainer:PropTypes.any,dialogStyle:{type:Object,default:void 0},dialogClass:String,closeIcon:PropTypes.any,forceRender:{type:Boolean,default:void 0},getOpenCount:Function,focusTriggerAfterClose:{type:Boolean,default:void 0},onClose:Function,modalRender:Function}}function getMotionName($n,Cn,_n){let Pn=Cn;return!Pn&&_n&&(Pn=`${$n}-${_n}`),Pn}let uuid$3=-1;function getUUID$1(){return uuid$3+=1,uuid$3}function getScroll$1($n,Cn){let _n=$n[`page${Cn?"Y":"X"}Offset`];const Pn=`scroll${Cn?"Top":"Left"}`;if(typeof _n!="number"){const In=$n.document;_n=In.documentElement[Pn],typeof _n!="number"&&(_n=In.body[Pn])}return _n}function offset$3($n){const Cn=$n.getBoundingClientRect(),_n={left:Cn.left,top:Cn.top},Pn=$n.ownerDocument,In=Pn.defaultView||Pn.parentWindow;return _n.left+=getScroll$1(In),_n.top+=getScroll$1(In,!0),_n}const sentinelStyle={width:0,height:0,overflow:"hidden",outline:"none"},Content$1=defineComponent({compatConfig:{MODE:3},name:"DialogContent",inheritAttrs:!1,props:_extends$1(_extends$1({},dialogPropTypes()),{motionName:String,ariaId:String,onVisibleChanged:Function,onMousedown:Function,onMouseup:Function}),setup($n,Cn){let{expose:_n,slots:Pn,attrs:In}=Cn;const Nn=ref(),Rn=ref(),Dn=ref();_n({focus:()=>{var zn;(zn=Nn.value)===null||zn===void 0||zn.focus()},changeActive:zn=>{const{activeElement:Wn}=document;zn&&Wn===Rn.value?Nn.value.focus():!zn&&Wn===Nn.value&&Rn.value.focus()}});const Ln=ref(),Fn=computed(()=>{const{width:zn,height:Wn}=$n,Yn={};return zn!==void 0&&(Yn.width=typeof zn=="number"?`${zn}px`:zn),Wn!==void 0&&(Yn.height=typeof Wn=="number"?`${Wn}px`:Wn),Ln.value&&(Yn.transformOrigin=Ln.value),Yn}),Bn=()=>{nextTick(()=>{if(Dn.value){const zn=offset$3(Dn.value);Ln.value=$n.mousePosition?`${$n.mousePosition.x-zn.left}px ${$n.mousePosition.y-zn.top}px`:""}})},Hn=zn=>{$n.onVisibleChanged(zn)};return()=>{var zn,Wn,Yn,Gn;const{prefixCls:Go,footer:Xn=(zn=Pn.footer)===null||zn===void 0?void 0:zn.call(Pn),title:Yo=(Wn=Pn.title)===null||Wn===void 0?void 0:Wn.call(Pn),ariaId:qo,closable:Jo,closeIcon:Zo=(Yn=Pn.closeIcon)===null||Yn===void 0?void 0:Yn.call(Pn),onClose:rr,bodyStyle:nr,bodyProps:ta,onMousedown:oa,onMouseup:ra,visible:ea,modalRender:la=Pn.modalRender,destroyOnClose:ua,motionName:ga}=$n;let aa;Xn&&(aa=createVNode("div",{class:`${Go}-footer`},[Xn]));let ca;Yo&&(ca=createVNode("div",{class:`${Go}-header`},[createVNode("div",{class:`${Go}-title`,id:qo},[Yo])]));let sa;Jo&&(sa=createVNode("button",{type:"button",onClick:rr,"aria-label":"Close",class:`${Go}-close`},[Zo||createVNode("span",{class:`${Go}-close-x`},null)]));const ia=createVNode("div",{class:`${Go}-content`},[sa,ca,createVNode("div",_objectSpread2$1({class:`${Go}-body`,style:nr},ta),[(Gn=Pn.default)===null||Gn===void 0?void 0:Gn.call(Pn)]),aa]),fa=getTransitionProps(ga);return createVNode(Transition,_objectSpread2$1(_objectSpread2$1({},fa),{},{onBeforeEnter:Bn,onAfterEnter:()=>Hn(!0),onAfterLeave:()=>Hn(!1)}),{default:()=>[ea||!ua?withDirectives(createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{ref:Dn,key:"dialog-element",role:"document",style:[Fn.value,In.style],class:[Go,In.class],onMousedown:oa,onMouseup:ra}),[createVNode("div",{tabindex:0,ref:Nn,style:sentinelStyle,"aria-hidden":"true"},null),la?la({originVNode:ia}):ia,createVNode("div",{tabindex:0,ref:Rn,style:sentinelStyle,"aria-hidden":"true"},null)]),[[vShow,ea]]):null]})}}}),Mask$2=defineComponent({compatConfig:{MODE:3},name:"DialogMask",props:{prefixCls:String,visible:Boolean,motionName:String,maskProps:Object},setup($n,Cn){return()=>{const{prefixCls:_n,visible:Pn,maskProps:In,motionName:Nn}=$n,Rn=getTransitionProps(Nn);return createVNode(Transition,Rn,{default:()=>[withDirectives(createVNode("div",_objectSpread2$1({class:`${_n}-mask`},In),null),[[vShow,Pn]])]})}}}),Dialog=defineComponent({compatConfig:{MODE:3},name:"VcDialog",inheritAttrs:!1,props:initDefaultProps(_extends$1(_extends$1({},dialogPropTypes()),{getOpenCount:Function,scrollLocker:Object}),{mask:!0,visible:!1,keyboard:!0,closable:!0,maskClosable:!0,destroyOnClose:!1,prefixCls:"rc-dialog",getOpenCount:()=>null,focusTriggerAfterClose:!0}),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=shallowRef(),Nn=shallowRef(),Rn=shallowRef(),Dn=shallowRef($n.visible),Ln=shallowRef(`vcDialogTitle${getUUID$1()}`),Fn=Xn=>{var Yo,qo;if(Xn)contains$2(Nn.value,document.activeElement)||(In.value=document.activeElement,(Yo=Rn.value)===null||Yo===void 0||Yo.focus());else{const Jo=Dn.value;if(Dn.value=!1,$n.mask&&In.value&&$n.focusTriggerAfterClose){try{In.value.focus({preventScroll:!0})}catch{}In.value=null}Jo&&((qo=$n.afterClose)===null||qo===void 0||qo.call($n))}},Bn=Xn=>{var Yo;(Yo=$n.onClose)===null||Yo===void 0||Yo.call($n,Xn)},Hn=shallowRef(!1),zn=shallowRef(),Wn=()=>{clearTimeout(zn.value),Hn.value=!0},Yn=()=>{zn.value=setTimeout(()=>{Hn.value=!1})},Gn=Xn=>{if(!$n.maskClosable)return null;Hn.value?Hn.value=!1:Nn.value===Xn.target&&Bn(Xn)},Go=Xn=>{if($n.keyboard&&Xn.keyCode===KeyCode$1.ESC){Xn.stopPropagation(),Bn(Xn);return}$n.visible&&Xn.keyCode===KeyCode$1.TAB&&Rn.value.changeActive(!Xn.shiftKey)};return watch(()=>$n.visible,()=>{$n.visible&&(Dn.value=!0)},{flush:"post"}),onBeforeUnmount(()=>{var Xn;clearTimeout(zn.value),(Xn=$n.scrollLocker)===null||Xn===void 0||Xn.unLock()}),watchEffect(()=>{var Xn,Yo;(Xn=$n.scrollLocker)===null||Xn===void 0||Xn.unLock(),Dn.value&&((Yo=$n.scrollLocker)===null||Yo===void 0||Yo.lock())}),()=>{const{prefixCls:Xn,mask:Yo,visible:qo,maskTransitionName:Jo,maskAnimation:Zo,zIndex:rr,wrapClassName:nr,rootClassName:ta,wrapStyle:oa,closable:ra,maskProps:ea,maskStyle:la,transitionName:ua,animation:ga,wrapProps:aa,title:ca=Pn.title}=$n,{style:sa,class:ia}=_n;return createVNode("div",_objectSpread2$1({class:[`${Xn}-root`,ta]},pickAttrs($n,{data:!0})),[createVNode(Mask$2,{prefixCls:Xn,visible:Yo&&qo,motionName:getMotionName(Xn,Jo,Zo),style:_extends$1({zIndex:rr},la),maskProps:ea},null),createVNode("div",_objectSpread2$1({tabIndex:-1,onKeydown:Go,class:classNames(`${Xn}-wrap`,nr),ref:Nn,onClick:Gn,role:"dialog","aria-labelledby":ca?Ln.value:null,style:_extends$1(_extends$1({zIndex:rr},oa),{display:Dn.value?null:"none"})},aa),[createVNode(Content$1,_objectSpread2$1(_objectSpread2$1({},omit$1($n,["scrollLocker"])),{},{style:sa,class:ia,onMousedown:Wn,onMouseup:Yn,ref:Rn,closable:ra,ariaId:Ln.value,prefixCls:Xn,visible:qo,onClose:Bn,onVisibleChanged:Fn,motionName:getMotionName(Xn,ua,ga)}),Pn)])])}}}),IDialogPropTypes=dialogPropTypes(),DialogWrap=defineComponent({compatConfig:{MODE:3},name:"DialogWrap",inheritAttrs:!1,props:initDefaultProps(IDialogPropTypes,{visible:!1}),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=ref($n.visible);return useProvidePortal({},{inTriggerContext:!1}),watch(()=>$n.visible,()=>{$n.visible&&(In.value=!0)},{flush:"post"}),()=>{const{visible:Nn,getContainer:Rn,forceRender:Dn,destroyOnClose:Ln=!1,afterClose:Fn}=$n;let Bn=_extends$1(_extends$1(_extends$1({},$n),_n),{ref:"_component",key:"dialog"});return Rn===!1?createVNode(Dialog,_objectSpread2$1(_objectSpread2$1({},Bn),{},{getOpenCount:()=>2}),Pn):!Dn&&Ln&&!In.value?null:createVNode(Portal,{autoLock:!0,visible:Nn,forceRender:Dn,getContainer:Rn},{default:Hn=>(Bn=_extends$1(_extends$1(_extends$1({},Bn),Hn),{afterClose:()=>{Fn==null||Fn(),In.value=!1}}),createVNode(Dialog,Bn,Pn))})}}}),DialogWrap$1=DialogWrap;function useFrameSetState($n){const Cn=ref(null),_n=reactive(_extends$1({},$n)),Pn=ref([]),In=Nn=>{Cn.value===null&&(Pn.value=[],Cn.value=wrapperRaf(()=>{let Rn;Pn.value.forEach(Dn=>{Rn=_extends$1(_extends$1({},Rn),Dn)}),_extends$1(_n,Rn),Cn.value=null})),Pn.value.push(Nn)};return onMounted(()=>{Cn.value&&wrapperRaf.cancel(Cn.value)}),[_n,In]}function fixPoint($n,Cn,_n,Pn){const In=Cn+_n,Nn=(_n-Pn)/2;if(_n>Pn){if(Cn>0)return{[$n]:Nn};if(Cn<0&&InPn)return{[$n]:Cn<0?Nn:-Nn};return{}}function getFixScaleEleTransPosition($n,Cn,_n,Pn){const{width:In,height:Nn}=getClientSize();let Rn=null;return $n<=In&&Cn<=Nn?Rn={x:0,y:0}:($n>In||Cn>Nn)&&(Rn=_extends$1(_extends$1({},fixPoint("x",_n,$n,In)),fixPoint("y",Pn,Cn,Nn))),Rn}var __rest$B=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{provide(previewGroupContext,$n)},inject:()=>inject(previewGroupContext,{isPreviewGroup:shallowRef(!1),previewUrls:computed(()=>new Map),setPreviewUrls:()=>{},current:ref(null),setCurrent:()=>{},setShowPreview:()=>{},setMousePosition:()=>{},registerImage:null,rootClassName:""})},imageGroupProps=()=>({previewPrefixCls:String,preview:{type:[Boolean,Object],default:!0},icons:{type:Object,default:()=>({})}}),Group=defineComponent({compatConfig:{MODE:3},name:"PreviewGroup",inheritAttrs:!1,props:imageGroupProps(),setup($n,Cn){let{slots:_n}=Cn;const Pn=computed(()=>{const Zo={visible:void 0,onVisibleChange:()=>{},getContainer:void 0,current:0};return typeof $n.preview=="object"?mergeDefaultValue($n.preview,Zo):Zo}),In=reactive(new Map),Nn=ref(),Rn=computed(()=>Pn.value.visible),Dn=computed(()=>Pn.value.getContainer),Ln=(Zo,rr)=>{var nr,ta;(ta=(nr=Pn.value).onVisibleChange)===null||ta===void 0||ta.call(nr,Zo,rr)},[Fn,Bn]=useMergedState(!!Rn.value,{value:Rn,onChange:Ln}),Hn=ref(null),zn=computed(()=>Rn.value!==void 0),Wn=computed(()=>Array.from(In.keys())),Yn=computed(()=>Wn.value[Pn.value.current]),Gn=computed(()=>new Map(Array.from(In).filter(Zo=>{let[,{canPreview:rr}]=Zo;return!!rr}).map(Zo=>{let[rr,{url:nr}]=Zo;return[rr,nr]}))),Go=function(Zo,rr){let nr=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;In.set(Zo,{url:rr,canPreview:nr})},Xn=Zo=>{Nn.value=Zo},Yo=Zo=>{Hn.value=Zo},qo=function(Zo,rr){let nr=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;const ta=()=>{In.delete(Zo)};return In.set(Zo,{url:rr,canPreview:nr}),ta},Jo=Zo=>{Zo==null||Zo.stopPropagation(),Bn(!1),Yo(null)};return watch(Yn,Zo=>{Xn(Zo)},{immediate:!0,flush:"post"}),watchEffect(()=>{Fn.value&&zn.value&&Xn(Yn.value)},{flush:"post"}),context.provide({isPreviewGroup:shallowRef(!0),previewUrls:Gn,setPreviewUrls:Go,current:Nn,setCurrent:Xn,setShowPreview:Bn,setMousePosition:Yo,registerImage:qo}),()=>{const Zo=__rest$B(Pn.value,[]);return createVNode(Fragment,null,[_n.default&&_n.default(),createVNode(Preview$1,_objectSpread2$1(_objectSpread2$1({},Zo),{},{"ria-hidden":!Fn.value,visible:Fn.value,prefixCls:$n.previewPrefixCls,onClose:Jo,mousePosition:Hn.value,src:Gn.value.get(Nn.value),icons:$n.icons,getContainer:Dn.value}),null)])}}}),PreviewGroup$1=Group,initialPosition={x:0,y:0},previewProps=_extends$1(_extends$1({},dialogPropTypes()),{src:String,alt:String,rootClassName:String,icons:{type:Object,default:()=>({})}}),Preview=defineComponent({compatConfig:{MODE:3},name:"Preview",inheritAttrs:!1,props:previewProps,emits:["close","afterClose"],setup($n,Cn){let{emit:_n,attrs:Pn}=Cn;const{rotateLeft:In,rotateRight:Nn,zoomIn:Rn,zoomOut:Dn,close:Ln,left:Fn,right:Bn,flipX:Hn,flipY:zn}=reactive($n.icons),Wn=shallowRef(1),Yn=shallowRef(0),Gn=reactive({x:1,y:1}),[Go,Xn]=useFrameSetState(initialPosition),Yo=()=>_n("close"),qo=shallowRef(),Jo=reactive({originX:0,originY:0,deltaX:0,deltaY:0}),Zo=shallowRef(!1),rr=context.inject(),{previewUrls:nr,current:ta,isPreviewGroup:oa,setCurrent:ra}=rr,ea=computed(()=>nr.value.size),la=computed(()=>Array.from(nr.value.keys())),ua=computed(()=>la.value.indexOf(ta.value)),ga=computed(()=>oa.value?nr.value.get(ta.value):$n.src),aa=computed(()=>oa.value&&ea.value>1),ca=shallowRef({wheelDirection:0}),sa=()=>{Wn.value=1,Yn.value=0,Gn.x=1,Gn.y=1,Xn(initialPosition),_n("afterClose")},ia=Ra=>{Ra?Wn.value+=.5:Wn.value++,Xn(initialPosition)},fa=Ra=>{Wn.value>1&&(Ra?Wn.value-=.5:Wn.value--),Xn(initialPosition)},ma=()=>{Yn.value+=90},ya=()=>{Yn.value-=90},ba=()=>{Gn.x=-Gn.x},Ia=()=>{Gn.y=-Gn.y},Ea=Ra=>{Ra.preventDefault(),Ra.stopPropagation(),ua.value>0&&ra(la.value[ua.value-1])},xa=Ra=>{Ra.preventDefault(),Ra.stopPropagation(),ua.valueia(),type:"zoomIn"},{icon:Dn,onClick:()=>fa(),type:"zoomOut",disabled:computed(()=>Wn.value===1)},{icon:Nn,onClick:ma,type:"rotateRight"},{icon:In,onClick:ya,type:"rotateLeft"},{icon:Hn,onClick:ba,type:"flipX"},{icon:zn,onClick:Ia,type:"flipY"}],$a=()=>{if($n.visible&&Zo.value){const Ra=qo.value.offsetWidth*Wn.value,Fa=qo.value.offsetHeight*Wn.value,{left:za,top:Wa}=getOffset(qo.value),Ya=Yn.value%180!==0;Zo.value=!1;const ja=getFixScaleEleTransPosition(Ya?Fa:Ra,Ya?Ra:Fa,za,Wa);ja&&Xn(_extends$1({},ja))}},ka=Ra=>{Ra.button===0&&(Ra.preventDefault(),Ra.stopPropagation(),Jo.deltaX=Ra.pageX-Go.x,Jo.deltaY=Ra.pageY-Go.y,Jo.originX=Go.x,Jo.originY=Go.y,Zo.value=!0)},Ha=Ra=>{$n.visible&&Zo.value&&Xn({x:Ra.pageX-Jo.deltaX,y:Ra.pageY-Jo.deltaY})},da=Ra=>{if(!$n.visible)return;Ra.preventDefault();const Fa=Ra.deltaY;ca.value={wheelDirection:Fa}},pa=Ra=>{!$n.visible||!aa.value||(Ra.preventDefault(),Ra.keyCode===KeyCode$1.LEFT?ua.value>0&&ra(la.value[ua.value-1]):Ra.keyCode===KeyCode$1.RIGHT&&ua.value{$n.visible&&(Wn.value!==1&&(Wn.value=1),(Go.x!==initialPosition.x||Go.y!==initialPosition.y)&&Xn(initialPosition))};let Aa=()=>{};return onMounted(()=>{watch([()=>$n.visible,Zo],()=>{Aa();let Ra,Fa;const za=addEventListenerWrap(window,"mouseup",$a,!1),Wa=addEventListenerWrap(window,"mousemove",Ha,!1),Ya=addEventListenerWrap(window,"wheel",da,{passive:!1}),ja=addEventListenerWrap(window,"keydown",pa,!1);try{window.top!==window.self&&(Ra=addEventListenerWrap(window.top,"mouseup",$a,!1),Fa=addEventListenerWrap(window.top,"mousemove",Ha,!1))}catch{}Aa=()=>{za.remove(),Wa.remove(),Ya.remove(),ja.remove(),Ra&&Ra.remove(),Fa&&Fa.remove()}},{flush:"post",immediate:!0}),watch([ca],()=>{const{wheelDirection:Ra}=ca.value;Ra>0?fa(!0):Ra<0&&ia(!0)})}),onUnmounted(()=>{Aa()}),()=>{const{visible:Ra,prefixCls:Fa,rootClassName:za}=$n;return createVNode(DialogWrap$1,_objectSpread2$1(_objectSpread2$1({},Pn),{},{transitionName:$n.transitionName,maskTransitionName:$n.maskTransitionName,closable:!1,keyboard:!0,prefixCls:Fa,onClose:Yo,afterClose:sa,visible:Ra,wrapClassName:Ta,rootClassName:za,getContainer:$n.getContainer}),{default:()=>[createVNode("div",{class:[`${$n.prefixCls}-operations-wrapper`,za]},[createVNode("ul",{class:`${$n.prefixCls}-operations`},[Na.map(Wa=>{let{icon:Ya,onClick:ja,type:qa,disabled:Xa}=Wa;return createVNode("li",{class:classNames(wa,{[`${$n.prefixCls}-operations-operation-disabled`]:Xa&&(Xa==null?void 0:Xa.value)}),onClick:ja,key:qa},[cloneVNode(Ya,{class:La})])})])]),createVNode("div",{class:`${$n.prefixCls}-img-wrapper`,style:{transform:`translate3d(${Go.x}px, ${Go.y}px, 0)`}},[createVNode("img",{onMousedown:ka,onDblclick:Sa,ref:qo,class:`${$n.prefixCls}-img`,src:ga.value,alt:$n.alt,style:{transform:`scale3d(${Gn.x*Wn.value}, ${Gn.y*Wn.value}, 1) rotate(${Yn.value}deg)`}},null)]),aa.value&&createVNode("div",{class:classNames(`${$n.prefixCls}-switch-left`,{[`${$n.prefixCls}-switch-left-disabled`]:ua.value<=0}),onClick:Ea},[Fn]),aa.value&&createVNode("div",{class:classNames(`${$n.prefixCls}-switch-right`,{[`${$n.prefixCls}-switch-right-disabled`]:ua.value>=ea.value-1}),onClick:xa},[Bn])]})}}}),Preview$1=Preview;var __rest$A=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({src:String,wrapperClassName:String,wrapperStyle:{type:Object,default:void 0},rootClassName:String,prefixCls:String,previewPrefixCls:String,previewMask:{type:[Boolean,Function],default:void 0},placeholder:PropTypes.any,fallback:String,preview:{type:[Boolean,Object],default:!0},onClick:{type:Function},onError:{type:Function}}),mergeDefaultValue=($n,Cn)=>{const _n=_extends$1({},$n);return Object.keys(Cn).forEach(Pn=>{$n[Pn]===void 0&&(_n[Pn]=Cn[Pn])}),_n};let uuid$2=0;const ImageInternal=defineComponent({compatConfig:{MODE:3},name:"VcImage",inheritAttrs:!1,props:imageProps(),emits:["click","error"],setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const Nn=computed(()=>$n.prefixCls),Rn=computed(()=>`${Nn.value}-preview`),Dn=computed(()=>{const ia={visible:void 0,onVisibleChange:()=>{},getContainer:void 0};return typeof $n.preview=="object"?mergeDefaultValue($n.preview,ia):ia}),Ln=computed(()=>{var ia;return(ia=Dn.value.src)!==null&&ia!==void 0?ia:$n.src}),Fn=computed(()=>$n.placeholder&&$n.placeholder!==!0||Pn.placeholder),Bn=computed(()=>Dn.value.visible),Hn=computed(()=>Dn.value.getContainer),zn=computed(()=>Bn.value!==void 0),Wn=(ia,fa)=>{var ma,ya;(ya=(ma=Dn.value).onVisibleChange)===null||ya===void 0||ya.call(ma,ia,fa)},[Yn,Gn]=useMergedState(!!Bn.value,{value:Bn,onChange:Wn}),Go=ref(Fn.value?"loading":"normal");watch(()=>$n.src,()=>{Go.value=Fn.value?"loading":"normal"});const Xn=ref(null),Yo=computed(()=>Go.value==="error"),qo=context.inject(),{isPreviewGroup:Jo,setCurrent:Zo,setShowPreview:rr,setMousePosition:nr,registerImage:ta}=qo,oa=ref(uuid$2++),ra=computed(()=>$n.preview&&!Yo.value),ea=()=>{Go.value="normal"},la=ia=>{Go.value="error",In("error",ia)},ua=ia=>{if(!zn.value){const{left:fa,top:ma}=getOffset(ia.target);Jo.value?(Zo(oa.value),nr({x:fa,y:ma})):Xn.value={x:fa,y:ma}}Jo.value?rr(!0):Gn(!0),In("click",ia)},ga=()=>{Gn(!1),zn.value||(Xn.value=null)},aa=ref(null);watch(()=>aa,()=>{Go.value==="loading"&&aa.value.complete&&(aa.value.naturalWidth||aa.value.naturalHeight)&&ea()});let ca=()=>{};onMounted(()=>{watch([Ln,ra],()=>{if(ca(),!Jo.value)return()=>{};ca=ta(oa.value,Ln.value,ra.value),ra.value||ca()},{flush:"post",immediate:!0})}),onUnmounted(()=>{ca()});const sa=ia=>isNumber$1(ia)?ia+"px":ia;return()=>{const{prefixCls:ia,wrapperClassName:fa,fallback:ma,src:ya,placeholder:ba,wrapperStyle:Ia,rootClassName:Ea}=$n,{width:xa,height:Ta,crossorigin:wa,decoding:La,alt:Na,sizes:$a,srcset:ka,usemap:Ha,class:da,style:pa}=_n,Sa=Dn.value,{icons:Aa,maskClassName:Ra}=Sa,Fa=__rest$A(Sa,["icons","maskClassName"]),za=classNames(ia,fa,Ea,{[`${ia}-error`]:Yo.value}),Wa=Yo.value&&ma?ma:Ln.value,Ya={crossorigin:wa,decoding:La,alt:Na,sizes:$a,srcset:ka,usemap:Ha,width:xa,height:Ta,class:classNames(`${ia}-img`,{[`${ia}-img-placeholder`]:ba===!0},da),style:_extends$1({height:sa(Ta)},pa)};return createVNode(Fragment,null,[createVNode("div",{class:za,onClick:ra.value?ua:ja=>{In("click",ja)},style:_extends$1({width:sa(xa),height:sa(Ta)},Ia)},[createVNode("img",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Ya),Yo.value&&ma?{src:ma}:{onLoad:ea,onError:la,src:ya}),{},{ref:aa}),null),Go.value==="loading"&&createVNode("div",{"aria-hidden":"true",class:`${ia}-placeholder`},[ba||Pn.placeholder&&Pn.placeholder()]),Pn.previewMask&&ra.value&&createVNode("div",{class:[`${ia}-mask`,Ra]},[Pn.previewMask()])]),!Jo.value&&ra.value&&createVNode(Preview$1,_objectSpread2$1(_objectSpread2$1({},Fa),{},{"aria-hidden":!Yn.value,visible:Yn.value,prefixCls:Rn.value,onClose:ga,mousePosition:Xn.value,src:Wa,alt:Na,getContainer:Hn.value,icons:Aa,rootClassName:Ea}),null)])}}});ImageInternal.PreviewGroup=PreviewGroup$1;const Image$3=ImageInternal;var RotateLeftOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32zm-44 402H188V494h440v326z"}},{tag:"path",attrs:{d:"M819.3 328.5c-78.8-100.7-196-153.6-314.6-154.2l-.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7.4 12.6-6.1v-63.9c12.9.1 25.9.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8a325.95 325.95 0 016.5 140.9h74.9c14.8-103.6-11.3-213-81-302.3z"}}]},name:"rotate-left",theme:"outlined"};const RotateLeftOutlinedSvg=RotateLeftOutlined$2;function _objectSpread$u($n){for(var Cn=1;Cn{const{componentCls:Cn}=$n;return[{[`${Cn}-root`]:{[`${Cn}${$n.antCls}-zoom-enter, ${Cn}${$n.antCls}-zoom-appear`]:{transform:"none",opacity:0,animationDuration:$n.motionDurationSlow,userSelect:"none"},[`${Cn}${$n.antCls}-zoom-leave ${Cn}-content`]:{pointerEvents:"none"},[`${Cn}-mask`]:_extends$1(_extends$1({},box("fixed")),{zIndex:$n.zIndexPopupBase,height:"100%",backgroundColor:$n.colorBgMask,[`${Cn}-hidden`]:{display:"none"}}),[`${Cn}-wrap`]:_extends$1(_extends$1({},box("fixed")),{overflow:"auto",outline:0,WebkitOverflowScrolling:"touch"})}},{[`${Cn}-root`]:initFadeMotion($n)}]},genModalStyle=$n=>{const{componentCls:Cn}=$n;return[{[`${Cn}-root`]:{[`${Cn}-wrap`]:{zIndex:$n.zIndexPopupBase,position:"fixed",inset:0,overflow:"auto",outline:0,WebkitOverflowScrolling:"touch"},[`${Cn}-wrap-rtl`]:{direction:"rtl"},[`${Cn}-centered`]:{textAlign:"center","&::before":{display:"inline-block",width:0,height:"100%",verticalAlign:"middle",content:'""'},[Cn]:{top:0,display:"inline-block",paddingBottom:0,textAlign:"start",verticalAlign:"middle"}},[`@media (max-width: ${$n.screenSMMax})`]:{[Cn]:{maxWidth:"calc(100vw - 16px)",margin:`${$n.marginXS} auto`},[`${Cn}-centered`]:{[Cn]:{flex:1}}}}},{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{pointerEvents:"none",position:"relative",top:100,width:"auto",maxWidth:`calc(100vw - ${$n.margin*2}px)`,margin:"0 auto",paddingBottom:$n.paddingLG,[`${Cn}-title`]:{margin:0,color:$n.modalHeadingColor,fontWeight:$n.fontWeightStrong,fontSize:$n.modalHeaderTitleFontSize,lineHeight:$n.modalHeaderTitleLineHeight,wordWrap:"break-word"},[`${Cn}-content`]:{position:"relative",backgroundColor:$n.modalContentBg,backgroundClip:"padding-box",border:0,borderRadius:$n.borderRadiusLG,boxShadow:$n.boxShadowSecondary,pointerEvents:"auto",padding:`${$n.paddingMD}px ${$n.paddingContentHorizontalLG}px`},[`${Cn}-close`]:_extends$1({position:"absolute",top:($n.modalHeaderCloseSize-$n.modalCloseBtnSize)/2,insetInlineEnd:($n.modalHeaderCloseSize-$n.modalCloseBtnSize)/2,zIndex:$n.zIndexPopupBase+10,padding:0,color:$n.modalCloseColor,fontWeight:$n.fontWeightStrong,lineHeight:1,textDecoration:"none",background:"transparent",borderRadius:$n.borderRadiusSM,width:$n.modalConfirmIconSize,height:$n.modalConfirmIconSize,border:0,outline:0,cursor:"pointer",transition:`color ${$n.motionDurationMid}, background-color ${$n.motionDurationMid}`,"&-x":{display:"block",fontSize:$n.fontSizeLG,fontStyle:"normal",lineHeight:`${$n.modalCloseBtnSize}px`,textAlign:"center",textTransform:"none",textRendering:"auto"},"&:hover":{color:$n.modalIconHoverColor,backgroundColor:$n.wireframe?"transparent":$n.colorFillContent,textDecoration:"none"},"&:active":{backgroundColor:$n.wireframe?"transparent":$n.colorFillContentHover}},genFocusStyle($n)),[`${Cn}-header`]:{color:$n.colorText,background:$n.modalHeaderBg,borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`,marginBottom:$n.marginXS},[`${Cn}-body`]:{fontSize:$n.fontSize,lineHeight:$n.lineHeight,wordWrap:"break-word"},[`${Cn}-footer`]:{textAlign:"end",background:$n.modalFooterBg,marginTop:$n.marginSM,[`${$n.antCls}-btn + ${$n.antCls}-btn:not(${$n.antCls}-dropdown-trigger)`]:{marginBottom:0,marginInlineStart:$n.marginXS}},[`${Cn}-open`]:{overflow:"hidden"}})},{[`${Cn}-pure-panel`]:{top:"auto",padding:0,display:"flex",flexDirection:"column",[`${Cn}-content, - ${Cn}-body, - ${Cn}-confirm-body-wrapper`]:{display:"flex",flexDirection:"column",flex:"auto"},[`${Cn}-confirm-body`]:{marginBottom:"auto"}}}]},genModalConfirmStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-confirm`;return{[_n]:{"&-rtl":{direction:"rtl"},[`${$n.antCls}-modal-header`]:{display:"none"},[`${_n}-body-wrapper`]:_extends$1({},clearFix()),[`${_n}-body`]:{display:"flex",flexWrap:"wrap",alignItems:"center",[`${_n}-title`]:{flex:"0 0 100%",display:"block",overflow:"hidden",color:$n.colorTextHeading,fontWeight:$n.fontWeightStrong,fontSize:$n.modalHeaderTitleFontSize,lineHeight:$n.modalHeaderTitleLineHeight,[`+ ${_n}-content`]:{marginBlockStart:$n.marginXS,flexBasis:"100%",maxWidth:`calc(100% - ${$n.modalConfirmIconSize+$n.marginSM}px)`}},[`${_n}-content`]:{color:$n.colorText,fontSize:$n.fontSize},[`> ${$n.iconCls}`]:{flex:"none",marginInlineEnd:$n.marginSM,fontSize:$n.modalConfirmIconSize,[`+ ${_n}-title`]:{flex:1},[`+ ${_n}-title + ${_n}-content`]:{marginInlineStart:$n.modalConfirmIconSize+$n.marginSM}}},[`${_n}-btns`]:{textAlign:"end",marginTop:$n.marginSM,[`${$n.antCls}-btn + ${$n.antCls}-btn`]:{marginBottom:0,marginInlineStart:$n.marginXS}}},[`${_n}-error ${_n}-body > ${$n.iconCls}`]:{color:$n.colorError},[`${_n}-warning ${_n}-body > ${$n.iconCls}, - ${_n}-confirm ${_n}-body > ${$n.iconCls}`]:{color:$n.colorWarning},[`${_n}-info ${_n}-body > ${$n.iconCls}`]:{color:$n.colorInfo},[`${_n}-success ${_n}-body > ${$n.iconCls}`]:{color:$n.colorSuccess},[`${Cn}-zoom-leave ${Cn}-btns`]:{pointerEvents:"none"}}},genRTLStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-root`]:{[`${Cn}-wrap-rtl`]:{direction:"rtl",[`${Cn}-confirm-body`]:{direction:"rtl"}}}}},genWireframeStyle=$n=>{const{componentCls:Cn,antCls:_n}=$n,Pn=`${Cn}-confirm`;return{[Cn]:{[`${Cn}-content`]:{padding:0},[`${Cn}-header`]:{padding:$n.modalHeaderPadding,borderBottom:`${$n.modalHeaderBorderWidth}px ${$n.modalHeaderBorderStyle} ${$n.modalHeaderBorderColorSplit}`,marginBottom:0},[`${Cn}-body`]:{padding:$n.modalBodyPadding},[`${Cn}-footer`]:{padding:`${$n.modalFooterPaddingVertical}px ${$n.modalFooterPaddingHorizontal}px`,borderTop:`${$n.modalFooterBorderWidth}px ${$n.modalFooterBorderStyle} ${$n.modalFooterBorderColorSplit}`,borderRadius:`0 0 ${$n.borderRadiusLG}px ${$n.borderRadiusLG}px`,marginTop:0}},[Pn]:{[`${_n}-modal-body`]:{padding:`${$n.padding*2}px ${$n.padding*2}px ${$n.paddingLG}px`},[`${Pn}-body`]:{[`> ${$n.iconCls}`]:{marginInlineEnd:$n.margin,[`+ ${Pn}-title + ${Pn}-content`]:{marginInlineStart:$n.modalConfirmIconSize+$n.margin}}},[`${Pn}-btns`]:{marginTop:$n.marginLG}}}},useStyle$q=genComponentStyleHook("Modal",$n=>{const Cn=$n.padding,_n=$n.fontSizeHeading5,Pn=$n.lineHeightHeading5,In=merge$1($n,{modalBodyPadding:$n.paddingLG,modalHeaderBg:$n.colorBgElevated,modalHeaderPadding:`${Cn}px ${$n.paddingLG}px`,modalHeaderBorderWidth:$n.lineWidth,modalHeaderBorderStyle:$n.lineType,modalHeaderTitleLineHeight:Pn,modalHeaderTitleFontSize:_n,modalHeaderBorderColorSplit:$n.colorSplit,modalHeaderCloseSize:Pn*_n+Cn*2,modalContentBg:$n.colorBgElevated,modalHeadingColor:$n.colorTextHeading,modalCloseColor:$n.colorTextDescription,modalFooterBg:"transparent",modalFooterBorderColorSplit:$n.colorSplit,modalFooterBorderStyle:$n.lineType,modalFooterPaddingVertical:$n.paddingXS,modalFooterPaddingHorizontal:$n.padding,modalFooterBorderWidth:$n.lineWidth,modalConfirmTitleFontSize:$n.fontSizeLG,modalIconHoverColor:$n.colorIconHover,modalConfirmIconSize:$n.fontSize*$n.lineHeight,modalCloseBtnSize:$n.controlHeightLG*.55});return[genModalStyle(In),genModalConfirmStyle(In),genRTLStyle(In),genModalMaskStyle(In),$n.wireframe&&genWireframeStyle(In),initZoomMotion(In,"zoom")]}),genBoxStyle=$n=>({position:$n||"absolute",inset:0}),genImageMaskStyle=$n=>{const{iconCls:Cn,motionDurationSlow:_n,paddingXXS:Pn,marginXXS:In,prefixCls:Nn}=$n;return{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",background:new TinyColor("#000").setAlpha(.5).toRgbString(),cursor:"pointer",opacity:0,transition:`opacity ${_n}`,[`.${Nn}-mask-info`]:_extends$1(_extends$1({},textEllipsis),{padding:`0 ${Pn}px`,[Cn]:{marginInlineEnd:In,svg:{verticalAlign:"baseline"}}})}},genPreviewOperationsStyle=$n=>{const{previewCls:Cn,modalMaskBg:_n,paddingSM:Pn,previewOperationColorDisabled:In,motionDurationSlow:Nn}=$n,Rn=new TinyColor(_n).setAlpha(.1),Dn=Rn.clone().setAlpha(.2);return{[`${Cn}-operations`]:_extends$1(_extends$1({},resetComponent($n)),{display:"flex",flexDirection:"row-reverse",alignItems:"center",color:$n.previewOperationColor,listStyle:"none",background:Rn.toRgbString(),pointerEvents:"auto","&-operation":{marginInlineStart:Pn,padding:Pn,cursor:"pointer",transition:`all ${Nn}`,userSelect:"none","&:hover":{background:Dn.toRgbString()},"&-disabled":{color:In,pointerEvents:"none"},"&:last-of-type":{marginInlineStart:0}},"&-progress":{position:"absolute",left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%)"},"&-icon":{fontSize:$n.previewOperationSize}})}},genPreviewSwitchStyle=$n=>{const{modalMaskBg:Cn,iconCls:_n,previewOperationColorDisabled:Pn,previewCls:In,zIndexPopup:Nn,motionDurationSlow:Rn}=$n,Dn=new TinyColor(Cn).setAlpha(.1),Ln=Dn.clone().setAlpha(.2);return{[`${In}-switch-left, ${In}-switch-right`]:{position:"fixed",insetBlockStart:"50%",zIndex:Nn+1,display:"flex",alignItems:"center",justifyContent:"center",width:$n.imagePreviewSwitchSize,height:$n.imagePreviewSwitchSize,marginTop:-$n.imagePreviewSwitchSize/2,color:$n.previewOperationColor,background:Dn.toRgbString(),borderRadius:"50%",transform:"translateY(-50%)",cursor:"pointer",transition:`all ${Rn}`,pointerEvents:"auto",userSelect:"none","&:hover":{background:Ln.toRgbString()},"&-disabled":{"&, &:hover":{color:Pn,background:"transparent",cursor:"not-allowed",[`> ${_n}`]:{cursor:"not-allowed"}}},[`> ${_n}`]:{fontSize:$n.previewOperationSize}},[`${In}-switch-left`]:{insetInlineStart:$n.marginSM},[`${In}-switch-right`]:{insetInlineEnd:$n.marginSM}}},genImagePreviewStyle=$n=>{const{motionEaseOut:Cn,previewCls:_n,motionDurationSlow:Pn,componentCls:In}=$n;return[{[`${In}-preview-root`]:{[_n]:{height:"100%",textAlign:"center",pointerEvents:"none"},[`${_n}-body`]:_extends$1(_extends$1({},genBoxStyle()),{overflow:"hidden"}),[`${_n}-img`]:{maxWidth:"100%",maxHeight:"100%",verticalAlign:"middle",transform:"scale3d(1, 1, 1)",cursor:"grab",transition:`transform ${Pn} ${Cn} 0s`,userSelect:"none",pointerEvents:"auto","&-wrapper":_extends$1(_extends$1({},genBoxStyle()),{transition:`transform ${Pn} ${Cn} 0s`,display:"flex",justifyContent:"center",alignItems:"center","&::before":{display:"inline-block",width:1,height:"50%",marginInlineEnd:-1,content:'""'}})},[`${_n}-moving`]:{[`${_n}-preview-img`]:{cursor:"grabbing","&-wrapper":{transitionDuration:"0s"}}}}},{[`${In}-preview-root`]:{[`${_n}-wrap`]:{zIndex:$n.zIndexPopup}}},{[`${In}-preview-operations-wrapper`]:{position:"fixed",insetBlockStart:0,insetInlineEnd:0,zIndex:$n.zIndexPopup+1,width:"100%"},"&":[genPreviewOperationsStyle($n),genPreviewSwitchStyle($n)]}]},genImageStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{position:"relative",display:"inline-block",[`${Cn}-img`]:{width:"100%",height:"auto",verticalAlign:"middle"},[`${Cn}-img-placeholder`]:{backgroundColor:$n.colorBgContainerDisabled,backgroundImage:"url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTQuNSAyLjVoLTEzQS41LjUgMCAwIDAgMSAzdjEwYS41LjUgMCAwIDAgLjUuNWgxM2EuNS41IDAgMCAwIC41LS41VjNhLjUuNSAwIDAgMC0uNS0uNXpNNS4yODEgNC43NWExIDEgMCAwIDEgMCAyIDEgMSAwIDAgMSAwLTJ6bTguMDMgNi44M2EuMTI3LjEyNyAwIDAgMS0uMDgxLjAzSDIuNzY5YS4xMjUuMTI1IDAgMCAxLS4wOTYtLjIwN2wyLjY2MS0zLjE1NmEuMTI2LjEyNiAwIDAgMSAuMTc3LS4wMTZsLjAxNi4wMTZMNy4wOCAxMC4wOWwyLjQ3LTIuOTNhLjEyNi4xMjYgMCAwIDEgLjE3Ny0uMDE2bC4wMTUuMDE2IDMuNTg4IDQuMjQ0YS4xMjcuMTI3IDAgMCAxLS4wMi4xNzV6IiBmaWxsPSIjOEM4QzhDIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L3N2Zz4=')",backgroundRepeat:"no-repeat",backgroundPosition:"center center",backgroundSize:"30%"},[`${Cn}-mask`]:_extends$1({},genImageMaskStyle($n)),[`${Cn}-mask:hover`]:{opacity:1},[`${Cn}-placeholder`]:_extends$1({},genBoxStyle())}}},genPreviewMotion=$n=>{const{previewCls:Cn}=$n;return{[`${Cn}-root`]:initZoomMotion($n,"zoom"),"&":initFadeMotion($n,!0)}},useStyle$p=genComponentStyleHook("Image",$n=>{const Cn=`${$n.componentCls}-preview`,_n=merge$1($n,{previewCls:Cn,modalMaskBg:new TinyColor("#000").setAlpha(.45).toRgbString(),imagePreviewSwitchSize:$n.controlHeightLG});return[genImageStyle(_n),genImagePreviewStyle(_n),genModalMaskStyle(merge$1(_n,{componentCls:Cn})),genPreviewMotion(_n)]},$n=>({zIndexPopup:$n.zIndexPopupBase+80,previewOperationColor:new TinyColor($n.colorTextLightSolid).toRgbString(),previewOperationColorDisabled:new TinyColor($n.colorTextLightSolid).setAlpha(.25).toRgbString(),previewOperationSize:$n.fontSizeIcon*1.5})),icons={rotateLeft:createVNode(RotateLeftOutlined$1,null,null),rotateRight:createVNode(RotateRightOutlined$1,null,null),zoomIn:createVNode(ZoomInOutlined$1,null,null),zoomOut:createVNode(ZoomOutOutlined$1,null,null),close:createVNode(CloseOutlined$1,null,null),left:createVNode(LeftOutlined$1,null,null),right:createVNode(RightOutlined$1,null,null),flipX:createVNode(SwapOutlined$1,null,null),flipY:createVNode(SwapOutlined$1,{rotate:90},null)},previewGroupProps=()=>({previewPrefixCls:String,preview:anyType()}),InternalPreviewGroup=defineComponent({compatConfig:{MODE:3},name:"AImagePreviewGroup",inheritAttrs:!1,props:previewGroupProps(),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{prefixCls:In,rootPrefixCls:Nn}=useConfigInject("image",$n),Rn=computed(()=>`${In.value}-preview`),[Dn,Ln]=useStyle$p(In),Fn=computed(()=>{const{preview:Bn}=$n;if(Bn===!1)return Bn;const Hn=typeof Bn=="object"?Bn:{};return _extends$1(_extends$1({},Hn),{rootClassName:Ln.value,transitionName:getTransitionName$1(Nn.value,"zoom",Hn.transitionName),maskTransitionName:getTransitionName$1(Nn.value,"fade",Hn.maskTransitionName)})});return()=>Dn(createVNode(PreviewGroup$1,_objectSpread2$1(_objectSpread2$1({},_extends$1(_extends$1({},_n),$n)),{},{preview:Fn.value,icons,previewPrefixCls:Rn.value}),Pn))}}),PreviewGroup=InternalPreviewGroup,Image$1=defineComponent({name:"AImage",inheritAttrs:!1,props:imageProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,rootPrefixCls:Nn,configProvider:Rn}=useConfigInject("image",$n),[Dn,Ln]=useStyle$p(In),Fn=computed(()=>{const{preview:Bn}=$n;if(Bn===!1)return Bn;const Hn=typeof Bn=="object"?Bn:{};return _extends$1(_extends$1({icons},Hn),{transitionName:getTransitionName$1(Nn.value,"zoom",Hn.transitionName),maskTransitionName:getTransitionName$1(Nn.value,"fade",Hn.maskTransitionName)})});return()=>{var Bn,Hn;const zn=((Hn=(Bn=Rn.locale)===null||Bn===void 0?void 0:Bn.value)===null||Hn===void 0?void 0:Hn.Image)||localeValues$1.Image,Wn=()=>createVNode("div",{class:`${In.value}-mask-info`},[createVNode(EyeOutlined$1,null,null),zn==null?void 0:zn.preview]),{previewMask:Yn=_n.previewMask||Wn}=$n;return Dn(createVNode(Image$3,_objectSpread2$1(_objectSpread2$1({},_extends$1(_extends$1(_extends$1({},Pn),$n),{prefixCls:In.value})),{},{preview:Fn.value,rootClassName:classNames($n.rootClassName,Ln.value)}),_extends$1(_extends$1({},_n),{previewMask:typeof Yn=="function"?Yn:null})))}}});Image$1.PreviewGroup=PreviewGroup;Image$1.install=function($n){return $n.component(Image$1.name,Image$1),$n.component(Image$1.PreviewGroup.name,Image$1.PreviewGroup),$n};const Image$2=Image$1;var UpOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"}}]},name:"up",theme:"outlined"};const UpOutlinedSvg=UpOutlined$2;function _objectSpread$p($n){for(var Cn=1;CnNumber.MAX_SAFE_INTEGER)return String(supportBigInt()?BigInt($n).toString():Number.MAX_SAFE_INTEGER);if($nNumber.MAX_SAFE_INTEGER)return new NumberDecimal(Number.MAX_SAFE_INTEGER);if(Pn0&&arguments[0]!==void 0?arguments[0]:!0)?this.isInvalidate()?"":num2str(this.number):this.origin}}class BigIntDecimal{constructor(Cn){if(this.origin="",isEmpty(Cn)){this.empty=!0;return}if(this.origin=String(Cn),Cn==="-"||Number.isNaN(Cn)){this.nan=!0;return}let _n=Cn;if(isE(_n)&&(_n=Number(_n)),_n=typeof _n=="string"?_n:num2str(_n),validateNumber(_n)){const Pn=trimNumber(_n);this.negative=Pn.negative;const In=Pn.trimStr.split(".");this.integer=BigInt(In[0]);const Nn=In[1]||"0";this.decimal=BigInt(Nn),this.decimalLen=Nn.length}else this.nan=!0}getMark(){return this.negative?"-":""}getIntegerStr(){return this.integer.toString()}getDecimalStr(){return this.decimal.toString().padStart(this.decimalLen,"0")}alignDecimal(Cn){const _n=`${this.getMark()}${this.getIntegerStr()}${this.getDecimalStr().padEnd(Cn,"0")}`;return BigInt(_n)}negate(){const Cn=new BigIntDecimal(this.toString());return Cn.negative=!Cn.negative,Cn}add(Cn){if(this.isInvalidate())return new BigIntDecimal(Cn);const _n=new BigIntDecimal(Cn);if(_n.isInvalidate())return this;const Pn=Math.max(this.getDecimalStr().length,_n.getDecimalStr().length),In=this.alignDecimal(Pn),Nn=_n.alignDecimal(Pn),Rn=(In+Nn).toString(),{negativeStr:Dn,trimStr:Ln}=trimNumber(Rn),Fn=`${Dn}${Ln.padStart(Pn+1,"0")}`;return new BigIntDecimal(`${Fn.slice(0,-Pn)}.${Fn.slice(-Pn)}`)}isEmpty(){return this.empty}isNaN(){return this.nan}isInvalidate(){return this.isEmpty()||this.isNaN()}equals(Cn){return this.toString()===(Cn==null?void 0:Cn.toString())}lessEquals(Cn){return this.add(Cn.negate().toString()).toNumber()<=0}toNumber(){return this.isNaN()?NaN:Number(this.toString())}toString(){return(arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0)?this.isInvalidate()?"":trimNumber(`${this.getMark()}${this.getIntegerStr()}.${this.getDecimalStr()}`).fullStr:this.origin}}function getMiniDecimal($n){return supportBigInt()?new BigIntDecimal($n):new NumberDecimal($n)}function toFixed($n,Cn,_n){let Pn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if($n==="")return"";const{negativeStr:In,integerStr:Nn,decimalStr:Rn}=trimNumber($n),Dn=`${Cn}${Rn}`,Ln=`${In}${Nn}`;if(_n>=0){const Fn=Number(Rn[_n]);if(Fn>=5&&!Pn){const Bn=getMiniDecimal($n).add(`${In}0.${"0".repeat(_n)}${10-Fn}`);return toFixed(Bn.toString(),Cn,_n,Pn)}return _n===0?Ln:`${Ln}${Cn}${Rn.padEnd(_n,"0").slice(0,_n)}`}return Dn===".0"?Ln:`${Ln}${Dn}`}const STEP_INTERVAL=200,STEP_DELAY=600,StepHandler=defineComponent({compatConfig:{MODE:3},name:"StepHandler",inheritAttrs:!1,props:{prefixCls:String,upDisabled:Boolean,downDisabled:Boolean,onStep:functionType()},slots:Object,setup($n,Cn){let{slots:_n,emit:Pn}=Cn;const In=ref(),Nn=(Dn,Ln)=>{Dn.preventDefault(),Pn("step",Ln);function Fn(){Pn("step",Ln),In.value=setTimeout(Fn,STEP_INTERVAL)}In.value=setTimeout(Fn,STEP_DELAY)},Rn=()=>{clearTimeout(In.value)};return onBeforeUnmount(()=>{Rn()}),()=>{if(isMobile())return null;const{prefixCls:Dn,upDisabled:Ln,downDisabled:Fn}=$n,Bn=`${Dn}-handler`,Hn=classNames(Bn,`${Bn}-up`,{[`${Bn}-up-disabled`]:Ln}),zn=classNames(Bn,`${Bn}-down`,{[`${Bn}-down-disabled`]:Fn}),Wn={unselectable:"on",role:"button",onMouseup:Rn,onMouseleave:Rn},{upNode:Yn,downNode:Gn}=_n;return createVNode("div",{class:`${Bn}-wrap`},[createVNode("span",_objectSpread2$1(_objectSpread2$1({},Wn),{},{onMousedown:Go=>{Nn(Go,!0)},"aria-label":"Increase Value","aria-disabled":Ln,class:Hn}),[(Yn==null?void 0:Yn())||createVNode("span",{unselectable:"on",class:`${Dn}-handler-up-inner`},null)]),createVNode("span",_objectSpread2$1(_objectSpread2$1({},Wn),{},{onMousedown:Go=>{Nn(Go,!1)},"aria-label":"Decrease Value","aria-disabled":Fn,class:zn}),[(Gn==null?void 0:Gn())||createVNode("span",{unselectable:"on",class:`${Dn}-handler-down-inner`},null)])])}}});function useCursor($n,Cn){const _n=ref(null);function Pn(){try{const{selectionStart:Nn,selectionEnd:Rn,value:Dn}=$n.value,Ln=Dn.substring(0,Nn),Fn=Dn.substring(Rn);_n.value={start:Nn,end:Rn,value:Dn,beforeTxt:Ln,afterTxt:Fn}}catch{}}function In(){if($n.value&&_n.value&&Cn.value)try{const{value:Nn}=$n.value,{beforeTxt:Rn,afterTxt:Dn,start:Ln}=_n.value;let Fn=Nn.length;if(Nn.endsWith(Dn))Fn=Nn.length-_n.value.afterTxt.length;else if(Nn.startsWith(Rn))Fn=Rn.length;else{const Bn=Rn[Ln-1],Hn=Nn.indexOf(Bn,Ln-1);Hn!==-1&&(Fn=Hn+1)}$n.value.setSelectionRange(Fn,Fn)}catch(Nn){`${Nn.message}`}}return[Pn,In]}const useFrame=()=>{const $n=shallowRef(0),Cn=()=>{wrapperRaf.cancel($n.value)};return onBeforeUnmount(()=>{Cn()}),_n=>{Cn(),$n.value=wrapperRaf(()=>{_n()})}};var __rest$z=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n||Cn.isEmpty()?Cn.toString():Cn.toNumber(),getDecimalIfValidate=$n=>{const Cn=getMiniDecimal($n);return Cn.isInvalidate()?null:Cn},inputNumberProps$1=()=>({stringMode:booleanType(),defaultValue:someType([String,Number]),value:someType([String,Number]),prefixCls:stringType(),min:someType([String,Number]),max:someType([String,Number]),step:someType([String,Number],1),tabindex:Number,controls:booleanType(!0),readonly:booleanType(),disabled:booleanType(),autofocus:booleanType(),keyboard:booleanType(!0),parser:functionType(),formatter:functionType(),precision:Number,decimalSeparator:String,onInput:functionType(),onChange:functionType(),onPressEnter:functionType(),onStep:functionType(),onBlur:functionType(),onFocus:functionType()}),VcInputNumber=defineComponent({compatConfig:{MODE:3},name:"InnerInputNumber",inheritAttrs:!1,props:_extends$1(_extends$1({},inputNumberProps$1()),{lazy:Boolean}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In,expose:Nn}=Cn;const Rn=shallowRef(),Dn=shallowRef(!1),Ln=shallowRef(!1),Fn=shallowRef(!1),Bn=shallowRef(getMiniDecimal($n.value));function Hn(ya){$n.value===void 0&&(Bn.value=ya)}const zn=(ya,ba)=>{if(!ba)return $n.precision>=0?$n.precision:Math.max(getNumberPrecision(ya),getNumberPrecision($n.step))},Wn=ya=>{const ba=String(ya);if($n.parser)return $n.parser(ba);let Ia=ba;return $n.decimalSeparator&&(Ia=Ia.replace($n.decimalSeparator,".")),Ia.replace(/[^\w.-]+/g,"")},Yn=shallowRef(""),Gn=(ya,ba)=>{if($n.formatter)return $n.formatter(ya,{userTyping:ba,input:String(Yn.value)});let Ia=typeof ya=="number"?num2str(ya):ya;if(!ba){const Ea=zn(Ia,ba);if(validateNumber(Ia)&&($n.decimalSeparator||Ea>=0)){const xa=$n.decimalSeparator||".";Ia=toFixed(Ia,xa,Ea)}}return Ia},Go=(()=>{const ya=$n.value;return Bn.value.isInvalidate()&&["string","number"].includes(typeof ya)?Number.isNaN(ya)?"":ya:Gn(Bn.value.toString(),!1)})();Yn.value=Go;function Xn(ya,ba){Yn.value=Gn(ya.isInvalidate()?ya.toString(!1):ya.toString(!ba),ba)}const Yo=computed(()=>getDecimalIfValidate($n.max)),qo=computed(()=>getDecimalIfValidate($n.min)),Jo=computed(()=>!Yo.value||!Bn.value||Bn.value.isInvalidate()?!1:Yo.value.lessEquals(Bn.value)),Zo=computed(()=>!qo.value||!Bn.value||Bn.value.isInvalidate()?!1:Bn.value.lessEquals(qo.value)),[rr,nr]=useCursor(Rn,Dn),ta=ya=>Yo.value&&!ya.lessEquals(Yo.value)?Yo.value:qo.value&&!qo.value.lessEquals(ya)?qo.value:null,oa=ya=>!ta(ya),ra=(ya,ba)=>{var Ia;let Ea=ya,xa=oa(Ea)||Ea.isEmpty();if(!Ea.isEmpty()&&!ba&&(Ea=ta(Ea)||Ea,xa=!0),!$n.readonly&&!$n.disabled&&xa){const Ta=Ea.toString(),wa=zn(Ta,ba);return wa>=0&&(Ea=getMiniDecimal(toFixed(Ta,".",wa))),Ea.equals(Bn.value)||(Hn(Ea),(Ia=$n.onChange)===null||Ia===void 0||Ia.call($n,Ea.isEmpty()?null:getDecimalValue($n.stringMode,Ea)),$n.value===void 0&&Xn(Ea,ba)),Ea}return Bn.value},ea=useFrame(),la=ya=>{var ba;if(rr(),Yn.value=ya,!Fn.value){const Ia=Wn(ya),Ea=getMiniDecimal(Ia);Ea.isNaN()||ra(Ea,!0)}(ba=$n.onInput)===null||ba===void 0||ba.call($n,ya),ea(()=>{let Ia=ya;$n.parser||(Ia=ya.replace(/。/g,".")),Ia!==ya&&la(Ia)})},ua=()=>{Fn.value=!0},ga=()=>{Fn.value=!1,la(Rn.value.value)},aa=ya=>{la(ya.target.value)},ca=ya=>{var ba,Ia;if(ya&&Jo.value||!ya&&Zo.value)return;Ln.value=!1;let Ea=getMiniDecimal($n.step);ya||(Ea=Ea.negate());const xa=(Bn.value||getMiniDecimal(0)).add(Ea.toString()),Ta=ra(xa,!1);(ba=$n.onStep)===null||ba===void 0||ba.call($n,getDecimalValue($n.stringMode,Ta),{offset:$n.step,type:ya?"up":"down"}),(Ia=Rn.value)===null||Ia===void 0||Ia.focus()},sa=ya=>{const ba=getMiniDecimal(Wn(Yn.value));let Ia=ba;ba.isNaN()?Ia=Bn.value:Ia=ra(ba,ya),$n.value!==void 0?Xn(Bn.value,!1):Ia.isNaN()||Xn(Ia,!1)},ia=ya=>{var ba;const{which:Ia}=ya;Ln.value=!0,Ia===KeyCode$1.ENTER&&(Fn.value||(Ln.value=!1),sa(!1),(ba=$n.onPressEnter)===null||ba===void 0||ba.call($n,ya)),$n.keyboard!==!1&&!Fn.value&&[KeyCode$1.UP,KeyCode$1.DOWN].includes(Ia)&&(ca(KeyCode$1.UP===Ia),ya.preventDefault())},fa=()=>{Ln.value=!1},ma=ya=>{sa(!1),Dn.value=!1,Ln.value=!1,In("blur",ya)};return watch(()=>$n.precision,()=>{Bn.value.isInvalidate()||Xn(Bn.value,!1)},{flush:"post"}),watch(()=>$n.value,()=>{const ya=getMiniDecimal($n.value);Bn.value=ya;const ba=getMiniDecimal(Wn(Yn.value));(!ya.equals(ba)||!Ln.value||$n.formatter)&&Xn(ya,Ln.value)},{flush:"post"}),watch(Yn,()=>{$n.formatter&&nr()},{flush:"post"}),watch(()=>$n.disabled,ya=>{ya&&(Dn.value=!1)}),Nn({focus:()=>{var ya;(ya=Rn.value)===null||ya===void 0||ya.focus()},blur:()=>{var ya;(ya=Rn.value)===null||ya===void 0||ya.blur()}}),()=>{const ya=_extends$1(_extends$1({},_n),$n),{prefixCls:ba="rc-input-number",min:Ia,max:Ea,step:xa=1,defaultValue:Ta,value:wa,disabled:La,readonly:Na,keyboard:$a,controls:ka=!0,autofocus:Ha,stringMode:da,parser:pa,formatter:Sa,precision:Aa,decimalSeparator:Ra,onChange:Fa,onInput:za,onPressEnter:Wa,onStep:Ya,lazy:ja,class:qa,style:Xa}=ya,Oa=__rest$z(ya,["prefixCls","min","max","step","defaultValue","value","disabled","readonly","keyboard","controls","autofocus","stringMode","parser","formatter","precision","decimalSeparator","onChange","onInput","onPressEnter","onStep","lazy","class","style"]),{upHandler:Ma,downHandler:Ua}=Pn,Qa=`${ba}-input`,ri={};return ja?ri.onChange=aa:ri.onInput=aa,createVNode("div",{class:classNames(ba,qa,{[`${ba}-focused`]:Dn.value,[`${ba}-disabled`]:La,[`${ba}-readonly`]:Na,[`${ba}-not-a-number`]:Bn.value.isNaN(),[`${ba}-out-of-range`]:!Bn.value.isInvalidate()&&!oa(Bn.value)}),style:Xa,onKeydown:ia,onKeyup:fa},[ka&&createVNode(StepHandler,{prefixCls:ba,upDisabled:Jo.value,downDisabled:Zo.value,onStep:ca},{upNode:Ma,downNode:Ua}),createVNode("div",{class:`${Qa}-wrap`},[createVNode("input",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({autofocus:Ha,autocomplete:"off",role:"spinbutton","aria-valuemin":Ia,"aria-valuemax":Ea,"aria-valuenow":Bn.value.isInvalidate()?null:Bn.value.toString(),step:xa},Oa),{},{ref:Rn,class:Qa,value:Yn.value,disabled:La,readonly:Na,onFocus:fi=>{Dn.value=!0,In("focus",fi)}},ri),{},{onBlur:ma,onCompositionstart:ua,onCompositionend:ga}),null)])])}}});function isValidValue($n){return $n!=null}const genInputNumberStyles=$n=>{const{componentCls:Cn,lineWidth:_n,lineType:Pn,colorBorder:In,borderRadius:Nn,fontSizeLG:Rn,controlHeightLG:Dn,controlHeightSM:Ln,colorError:Fn,inputPaddingHorizontalSM:Bn,colorTextDescription:Hn,motionDurationMid:zn,colorPrimary:Wn,controlHeight:Yn,inputPaddingHorizontal:Gn,colorBgContainer:Go,colorTextDisabled:Xn,borderRadiusSM:Yo,borderRadiusLG:qo,controlWidth:Jo,handleVisible:Zo}=$n;return[{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),genBasicInputStyle($n)),genStatusStyle($n,Cn)),{display:"inline-block",width:Jo,margin:0,padding:0,border:`${_n}px ${Pn} ${In}`,borderRadius:Nn,"&-rtl":{direction:"rtl",[`${Cn}-input`]:{direction:"rtl"}},"&-lg":{padding:0,fontSize:Rn,borderRadius:qo,[`input${Cn}-input`]:{height:Dn-2*_n}},"&-sm":{padding:0,borderRadius:Yo,[`input${Cn}-input`]:{height:Ln-2*_n,padding:`0 ${Bn}px`}},"&:hover":_extends$1({},genHoverStyle($n)),"&-focused":_extends$1({},genActiveStyle($n)),"&-disabled":_extends$1(_extends$1({},genDisabledStyle($n)),{[`${Cn}-input`]:{cursor:"not-allowed"}}),"&-out-of-range":{input:{color:Fn}},"&-group":_extends$1(_extends$1(_extends$1({},resetComponent($n)),genInputGroupStyle($n)),{"&-wrapper":{display:"inline-block",textAlign:"start",verticalAlign:"top",[`${Cn}-affix-wrapper`]:{width:"100%"},"&-lg":{[`${Cn}-group-addon`]:{borderRadius:qo}},"&-sm":{[`${Cn}-group-addon`]:{borderRadius:Yo}}}}),[Cn]:{"&-input":_extends$1(_extends$1({width:"100%",height:Yn-2*_n,padding:`0 ${Gn}px`,textAlign:"start",backgroundColor:"transparent",border:0,borderRadius:Nn,outline:0,transition:`all ${zn} linear`,appearance:"textfield",color:$n.colorText,fontSize:"inherit",verticalAlign:"top"},genPlaceholderStyle($n.colorTextPlaceholder)),{'&[type="number"]::-webkit-inner-spin-button, &[type="number"]::-webkit-outer-spin-button':{margin:0,webkitAppearance:"none",appearance:"none"}})}})},{[Cn]:{[`&:hover ${Cn}-handler-wrap, &-focused ${Cn}-handler-wrap`]:{opacity:1},[`${Cn}-handler-wrap`]:{position:"absolute",insetBlockStart:0,insetInlineEnd:0,width:$n.handleWidth,height:"100%",background:Go,borderStartStartRadius:0,borderStartEndRadius:Nn,borderEndEndRadius:Nn,borderEndStartRadius:0,opacity:Zo===!0?1:0,display:"flex",flexDirection:"column",alignItems:"stretch",transition:`opacity ${zn} linear ${zn}`,[`${Cn}-handler`]:{display:"flex",alignItems:"center",justifyContent:"center",flex:"auto",height:"40%",[` - ${Cn}-handler-up-inner, - ${Cn}-handler-down-inner - `]:{marginInlineEnd:0,fontSize:$n.handleFontSize}}},[`${Cn}-handler`]:{height:"50%",overflow:"hidden",color:Hn,fontWeight:"bold",lineHeight:0,textAlign:"center",cursor:"pointer",borderInlineStart:`${_n}px ${Pn} ${In}`,transition:`all ${zn} linear`,"&:active":{background:$n.colorFillAlter},"&:hover":{height:"60%",[` - ${Cn}-handler-up-inner, - ${Cn}-handler-down-inner - `]:{color:Wn}},"&-up-inner, &-down-inner":_extends$1(_extends$1({},resetIcon()),{color:Hn,transition:`all ${zn} linear`,userSelect:"none"})},[`${Cn}-handler-up`]:{borderStartEndRadius:Nn},[`${Cn}-handler-down`]:{borderBlockStart:`${_n}px ${Pn} ${In}`,borderEndEndRadius:Nn},"&-disabled, &-readonly":{[`${Cn}-handler-wrap`]:{display:"none"}},[` - ${Cn}-handler-up-disabled, - ${Cn}-handler-down-disabled - `]:{cursor:"not-allowed"},[` - ${Cn}-handler-up-disabled:hover &-handler-up-inner, - ${Cn}-handler-down-disabled:hover &-handler-down-inner - `]:{color:Xn}}},{[`${Cn}-borderless`]:{borderColor:"transparent",boxShadow:"none",[`${Cn}-handler-down`]:{borderBlockStartWidth:0}}}]},genAffixWrapperStyles=$n=>{const{componentCls:Cn,inputPaddingHorizontal:_n,inputAffixPadding:Pn,controlWidth:In,borderRadiusLG:Nn,borderRadiusSM:Rn}=$n;return{[`${Cn}-affix-wrapper`]:_extends$1(_extends$1(_extends$1({},genBasicInputStyle($n)),genStatusStyle($n,`${Cn}-affix-wrapper`)),{position:"relative",display:"inline-flex",width:In,padding:0,paddingInlineStart:_n,"&-lg":{borderRadius:Nn},"&-sm":{borderRadius:Rn},[`&:not(${Cn}-affix-wrapper-disabled):hover`]:_extends$1(_extends$1({},genHoverStyle($n)),{zIndex:1}),"&-focused, &:focus":{zIndex:1},"&-disabled":{[`${Cn}[disabled]`]:{background:"transparent"}},[`> div${Cn}`]:{width:"100%",border:"none",outline:"none",[`&${Cn}-focused`]:{boxShadow:"none !important"}},[`input${Cn}-input`]:{padding:0},"&::before":{width:0,visibility:"hidden",content:'"\\a0"'},[`${Cn}-handler-wrap`]:{zIndex:2},[Cn]:{"&-prefix, &-suffix":{display:"flex",flex:"none",alignItems:"center",pointerEvents:"none"},"&-prefix":{marginInlineEnd:Pn},"&-suffix":{position:"absolute",insetBlockStart:0,insetInlineEnd:0,zIndex:1,height:"100%",marginInlineEnd:_n,marginInlineStart:Pn}}})}},useStyle$o=genComponentStyleHook("InputNumber",$n=>{const Cn=initInputToken($n);return[genInputNumberStyles(Cn),genAffixWrapperStyles(Cn),genCompactItemStyle(Cn)]},$n=>({controlWidth:90,handleWidth:$n.controlHeightSM-$n.lineWidth*2,handleFontSize:$n.fontSize/2,handleVisible:"auto"}));var __rest$y=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In_extends$1(_extends$1({},baseProps$1),{size:stringType(),bordered:booleanType(!0),placeholder:String,name:String,id:String,type:String,addonBefore:PropTypes.any,addonAfter:PropTypes.any,prefix:PropTypes.any,"onUpdate:value":baseProps$1.onChange,valueModifiers:Object,status:stringType()}),InputNumber=defineComponent({compatConfig:{MODE:3},name:"AInputNumber",inheritAttrs:!1,props:inputNumberProps(),slots:Object,setup($n,Cn){let{emit:_n,expose:Pn,attrs:In,slots:Nn}=Cn;const Rn=useInjectFormItemContext(),Dn=FormItemInputContext.useInject(),Ln=computed(()=>getMergedStatus(Dn.status,$n.status)),{prefixCls:Fn,size:Bn,direction:Hn,disabled:zn}=useConfigInject("input-number",$n),{compactSize:Wn,compactItemClassnames:Yn}=useCompactItemContext(Fn,Hn),Gn=useInjectDisabled(),Go=computed(()=>{var la;return(la=zn.value)!==null&&la!==void 0?la:Gn.value}),[Xn,Yo]=useStyle$o(Fn),qo=computed(()=>Wn.value||Bn.value),Jo=shallowRef($n.value===void 0?$n.defaultValue:$n.value),Zo=shallowRef(!1);watch(()=>$n.value,()=>{Jo.value=$n.value});const rr=shallowRef(null),nr=()=>{var la;(la=rr.value)===null||la===void 0||la.focus()};Pn({focus:nr,blur:()=>{var la;(la=rr.value)===null||la===void 0||la.blur()}});const oa=la=>{$n.value===void 0&&(Jo.value=la),_n("update:value",la),_n("change",la),Rn.onFieldChange()},ra=la=>{Zo.value=!1,_n("blur",la),Rn.onFieldBlur()},ea=la=>{Zo.value=!0,_n("focus",la)};return()=>{var la,ua,ga,aa;const{hasFeedback:ca,isFormItemInput:sa,feedbackIcon:ia}=Dn,fa=(la=$n.id)!==null&&la!==void 0?la:Rn.id.value,ma=_extends$1(_extends$1(_extends$1({},In),$n),{id:fa,disabled:Go.value}),{class:ya,bordered:ba,readonly:Ia,style:Ea,addonBefore:xa=(ua=Nn.addonBefore)===null||ua===void 0?void 0:ua.call(Nn),addonAfter:Ta=(ga=Nn.addonAfter)===null||ga===void 0?void 0:ga.call(Nn),prefix:wa=(aa=Nn.prefix)===null||aa===void 0?void 0:aa.call(Nn),valueModifiers:La={}}=ma,Na=__rest$y(ma,["class","bordered","readonly","style","addonBefore","addonAfter","prefix","valueModifiers"]),$a=Fn.value,ka=classNames({[`${$a}-lg`]:qo.value==="large",[`${$a}-sm`]:qo.value==="small",[`${$a}-rtl`]:Hn.value==="rtl",[`${$a}-readonly`]:Ia,[`${$a}-borderless`]:!ba,[`${$a}-in-form-item`]:sa},getStatusClassNames($a,Ln.value),ya,Yn.value,Yo.value);let Ha=createVNode(VcInputNumber,_objectSpread2$1(_objectSpread2$1({},omit$1(Na,["size","defaultValue"])),{},{ref:rr,lazy:!!La.lazy,value:Jo.value,class:ka,prefixCls:$a,readonly:Ia,onChange:oa,onBlur:ra,onFocus:ea}),{upHandler:Nn.upIcon?()=>createVNode("span",{class:`${$a}-handler-up-inner`},[Nn.upIcon()]):()=>createVNode(UpOutlined$1,{class:`${$a}-handler-up-inner`},null),downHandler:Nn.downIcon?()=>createVNode("span",{class:`${$a}-handler-down-inner`},[Nn.downIcon()]):()=>createVNode(DownOutlined$1,{class:`${$a}-handler-down-inner`},null)});const da=isValidValue(xa)||isValidValue(Ta),pa=isValidValue(wa);if(pa||ca){const Sa=classNames(`${$a}-affix-wrapper`,getStatusClassNames(`${$a}-affix-wrapper`,Ln.value,ca),{[`${$a}-affix-wrapper-focused`]:Zo.value,[`${$a}-affix-wrapper-disabled`]:Go.value,[`${$a}-affix-wrapper-sm`]:qo.value==="small",[`${$a}-affix-wrapper-lg`]:qo.value==="large",[`${$a}-affix-wrapper-rtl`]:Hn.value==="rtl",[`${$a}-affix-wrapper-readonly`]:Ia,[`${$a}-affix-wrapper-borderless`]:!ba,[`${ya}`]:!da&&ya},Yo.value);Ha=createVNode("div",{class:Sa,style:Ea,onClick:nr},[pa&&createVNode("span",{class:`${$a}-prefix`},[wa]),Ha,ca&&createVNode("span",{class:`${$a}-suffix`},[ia])])}if(da){const Sa=`${$a}-group`,Aa=`${Sa}-addon`,Ra=xa?createVNode("div",{class:Aa},[xa]):null,Fa=Ta?createVNode("div",{class:Aa},[Ta]):null,za=classNames(`${$a}-wrapper`,Sa,{[`${Sa}-rtl`]:Hn.value==="rtl"},Yo.value),Wa=classNames(`${$a}-group-wrapper`,{[`${$a}-group-wrapper-sm`]:qo.value==="small",[`${$a}-group-wrapper-lg`]:qo.value==="large",[`${$a}-group-wrapper-rtl`]:Hn.value==="rtl"},getStatusClassNames(`${Fn}-group-wrapper`,Ln.value,ca),ya,Yo.value);Ha=createVNode("div",{class:Wa,style:Ea},[createVNode("div",{class:za},[Ra&&createVNode(NoCompactStyle,null,{default:()=>[createVNode(NoFormStatus,null,{default:()=>[Ra]})]}),Ha,Fa&&createVNode(NoCompactStyle,null,{default:()=>[createVNode(NoFormStatus,null,{default:()=>[Fa]})]})])])}return Xn(cloneElement(Ha,{style:Ea}))}}}),index$j=_extends$1(InputNumber,{install:$n=>($n.component(InputNumber.name,InputNumber),$n)}),genLayoutLightStyle=$n=>{const{componentCls:Cn,colorBgContainer:_n,colorBgBody:Pn,colorText:In}=$n;return{[`${Cn}-sider-light`]:{background:_n,[`${Cn}-sider-trigger`]:{color:In,background:_n},[`${Cn}-sider-zero-width-trigger`]:{color:In,background:_n,border:`1px solid ${Pn}`,borderInlineStart:0}}}},genLayoutStyle=$n=>{const{antCls:Cn,componentCls:_n,colorText:Pn,colorTextLightSolid:In,colorBgHeader:Nn,colorBgBody:Rn,colorBgTrigger:Dn,layoutHeaderHeight:Ln,layoutHeaderPaddingInline:Fn,layoutHeaderColor:Bn,layoutFooterPadding:Hn,layoutTriggerHeight:zn,layoutZeroTriggerSize:Wn,motionDurationMid:Yn,motionDurationSlow:Gn,fontSize:Go,borderRadius:Xn}=$n;return{[_n]:_extends$1(_extends$1({display:"flex",flex:"auto",flexDirection:"column",minHeight:0,background:Rn,"&, *":{boxSizing:"border-box"},[`&${_n}-has-sider`]:{flexDirection:"row",[`> ${_n}, > ${_n}-content`]:{width:0}},[`${_n}-header, &${_n}-footer`]:{flex:"0 0 auto"},[`${_n}-header`]:{height:Ln,paddingInline:Fn,color:Bn,lineHeight:`${Ln}px`,background:Nn,[`${Cn}-menu`]:{lineHeight:"inherit"}},[`${_n}-footer`]:{padding:Hn,color:Pn,fontSize:Go,background:Rn},[`${_n}-content`]:{flex:"auto",minHeight:0},[`${_n}-sider`]:{position:"relative",minWidth:0,background:Nn,transition:`all ${Yn}, background 0s`,"&-children":{height:"100%",marginTop:-.1,paddingTop:.1,[`${Cn}-menu${Cn}-menu-inline-collapsed`]:{width:"auto"}},"&-has-trigger":{paddingBottom:zn},"&-right":{order:1},"&-trigger":{position:"fixed",bottom:0,zIndex:1,height:zn,color:In,lineHeight:`${zn}px`,textAlign:"center",background:Dn,cursor:"pointer",transition:`all ${Yn}`},"&-zero-width":{"> *":{overflow:"hidden"},"&-trigger":{position:"absolute",top:Ln,insetInlineEnd:-Wn,zIndex:1,width:Wn,height:Wn,color:In,fontSize:$n.fontSizeXL,display:"flex",alignItems:"center",justifyContent:"center",background:Nn,borderStartStartRadius:0,borderStartEndRadius:Xn,borderEndEndRadius:Xn,borderEndStartRadius:0,cursor:"pointer",transition:`background ${Gn} ease`,"&::after":{position:"absolute",inset:0,background:"transparent",transition:`all ${Gn}`,content:'""'},"&:hover::after":{background:"rgba(255, 255, 255, 0.2)"},"&-right":{insetInlineStart:-Wn,borderStartStartRadius:Xn,borderStartEndRadius:0,borderEndEndRadius:0,borderEndStartRadius:Xn}}}}},genLayoutLightStyle($n)),{"&-rtl":{direction:"rtl"}})}},useStyle$n=genComponentStyleHook("Layout",$n=>{const{colorText:Cn,controlHeightSM:_n,controlHeight:Pn,controlHeightLG:In,marginXXS:Nn}=$n,Rn=In*1.25,Dn=merge$1($n,{layoutHeaderHeight:Pn*2,layoutHeaderPaddingInline:Rn,layoutHeaderColor:Cn,layoutFooterPadding:`${_n}px ${Rn}px`,layoutTriggerHeight:In+Nn*2,layoutZeroTriggerSize:In});return[genLayoutStyle(Dn)]},$n=>{const{colorBgLayout:Cn}=$n;return{colorBgHeader:"#001529",colorBgBody:Cn,colorBgTrigger:"#002140"}}),basicProps=()=>({prefixCls:String,hasSider:{type:Boolean,default:void 0},tagName:String});function generator($n){let{suffixCls:Cn,tagName:_n,name:Pn}=$n;return In=>defineComponent({compatConfig:{MODE:3},name:Pn,props:basicProps(),setup(Rn,Dn){let{slots:Ln}=Dn;const{prefixCls:Fn}=useConfigInject(Cn,Rn);return()=>{const Bn=_extends$1(_extends$1({},Rn),{prefixCls:Fn.value,tagName:_n});return createVNode(In,Bn,Ln)}}})}const Basic=defineComponent({compatConfig:{MODE:3},props:basicProps(),setup($n,Cn){let{slots:_n}=Cn;return()=>createVNode($n.tagName,{class:$n.prefixCls},_n)}}),BasicLayout=defineComponent({compatConfig:{MODE:3},inheritAttrs:!1,props:basicProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("",$n),[Rn,Dn]=useStyle$n(In),Ln=ref([]);provide(SiderHookProviderKey,{addSider:Hn=>{Ln.value=[...Ln.value,Hn]},removeSider:Hn=>{Ln.value=Ln.value.filter(zn=>zn!==Hn)}});const Bn=computed(()=>{const{prefixCls:Hn,hasSider:zn}=$n;return{[Dn.value]:!0,[`${Hn}`]:!0,[`${Hn}-has-sider`]:typeof zn=="boolean"?zn:Ln.value.length>0,[`${Hn}-rtl`]:Nn.value==="rtl"}});return()=>{const{tagName:Hn}=$n;return Rn(createVNode(Hn,_extends$1(_extends$1({},Pn),{class:[Bn.value,Pn.class]}),_n))}}}),Layout=generator({suffixCls:"layout",tagName:"section",name:"ALayout"})(BasicLayout),Header$1=generator({suffixCls:"layout-header",tagName:"header",name:"ALayoutHeader"})(Basic),Footer$1=generator({suffixCls:"layout-footer",tagName:"footer",name:"ALayoutFooter"})(Basic),Content=generator({suffixCls:"layout-content",tagName:"main",name:"ALayoutContent"})(Basic),Layout$1=Layout;var BarsOutlined$2={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 192H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM104 228a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"bars",theme:"outlined"};const BarsOutlinedSvg=BarsOutlined$2;function _objectSpread$o($n){for(var Cn=1;Cn({prefixCls:String,collapsible:{type:Boolean,default:void 0},collapsed:{type:Boolean,default:void 0},defaultCollapsed:{type:Boolean,default:void 0},reverseArrow:{type:Boolean,default:void 0},zeroWidthTriggerStyle:{type:Object,default:void 0},trigger:PropTypes.any,width:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),collapsedWidth:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),breakpoint:PropTypes.oneOf(tuple$1("xs","sm","md","lg","xl","xxl","xxxl")),theme:PropTypes.oneOf(tuple$1("light","dark")).def("dark"),onBreakpoint:Function,onCollapse:Function}),generateId=(()=>{let $n=0;return function(){let Cn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"";return $n+=1,`${Cn}${$n}`}})(),Sider=defineComponent({compatConfig:{MODE:3},name:"ALayoutSider",inheritAttrs:!1,props:initDefaultProps(siderProps(),{collapsible:!1,defaultCollapsed:!1,reverseArrow:!1,width:200,collapsedWidth:80}),emits:["breakpoint","update:collapsed","collapse"],setup($n,Cn){let{emit:_n,attrs:Pn,slots:In}=Cn;const{prefixCls:Nn}=useConfigInject("layout-sider",$n),Rn=inject(SiderHookProviderKey,void 0),Dn=shallowRef(!!($n.collapsed!==void 0?$n.collapsed:$n.defaultCollapsed)),Ln=shallowRef(!1);watch(()=>$n.collapsed,()=>{Dn.value=!!$n.collapsed}),provide(SiderCollapsedKey,Dn);const Fn=(Gn,Go)=>{$n.collapsed===void 0&&(Dn.value=Gn),_n("update:collapsed",Gn),_n("collapse",Gn,Go)},Bn=shallowRef(Gn=>{Ln.value=Gn.matches,_n("breakpoint",Gn.matches),Dn.value!==Gn.matches&&Fn(Gn.matches,"responsive")});let Hn;function zn(Gn){return Bn.value(Gn)}const Wn=generateId("ant-sider-");Rn&&Rn.addSider(Wn),onMounted(()=>{watch(()=>$n.breakpoint,()=>{try{Hn==null||Hn.removeEventListener("change",zn)}catch{Hn==null||Hn.removeListener(zn)}if(typeof window<"u"){const{matchMedia:Gn}=window;if(Gn&&$n.breakpoint&&$n.breakpoint in dimensionMaxMap){Hn=Gn(`(max-width: ${dimensionMaxMap[$n.breakpoint]})`);try{Hn.addEventListener("change",zn)}catch{Hn.addListener(zn)}zn(Hn)}}},{immediate:!0})}),onBeforeUnmount(()=>{try{Hn==null||Hn.removeEventListener("change",zn)}catch{Hn==null||Hn.removeListener(zn)}Rn&&Rn.removeSider(Wn)});const Yn=()=>{Fn(!Dn.value,"clickTrigger")};return()=>{var Gn,Go;const Xn=Nn.value,{collapsedWidth:Yo,width:qo,reverseArrow:Jo,zeroWidthTriggerStyle:Zo,trigger:rr=(Gn=In.trigger)===null||Gn===void 0?void 0:Gn.call(In),collapsible:nr,theme:ta}=$n,oa=Dn.value?Yo:qo,ra=isNumeric(oa)?`${oa}px`:String(oa),ea=parseFloat(String(Yo||0))===0?createVNode("span",{onClick:Yn,class:classNames(`${Xn}-zero-width-trigger`,`${Xn}-zero-width-trigger-${Jo?"right":"left"}`),style:Zo},[rr||createVNode(BarsOutlined$1,null,null)]):null,la={expanded:createVNode(Jo?RightOutlined$1:LeftOutlined$1,null,null),collapsed:createVNode(Jo?LeftOutlined$1:RightOutlined$1,null,null)},ua=Dn.value?"collapsed":"expanded",ga=la[ua],aa=rr!==null?ea||createVNode("div",{class:`${Xn}-trigger`,onClick:Yn,style:{width:ra}},[rr||ga]):null,ca=[Pn.style,{flex:`0 0 ${ra}`,maxWidth:ra,minWidth:ra,width:ra}],sa=classNames(Xn,`${Xn}-${ta}`,{[`${Xn}-collapsed`]:!!Dn.value,[`${Xn}-has-trigger`]:nr&&rr!==null&&!ea,[`${Xn}-below`]:!!Ln.value,[`${Xn}-zero-width`]:parseFloat(ra)===0},Pn.class);return createVNode("aside",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:sa,style:ca}),[createVNode("div",{class:`${Xn}-children`},[(Go=In.default)===null||Go===void 0?void 0:Go.call(In)]),nr||Ln.value&&ea?aa:null])}}}),LayoutHeader=Header$1,LayoutFooter=Footer$1,LayoutSider=Sider,LayoutContent=Content,index$i=_extends$1(Layout$1,{Header:Header$1,Footer:Footer$1,Content,Sider,install:$n=>($n.component(Layout$1.name,Layout$1),$n.component(Header$1.name,Header$1),$n.component(Footer$1.name,Footer$1),$n.component(Sider.name,Sider),$n.component(Content.name,Content),$n)});function throttle($n,Cn,_n){var Pn=_n||{},In=Pn.noTrailing,Nn=In===void 0?!1:In,Rn=Pn.noLeading,Dn=Rn===void 0?!1:Rn,Ln=Pn.debounceMode,Fn=Ln===void 0?void 0:Ln,Bn,Hn=!1,zn=0;function Wn(){Bn&&clearTimeout(Bn)}function Yn(Go){var Xn=Go||{},Yo=Xn.upcomingOnly,qo=Yo===void 0?!1:Yo;Wn(),Hn=!qo}function Gn(){for(var Go=arguments.length,Xn=new Array(Go),Yo=0;Yo$n?Dn?(zn=Date.now(),Nn||(Bn=setTimeout(Fn?rr:Zo,$n))):Zo():Nn!==!0&&(Bn=setTimeout(Fn?rr:Zo,Fn===void 0?$n-Jo:$n))}return Gn.cancel=Yn,Gn}function debounce$1($n,Cn,_n){var Pn=_n||{},In=Pn.atBegin,Nn=In===void 0?!1:In;return throttle($n,Cn,{debounceMode:Nn!==!1})}const antSpinMove=new Keyframes("antSpinMove",{to:{opacity:1}}),antRotate=new Keyframes("antRotate",{to:{transform:"rotate(405deg)"}}),genSpinStyle=$n=>({[`${$n.componentCls}`]:_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",display:"none",color:$n.colorPrimary,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${$n.motionDurationSlow} ${$n.motionEaseInOutCirc}`,"&-spinning":{position:"static",display:"inline-block",opacity:1},"&-nested-loading":{position:"relative",[`> div > ${$n.componentCls}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:$n.contentHeight,[`${$n.componentCls}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:-$n.spinDotSize/2},[`${$n.componentCls}-text`]:{position:"absolute",top:"50%",width:"100%",paddingTop:($n.spinDotSize-$n.fontSize)/2+2,textShadow:`0 1px 2px ${$n.colorBgContainer}`},[`&${$n.componentCls}-show-text ${$n.componentCls}-dot`]:{marginTop:-($n.spinDotSize/2)-10},"&-sm":{[`${$n.componentCls}-dot`]:{margin:-$n.spinDotSizeSM/2},[`${$n.componentCls}-text`]:{paddingTop:($n.spinDotSizeSM-$n.fontSize)/2+2},[`&${$n.componentCls}-show-text ${$n.componentCls}-dot`]:{marginTop:-($n.spinDotSizeSM/2)-10}},"&-lg":{[`${$n.componentCls}-dot`]:{margin:-($n.spinDotSizeLG/2)},[`${$n.componentCls}-text`]:{paddingTop:($n.spinDotSizeLG-$n.fontSize)/2+2},[`&${$n.componentCls}-show-text ${$n.componentCls}-dot`]:{marginTop:-($n.spinDotSizeLG/2)-10}}},[`${$n.componentCls}-container`]:{position:"relative",transition:`opacity ${$n.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:$n.colorBgContainer,opacity:0,transition:`all ${$n.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${$n.componentCls}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none","&::after":{opacity:.4,pointerEvents:"auto"}}},"&-tip":{color:$n.spinDotDefault},[`${$n.componentCls}-dot`]:{position:"relative",display:"inline-block",fontSize:$n.spinDotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:($n.spinDotSize-$n.marginXXS/2)/2,height:($n.spinDotSize-$n.marginXXS/2)/2,backgroundColor:$n.colorPrimary,borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:antSpinMove,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:antRotate,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},[`&-sm ${$n.componentCls}-dot`]:{fontSize:$n.spinDotSizeSM,i:{width:($n.spinDotSizeSM-$n.marginXXS/2)/2,height:($n.spinDotSizeSM-$n.marginXXS/2)/2}},[`&-lg ${$n.componentCls}-dot`]:{fontSize:$n.spinDotSizeLG,i:{width:($n.spinDotSizeLG-$n.marginXXS)/2,height:($n.spinDotSizeLG-$n.marginXXS)/2}},[`&${$n.componentCls}-show-text ${$n.componentCls}-text`]:{display:"block"}})}),useStyle$m=genComponentStyleHook("Spin",$n=>{const Cn=merge$1($n,{spinDotDefault:$n.colorTextDescription,spinDotSize:$n.controlHeightLG/2,spinDotSizeSM:$n.controlHeightLG*.35,spinDotSizeLG:$n.controlHeight});return[genSpinStyle(Cn)]},{contentHeight:400});var __rest$x=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,spinning:{type:Boolean,default:void 0},size:String,wrapperClassName:String,tip:PropTypes.any,delay:Number,indicator:PropTypes.any});let defaultIndicator=null;function shouldDelay($n,Cn){return!!$n&&!!Cn&&!isNaN(Number(Cn))}function setDefaultIndicator($n){const Cn=$n.indicator;defaultIndicator=typeof Cn=="function"?Cn:()=>createVNode(Cn,null,null)}const Spin=defineComponent({compatConfig:{MODE:3},name:"ASpin",inheritAttrs:!1,props:initDefaultProps(spinProps(),{size:"default",spinning:!0,wrapperClassName:""}),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{prefixCls:In,size:Nn,direction:Rn}=useConfigInject("spin",$n),[Dn,Ln]=useStyle$m(In),Fn=shallowRef($n.spinning&&!shouldDelay($n.spinning,$n.delay));let Bn;return watch([()=>$n.spinning,()=>$n.delay],()=>{Bn==null||Bn.cancel(),Bn=debounce$1($n.delay,()=>{Fn.value=$n.spinning}),Bn==null||Bn()},{immediate:!0,flush:"post"}),onBeforeUnmount(()=>{Bn==null||Bn.cancel()}),()=>{var Hn,zn;const{class:Wn}=_n,Yn=__rest$x(_n,["class"]),{tip:Gn=(Hn=Pn.tip)===null||Hn===void 0?void 0:Hn.call(Pn)}=$n,Go=(zn=Pn.default)===null||zn===void 0?void 0:zn.call(Pn),Xn={[Ln.value]:!0,[In.value]:!0,[`${In.value}-sm`]:Nn.value==="small",[`${In.value}-lg`]:Nn.value==="large",[`${In.value}-spinning`]:Fn.value,[`${In.value}-show-text`]:!!Gn,[`${In.value}-rtl`]:Rn.value==="rtl",[Wn]:!!Wn};function Yo(Jo){const Zo=`${Jo}-dot`;let rr=getPropsSlot(Pn,$n,"indicator");return rr===null?null:(Array.isArray(rr)&&(rr=rr.length===1?rr[0]:rr),isVNode$1(rr)?cloneVNode(rr,{class:Zo}):defaultIndicator&&isVNode$1(defaultIndicator())?cloneVNode(defaultIndicator(),{class:Zo}):createVNode("span",{class:`${Zo} ${Jo}-dot-spin`},[createVNode("i",{class:`${Jo}-dot-item`},null),createVNode("i",{class:`${Jo}-dot-item`},null),createVNode("i",{class:`${Jo}-dot-item`},null),createVNode("i",{class:`${Jo}-dot-item`},null)]))}const qo=createVNode("div",_objectSpread2$1(_objectSpread2$1({},Yn),{},{class:Xn,"aria-live":"polite","aria-busy":Fn.value}),[Yo(In.value),Gn?createVNode("div",{class:`${In.value}-text`},[Gn]):null]);if(Go&&filterEmpty(Go).length){const Jo={[`${In.value}-container`]:!0,[`${In.value}-blur`]:Fn.value};return Dn(createVNode("div",{class:[`${In.value}-nested-loading`,$n.wrapperClassName,Ln.value]},[Fn.value&&createVNode("div",{key:"loading"},[qo]),createVNode("div",{class:Jo,key:"container"},[Go])]))}return Dn(qo)}}});Spin.setDefaultIndicator=setDefaultIndicator;Spin.install=function($n){return $n.component(Spin.name,Spin),$n};var DoubleLeftOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M272.9 512l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L186.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H532c6.7 0 10.4-7.7 6.3-12.9L272.9 512zm304 0l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L490.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H836c6.7 0 10.4-7.7 6.3-12.9L576.9 512z"}}]},name:"double-left",theme:"outlined"};const DoubleLeftOutlinedSvg=DoubleLeftOutlined$2;function _objectSpread$n($n){for(var Cn=1;Cn{const In=_extends$1(_extends$1(_extends$1({},$n),{size:"small"}),_n);return createVNode(VcSelect,In,Pn)}}}),MiddleSelect=defineComponent({name:"MiddleSelect",inheritAttrs:!1,props:selectProps(),Option:VcSelect.Option,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;return()=>{const In=_extends$1(_extends$1(_extends$1({},$n),{size:"middle"}),_n);return createVNode(VcSelect,In,Pn)}}}),Pager=defineComponent({compatConfig:{MODE:3},name:"Pager",inheritAttrs:!1,props:{rootPrefixCls:String,page:Number,active:{type:Boolean,default:void 0},last:{type:Boolean,default:void 0},locale:PropTypes.object,showTitle:{type:Boolean,default:void 0},itemRender:{type:Function,default:()=>{}},onClick:{type:Function},onKeypress:{type:Function}},eimt:["click","keypress"],setup($n,Cn){let{emit:_n,attrs:Pn}=Cn;const In=()=>{_n("click",$n.page)},Nn=Rn=>{_n("keypress",Rn,In,$n.page)};return()=>{const{showTitle:Rn,page:Dn,itemRender:Ln}=$n,{class:Fn,style:Bn}=Pn,Hn=`${$n.rootPrefixCls}-item`,zn=classNames(Hn,`${Hn}-${$n.page}`,{[`${Hn}-active`]:$n.active,[`${Hn}-disabled`]:!$n.page},Fn);return createVNode("li",{onClick:In,onKeypress:Nn,title:Rn?String(Dn):null,tabindex:"0",class:zn,style:Bn},[Ln({page:Dn,type:"page",originalElement:createVNode("a",{rel:"nofollow"},[Dn])})])}}}),KEYCODE={ZERO:48,NINE:57,NUMPAD_ZERO:96,NUMPAD_NINE:105,BACKSPACE:8,DELETE:46,ENTER:13,ARROW_UP:38,ARROW_DOWN:40},Options=defineComponent({compatConfig:{MODE:3},props:{disabled:{type:Boolean,default:void 0},changeSize:Function,quickGo:Function,selectComponentClass:PropTypes.any,current:Number,pageSizeOptions:PropTypes.array.def(["10","20","50","100"]),pageSize:Number,buildOptionText:Function,locale:PropTypes.object,rootPrefixCls:String,selectPrefixCls:String,goButton:PropTypes.any},setup($n){const Cn=ref(""),_n=computed(()=>!Cn.value||isNaN(Cn.value)?void 0:Number(Cn.value)),Pn=Ln=>`${Ln.value} ${$n.locale.items_per_page}`,In=Ln=>{const{value:Fn,composing:Bn}=Ln.target;Ln.isComposing||Bn||Cn.value===Fn||(Cn.value=Fn)},Nn=Ln=>{const{goButton:Fn,quickGo:Bn,rootPrefixCls:Hn}=$n;if(!(Fn||Cn.value===""))if(Ln.relatedTarget&&(Ln.relatedTarget.className.indexOf(`${Hn}-item-link`)>=0||Ln.relatedTarget.className.indexOf(`${Hn}-item`)>=0)){Cn.value="";return}else Bn(_n.value),Cn.value=""},Rn=Ln=>{Cn.value!==""&&(Ln.keyCode===KEYCODE.ENTER||Ln.type==="click")&&($n.quickGo(_n.value),Cn.value="")},Dn=computed(()=>{const{pageSize:Ln,pageSizeOptions:Fn}=$n;return Fn.some(Bn=>Bn.toString()===Ln.toString())?Fn:Fn.concat([Ln.toString()]).sort((Bn,Hn)=>{const zn=isNaN(Number(Bn))?0:Number(Bn),Wn=isNaN(Number(Hn))?0:Number(Hn);return zn-Wn})});return()=>{const{rootPrefixCls:Ln,locale:Fn,changeSize:Bn,quickGo:Hn,goButton:zn,selectComponentClass:Wn,selectPrefixCls:Yn,pageSize:Gn,disabled:Go}=$n,Xn=`${Ln}-options`;let Yo=null,qo=null,Jo=null;if(!Bn&&!Hn)return null;if(Bn&&Wn){const Zo=$n.buildOptionText||Pn,rr=Dn.value.map((nr,ta)=>createVNode(Wn.Option,{key:ta,value:nr},{default:()=>[Zo({value:nr})]}));Yo=createVNode(Wn,{disabled:Go,prefixCls:Yn,showSearch:!1,class:`${Xn}-size-changer`,optionLabelProp:"children",value:(Gn||Dn.value[0]).toString(),onChange:nr=>Bn(Number(nr)),getPopupContainer:nr=>nr.parentNode},{default:()=>[rr]})}return Hn&&(zn&&(Jo=typeof zn=="boolean"?createVNode("button",{type:"button",onClick:Rn,onKeyup:Rn,disabled:Go,class:`${Xn}-quick-jumper-button`},[Fn.jump_to_confirm]):createVNode("span",{onClick:Rn,onKeyup:Rn},[zn])),qo=createVNode("div",{class:`${Xn}-quick-jumper`},[Fn.jump_to,withDirectives(createVNode("input",{disabled:Go,type:"text",value:Cn.value,onInput:In,onChange:In,onKeyup:Rn,onBlur:Nn},null),[[antInputDirective]]),Fn.page,Jo])),createVNode("li",{class:`${Xn}`},[Yo,qo])}}}),Pagination$2={items_per_page:"条/页",jump_to:"跳至",jump_to_confirm:"确定",page:"页",prev_page:"上一页",next_page:"下一页",prev_5:"向前 5 页",next_5:"向后 5 页",prev_3:"向前 3 页",next_3:"向后 3 页"};var __rest$w=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In"u"?Cn.statePageSize:$n;return Math.floor((_n.total-1)/Pn)+1}const VcPagination=defineComponent({compatConfig:{MODE:3},name:"Pagination",mixins:[BaseMixin],inheritAttrs:!1,props:{disabled:{type:Boolean,default:void 0},prefixCls:PropTypes.string.def("rc-pagination"),selectPrefixCls:PropTypes.string.def("rc-select"),current:Number,defaultCurrent:PropTypes.number.def(1),total:PropTypes.number.def(0),pageSize:Number,defaultPageSize:PropTypes.number.def(10),hideOnSinglePage:{type:Boolean,default:!1},showSizeChanger:{type:Boolean,default:void 0},showLessItems:{type:Boolean,default:!1},selectComponentClass:PropTypes.any,showPrevNextJumpers:{type:Boolean,default:!0},showQuickJumper:PropTypes.oneOfType([PropTypes.looseBool,PropTypes.object]).def(!1),showTitle:{type:Boolean,default:!0},pageSizeOptions:PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number,PropTypes.string])),buildOptionText:Function,showTotal:Function,simple:{type:Boolean,default:void 0},locale:PropTypes.object.def(Pagination$2),itemRender:PropTypes.func.def(defaultItemRender),prevIcon:PropTypes.any,nextIcon:PropTypes.any,jumpPrevIcon:PropTypes.any,jumpNextIcon:PropTypes.any,totalBoundaryShowSizeChanger:PropTypes.number.def(50)},data(){const $n=this.$props;let Cn=firstNotUndefined([this.current,this.defaultCurrent]);const _n=firstNotUndefined([this.pageSize,this.defaultPageSize]);return Cn=Math.min(Cn,calculatePage(_n,void 0,$n)),{stateCurrent:Cn,stateCurrentInputValue:Cn,statePageSize:_n}},watch:{current($n){this.setState({stateCurrent:$n,stateCurrentInputValue:$n})},pageSize($n){const Cn={};let _n=this.stateCurrent;const Pn=calculatePage($n,this.$data,this.$props);_n=_n>Pn?Pn:_n,hasProp(this,"current")||(Cn.stateCurrent=_n,Cn.stateCurrentInputValue=_n),Cn.statePageSize=$n,this.setState(Cn)},stateCurrent($n,Cn){this.$nextTick(()=>{if(this.$refs.paginationNode){const _n=this.$refs.paginationNode.querySelector(`.${this.prefixCls}-item-${Cn}`);_n&&document.activeElement===_n&&_n.blur()}})},total(){const $n={},Cn=calculatePage(this.pageSize,this.$data,this.$props);if(hasProp(this,"current")){const _n=Math.min(this.current,Cn);$n.stateCurrent=_n,$n.stateCurrentInputValue=_n}else{let _n=this.stateCurrent;_n===0&&Cn>0?_n=1:_n=Math.min(this.stateCurrent,Cn),$n.stateCurrent=_n}this.setState($n)}},methods:{getJumpPrevPage(){return Math.max(1,this.stateCurrent-(this.showLessItems?3:5))},getJumpNextPage(){return Math.min(calculatePage(void 0,this.$data,this.$props),this.stateCurrent+(this.showLessItems?3:5))},getItemIcon($n,Cn){const{prefixCls:_n}=this.$props;return getComponent(this,$n,this.$props)||createVNode("button",{type:"button","aria-label":Cn,class:`${_n}-item-link`},null)},getValidValue($n){const Cn=$n.target.value,_n=calculatePage(void 0,this.$data,this.$props),{stateCurrentInputValue:Pn}=this.$data;let In;return Cn===""?In=Cn:isNaN(Number(Cn))?In=Pn:Cn>=_n?In=_n:In=Number(Cn),In},isValid($n){return isInteger($n)&&$n!==this.stateCurrent},shouldDisplayQuickJumper(){const{showQuickJumper:$n,pageSize:Cn,total:_n}=this.$props;return _n<=Cn?!1:$n},handleKeyDown($n){($n.keyCode===KEYCODE.ARROW_UP||$n.keyCode===KEYCODE.ARROW_DOWN)&&$n.preventDefault()},handleKeyUp($n){if($n.isComposing||$n.target.composing)return;const Cn=this.getValidValue($n),_n=this.stateCurrentInputValue;Cn!==_n&&this.setState({stateCurrentInputValue:Cn}),$n.keyCode===KEYCODE.ENTER?this.handleChange(Cn):$n.keyCode===KEYCODE.ARROW_UP?this.handleChange(Cn-1):$n.keyCode===KEYCODE.ARROW_DOWN&&this.handleChange(Cn+1)},changePageSize($n){let Cn=this.stateCurrent;const _n=Cn,Pn=calculatePage($n,this.$data,this.$props);Cn=Cn>Pn?Pn:Cn,Pn===0&&(Cn=this.stateCurrent),typeof $n=="number"&&(hasProp(this,"pageSize")||this.setState({statePageSize:$n}),hasProp(this,"current")||this.setState({stateCurrent:Cn,stateCurrentInputValue:Cn})),this.__emit("update:pageSize",$n),Cn!==_n&&this.__emit("update:current",Cn),this.__emit("showSizeChange",Cn,$n),this.__emit("change",Cn,$n)},handleChange($n){const{disabled:Cn}=this.$props;let _n=$n;if(this.isValid(_n)&&!Cn){const Pn=calculatePage(void 0,this.$data,this.$props);return _n>Pn?_n=Pn:_n<1&&(_n=1),hasProp(this,"current")||this.setState({stateCurrent:_n,stateCurrentInputValue:_n}),this.__emit("update:current",_n),this.__emit("change",_n,this.statePageSize),_n}return this.stateCurrent},prev(){this.hasPrev()&&this.handleChange(this.stateCurrent-1)},next(){this.hasNext()&&this.handleChange(this.stateCurrent+1)},jumpPrev(){this.handleChange(this.getJumpPrevPage())},jumpNext(){this.handleChange(this.getJumpNextPage())},hasPrev(){return this.stateCurrent>1},hasNext(){return this.stateCurrent_n},runIfEnter($n,Cn){if($n.key==="Enter"||$n.charCode===13){for(var _n=arguments.length,Pn=new Array(_n>2?_n-2:0),In=2;In<_n;In++)Pn[In-2]=arguments[In];Cn(...Pn)}},runIfEnterPrev($n){this.runIfEnter($n,this.prev)},runIfEnterNext($n){this.runIfEnter($n,this.next)},runIfEnterJumpPrev($n){this.runIfEnter($n,this.jumpPrev)},runIfEnterJumpNext($n){this.runIfEnter($n,this.jumpNext)},handleGoTO($n){($n.keyCode===KEYCODE.ENTER||$n.type==="click")&&this.handleChange(this.stateCurrentInputValue)},renderPrev($n){const{itemRender:Cn}=this.$props,_n=Cn({page:$n,type:"prev",originalElement:this.getItemIcon("prevIcon","prev page")}),Pn=!this.hasPrev();return isValidElement(_n)?cloneElement(_n,Pn?{disabled:Pn}:{}):_n},renderNext($n){const{itemRender:Cn}=this.$props,_n=Cn({page:$n,type:"next",originalElement:this.getItemIcon("nextIcon","next page")}),Pn=!this.hasNext();return isValidElement(_n)?cloneElement(_n,Pn?{disabled:Pn}:{}):_n}},render(){const{prefixCls:$n,disabled:Cn,hideOnSinglePage:_n,total:Pn,locale:In,showQuickJumper:Nn,showLessItems:Rn,showTitle:Dn,showTotal:Ln,simple:Fn,itemRender:Bn,showPrevNextJumpers:Hn,jumpPrevIcon:zn,jumpNextIcon:Wn,selectComponentClass:Yn,selectPrefixCls:Gn,pageSizeOptions:Go}=this.$props,{stateCurrent:Xn,statePageSize:Yo}=this,qo=splitAttrs(this.$attrs).extraAttrs,{class:Jo}=qo,Zo=__rest$w(qo,["class"]);if(_n===!0&&this.total<=Yo)return null;const rr=calculatePage(void 0,this.$data,this.$props),nr=[];let ta=null,oa=null,ra=null,ea=null,la=null;const ua=Nn&&Nn.goButton,ga=Rn?1:2,aa=Xn-1>0?Xn-1:0,ca=Xn+1=ga*2&&Xn!==3&&(nr[0]=createVNode(Pager,{locale:In,rootPrefixCls:$n,onClick:this.handleChange,onKeypress:this.runIfEnter,key:xa,page:xa,class:`${$n}-item-after-jump-prev`,active:!1,showTitle:this.showTitle,itemRender:Bn},null),nr.unshift(ta)),rr-Xn>=ga*2&&Xn!==rr-2&&(nr[nr.length-1]=createVNode(Pager,{locale:In,rootPrefixCls:$n,onClick:this.handleChange,onKeypress:this.runIfEnter,key:Ta,page:Ta,class:`${$n}-item-before-jump-next`,active:!1,showTitle:this.showTitle,itemRender:Bn},null),nr.push(oa)),xa!==1&&nr.unshift(ra),Ta!==rr&&nr.push(ea)}let fa=null;Ln&&(fa=createVNode("li",{class:`${$n}-total-text`},[Ln(Pn,[Pn===0?0:(Xn-1)*Yo+1,Xn*Yo>Pn?Pn:Xn*Yo])]));const ma=!sa||!rr,ya=!ia||!rr,ba=this.buildOptionText||this.$slots.buildOptionText;return createVNode("ul",_objectSpread2$1(_objectSpread2$1({unselectable:"on",ref:"paginationNode"},Zo),{},{class:classNames({[`${$n}`]:!0,[`${$n}-disabled`]:Cn},Jo)}),[fa,createVNode("li",{title:Dn?In.prev_page:null,onClick:this.prev,tabindex:ma?null:0,onKeypress:this.runIfEnterPrev,class:classNames(`${$n}-prev`,{[`${$n}-disabled`]:ma}),"aria-disabled":ma},[this.renderPrev(aa)]),nr,createVNode("li",{title:Dn?In.next_page:null,onClick:this.next,tabindex:ya?null:0,onKeypress:this.runIfEnterNext,class:classNames(`${$n}-next`,{[`${$n}-disabled`]:ya}),"aria-disabled":ya},[this.renderNext(ca)]),createVNode(Options,{disabled:Cn,locale:In,rootPrefixCls:$n,selectComponentClass:Yn,selectPrefixCls:Gn,changeSize:this.getShowSizeChanger()?this.changePageSize:null,current:Xn,pageSize:Yo,pageSizeOptions:Go,buildOptionText:ba||null,quickGo:this.shouldDisplayQuickJumper()?this.handleChange:null,goButton:ua},null)])}}),genPaginationDisabledStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-disabled`]:{"&, &:hover":{cursor:"not-allowed",[`${Cn}-item-link`]:{color:$n.colorTextDisabled,cursor:"not-allowed"}},"&:focus-visible":{cursor:"not-allowed",[`${Cn}-item-link`]:{color:$n.colorTextDisabled,cursor:"not-allowed"}}},[`&${Cn}-disabled`]:{cursor:"not-allowed",[`&${Cn}-mini`]:{[` - &:hover ${Cn}-item:not(${Cn}-item-active), - &:active ${Cn}-item:not(${Cn}-item-active), - &:hover ${Cn}-item-link, - &:active ${Cn}-item-link - `]:{backgroundColor:"transparent"}},[`${Cn}-item`]:{cursor:"not-allowed","&:hover, &:active":{backgroundColor:"transparent"},a:{color:$n.colorTextDisabled,backgroundColor:"transparent",border:"none",cursor:"not-allowed"},"&-active":{borderColor:$n.colorBorder,backgroundColor:$n.paginationItemDisabledBgActive,"&:hover, &:active":{backgroundColor:$n.paginationItemDisabledBgActive},a:{color:$n.paginationItemDisabledColorActive}}},[`${Cn}-item-link`]:{color:$n.colorTextDisabled,cursor:"not-allowed","&:hover, &:active":{backgroundColor:"transparent"},[`${Cn}-simple&`]:{backgroundColor:"transparent","&:hover, &:active":{backgroundColor:"transparent"}}},[`${Cn}-simple-pager`]:{color:$n.colorTextDisabled},[`${Cn}-jump-prev, ${Cn}-jump-next`]:{[`${Cn}-item-link-icon`]:{opacity:0},[`${Cn}-item-ellipsis`]:{opacity:1}}},[`&${Cn}-simple`]:{[`${Cn}-prev, ${Cn}-next`]:{[`&${Cn}-disabled ${Cn}-item-link`]:{"&:hover, &:active":{backgroundColor:"transparent"}}}}}},genPaginationMiniStyle=$n=>{const{componentCls:Cn}=$n;return{[`&${Cn}-mini ${Cn}-total-text, &${Cn}-mini ${Cn}-simple-pager`]:{height:$n.paginationItemSizeSM,lineHeight:`${$n.paginationItemSizeSM}px`},[`&${Cn}-mini ${Cn}-item`]:{minWidth:$n.paginationItemSizeSM,height:$n.paginationItemSizeSM,margin:0,lineHeight:`${$n.paginationItemSizeSM-2}px`},[`&${Cn}-mini ${Cn}-item:not(${Cn}-item-active)`]:{backgroundColor:"transparent",borderColor:"transparent","&:hover":{backgroundColor:$n.colorBgTextHover},"&:active":{backgroundColor:$n.colorBgTextActive}},[`&${Cn}-mini ${Cn}-prev, &${Cn}-mini ${Cn}-next`]:{minWidth:$n.paginationItemSizeSM,height:$n.paginationItemSizeSM,margin:0,lineHeight:`${$n.paginationItemSizeSM}px`,[`&:hover ${Cn}-item-link`]:{backgroundColor:$n.colorBgTextHover},[`&:active ${Cn}-item-link`]:{backgroundColor:$n.colorBgTextActive},[`&${Cn}-disabled:hover ${Cn}-item-link`]:{backgroundColor:"transparent"}},[` - &${Cn}-mini ${Cn}-prev ${Cn}-item-link, - &${Cn}-mini ${Cn}-next ${Cn}-item-link - `]:{backgroundColor:"transparent",borderColor:"transparent","&::after":{height:$n.paginationItemSizeSM,lineHeight:`${$n.paginationItemSizeSM}px`}},[`&${Cn}-mini ${Cn}-jump-prev, &${Cn}-mini ${Cn}-jump-next`]:{height:$n.paginationItemSizeSM,marginInlineEnd:0,lineHeight:`${$n.paginationItemSizeSM}px`},[`&${Cn}-mini ${Cn}-options`]:{marginInlineStart:$n.paginationMiniOptionsMarginInlineStart,"&-size-changer":{top:$n.paginationMiniOptionsSizeChangerTop},"&-quick-jumper":{height:$n.paginationItemSizeSM,lineHeight:`${$n.paginationItemSizeSM}px`,input:_extends$1(_extends$1({},genInputSmallStyle($n)),{width:$n.paginationMiniQuickJumperInputWidth,height:$n.controlHeightSM})}}}},genPaginationSimpleStyle=$n=>{const{componentCls:Cn}=$n;return{[` - &${Cn}-simple ${Cn}-prev, - &${Cn}-simple ${Cn}-next - `]:{height:$n.paginationItemSizeSM,lineHeight:`${$n.paginationItemSizeSM}px`,verticalAlign:"top",[`${Cn}-item-link`]:{height:$n.paginationItemSizeSM,backgroundColor:"transparent",border:0,"&:hover":{backgroundColor:$n.colorBgTextHover},"&:active":{backgroundColor:$n.colorBgTextActive},"&::after":{height:$n.paginationItemSizeSM,lineHeight:`${$n.paginationItemSizeSM}px`}}},[`&${Cn}-simple ${Cn}-simple-pager`]:{display:"inline-block",height:$n.paginationItemSizeSM,marginInlineEnd:$n.marginXS,input:{boxSizing:"border-box",height:"100%",marginInlineEnd:$n.marginXS,padding:`0 ${$n.paginationItemPaddingInline}px`,textAlign:"center",backgroundColor:$n.paginationItemInputBg,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:$n.borderRadius,outline:"none",transition:`border-color ${$n.motionDurationMid}`,color:"inherit","&:hover":{borderColor:$n.colorPrimary},"&:focus":{borderColor:$n.colorPrimaryHover,boxShadow:`${$n.inputOutlineOffset}px 0 ${$n.controlOutlineWidth}px ${$n.controlOutline}`},"&[disabled]":{color:$n.colorTextDisabled,backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,cursor:"not-allowed"}}}}},genPaginationJumpStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-jump-prev, ${Cn}-jump-next`]:{outline:0,[`${Cn}-item-container`]:{position:"relative",[`${Cn}-item-link-icon`]:{color:$n.colorPrimary,fontSize:$n.fontSizeSM,opacity:0,transition:`all ${$n.motionDurationMid}`,"&-svg":{top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,margin:"auto"}},[`${Cn}-item-ellipsis`]:{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,display:"block",margin:"auto",color:$n.colorTextDisabled,fontFamily:"Arial, Helvetica, sans-serif",letterSpacing:$n.paginationEllipsisLetterSpacing,textAlign:"center",textIndent:$n.paginationEllipsisTextIndent,opacity:1,transition:`all ${$n.motionDurationMid}`}},"&:hover":{[`${Cn}-item-link-icon`]:{opacity:1},[`${Cn}-item-ellipsis`]:{opacity:0}},"&:focus-visible":_extends$1({[`${Cn}-item-link-icon`]:{opacity:1},[`${Cn}-item-ellipsis`]:{opacity:0}},genFocusOutline($n))},[` - ${Cn}-prev, - ${Cn}-jump-prev, - ${Cn}-jump-next - `]:{marginInlineEnd:$n.marginXS},[` - ${Cn}-prev, - ${Cn}-next, - ${Cn}-jump-prev, - ${Cn}-jump-next - `]:{display:"inline-block",minWidth:$n.paginationItemSize,height:$n.paginationItemSize,color:$n.colorText,fontFamily:$n.paginationFontFamily,lineHeight:`${$n.paginationItemSize}px`,textAlign:"center",verticalAlign:"middle",listStyle:"none",borderRadius:$n.borderRadius,cursor:"pointer",transition:`all ${$n.motionDurationMid}`},[`${Cn}-prev, ${Cn}-next`]:{fontFamily:"Arial, Helvetica, sans-serif",outline:0,button:{color:$n.colorText,cursor:"pointer",userSelect:"none"},[`${Cn}-item-link`]:{display:"block",width:"100%",height:"100%",padding:0,fontSize:$n.fontSizeSM,textAlign:"center",backgroundColor:"transparent",border:`${$n.lineWidth}px ${$n.lineType} transparent`,borderRadius:$n.borderRadius,outline:"none",transition:`all ${$n.motionDurationMid}`},[`&:focus-visible ${Cn}-item-link`]:_extends$1({},genFocusOutline($n)),[`&:hover ${Cn}-item-link`]:{backgroundColor:$n.colorBgTextHover},[`&:active ${Cn}-item-link`]:{backgroundColor:$n.colorBgTextActive},[`&${Cn}-disabled:hover`]:{[`${Cn}-item-link`]:{backgroundColor:"transparent"}}},[`${Cn}-slash`]:{marginInlineEnd:$n.paginationSlashMarginInlineEnd,marginInlineStart:$n.paginationSlashMarginInlineStart},[`${Cn}-options`]:{display:"inline-block",marginInlineStart:$n.margin,verticalAlign:"middle","&-size-changer.-select":{display:"inline-block",width:"auto"},"&-quick-jumper":{display:"inline-block",height:$n.controlHeight,marginInlineStart:$n.marginXS,lineHeight:`${$n.controlHeight}px`,verticalAlign:"top",input:_extends$1(_extends$1({},genBasicInputStyle($n)),{width:$n.controlHeightLG*1.25,height:$n.controlHeight,boxSizing:"border-box",margin:0,marginInlineStart:$n.marginXS,marginInlineEnd:$n.marginXS})}}}},genPaginationItemStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-item`]:_extends$1(_extends$1({display:"inline-block",minWidth:$n.paginationItemSize,height:$n.paginationItemSize,marginInlineEnd:$n.marginXS,fontFamily:$n.paginationFontFamily,lineHeight:`${$n.paginationItemSize-2}px`,textAlign:"center",verticalAlign:"middle",listStyle:"none",backgroundColor:"transparent",border:`${$n.lineWidth}px ${$n.lineType} transparent`,borderRadius:$n.borderRadius,outline:0,cursor:"pointer",userSelect:"none",a:{display:"block",padding:`0 ${$n.paginationItemPaddingInline}px`,color:$n.colorText,transition:"none","&:hover":{textDecoration:"none"}},[`&:not(${Cn}-item-active)`]:{"&:hover":{transition:`all ${$n.motionDurationMid}`,backgroundColor:$n.colorBgTextHover},"&:active":{backgroundColor:$n.colorBgTextActive}}},genFocusStyle($n)),{"&-active":{fontWeight:$n.paginationFontWeightActive,backgroundColor:$n.paginationItemBgActive,borderColor:$n.colorPrimary,a:{color:$n.colorPrimary},"&:hover":{borderColor:$n.colorPrimaryHover},"&:hover a":{color:$n.colorPrimaryHover}}})}},genPaginationStyle$2=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{"ul, ol":{margin:0,padding:0,listStyle:"none"},"&::after":{display:"block",clear:"both",height:0,overflow:"hidden",visibility:"hidden",content:'""'},[`${Cn}-total-text`]:{display:"inline-block",height:$n.paginationItemSize,marginInlineEnd:$n.marginXS,lineHeight:`${$n.paginationItemSize-2}px`,verticalAlign:"middle"}}),genPaginationItemStyle($n)),genPaginationJumpStyle($n)),genPaginationSimpleStyle($n)),genPaginationMiniStyle($n)),genPaginationDisabledStyle($n)),{[`@media only screen and (max-width: ${$n.screenLG}px)`]:{[`${Cn}-item`]:{"&-after-jump-prev, &-before-jump-next":{display:"none"}}},[`@media only screen and (max-width: ${$n.screenSM}px)`]:{[`${Cn}-options`]:{display:"none"}}}),[`&${$n.componentCls}-rtl`]:{direction:"rtl"}}},genBorderedStyle$3=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}${Cn}-disabled`]:{"&, &:hover":{[`${Cn}-item-link`]:{borderColor:$n.colorBorder}},"&:focus-visible":{[`${Cn}-item-link`]:{borderColor:$n.colorBorder}},[`${Cn}-item, ${Cn}-item-link`]:{backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,[`&:hover:not(${Cn}-item-active)`]:{backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,a:{color:$n.colorTextDisabled}},[`&${Cn}-item-active`]:{backgroundColor:$n.paginationItemDisabledBgActive}},[`${Cn}-prev, ${Cn}-next`]:{"&:hover button":{backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder,color:$n.colorTextDisabled},[`${Cn}-item-link`]:{backgroundColor:$n.colorBgContainerDisabled,borderColor:$n.colorBorder}}},[Cn]:{[`${Cn}-prev, ${Cn}-next`]:{"&:hover button":{borderColor:$n.colorPrimaryHover,backgroundColor:$n.paginationItemBg},[`${Cn}-item-link`]:{backgroundColor:$n.paginationItemLinkBg,borderColor:$n.colorBorder},[`&:hover ${Cn}-item-link`]:{borderColor:$n.colorPrimary,backgroundColor:$n.paginationItemBg,color:$n.colorPrimary},[`&${Cn}-disabled`]:{[`${Cn}-item-link`]:{borderColor:$n.colorBorder,color:$n.colorTextDisabled}}},[`${Cn}-item`]:{backgroundColor:$n.paginationItemBg,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,[`&:hover:not(${Cn}-item-active)`]:{borderColor:$n.colorPrimary,backgroundColor:$n.paginationItemBg,a:{color:$n.colorPrimary}},"&-active":{borderColor:$n.colorPrimary}}}}},useStyle$l=genComponentStyleHook("Pagination",$n=>{const Cn=merge$1($n,{paginationItemSize:$n.controlHeight,paginationFontFamily:$n.fontFamily,paginationItemBg:$n.colorBgContainer,paginationItemBgActive:$n.colorBgContainer,paginationFontWeightActive:$n.fontWeightStrong,paginationItemSizeSM:$n.controlHeightSM,paginationItemInputBg:$n.colorBgContainer,paginationMiniOptionsSizeChangerTop:0,paginationItemDisabledBgActive:$n.controlItemBgActiveDisabled,paginationItemDisabledColorActive:$n.colorTextDisabled,paginationItemLinkBg:$n.colorBgContainer,inputOutlineOffset:"0 0",paginationMiniOptionsMarginInlineStart:$n.marginXXS/2,paginationMiniQuickJumperInputWidth:$n.controlHeightLG*1.1,paginationItemPaddingInline:$n.marginXXS*1.5,paginationEllipsisLetterSpacing:$n.marginXXS/2,paginationSlashMarginInlineStart:$n.marginXXS,paginationSlashMarginInlineEnd:$n.marginSM,paginationEllipsisTextIndent:"0.13em"},initInputToken($n));return[genPaginationStyle$2(Cn),$n.wireframe&&genBorderedStyle$3(Cn)]});var __rest$v=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({total:Number,defaultCurrent:Number,disabled:booleanType(),current:Number,defaultPageSize:Number,pageSize:Number,hideOnSinglePage:booleanType(),showSizeChanger:booleanType(),pageSizeOptions:arrayType(),buildOptionText:functionType(),showQuickJumper:someType([Boolean,Object]),showTotal:functionType(),size:stringType(),simple:booleanType(),locale:Object,prefixCls:String,selectPrefixCls:String,totalBoundaryShowSizeChanger:Number,selectComponentClass:String,itemRender:functionType(),role:String,responsive:Boolean,showLessItems:booleanType(),onChange:functionType(),onShowSizeChange:functionType(),"onUpdate:current":functionType(),"onUpdate:pageSize":functionType()}),Pagination$1=defineComponent({compatConfig:{MODE:3},name:"APagination",inheritAttrs:!1,props:paginationProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,configProvider:Nn,direction:Rn,size:Dn}=useConfigInject("pagination",$n),[Ln,Fn]=useStyle$l(In),Bn=computed(()=>Nn.getPrefixCls("select",$n.selectPrefixCls)),Hn=useBreakpoint(),[zn]=useLocaleReceiver("Pagination",enUS$1,toRef($n,"locale")),Wn=Yn=>{const Gn=createVNode("span",{class:`${Yn}-item-ellipsis`},[createTextVNode("•••")]),Go=createVNode("button",{class:`${Yn}-item-link`,type:"button",tabindex:-1},[Rn.value==="rtl"?createVNode(RightOutlined$1,null,null):createVNode(LeftOutlined$1,null,null)]),Xn=createVNode("button",{class:`${Yn}-item-link`,type:"button",tabindex:-1},[Rn.value==="rtl"?createVNode(LeftOutlined$1,null,null):createVNode(RightOutlined$1,null,null)]),Yo=createVNode("a",{rel:"nofollow",class:`${Yn}-item-link`},[createVNode("div",{class:`${Yn}-item-container`},[Rn.value==="rtl"?createVNode(DoubleRightOutlined$1,{class:`${Yn}-item-link-icon`},null):createVNode(DoubleLeftOutlined$1,{class:`${Yn}-item-link-icon`},null),Gn])]),qo=createVNode("a",{rel:"nofollow",class:`${Yn}-item-link`},[createVNode("div",{class:`${Yn}-item-container`},[Rn.value==="rtl"?createVNode(DoubleLeftOutlined$1,{class:`${Yn}-item-link-icon`},null):createVNode(DoubleRightOutlined$1,{class:`${Yn}-item-link-icon`},null),Gn])]);return{prevIcon:Go,nextIcon:Xn,jumpPrevIcon:Yo,jumpNextIcon:qo}};return()=>{var Yn;const{itemRender:Gn=_n.itemRender,buildOptionText:Go=_n.buildOptionText,selectComponentClass:Xn,responsive:Yo}=$n,qo=__rest$v($n,["itemRender","buildOptionText","selectComponentClass","responsive"]),Jo=Dn.value==="small"||!!(!((Yn=Hn.value)===null||Yn===void 0)&&Yn.xs&&!Dn.value&&Yo),Zo=_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},qo),Wn(In.value)),{prefixCls:In.value,selectPrefixCls:Bn.value,selectComponentClass:Xn||(Jo?MiniSelect:MiddleSelect),locale:zn.value,buildOptionText:Go}),Pn),{class:classNames({[`${In.value}-mini`]:Jo,[`${In.value}-rtl`]:Rn.value==="rtl"},Pn.class,Fn.value),itemRender:Gn});return Ln(createVNode(VcPagination,Zo,null))}}}),Pagination=withInstall(Pagination$1),listItemMetaProps=()=>({avatar:PropTypes.any,description:PropTypes.any,prefixCls:String,title:PropTypes.any}),ItemMeta=defineComponent({compatConfig:{MODE:3},name:"AListItemMeta",props:listItemMetaProps(),displayName:"AListItemMeta",__ANT_LIST_ITEM_META:!0,slots:Object,setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn}=useConfigInject("list",$n);return()=>{var In,Nn,Rn,Dn,Ln,Fn;const Bn=`${Pn.value}-item-meta`,Hn=(In=$n.title)!==null&&In!==void 0?In:(Nn=_n.title)===null||Nn===void 0?void 0:Nn.call(_n),zn=(Rn=$n.description)!==null&&Rn!==void 0?Rn:(Dn=_n.description)===null||Dn===void 0?void 0:Dn.call(_n),Wn=(Ln=$n.avatar)!==null&&Ln!==void 0?Ln:(Fn=_n.avatar)===null||Fn===void 0?void 0:Fn.call(_n),Yn=createVNode("div",{class:`${Pn.value}-item-meta-content`},[Hn&&createVNode("h4",{class:`${Pn.value}-item-meta-title`},[Hn]),zn&&createVNode("div",{class:`${Pn.value}-item-meta-description`},[zn])]);return createVNode("div",{class:Bn},[Wn&&createVNode("div",{class:`${Pn.value}-item-meta-avatar`},[Wn]),(Hn||zn)&&Yn])}}}),ListContextKey=Symbol("ListContextKey");var __rest$u=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,extra:PropTypes.any,actions:PropTypes.array,grid:Object,colStyle:{type:Object,default:void 0}}),Item=defineComponent({compatConfig:{MODE:3},name:"AListItem",inheritAttrs:!1,Meta:ItemMeta,props:listItemProps$1(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{itemLayout:In,grid:Nn}=inject(ListContextKey,{grid:ref(),itemLayout:ref()}),{prefixCls:Rn}=useConfigInject("list",$n),Dn=()=>{var Fn;const Bn=((Fn=_n.default)===null||Fn===void 0?void 0:Fn.call(_n))||[];let Hn;return Bn.forEach(zn=>{isStringElement(zn)&&!isEmptyElement(zn)&&(Hn=!0)}),Hn&&Bn.length>1},Ln=()=>{var Fn,Bn;const Hn=(Fn=$n.extra)!==null&&Fn!==void 0?Fn:(Bn=_n.extra)===null||Bn===void 0?void 0:Bn.call(_n);return In.value==="vertical"?!!Hn:!Dn()};return()=>{var Fn,Bn,Hn,zn,Wn;const{class:Yn}=Pn,Gn=__rest$u(Pn,["class"]),Go=Rn.value,Xn=(Fn=$n.extra)!==null&&Fn!==void 0?Fn:(Bn=_n.extra)===null||Bn===void 0?void 0:Bn.call(_n),Yo=(Hn=_n.default)===null||Hn===void 0?void 0:Hn.call(_n);let qo=(zn=$n.actions)!==null&&zn!==void 0?zn:flattenChildren((Wn=_n.actions)===null||Wn===void 0?void 0:Wn.call(_n));qo=qo&&!Array.isArray(qo)?[qo]:qo;const Jo=qo&&qo.length>0&&createVNode("ul",{class:`${Go}-item-action`,key:"actions"},[qo.map((nr,ta)=>createVNode("li",{key:`${Go}-item-action-${ta}`},[nr,ta!==qo.length-1&&createVNode("em",{class:`${Go}-item-action-split`},null)]))]),Zo=Nn.value?"div":"li",rr=createVNode(Zo,_objectSpread2$1(_objectSpread2$1({},Gn),{},{class:classNames(`${Go}-item`,{[`${Go}-item-no-flex`]:!Ln()},Yn)}),{default:()=>[In.value==="vertical"&&Xn?[createVNode("div",{class:`${Go}-item-main`,key:"content"},[Yo,Jo]),createVNode("div",{class:`${Go}-item-extra`,key:"extra"},[Xn])]:[Yo,Jo,cloneElement(Xn,{key:"extra"})]]});return Nn.value?createVNode(Col,{flex:1,style:$n.colStyle},{default:()=>[rr]}):rr}}}),genBorderedStyle$2=$n=>{const{listBorderedCls:Cn,componentCls:_n,paddingLG:Pn,margin:In,padding:Nn,listItemPaddingSM:Rn,marginLG:Dn,borderRadiusLG:Ln}=$n;return{[`${Cn}`]:{border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:Ln,[`${_n}-header,${_n}-footer,${_n}-item`]:{paddingInline:Pn},[`${_n}-pagination`]:{margin:`${In}px ${Dn}px`}},[`${Cn}${_n}-sm`]:{[`${_n}-item,${_n}-header,${_n}-footer`]:{padding:Rn}},[`${Cn}${_n}-lg`]:{[`${_n}-item,${_n}-header,${_n}-footer`]:{padding:`${Nn}px ${Pn}px`}}}},genResponsiveStyle=$n=>{const{componentCls:Cn,screenSM:_n,screenMD:Pn,marginLG:In,marginSM:Nn,margin:Rn}=$n;return{[`@media screen and (max-width:${Pn})`]:{[`${Cn}`]:{[`${Cn}-item`]:{[`${Cn}-item-action`]:{marginInlineStart:In}}},[`${Cn}-vertical`]:{[`${Cn}-item`]:{[`${Cn}-item-extra`]:{marginInlineStart:In}}}},[`@media screen and (max-width: ${_n})`]:{[`${Cn}`]:{[`${Cn}-item`]:{flexWrap:"wrap",[`${Cn}-action`]:{marginInlineStart:Nn}}},[`${Cn}-vertical`]:{[`${Cn}-item`]:{flexWrap:"wrap-reverse",[`${Cn}-item-main`]:{minWidth:$n.contentWidth},[`${Cn}-item-extra`]:{margin:`auto auto ${Rn}px`}}}}}},genBaseStyle$9=$n=>{const{componentCls:Cn,antCls:_n,controlHeight:Pn,minHeight:In,paddingSM:Nn,marginLG:Rn,padding:Dn,listItemPadding:Ln,colorPrimary:Fn,listItemPaddingSM:Bn,listItemPaddingLG:Hn,paddingXS:zn,margin:Wn,colorText:Yn,colorTextDescription:Gn,motionDurationSlow:Go,lineWidth:Xn}=$n;return{[`${Cn}`]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative","*":{outline:"none"},[`${Cn}-header, ${Cn}-footer`]:{background:"transparent",paddingBlock:Nn},[`${Cn}-pagination`]:{marginBlockStart:Rn,textAlign:"end",[`${_n}-pagination-options`]:{textAlign:"start"}},[`${Cn}-spin`]:{minHeight:In,textAlign:"center"},[`${Cn}-items`]:{margin:0,padding:0,listStyle:"none"},[`${Cn}-item`]:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:Ln,color:Yn,[`${Cn}-item-meta`]:{display:"flex",flex:1,alignItems:"flex-start",maxWidth:"100%",[`${Cn}-item-meta-avatar`]:{marginInlineEnd:Dn},[`${Cn}-item-meta-content`]:{flex:"1 0",width:0,color:Yn},[`${Cn}-item-meta-title`]:{marginBottom:$n.marginXXS,color:Yn,fontSize:$n.fontSize,lineHeight:$n.lineHeight,"> a":{color:Yn,transition:`all ${Go}`,"&:hover":{color:Fn}}},[`${Cn}-item-meta-description`]:{color:Gn,fontSize:$n.fontSize,lineHeight:$n.lineHeight}},[`${Cn}-item-action`]:{flex:"0 0 auto",marginInlineStart:$n.marginXXL,padding:0,fontSize:0,listStyle:"none","& > li":{position:"relative",display:"inline-block",padding:`0 ${zn}px`,color:Gn,fontSize:$n.fontSize,lineHeight:$n.lineHeight,textAlign:"center","&:first-child":{paddingInlineStart:0}},[`${Cn}-item-action-split`]:{position:"absolute",insetBlockStart:"50%",insetInlineEnd:0,width:Xn,height:Math.ceil($n.fontSize*$n.lineHeight)-$n.marginXXS*2,transform:"translateY(-50%)",backgroundColor:$n.colorSplit}}},[`${Cn}-empty`]:{padding:`${Dn}px 0`,color:Gn,fontSize:$n.fontSizeSM,textAlign:"center"},[`${Cn}-empty-text`]:{padding:Dn,color:$n.colorTextDisabled,fontSize:$n.fontSize,textAlign:"center"},[`${Cn}-item-no-flex`]:{display:"block"}}),[`${Cn}-grid ${_n}-col > ${Cn}-item`]:{display:"block",maxWidth:"100%",marginBlockEnd:Wn,paddingBlock:0,borderBlockEnd:"none"},[`${Cn}-vertical ${Cn}-item`]:{alignItems:"initial",[`${Cn}-item-main`]:{display:"block",flex:1},[`${Cn}-item-extra`]:{marginInlineStart:Rn},[`${Cn}-item-meta`]:{marginBlockEnd:Dn,[`${Cn}-item-meta-title`]:{marginBlockEnd:Nn,color:Yn,fontSize:$n.fontSizeLG,lineHeight:$n.lineHeightLG}},[`${Cn}-item-action`]:{marginBlockStart:Dn,marginInlineStart:"auto","> li":{padding:`0 ${Dn}px`,"&:first-child":{paddingInlineStart:0}}}},[`${Cn}-split ${Cn}-item`]:{borderBlockEnd:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,"&:last-child":{borderBlockEnd:"none"}},[`${Cn}-split ${Cn}-header`]:{borderBlockEnd:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},[`${Cn}-split${Cn}-empty ${Cn}-footer`]:{borderTop:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},[`${Cn}-loading ${Cn}-spin-nested-loading`]:{minHeight:Pn},[`${Cn}-split${Cn}-something-after-last-item ${_n}-spin-container > ${Cn}-items > ${Cn}-item:last-child`]:{borderBlockEnd:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`},[`${Cn}-lg ${Cn}-item`]:{padding:Hn},[`${Cn}-sm ${Cn}-item`]:{padding:Bn},[`${Cn}:not(${Cn}-vertical)`]:{[`${Cn}-item-no-flex`]:{[`${Cn}-item-action`]:{float:"right"}}}}},useStyle$k=genComponentStyleHook("List",$n=>{const Cn=merge$1($n,{listBorderedCls:`${$n.componentCls}-bordered`,minHeight:$n.controlHeightLG,listItemPadding:`${$n.paddingContentVertical}px ${$n.paddingContentHorizontalLG}px`,listItemPaddingSM:`${$n.paddingContentVerticalSM}px ${$n.paddingContentHorizontal}px`,listItemPaddingLG:`${$n.paddingContentVerticalLG}px ${$n.paddingContentHorizontalLG}px`});return[genBaseStyle$9(Cn),genBorderedStyle$2(Cn),genResponsiveStyle(Cn)]},{contentWidth:220}),listProps=()=>({bordered:booleanType(),dataSource:arrayType(),extra:vNodeType(),grid:objectType(),itemLayout:String,loading:someType([Boolean,Object]),loadMore:vNodeType(),pagination:someType([Boolean,Object]),prefixCls:String,rowKey:someType([String,Number,Function]),renderItem:functionType(),size:String,split:booleanType(),header:vNodeType(),footer:vNodeType(),locale:objectType()}),List$1=defineComponent({compatConfig:{MODE:3},name:"AList",inheritAttrs:!1,Item,props:initDefaultProps(listProps(),{dataSource:[],bordered:!1,split:!0,loading:!1,pagination:!1}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;var In,Nn;provide(ListContextKey,{grid:toRef($n,"grid"),itemLayout:toRef($n,"itemLayout")});const Rn={current:1,total:0},{prefixCls:Dn,direction:Ln,renderEmpty:Fn}=useConfigInject("list",$n),[Bn,Hn]=useStyle$k(Dn),zn=computed(()=>$n.pagination&&typeof $n.pagination=="object"?$n.pagination:{}),Wn=ref((In=zn.value.defaultCurrent)!==null&&In!==void 0?In:1),Yn=ref((Nn=zn.value.defaultPageSize)!==null&&Nn!==void 0?Nn:10);watch(zn,()=>{"current"in zn.value&&(Wn.value=zn.value.current),"pageSize"in zn.value&&(Yn.value=zn.value.pageSize)});const Gn=[],Go=ua=>(ga,aa)=>{Wn.value=ga,Yn.value=aa,zn.value[ua]&&zn.value[ua](ga,aa)},Xn=Go("onChange"),Yo=Go("onShowSizeChange"),qo=computed(()=>typeof $n.loading=="boolean"?{spinning:$n.loading}:$n.loading),Jo=computed(()=>qo.value&&qo.value.spinning),Zo=computed(()=>{let ua="";switch($n.size){case"large":ua="lg";break;case"small":ua="sm";break}return ua}),rr=computed(()=>({[`${Dn.value}`]:!0,[`${Dn.value}-vertical`]:$n.itemLayout==="vertical",[`${Dn.value}-${Zo.value}`]:Zo.value,[`${Dn.value}-split`]:$n.split,[`${Dn.value}-bordered`]:$n.bordered,[`${Dn.value}-loading`]:Jo.value,[`${Dn.value}-grid`]:!!$n.grid,[`${Dn.value}-rtl`]:Ln.value==="rtl"})),nr=computed(()=>{const ua=_extends$1(_extends$1(_extends$1({},Rn),{total:$n.dataSource.length,current:Wn.value,pageSize:Yn.value}),$n.pagination||{}),ga=Math.ceil(ua.total/ua.pageSize);return ua.current>ga&&(ua.current=ga),ua}),ta=computed(()=>{let ua=[...$n.dataSource];return $n.pagination&&$n.dataSource.length>(nr.value.current-1)*nr.value.pageSize&&(ua=[...$n.dataSource].splice((nr.value.current-1)*nr.value.pageSize,nr.value.pageSize)),ua}),oa=useBreakpoint(),ra=eagerComputed(()=>{for(let ua=0;ua{if(!$n.grid)return;const ua=ra.value&&$n.grid[ra.value]?$n.grid[ra.value]:$n.grid.column;if(ua)return{width:`${100/ua}%`,maxWidth:`${100/ua}%`}}),la=(ua,ga)=>{var aa;const ca=(aa=$n.renderItem)!==null&&aa!==void 0?aa:_n.renderItem;if(!ca)return null;let sa;const ia=typeof $n.rowKey;return ia==="function"?sa=$n.rowKey(ua):ia==="string"||ia==="number"?sa=ua[$n.rowKey]:sa=ua.key,sa||(sa=`list-item-${ga}`),Gn[ga]=sa,ca({item:ua,index:ga})};return()=>{var ua,ga,aa,ca,sa,ia,fa,ma;const ya=(ua=$n.loadMore)!==null&&ua!==void 0?ua:(ga=_n.loadMore)===null||ga===void 0?void 0:ga.call(_n),ba=(aa=$n.footer)!==null&&aa!==void 0?aa:(ca=_n.footer)===null||ca===void 0?void 0:ca.call(_n),Ia=(sa=$n.header)!==null&&sa!==void 0?sa:(ia=_n.header)===null||ia===void 0?void 0:ia.call(_n),Ea=flattenChildren((fa=_n.default)===null||fa===void 0?void 0:fa.call(_n)),xa=!!(ya||$n.pagination||ba),Ta=classNames(_extends$1(_extends$1({},rr.value),{[`${Dn.value}-something-after-last-item`]:xa}),Pn.class,Hn.value),wa=$n.pagination?createVNode("div",{class:`${Dn.value}-pagination`},[createVNode(Pagination,_objectSpread2$1(_objectSpread2$1({},nr.value),{},{onChange:Xn,onShowSizeChange:Yo}),null)]):null;let La=Jo.value&&createVNode("div",{style:{minHeight:"53px"}},null);if(ta.value.length>0){Gn.length=0;const $a=ta.value.map((Ha,da)=>la(Ha,da)),ka=$a.map((Ha,da)=>createVNode("div",{key:Gn[da],style:ea.value},[Ha]));La=$n.grid?createVNode(Row$2,{gutter:$n.grid.gutter},{default:()=>[ka]}):createVNode("ul",{class:`${Dn.value}-items`},[$a])}else!Ea.length&&!Jo.value&&(La=createVNode("div",{class:`${Dn.value}-empty-text`},[((ma=$n.locale)===null||ma===void 0?void 0:ma.emptyText)||Fn("List")]));const Na=nr.value.position||"bottom";return Bn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:Ta}),[(Na==="top"||Na==="both")&&wa,Ia&&createVNode("div",{class:`${Dn.value}-header`},[Ia]),createVNode(Spin,qo.value,{default:()=>[La,Ea]}),ba&&createVNode("div",{class:`${Dn.value}-footer`},[ba]),ya||(Na==="bottom"||Na==="both")&&wa]))}}});List$1.install=function($n){return $n.component(List$1.name,List$1),$n.component(List$1.Item.name,List$1.Item),$n.component(List$1.Item.Meta.name,List$1.Item.Meta),$n};const List$2=List$1;function getBeforeSelectionText($n){const{selectionStart:Cn}=$n;return $n.value.slice(0,Cn)}function getLastMeasureIndex($n){let Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";return(Array.isArray(Cn)?Cn:[Cn]).reduce((Pn,In)=>{const Nn=$n.lastIndexOf(In);return Nn>Pn.location?{location:Nn,prefix:In}:Pn},{location:-1,prefix:""})}function lower($n){return($n||"").toLowerCase()}function reduceText($n,Cn,_n){const Pn=$n[0];if(!Pn||Pn===_n)return $n;let In=$n;const Nn=Cn.length;for(let Rn=0;Rn[]}},setup($n,Cn){let{slots:_n}=Cn;const{activeIndex:Pn,setActiveIndex:In,selectOption:Nn,onFocus:Rn=noop$8,loading:Dn}=inject(MentionsContextKey$1,{activeIndex:shallowRef(),loading:shallowRef(!1)});let Ln;const Fn=Bn=>{clearTimeout(Ln),Ln=setTimeout(()=>{Rn(Bn)})};return onBeforeUnmount(()=>{clearTimeout(Ln)}),()=>{var Bn;const{prefixCls:Hn,options:zn}=$n,Wn=zn[Pn.value]||{};return createVNode(Menu,{prefixCls:`${Hn}-menu`,activeKey:Wn.value,onSelect:Yn=>{let{key:Gn}=Yn;const Go=zn.find(Xn=>{let{value:Yo}=Xn;return Yo===Gn});Nn(Go)},onMousedown:Fn},{default:()=>[!Dn.value&&zn.map((Yn,Gn)=>{var Go,Xn;const{value:Yo,disabled:qo,label:Jo=Yn.value,class:Zo,style:rr}=Yn;return createVNode(MenuItem$1,{key:Yo,disabled:qo,onMouseenter:()=>{In(Gn)},class:Zo,style:rr},{default:()=>[(Xn=(Go=_n.option)===null||Go===void 0?void 0:Go.call(_n,Yn))!==null&&Xn!==void 0?Xn:typeof Jo=="function"?Jo(Yn):Jo]})}),!Dn.value&&zn.length===0?createVNode(MenuItem$1,{key:"notFoundContent",disabled:!0},{default:()=>[(Bn=_n.notFoundContent)===null||Bn===void 0?void 0:Bn.call(_n)]}):null,Dn.value&&createVNode(MenuItem$1,{key:"loading",disabled:!0},{default:()=>[createVNode(Spin,{size:"small"},null)]})]})}}}),BUILT_IN_PLACEMENTS={bottomRight:{points:["tl","br"],offset:[0,4],overflow:{adjustX:0,adjustY:1}},bottomLeft:{points:["tr","bl"],offset:[0,4],overflow:{adjustX:0,adjustY:1}},topRight:{points:["bl","tr"],offset:[0,-4],overflow:{adjustX:0,adjustY:1}},topLeft:{points:["br","tl"],offset:[0,-4],overflow:{adjustX:0,adjustY:1}}},KeywordTrigger=defineComponent({compatConfig:{MODE:3},name:"KeywordTrigger",props:{loading:{type:Boolean,default:void 0},options:{type:Array,default:()=>[]},prefixCls:String,placement:String,visible:{type:Boolean,default:void 0},transitionName:String,getPopupContainer:Function,direction:String,dropdownClassName:String},setup($n,Cn){let{slots:_n}=Cn;const Pn=()=>`${$n.prefixCls}-dropdown`,In=()=>{const{options:Rn}=$n;return createVNode(DropdownMenu,{prefixCls:Pn(),options:Rn},{notFoundContent:_n.notFoundContent,option:_n.option})},Nn=computed(()=>{const{placement:Rn,direction:Dn}=$n;let Ln="topRight";return Dn==="rtl"?Ln=Rn==="top"?"topLeft":"bottomLeft":Ln=Rn==="top"?"topRight":"bottomRight",Ln});return()=>{const{visible:Rn,transitionName:Dn,getPopupContainer:Ln}=$n;return createVNode(Trigger,{prefixCls:Pn(),popupVisible:Rn,popup:In(),popupClassName:$n.dropdownClassName,popupPlacement:Nn.value,popupTransitionName:Dn,builtinPlacements:BUILT_IN_PLACEMENTS,getPopupContainer:Ln},{default:_n.default})}}}),PlaceMent=tuple$1("top","bottom"),mentionsProps$1={autofocus:{type:Boolean,default:void 0},prefix:PropTypes.oneOfType([PropTypes.string,PropTypes.arrayOf(PropTypes.string)]),prefixCls:String,value:String,disabled:{type:Boolean,default:void 0},split:String,transitionName:String,placement:PropTypes.oneOf(PlaceMent),character:PropTypes.any,characterRender:Function,filterOption:{type:[Boolean,Function]},validateSearch:Function,getPopupContainer:{type:Function},options:arrayType(),loading:{type:Boolean,default:void 0},rows:[Number,String],direction:{type:String}},vcMentionsProps=_extends$1(_extends$1({},mentionsProps$1),{dropdownClassName:String}),defaultProps$1={prefix:"@",split:" ",rows:1,validateSearch,filterOption:()=>filterOption};initDefaultProps(vcMentionsProps,defaultProps$1);var __rest$t=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{Fn.value=$n.value});const Bn=ea=>{_n("change",ea)},Hn=ea=>{let{target:{value:la,composing:ua},isComposing:ga}=ea;ga||ua||Bn(la)},zn=(ea,la,ua)=>{_extends$1(Fn,{measuring:!0,measureText:ea,measurePrefix:la,measureLocation:ua,activeIndex:0})},Wn=ea=>{_extends$1(Fn,{measuring:!1,measureLocation:0,measureText:null}),ea==null||ea()},Yn=ea=>{const{which:la}=ea;if(Fn.measuring){if(la===KeyCode$1.UP||la===KeyCode$1.DOWN){const ua=ta.value.length,ga=la===KeyCode$1.UP?-1:1,aa=(Fn.activeIndex+ga+ua)%ua;Fn.activeIndex=aa,ea.preventDefault()}else if(la===KeyCode$1.ESC)Wn();else if(la===KeyCode$1.ENTER){if(ea.preventDefault(),!ta.value.length){Wn();return}const ua=ta.value[Fn.activeIndex];Zo(ua)}}},Gn=ea=>{const{key:la,which:ua}=ea,{measureText:ga,measuring:aa}=Fn,{prefix:ca,validateSearch:sa}=$n,ia=ea.target;if(ia.composing)return;const fa=getBeforeSelectionText(ia),{location:ma,prefix:ya}=getLastMeasureIndex(fa,ca);if([KeyCode$1.ESC,KeyCode$1.UP,KeyCode$1.DOWN,KeyCode$1.ENTER].indexOf(ua)===-1)if(ma!==-1){const ba=fa.slice(ma+ya.length),Ia=sa(ba,$n),Ea=!!nr(ba).length;Ia?(la===ya||la==="Shift"||aa||ba!==ga&&Ea)&&zn(ba,ya,ma):aa&&Wn(),Ia&&_n("search",ba,ya)}else aa&&Wn()},Go=ea=>{Fn.measuring||_n("pressenter",ea)},Xn=ea=>{qo(ea)},Yo=ea=>{Jo(ea)},qo=ea=>{clearTimeout(Ln.value);const{isFocus:la}=Fn;!la&&ea&&_n("focus",ea),Fn.isFocus=!0},Jo=ea=>{Ln.value=setTimeout(()=>{Fn.isFocus=!1,Wn(),_n("blur",ea)},100)},Zo=ea=>{const{split:la}=$n,{value:ua=""}=ea,{text:ga,selectionLocation:aa}=replaceWithMeasure(Fn.value,{measureLocation:Fn.measureLocation,targetText:ua,prefix:Fn.measurePrefix,selectionStart:Dn.value.selectionStart,split:la});Bn(ga),Wn(()=>{setInputSelection(Dn.value,aa)}),_n("select",ea,Fn.measurePrefix)},rr=ea=>{Fn.activeIndex=ea},nr=ea=>{const la=ea||Fn.measureText||"",{filterOption:ua}=$n;return $n.options.filter(aa=>ua?ua(la,aa):!0)},ta=computed(()=>nr());return In({blur:()=>{Dn.value.blur()},focus:()=>{Dn.value.focus()}}),provide(MentionsContextKey$1,{activeIndex:toRef(Fn,"activeIndex"),setActiveIndex:rr,selectOption:Zo,onFocus:qo,onBlur:Jo,loading:toRef($n,"loading")}),onUpdated(()=>{nextTick(()=>{Fn.measuring&&(Rn.value.scrollTop=Dn.value.scrollTop)})}),()=>{const{measureLocation:ea,measurePrefix:la,measuring:ua}=Fn,{prefixCls:ga,placement:aa,transitionName:ca,getPopupContainer:sa,direction:ia}=$n,fa=__rest$t($n,["prefixCls","placement","transitionName","getPopupContainer","direction"]),{class:ma,style:ya}=Pn,ba=__rest$t(Pn,["class","style"]),Ia=omit$1(fa,["value","prefix","split","validateSearch","filterOption","options","loading"]),Ea=_extends$1(_extends$1(_extends$1({},Ia),ba),{onChange:noop$7,onSelect:noop$7,value:Fn.value,onInput:Hn,onBlur:Yo,onKeydown:Yn,onKeyup:Gn,onFocus:Xn,onPressenter:Go});return createVNode("div",{class:classNames(ga,ma),style:ya},[withDirectives(createVNode("textarea",_objectSpread2$1({ref:Dn},Ea),null),[[antInputDirective]]),ua&&createVNode("div",{ref:Rn,class:`${ga}-measure`},[Fn.value.slice(0,ea),createVNode(KeywordTrigger,{prefixCls:ga,transitionName:ca,dropdownClassName:$n.dropdownClassName,placement:aa,options:ua?ta.value:[],visible:!0,direction:ia,getPopupContainer:sa},{default:()=>[createVNode("span",null,[la])],notFoundContent:Nn.notFoundContent,option:Nn.option}),Fn.value.slice(ea+la.length)])])}}}),baseOptionsProps={value:String,disabled:Boolean,payload:objectType()},optionProps=_extends$1(_extends$1({},baseOptionsProps),{label:anyType([])}),optionOptions={name:"Option",props:optionProps,render($n,Cn){let{slots:_n}=Cn;var Pn;return(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)}};_extends$1({compatConfig:{MODE:3}},optionOptions);const genMentionsStyle=$n=>{const{componentCls:Cn,colorTextDisabled:_n,controlItemBgHover:Pn,controlPaddingHorizontal:In,colorText:Nn,motionDurationSlow:Rn,lineHeight:Dn,controlHeight:Ln,inputPaddingHorizontal:Fn,inputPaddingVertical:Bn,fontSize:Hn,colorBgElevated:zn,borderRadiusLG:Wn,boxShadowSecondary:Yn}=$n,Gn=Math.round(($n.controlHeight-$n.fontSize*$n.lineHeight)/2);return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),genBasicInputStyle($n)),{position:"relative",display:"inline-block",height:"auto",padding:0,overflow:"hidden",lineHeight:Dn,whiteSpace:"pre-wrap",verticalAlign:"bottom"}),genStatusStyle($n,Cn)),{"&-disabled":{"> textarea":_extends$1({},genDisabledStyle($n))},"&-focused":_extends$1({},genActiveStyle($n)),[`&-affix-wrapper ${Cn}-suffix`]:{position:"absolute",top:0,insetInlineEnd:Fn,bottom:0,zIndex:1,display:"inline-flex",alignItems:"center",margin:"auto"},[`> textarea, ${Cn}-measure`]:{color:Nn,boxSizing:"border-box",minHeight:Ln-2,margin:0,padding:`${Bn}px ${Fn}px`,overflow:"inherit",overflowX:"hidden",overflowY:"auto",fontWeight:"inherit",fontSize:"inherit",fontFamily:"inherit",fontStyle:"inherit",fontVariant:"inherit",fontSizeAdjust:"inherit",fontStretch:"inherit",lineHeight:"inherit",direction:"inherit",letterSpacing:"inherit",whiteSpace:"inherit",textAlign:"inherit",verticalAlign:"top",wordWrap:"break-word",wordBreak:"inherit",tabSize:"inherit"},"> textarea":_extends$1({width:"100%",border:"none",outline:"none",resize:"none",backgroundColor:"inherit"},genPlaceholderStyle($n.colorTextPlaceholder)),[`${Cn}-measure`]:{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:-1,color:"transparent",pointerEvents:"none","> span":{display:"inline-block",minHeight:"1em"}},"&-dropdown":_extends$1(_extends$1({},resetComponent($n)),{position:"absolute",top:-9999,insetInlineStart:-9999,zIndex:$n.zIndexPopup,boxSizing:"border-box",fontSize:Hn,fontVariant:"initial",backgroundColor:zn,borderRadius:Wn,outline:"none",boxShadow:Yn,"&-hidden":{display:"none"},[`${Cn}-dropdown-menu`]:{maxHeight:$n.dropdownHeight,marginBottom:0,paddingInlineStart:0,overflow:"auto",listStyle:"none",outline:"none","&-item":_extends$1(_extends$1({},textEllipsis),{position:"relative",display:"block",minWidth:$n.controlItemWidth,padding:`${Gn}px ${In}px`,color:Nn,fontWeight:"normal",lineHeight:Dn,cursor:"pointer",transition:`background ${Rn} ease`,"&:hover":{backgroundColor:Pn},"&:first-child":{borderStartStartRadius:Wn,borderStartEndRadius:Wn,borderEndStartRadius:0,borderEndEndRadius:0},"&:last-child":{borderStartStartRadius:0,borderStartEndRadius:0,borderEndStartRadius:Wn,borderEndEndRadius:Wn},"&-disabled":{color:_n,cursor:"not-allowed","&:hover":{color:_n,backgroundColor:Pn,cursor:"not-allowed"}},"&-selected":{color:Nn,fontWeight:$n.fontWeightStrong,backgroundColor:Pn},"&-active":{backgroundColor:Pn}})}})})}},useStyle$j=genComponentStyleHook("Mentions",$n=>{const Cn=initInputToken($n);return[genMentionsStyle(Cn)]},$n=>({dropdownHeight:250,controlItemWidth:100,zIndexPopup:$n.zIndexPopupBase+50}));var __rest$s=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In0&&arguments[0]!==void 0?arguments[0]:"",Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const{prefix:_n="@",split:Pn=" "}=Cn,In=Array.isArray(_n)?_n:[_n];return $n.split(Pn).map(function(){let Nn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"",Rn=null;return In.some(Dn=>Nn.slice(0,Dn.length)===Dn?(Rn=Dn,!0):!1),Rn!==null?{prefix:Rn,value:Nn.slice(Rn.length)}:null}).filter(Nn=>!!Nn&&!!Nn.value)},mentionsProps=()=>_extends$1(_extends$1({},mentionsProps$1),{loading:{type:Boolean,default:void 0},onFocus:{type:Function},onBlur:{type:Function},onSelect:{type:Function},onChange:{type:Function},onPressenter:{type:Function},"onUpdate:value":{type:Function},notFoundContent:PropTypes.any,defaultValue:String,id:String,status:String}),Mentions=defineComponent({compatConfig:{MODE:3},name:"AMentions",inheritAttrs:!1,props:mentionsProps(),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,attrs:In,expose:Nn}=Cn;var Rn,Dn;const{prefixCls:Ln,renderEmpty:Fn,direction:Bn}=useConfigInject("mentions",$n),[Hn,zn]=useStyle$j(Ln),Wn=shallowRef(!1),Yn=shallowRef(null),Gn=shallowRef((Dn=(Rn=$n.value)!==null&&Rn!==void 0?Rn:$n.defaultValue)!==null&&Dn!==void 0?Dn:""),Go=useInjectFormItemContext(),Xn=FormItemInputContext.useInject(),Yo=computed(()=>getMergedStatus(Xn.status,$n.status));useProvideOverride({prefixCls:computed(()=>`${Ln.value}-menu`),mode:computed(()=>"vertical"),selectable:computed(()=>!1),onClick:()=>{},validator:la=>{warning$3()}}),watch(()=>$n.value,la=>{Gn.value=la});const qo=la=>{Wn.value=!0,Pn("focus",la)},Jo=la=>{Wn.value=!1,Pn("blur",la),Go.onFieldBlur()},Zo=function(){for(var la=arguments.length,ua=new Array(la),ga=0;ga{$n.value===void 0&&(Gn.value=la),Pn("update:value",la),Pn("change",la),Go.onFieldChange()},nr=()=>{const la=$n.notFoundContent;return la!==void 0?la:_n.notFoundContent?_n.notFoundContent():Fn("Select")},ta=()=>{var la;return flattenChildren(((la=_n.default)===null||la===void 0?void 0:la.call(_n))||[]).map(ua=>{var ga,aa;return _extends$1(_extends$1({},getOptionProps(ua)),{label:(aa=(ga=ua.children)===null||ga===void 0?void 0:ga.default)===null||aa===void 0?void 0:aa.call(ga)})})};Nn({focus:()=>{Yn.value.focus()},blur:()=>{Yn.value.blur()}});const ea=computed(()=>$n.loading?loadingFilterOption:$n.filterOption);return()=>{const{disabled:la,getPopupContainer:ua,rows:ga=1,id:aa=Go.id.value}=$n,ca=__rest$s($n,["disabled","getPopupContainer","rows","id"]),{hasFeedback:sa,feedbackIcon:ia}=Xn,{class:fa}=In,ma=__rest$s(In,["class"]),ya=omit$1(ca,["defaultValue","onUpdate:value","prefixCls"]),ba=classNames({[`${Ln.value}-disabled`]:la,[`${Ln.value}-focused`]:Wn.value,[`${Ln.value}-rtl`]:Bn.value==="rtl"},getStatusClassNames(Ln.value,Yo.value),!sa&&fa,zn.value),Ia=_extends$1(_extends$1(_extends$1(_extends$1({prefixCls:Ln.value},ya),{disabled:la,direction:Bn.value,filterOption:ea.value,getPopupContainer:ua,options:$n.loading?[{value:"ANTDV_SEARCHING",disabled:!0,label:createVNode(Spin,{size:"small"},null)}]:$n.options||ta(),class:ba}),ma),{rows:ga,onChange:rr,onSelect:Zo,onFocus:qo,onBlur:Jo,ref:Yn,value:Gn.value,id:aa}),Ea=createVNode(Mentions$1,_objectSpread2$1(_objectSpread2$1({},Ia),{},{dropdownClassName:zn.value}),{notFoundContent:nr,option:_n.option});return Hn(sa?createVNode("div",{class:classNames(`${Ln.value}-affix-wrapper`,getStatusClassNames(`${Ln.value}-affix-wrapper`,Yo.value,sa),fa,zn.value)},[Ea,createVNode("span",{class:`${Ln.value}-suffix`},[ia])]):Ea)}}}),MentionsOption=defineComponent(_extends$1(_extends$1({compatConfig:{MODE:3}},optionOptions),{name:"AMentionsOption",props:optionProps})),index$h=_extends$1(Mentions,{Option:MentionsOption,getMentions,install:$n=>($n.component(Mentions.name,Mentions),$n.component(MentionsOption.name,MentionsOption),$n)});var __rest$r=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{mousePosition={x:$n.pageX,y:$n.pageY},setTimeout(()=>mousePosition=null,100)};canUseDocElement()&&addEventListenerWrap(document.documentElement,"click",getClickPosition,!0);const modalProps=()=>({prefixCls:String,visible:{type:Boolean,default:void 0},open:{type:Boolean,default:void 0},confirmLoading:{type:Boolean,default:void 0},title:PropTypes.any,closable:{type:Boolean,default:void 0},closeIcon:PropTypes.any,onOk:Function,onCancel:Function,"onUpdate:visible":Function,"onUpdate:open":Function,onChange:Function,afterClose:Function,centered:{type:Boolean,default:void 0},width:[String,Number],footer:PropTypes.any,okText:PropTypes.any,okType:String,cancelText:PropTypes.any,icon:PropTypes.any,maskClosable:{type:Boolean,default:void 0},forceRender:{type:Boolean,default:void 0},okButtonProps:objectType(),cancelButtonProps:objectType(),destroyOnClose:{type:Boolean,default:void 0},wrapClassName:String,maskTransitionName:String,transitionName:String,getContainer:{type:[String,Function,Boolean,Object],default:void 0},zIndex:Number,bodyStyle:objectType(),maskStyle:objectType(),mask:{type:Boolean,default:void 0},keyboard:{type:Boolean,default:void 0},wrapProps:Object,focusTriggerAfterClose:{type:Boolean,default:void 0},modalRender:Function,mousePosition:objectType()}),Modal=defineComponent({compatConfig:{MODE:3},name:"AModal",inheritAttrs:!1,props:initDefaultProps(modalProps(),{width:520,confirmLoading:!1,okType:"primary"}),setup($n,Cn){let{emit:_n,slots:Pn,attrs:In}=Cn;const[Nn]=useLocaleReceiver("Modal"),{prefixCls:Rn,rootPrefixCls:Dn,direction:Ln,getPopupContainer:Fn}=useConfigInject("modal",$n),[Bn,Hn]=useStyle$q(Rn);warning$3($n.visible===void 0);const zn=Gn=>{_n("update:visible",!1),_n("update:open",!1),_n("cancel",Gn),_n("change",!1)},Wn=Gn=>{_n("ok",Gn)},Yn=()=>{var Gn,Go;const{okText:Xn=(Gn=Pn.okText)===null||Gn===void 0?void 0:Gn.call(Pn),okType:Yo,cancelText:qo=(Go=Pn.cancelText)===null||Go===void 0?void 0:Go.call(Pn),confirmLoading:Jo}=$n;return createVNode(Fragment,null,[createVNode(Button$1,_objectSpread2$1({onClick:zn},$n.cancelButtonProps),{default:()=>[qo||Nn.value.cancelText]}),createVNode(Button$1,_objectSpread2$1(_objectSpread2$1({},convertLegacyProps(Yo)),{},{loading:Jo,onClick:Wn},$n.okButtonProps),{default:()=>[Xn||Nn.value.okText]})])};return()=>{var Gn,Go;const{prefixCls:Xn,visible:Yo,open:qo,wrapClassName:Jo,centered:Zo,getContainer:rr,closeIcon:nr=(Gn=Pn.closeIcon)===null||Gn===void 0?void 0:Gn.call(Pn),focusTriggerAfterClose:ta=!0}=$n,oa=__rest$r($n,["prefixCls","visible","open","wrapClassName","centered","getContainer","closeIcon","focusTriggerAfterClose"]),ra=classNames(Jo,{[`${Rn.value}-centered`]:!!Zo,[`${Rn.value}-wrap-rtl`]:Ln.value==="rtl"});return Bn(createVNode(DialogWrap$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},oa),In),{},{rootClassName:Hn.value,class:classNames(Hn.value,In.class),getContainer:rr||(Fn==null?void 0:Fn.value),prefixCls:Rn.value,wrapClassName:ra,visible:qo??Yo,onClose:zn,focusTriggerAfterClose:ta,transitionName:getTransitionName$1(Dn.value,"zoom",$n.transitionName),maskTransitionName:getTransitionName$1(Dn.value,"fade",$n.maskTransitionName),mousePosition:(Go=oa.mousePosition)!==null&&Go!==void 0?Go:mousePosition}),_extends$1(_extends$1({},Pn),{footer:Pn.footer||Yn,closeIcon:()=>createVNode("span",{class:`${Rn.value}-close-x`},[nr||createVNode(CloseOutlined$1,{class:`${Rn.value}-close-icon`},null)])})))}}}),useDestroyed=()=>{const $n=shallowRef(!1);return onBeforeUnmount(()=>{$n.value=!0}),$n},actionButtonProps={type:{type:String},actionFn:Function,close:Function,autofocus:Boolean,prefixCls:String,buttonProps:objectType(),emitEvent:Boolean,quitOnNullishReturnValue:Boolean};function isThenable($n){return!!($n&&$n.then)}const ActionButton=defineComponent({compatConfig:{MODE:3},name:"ActionButton",props:actionButtonProps,setup($n,Cn){let{slots:_n}=Cn;const Pn=shallowRef(!1),In=shallowRef(),Nn=shallowRef(!1);let Rn;const Dn=useDestroyed();onMounted(()=>{$n.autofocus&&(Rn=setTimeout(()=>{var Hn,zn;return(zn=(Hn=findDOMNode(In.value))===null||Hn===void 0?void 0:Hn.focus)===null||zn===void 0?void 0:zn.call(Hn)}))}),onBeforeUnmount(()=>{clearTimeout(Rn)});const Ln=function(){for(var Hn,zn=arguments.length,Wn=new Array(zn),Yn=0;Yn{isThenable(Hn)&&(Nn.value=!0,Hn.then(function(){Dn.value||(Nn.value=!1),Ln(...arguments),Pn.value=!1},zn=>(Dn.value||(Nn.value=!1),Pn.value=!1,Promise.reject(zn))))},Bn=Hn=>{const{actionFn:zn}=$n;if(Pn.value)return;if(Pn.value=!0,!zn){Ln();return}let Wn;if($n.emitEvent){if(Wn=zn(Hn),$n.quitOnNullishReturnValue&&!isThenable(Wn)){Pn.value=!1,Ln(Hn);return}}else if(zn.length)Wn=zn($n.close),Pn.value=!1;else if(Wn=zn(),!Wn){Ln();return}Fn(Wn)};return()=>{const{type:Hn,prefixCls:zn,buttonProps:Wn}=$n;return createVNode(Button$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},convertLegacyProps(Hn)),{},{onClick:Bn,loading:Nn.value,prefixCls:zn},Wn),{},{ref:In}),_n)}}});function renderSomeContent($n){return typeof $n=="function"?$n():$n}const ConfirmDialog=defineComponent({name:"ConfirmDialog",inheritAttrs:!1,props:["icon","onCancel","onOk","close","closable","zIndex","afterClose","visible","open","keyboard","centered","getContainer","maskStyle","okButtonProps","cancelButtonProps","okType","prefixCls","okCancel","width","mask","maskClosable","okText","cancelText","autoFocusButton","transitionName","maskTransitionName","type","title","content","direction","rootPrefixCls","bodyStyle","closeIcon","modalRender","focusTriggerAfterClose","wrapClassName","confirmPrefixCls","footer"],setup($n,Cn){let{attrs:_n}=Cn;const[Pn]=useLocaleReceiver("Modal");return()=>{const{icon:In,onCancel:Nn,onOk:Rn,close:Dn,okText:Ln,closable:Fn=!1,zIndex:Bn,afterClose:Hn,keyboard:zn,centered:Wn,getContainer:Yn,maskStyle:Gn,okButtonProps:Go,cancelButtonProps:Xn,okCancel:Yo,width:qo=416,mask:Jo=!0,maskClosable:Zo=!1,type:rr,open:nr,title:ta,content:oa,direction:ra,closeIcon:ea,modalRender:la,focusTriggerAfterClose:ua,rootPrefixCls:ga,bodyStyle:aa,wrapClassName:ca,footer:sa}=$n;let ia=In;if(!In&&In!==null)switch(rr){case"info":ia=createVNode(InfoCircleFilled$1,null,null);break;case"success":ia=createVNode(CheckCircleFilled$1,null,null);break;case"error":ia=createVNode(CloseCircleFilled$1,null,null);break;default:ia=createVNode(ExclamationCircleFilled$1,null,null)}const fa=$n.okType||"primary",ma=$n.prefixCls||"ant-modal",ya=`${ma}-confirm`,ba=_n.style||{},Ia=Yo??rr==="confirm",Ea=$n.autoFocusButton===null?!1:$n.autoFocusButton||"ok",xa=`${ma}-confirm`,Ta=classNames(xa,`${xa}-${$n.type}`,{[`${xa}-rtl`]:ra==="rtl"},_n.class),wa=Pn.value,La=Ia&&createVNode(ActionButton,{actionFn:Nn,close:Dn,autofocus:Ea==="cancel",buttonProps:Xn,prefixCls:`${ga}-btn`},{default:()=>[renderSomeContent($n.cancelText)||wa.cancelText]});return createVNode(Modal,{prefixCls:ma,class:Ta,wrapClassName:classNames({[`${xa}-centered`]:!!Wn},ca),onCancel:Na=>Dn==null?void 0:Dn({triggerCancel:!0},Na),open:nr,title:"",footer:"",transitionName:getTransitionName$1(ga,"zoom",$n.transitionName),maskTransitionName:getTransitionName$1(ga,"fade",$n.maskTransitionName),mask:Jo,maskClosable:Zo,maskStyle:Gn,style:ba,bodyStyle:aa,width:qo,zIndex:Bn,afterClose:Hn,keyboard:zn,centered:Wn,getContainer:Yn,closable:Fn,closeIcon:ea,modalRender:la,focusTriggerAfterClose:ua},{default:()=>[createVNode("div",{class:`${ya}-body-wrapper`},[createVNode("div",{class:`${ya}-body`},[renderSomeContent(ia),ta===void 0?null:createVNode("span",{class:`${ya}-title`},[renderSomeContent(ta)]),createVNode("div",{class:`${ya}-content`},[renderSomeContent(oa)])]),sa!==void 0?renderSomeContent(sa):createVNode("div",{class:`${ya}-btns`},[La,createVNode(ActionButton,{type:fa,actionFn:Rn,close:Dn,autofocus:Ea==="ok",buttonProps:Go,prefixCls:`${ga}-btn`},{default:()=>[renderSomeContent(Ln)||(Ia?wa.okText:wa.justOkText)]})])])]})}}}),destroyFns=[],confirm=$n=>{const Cn=document.createDocumentFragment();let _n=_extends$1(_extends$1({},omit$1($n,["parentContext","appContext"])),{close:Nn,open:!0}),Pn=null;function In(){Pn&&(render$1(null,Cn),Pn=null);for(var Fn=arguments.length,Bn=new Array(Fn),Hn=0;HnWn&&Wn.triggerCancel);$n.onCancel&&zn&&$n.onCancel(()=>{},...Bn.slice(1));for(let Wn=0;Wn{typeof $n.afterClose=="function"&&$n.afterClose(),In.apply(this,Bn)}}),_n.visible&&delete _n.visible,Rn(_n)}function Rn(Fn){typeof Fn=="function"?_n=Fn(_n):_n=_extends$1(_extends$1({},_n),Fn),Pn&&triggerVNodeUpdate(Pn,_n,Cn)}const Dn=Fn=>{const Bn=globalConfigForApi,Hn=Bn.prefixCls,zn=Fn.prefixCls||`${Hn}-modal`,Wn=Bn.iconPrefixCls,Yn=getConfirmLocale();return createVNode(ConfigProvider$1,_objectSpread2$1(_objectSpread2$1({},Bn),{},{prefixCls:Hn}),{default:()=>[createVNode(ConfirmDialog,_objectSpread2$1(_objectSpread2$1({},Fn),{},{rootPrefixCls:Hn,prefixCls:zn,iconPrefixCls:Wn,locale:Yn,cancelText:Fn.cancelText||Yn.cancelText}),null)]})};function Ln(Fn){const Bn=createVNode(Dn,_extends$1({},Fn));return Bn.appContext=$n.parentContext||$n.appContext||Bn.appContext,render$1(Bn,Cn),Bn}return Pn=Ln(_n),destroyFns.push(Nn),{destroy:Nn,update:Rn}};function withWarn($n){return _extends$1(_extends$1({},$n),{type:"warning"})}function withInfo($n){return _extends$1(_extends$1({},$n),{type:"info"})}function withSuccess($n){return _extends$1(_extends$1({},$n),{type:"success"})}function withError($n){return _extends$1(_extends$1({},$n),{type:"error"})}function withConfirm($n){return _extends$1(_extends$1({},$n),{type:"confirm"})}const comfirmFuncProps=()=>({config:Object,afterClose:Function,destroyAction:Function,open:Boolean}),HookModal=defineComponent({name:"HookModal",inheritAttrs:!1,props:initDefaultProps(comfirmFuncProps(),{config:{width:520,okType:"primary"}}),setup($n,Cn){let{expose:_n}=Cn;var Pn;const In=computed(()=>$n.open),Nn=computed(()=>$n.config),{direction:Rn,getPrefixCls:Dn}=useConfigContextInject(),Ln=Dn("modal"),Fn=Dn(),Bn=()=>{var Yn,Gn;$n==null||$n.afterClose(),(Gn=(Yn=Nn.value).afterClose)===null||Gn===void 0||Gn.call(Yn)},Hn=function(){$n.destroyAction(...arguments)};_n({destroy:Hn});const zn=(Pn=Nn.value.okCancel)!==null&&Pn!==void 0?Pn:Nn.value.type==="confirm",[Wn]=useLocaleReceiver("Modal",localeValues$1.Modal);return()=>createVNode(ConfirmDialog,_objectSpread2$1(_objectSpread2$1({prefixCls:Ln,rootPrefixCls:Fn},Nn.value),{},{close:Hn,open:In.value,afterClose:Bn,okText:Nn.value.okText||(zn?Wn==null?void 0:Wn.value.okText:Wn==null?void 0:Wn.value.justOkText),direction:Nn.value.direction||Rn.value,cancelText:Nn.value.cancelText||(Wn==null?void 0:Wn.value.cancelText)}),null)}});let uuid$1=0;const ElementsHolder=defineComponent({name:"ElementsHolder",inheritAttrs:!1,setup($n,Cn){let{expose:_n}=Cn;const Pn=shallowRef([]);return _n({addModal:Nn=>(Pn.value.push(Nn),Pn.value=Pn.value.slice(),()=>{Pn.value=Pn.value.filter(Rn=>Rn!==Nn)})}),()=>Pn.value.map(Nn=>Nn())}});function useModal(){const $n=shallowRef(null),Cn=shallowRef([]);watch(Cn,()=>{Cn.value.length&&([...Cn.value].forEach(Rn=>{Rn()}),Cn.value=[])},{immediate:!0});const _n=Nn=>function(Dn){var Ln;uuid$1+=1;const Fn=shallowRef(!0),Bn=shallowRef(null),Hn=shallowRef(unref(Dn)),zn=shallowRef({});watch(()=>Dn,qo=>{Go(_extends$1(_extends$1({},isRef(qo)?qo.value:qo),zn.value))});const Wn=function(){Fn.value=!1;for(var qo=arguments.length,Jo=new Array(qo),Zo=0;Zonr&&nr.triggerCancel);Hn.value.onCancel&&rr&&Hn.value.onCancel(()=>{},...Jo.slice(1))};let Yn;const Gn=()=>createVNode(HookModal,{key:`modal-${uuid$1}`,config:Nn(Hn.value),ref:Bn,open:Fn.value,destroyAction:Wn,afterClose:()=>{Yn==null||Yn()}},null);Yn=(Ln=$n.value)===null||Ln===void 0?void 0:Ln.addModal(Gn),Yn&&destroyFns.push(Yn);const Go=qo=>{Hn.value=_extends$1(_extends$1({},Hn.value),qo)};return{destroy:()=>{Bn.value?Wn():Cn.value=[...Cn.value,Wn]},update:qo=>{zn.value=qo,Bn.value?Go(qo):Cn.value=[...Cn.value,()=>Go(qo)]}}},Pn=computed(()=>({info:_n(withInfo),success:_n(withSuccess),error:_n(withError),warning:_n(withWarn),confirm:_n(withConfirm)})),In=Symbol("modalHolderKey");return[Pn.value,()=>createVNode(ElementsHolder,{key:In,ref:$n},null)]}function modalWarn($n){return confirm(withWarn($n))}Modal.useModal=useModal;Modal.info=function(Cn){return confirm(withInfo(Cn))};Modal.success=function(Cn){return confirm(withSuccess(Cn))};Modal.error=function(Cn){return confirm(withError(Cn))};Modal.warning=modalWarn;Modal.warn=modalWarn;Modal.confirm=function(Cn){return confirm(withConfirm(Cn))};Modal.destroyAll=function(){for(;destroyFns.length;){const Cn=destroyFns.pop();Cn&&Cn()}};Modal.install=function($n){return $n.component(Modal.name,Modal),$n};const StatisticNumber=$n=>{const{value:Cn,formatter:_n,precision:Pn,decimalSeparator:In,groupSeparator:Nn="",prefixCls:Rn}=$n;let Dn;if(typeof _n=="function")Dn=_n({value:Cn});else{const Ln=String(Cn),Fn=Ln.match(/^(-?)(\d*)(\.(\d+))?$/);if(!Fn)Dn=Ln;else{const Bn=Fn[1];let Hn=Fn[2]||"0",zn=Fn[4]||"";Hn=Hn.replace(/\B(?=(\d{3})+(?!\d))/g,Nn),typeof Pn=="number"&&(zn=zn.padEnd(Pn,"0").slice(0,Pn>0?Pn:0)),zn&&(zn=`${In}${zn}`),Dn=[createVNode("span",{key:"int",class:`${Rn}-content-value-int`},[Bn,Hn]),zn&&createVNode("span",{key:"decimal",class:`${Rn}-content-value-decimal`},[zn])]}}return createVNode("span",{class:`${Rn}-content-value`},[Dn])};StatisticNumber.displayName="StatisticNumber";const StatisticNumber$1=StatisticNumber,genStatisticStyle=$n=>{const{componentCls:Cn,marginXXS:_n,padding:Pn,colorTextDescription:In,statisticTitleFontSize:Nn,colorTextHeading:Rn,statisticContentFontSize:Dn,statisticFontFamily:Ln}=$n;return{[`${Cn}`]:_extends$1(_extends$1({},resetComponent($n)),{[`${Cn}-title`]:{marginBottom:_n,color:In,fontSize:Nn},[`${Cn}-skeleton`]:{paddingTop:Pn},[`${Cn}-content`]:{color:Rn,fontSize:Dn,fontFamily:Ln,[`${Cn}-content-value`]:{display:"inline-block",direction:"ltr"},[`${Cn}-content-prefix, ${Cn}-content-suffix`]:{display:"inline-block"},[`${Cn}-content-prefix`]:{marginInlineEnd:_n},[`${Cn}-content-suffix`]:{marginInlineStart:_n}}})}},useStyle$i=genComponentStyleHook("Statistic",$n=>{const{fontSizeHeading3:Cn,fontSize:_n,fontFamily:Pn}=$n,In=merge$1($n,{statisticTitleFontSize:_n,statisticContentFontSize:Cn,statisticFontFamily:Pn});return[genStatisticStyle(In)]}),statisticProps=()=>({prefixCls:String,decimalSeparator:String,groupSeparator:String,format:String,value:someType([Number,String,Object]),valueStyle:{type:Object,default:void 0},valueRender:functionType(),formatter:anyType(),precision:Number,prefix:vNodeType(),suffix:vNodeType(),title:vNodeType(),loading:booleanType()}),Statistic=defineComponent({compatConfig:{MODE:3},name:"AStatistic",inheritAttrs:!1,props:initDefaultProps(statisticProps(),{decimalSeparator:".",groupSeparator:",",loading:!1}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("statistic",$n),[Rn,Dn]=useStyle$i(In);return()=>{var Ln,Fn,Bn,Hn,zn,Wn,Yn;const{value:Gn=0,valueStyle:Go,valueRender:Xn}=$n,Yo=In.value,qo=(Ln=$n.title)!==null&&Ln!==void 0?Ln:(Fn=_n.title)===null||Fn===void 0?void 0:Fn.call(_n),Jo=(Bn=$n.prefix)!==null&&Bn!==void 0?Bn:(Hn=_n.prefix)===null||Hn===void 0?void 0:Hn.call(_n),Zo=(zn=$n.suffix)!==null&&zn!==void 0?zn:(Wn=_n.suffix)===null||Wn===void 0?void 0:Wn.call(_n),rr=(Yn=$n.formatter)!==null&&Yn!==void 0?Yn:_n.formatter;let nr=createVNode(StatisticNumber$1,_objectSpread2$1({"data-for-update":Date.now()},_extends$1(_extends$1({},$n),{prefixCls:Yo,value:Gn,formatter:rr})),null);return Xn&&(nr=Xn(nr)),Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Yo,{[`${Yo}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value]}),[qo&&createVNode("div",{class:`${Yo}-title`},[qo]),createVNode(Skeleton$1,{paragraph:!1,loading:$n.loading},{default:()=>[createVNode("div",{style:Go,class:`${Yo}-content`},[Jo&&createVNode("span",{class:`${Yo}-content-prefix`},[Jo]),nr,Zo&&createVNode("span",{class:`${Yo}-content-suffix`},[Zo])])]})]))}}}),timeUnits=[["Y",1e3*60*60*24*365],["M",1e3*60*60*24*30],["D",1e3*60*60*24],["H",1e3*60*60],["m",1e3*60],["s",1e3],["S",1]];function formatTimeStr($n,Cn){let _n=$n;const Pn=/\[[^\]]*]/g,In=(Cn.match(Pn)||[]).map(Ln=>Ln.slice(1,-1)),Nn=Cn.replace(Pn,"[]"),Rn=timeUnits.reduce((Ln,Fn)=>{let[Bn,Hn]=Fn;if(Ln.includes(Bn)){const zn=Math.floor(_n/Hn);return _n-=zn*Hn,Ln.replace(new RegExp(`${Bn}+`,"g"),Wn=>{const Yn=Wn.length;return zn.toString().padStart(Yn,"0")})}return Ln},Nn);let Dn=0;return Rn.replace(Pn,()=>{const Ln=In[Dn];return Dn+=1,Ln})}function formatCountdown($n,Cn){const{format:_n=""}=Cn,Pn=new Date($n).getTime(),In=Date.now(),Nn=Math.max(Pn-In,0);return formatTimeStr(Nn,_n)}const REFRESH_INTERVAL=1e3/30;function getTime($n){return new Date($n).getTime()}const countdownProps=()=>_extends$1(_extends$1({},statisticProps()),{value:someType([Number,String,Object]),format:String,onFinish:Function,onChange:Function}),Countdown=defineComponent({compatConfig:{MODE:3},name:"AStatisticCountdown",props:initDefaultProps(countdownProps(),{format:"HH:mm:ss"}),setup($n,Cn){let{emit:_n,slots:Pn}=Cn;const In=ref(),Nn=ref(),Rn=()=>{const{value:Hn}=$n;getTime(Hn)>=Date.now()?Dn():Ln()},Dn=()=>{if(In.value)return;const Hn=getTime($n.value);In.value=setInterval(()=>{Nn.value.$forceUpdate(),Hn>Date.now()&&_n("change",Hn-Date.now()),Rn()},REFRESH_INTERVAL)},Ln=()=>{const{value:Hn}=$n;In.value&&(clearInterval(In.value),In.value=void 0,getTime(Hn){let{value:zn,config:Wn}=Hn;const{format:Yn}=$n;return formatCountdown(zn,_extends$1(_extends$1({},Wn),{format:Yn}))},Bn=Hn=>Hn;return onMounted(()=>{Rn()}),onUpdated(()=>{Rn()}),onBeforeUnmount(()=>{Ln()}),()=>{const Hn=$n.value;return createVNode(Statistic,_objectSpread2$1({ref:Nn},_extends$1(_extends$1({},omit$1($n,["onFinish","onChange"])),{value:Hn,valueRender:Bn,formatter:Fn})),Pn)}}});Statistic.Countdown=Countdown;Statistic.install=function($n){return $n.component(Statistic.name,Statistic),$n.component(Statistic.Countdown.name,Statistic.Countdown),$n};const StatisticCountdown=Statistic.Countdown;var ArrowLeftOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};const ArrowLeftOutlinedSvg=ArrowLeftOutlined$2;function _objectSpread$l($n){for(var Cn=1;Cn{const{keyCode:Wn}=zn;Wn===KeyCode$1.ENTER&&zn.preventDefault()},Ln=zn=>{const{keyCode:Wn}=zn;Wn===KeyCode$1.ENTER&&Pn("click",zn)},Fn=zn=>{Pn("click",zn)},Bn=()=>{Rn.value&&Rn.value.focus()},Hn=()=>{Rn.value&&Rn.value.blur()};return onMounted(()=>{$n.autofocus&&Bn()}),Nn({focus:Bn,blur:Hn}),()=>{var zn;const{noStyle:Wn,disabled:Yn}=$n,Gn=__rest$q($n,["noStyle","disabled"]);let Go={};return Wn||(Go=_extends$1({},inlineStyle)),Yn&&(Go.pointerEvents="none"),createVNode("div",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({role:"button",tabindex:0,ref:Rn},Gn),In),{},{onClick:Fn,onKeydown:Dn,onKeyup:Ln,style:_extends$1(_extends$1({},Go),In.style||{})}),[(zn=_n.default)===null||zn===void 0?void 0:zn.call(_n)])}}}),TransButton$1=TransButton,spaceSize={small:8,middle:16,large:24},spaceProps=()=>({prefixCls:String,size:{type:[String,Number,Array]},direction:PropTypes.oneOf(tuple$1("horizontal","vertical")).def("horizontal"),align:PropTypes.oneOf(tuple$1("start","end","center","baseline")),wrap:booleanType()});function getNumberSize($n){return typeof $n=="string"?spaceSize[$n]:$n||0}const Space=defineComponent({compatConfig:{MODE:3},name:"ASpace",inheritAttrs:!1,props:spaceProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,space:Nn,direction:Rn}=useConfigInject("space",$n),[Dn,Ln]=useStyle$W(In),Fn=useFlexGapSupport(),Bn=computed(()=>{var Xn,Yo,qo;return(qo=(Xn=$n.size)!==null&&Xn!==void 0?Xn:(Yo=Nn==null?void 0:Nn.value)===null||Yo===void 0?void 0:Yo.size)!==null&&qo!==void 0?qo:"small"}),Hn=ref(),zn=ref();watch(Bn,()=>{[Hn.value,zn.value]=(Array.isArray(Bn.value)?Bn.value:[Bn.value,Bn.value]).map(Xn=>getNumberSize(Xn))},{immediate:!0});const Wn=computed(()=>$n.align===void 0&&$n.direction==="horizontal"?"center":$n.align),Yn=computed(()=>classNames(In.value,Ln.value,`${In.value}-${$n.direction}`,{[`${In.value}-rtl`]:Rn.value==="rtl",[`${In.value}-align-${Wn.value}`]:Wn.value})),Gn=computed(()=>Rn.value==="rtl"?"marginLeft":"marginRight"),Go=computed(()=>{const Xn={};return Fn.value&&(Xn.columnGap=`${Hn.value}px`,Xn.rowGap=`${zn.value}px`),_extends$1(_extends$1({},Xn),$n.wrap&&{flexWrap:"wrap",marginBottom:`${-zn.value}px`})});return()=>{var Xn,Yo;const{wrap:qo,direction:Jo="horizontal"}=$n,Zo=(Xn=_n.default)===null||Xn===void 0?void 0:Xn.call(_n),rr=filterEmpty(Zo),nr=rr.length;if(nr===0)return null;const ta=(Yo=_n.split)===null||Yo===void 0?void 0:Yo.call(_n),oa=`${In.value}-item`,ra=Hn.value,ea=nr-1;return createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Yn.value,Pn.class],style:[Go.value,Pn.style]}),[rr.map((la,ua)=>{let ga=Zo.indexOf(la);ga===-1&&(ga=`$$space-${ua}`);let aa={};return Fn.value||(Jo==="vertical"?ua{const{componentCls:Cn,antCls:_n}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",padding:`${$n.pageHeaderPaddingVertical}px ${$n.pageHeaderPadding}px`,backgroundColor:$n.colorBgContainer,[`&${Cn}-ghost`]:{backgroundColor:$n.pageHeaderGhostBg},"&.has-footer":{paddingBottom:0},[`${Cn}-back`]:{marginRight:$n.marginMD,fontSize:$n.fontSizeLG,lineHeight:1,"&-button":_extends$1(_extends$1({},operationUnit($n)),{color:$n.pageHeaderBackColor,cursor:"pointer"})},[`${_n}-divider-vertical`]:{height:"14px",margin:`0 ${$n.marginSM}`,verticalAlign:"middle"},[`${_n}-breadcrumb + &-heading`]:{marginTop:$n.marginXS},[`${Cn}-heading`]:{display:"flex",justifyContent:"space-between","&-left":{display:"flex",alignItems:"center",margin:`${$n.marginXS/2}px 0`,overflow:"hidden"},"&-title":_extends$1({marginRight:$n.marginSM,marginBottom:0,color:$n.colorTextHeading,fontWeight:600,fontSize:$n.pageHeaderHeadingTitle,lineHeight:`${$n.controlHeight}px`},textEllipsis),[`${_n}-avatar`]:{marginRight:$n.marginSM},"&-sub-title":_extends$1({marginRight:$n.marginSM,color:$n.colorTextDescription,fontSize:$n.pageHeaderHeadingSubTitle,lineHeight:$n.lineHeight},textEllipsis),"&-extra":{margin:`${$n.marginXS/2}px 0`,whiteSpace:"nowrap","> *":{marginLeft:$n.marginSM,whiteSpace:"unset"},"> *:first-child":{marginLeft:0}}},[`${Cn}-content`]:{paddingTop:$n.pageHeaderContentPaddingVertical},[`${Cn}-footer`]:{marginTop:$n.marginMD,[`${_n}-tabs`]:{[`> ${_n}-tabs-nav`]:{margin:0,"&::before":{border:"none"}},[`${_n}-tabs-tab`]:{paddingTop:$n.paddingXS,paddingBottom:$n.paddingXS,fontSize:$n.pageHeaderTabFontSize}}},[`${Cn}-compact ${Cn}-heading`]:{flexWrap:"wrap"},[`&${$n.componentCls}-rtl`]:{direction:"rtl"}})}},useStyle$h=genComponentStyleHook("PageHeader",$n=>{const Cn=merge$1($n,{pageHeaderPadding:$n.paddingLG,pageHeaderPaddingVertical:$n.paddingMD,pageHeaderPaddingBreadcrumb:$n.paddingSM,pageHeaderContentPaddingVertical:$n.paddingSM,pageHeaderBackColor:$n.colorTextBase,pageHeaderGhostBg:"transparent",pageHeaderHeadingTitle:$n.fontSizeHeading4,pageHeaderHeadingSubTitle:$n.fontSize,pageHeaderTabFontSize:$n.fontSizeLG});return[genPageHeaderStyle(Cn)]}),pageHeaderProps=()=>({backIcon:vNodeType(),prefixCls:String,title:vNodeType(),subTitle:vNodeType(),breadcrumb:PropTypes.object,tags:vNodeType(),footer:vNodeType(),extra:vNodeType(),avatar:objectType(),ghost:{type:Boolean,default:void 0},onBack:Function}),PageHeader=defineComponent({compatConfig:{MODE:3},name:"APageHeader",inheritAttrs:!1,props:pageHeaderProps(),slots:Object,setup($n,Cn){let{emit:_n,slots:Pn,attrs:In}=Cn;const{prefixCls:Nn,direction:Rn,pageHeader:Dn}=useConfigInject("page-header",$n),[Ln,Fn]=useStyle$h(Nn),Bn=shallowRef(!1),Hn=useDestroyed(),zn=Jo=>{let{width:Zo}=Jo;Hn.value||(Bn.value=Zo<768)},Wn=computed(()=>{var Jo,Zo,rr;return(rr=(Jo=$n.ghost)!==null&&Jo!==void 0?Jo:(Zo=Dn==null?void 0:Dn.value)===null||Zo===void 0?void 0:Zo.ghost)!==null&&rr!==void 0?rr:!0}),Yn=()=>{var Jo,Zo,rr;return(rr=(Jo=$n.backIcon)!==null&&Jo!==void 0?Jo:(Zo=Pn.backIcon)===null||Zo===void 0?void 0:Zo.call(Pn))!==null&&rr!==void 0?rr:Rn.value==="rtl"?createVNode(ArrowRightOutlined$1,null,null):createVNode(ArrowLeftOutlined$1,null,null)},Gn=Jo=>!Jo||!$n.onBack?null:createVNode(LocaleReceiver,{componentName:"PageHeader",children:Zo=>{let{back:rr}=Zo;return createVNode("div",{class:`${Nn.value}-back`},[createVNode(TransButton$1,{onClick:nr=>{_n("back",nr)},class:`${Nn.value}-back-button`,"aria-label":rr},{default:()=>[Jo]})])}},null),Go=()=>{var Jo;return $n.breadcrumb?createVNode(Breadcrumb,$n.breadcrumb,null):(Jo=Pn.breadcrumb)===null||Jo===void 0?void 0:Jo.call(Pn)},Xn=()=>{var Jo,Zo,rr,nr,ta,oa,ra,ea,la;const{avatar:ua}=$n,ga=(Jo=$n.title)!==null&&Jo!==void 0?Jo:(Zo=Pn.title)===null||Zo===void 0?void 0:Zo.call(Pn),aa=(rr=$n.subTitle)!==null&&rr!==void 0?rr:(nr=Pn.subTitle)===null||nr===void 0?void 0:nr.call(Pn),ca=(ta=$n.tags)!==null&&ta!==void 0?ta:(oa=Pn.tags)===null||oa===void 0?void 0:oa.call(Pn),sa=(ra=$n.extra)!==null&&ra!==void 0?ra:(ea=Pn.extra)===null||ea===void 0?void 0:ea.call(Pn),ia=`${Nn.value}-heading`,fa=ga||aa||ca||sa;if(!fa)return null;const ma=Yn(),ya=Gn(ma);return createVNode("div",{class:ia},[(ya||ua||fa)&&createVNode("div",{class:`${ia}-left`},[ya,ua?createVNode(Avatar$1,ua,null):(la=Pn.avatar)===null||la===void 0?void 0:la.call(Pn),ga&&createVNode("span",{class:`${ia}-title`,title:typeof ga=="string"?ga:void 0},[ga]),aa&&createVNode("span",{class:`${ia}-sub-title`,title:typeof aa=="string"?aa:void 0},[aa]),ca&&createVNode("span",{class:`${ia}-tags`},[ca])]),sa&&createVNode("span",{class:`${ia}-extra`},[createVNode(Space$1,null,{default:()=>[sa]})])])},Yo=()=>{var Jo,Zo;const rr=(Jo=$n.footer)!==null&&Jo!==void 0?Jo:filterEmpty((Zo=Pn.footer)===null||Zo===void 0?void 0:Zo.call(Pn));return isEmptyContent(rr)?null:createVNode("div",{class:`${Nn.value}-footer`},[rr])},qo=Jo=>createVNode("div",{class:`${Nn.value}-content`},[Jo]);return()=>{var Jo,Zo;const rr=((Jo=$n.breadcrumb)===null||Jo===void 0?void 0:Jo.routes)||Pn.breadcrumb,nr=$n.footer||Pn.footer,ta=flattenChildren((Zo=Pn.default)===null||Zo===void 0?void 0:Zo.call(Pn)),oa=classNames(Nn.value,{"has-breadcrumb":rr,"has-footer":nr,[`${Nn.value}-ghost`]:Wn.value,[`${Nn.value}-rtl`]:Rn.value==="rtl",[`${Nn.value}-compact`]:Bn.value},In.class,Fn.value);return Ln(createVNode(ResizeObserver$1,{onResize:zn},{default:()=>[createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{class:oa}),[Go(),Xn(),ta.length?qo(ta):null,Yo()])]}))}}}),index$g=withInstall(PageHeader),genBaseStyle$8=$n=>{const{componentCls:Cn,iconCls:_n,zIndexPopup:Pn,colorText:In,colorWarning:Nn,marginXS:Rn,fontSize:Dn,fontWeightStrong:Ln,lineHeight:Fn}=$n;return{[Cn]:{zIndex:Pn,[`${Cn}-inner-content`]:{color:In},[`${Cn}-message`]:{position:"relative",marginBottom:Rn,color:In,fontSize:Dn,display:"flex",flexWrap:"nowrap",alignItems:"start",[`> ${Cn}-message-icon ${_n}`]:{color:Nn,fontSize:Dn,flex:"none",lineHeight:1,paddingTop:(Math.round(Dn*Fn)-Dn)/2},"&-title":{flex:"auto",marginInlineStart:Rn},"&-title-only":{fontWeight:Ln}},[`${Cn}-description`]:{position:"relative",marginInlineStart:Dn+Rn,marginBottom:Rn,color:In,fontSize:Dn},[`${Cn}-buttons`]:{textAlign:"end",button:{marginInlineStart:Rn}}}}},usePopconfirmStyle=genComponentStyleHook("Popconfirm",$n=>genBaseStyle$8($n),$n=>{const{zIndexPopupBase:Cn}=$n;return{zIndexPopup:Cn+60}});var __rest$p=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In_extends$1(_extends$1({},abstractTooltipProps()),{prefixCls:String,content:anyType(),title:anyType(),description:anyType(),okType:stringType("primary"),disabled:{type:Boolean,default:!1},okText:anyType(),cancelText:anyType(),icon:anyType(),okButtonProps:objectType(),cancelButtonProps:objectType(),showCancel:{type:Boolean,default:!0},onConfirm:Function,onCancel:Function}),Popconfirm=defineComponent({compatConfig:{MODE:3},name:"APopconfirm",inheritAttrs:!1,props:initDefaultProps(popconfirmProps(),_extends$1(_extends$1({},tooltipDefaultProps()),{trigger:"click",placement:"top",mouseEnterDelay:.1,mouseLeaveDelay:.1,arrowPointAtCenter:!1,autoAdjustOverflow:!0,okType:"primary",disabled:!1})),slots:Object,setup($n,Cn){let{slots:_n,emit:Pn,expose:In,attrs:Nn}=Cn;const Rn=ref();warning$3($n.visible===void 0),In({getPopupDomNode:()=>{var rr,nr;return(nr=(rr=Rn.value)===null||rr===void 0?void 0:rr.getPopupDomNode)===null||nr===void 0?void 0:nr.call(rr)}});const[Dn,Ln]=useMergedState(!1,{value:toRef($n,"open")}),Fn=(rr,nr)=>{$n.open===void 0&&Ln(rr),Pn("update:open",rr),Pn("openChange",rr,nr)},Bn=rr=>{Fn(!1,rr)},Hn=rr=>{var nr;return(nr=$n.onConfirm)===null||nr===void 0?void 0:nr.call($n,rr)},zn=rr=>{var nr;Fn(!1,rr),(nr=$n.onCancel)===null||nr===void 0||nr.call($n,rr)},Wn=rr=>{rr.keyCode===KeyCode$1.ESC&&Dn&&Fn(!1,rr)},Yn=rr=>{const{disabled:nr}=$n;nr||Fn(rr)},{prefixCls:Gn,getPrefixCls:Go}=useConfigInject("popconfirm",$n),Xn=computed(()=>Go()),Yo=computed(()=>Go("btn")),[qo]=usePopconfirmStyle(Gn),[Jo]=useLocaleReceiver("Popconfirm",localeValues$1.Popconfirm),Zo=()=>{var rr,nr,ta,oa,ra;const{okButtonProps:ea,cancelButtonProps:la,title:ua=(rr=_n.title)===null||rr===void 0?void 0:rr.call(_n),description:ga=(nr=_n.description)===null||nr===void 0?void 0:nr.call(_n),cancelText:aa=(ta=_n.cancel)===null||ta===void 0?void 0:ta.call(_n),okText:ca=(oa=_n.okText)===null||oa===void 0?void 0:oa.call(_n),okType:sa,icon:ia=((ra=_n.icon)===null||ra===void 0?void 0:ra.call(_n))||createVNode(ExclamationCircleFilled$1,null,null),showCancel:fa=!0}=$n,{cancelButton:ma,okButton:ya}=_n,ba=_extends$1({onClick:zn,size:"small"},la),Ia=_extends$1(_extends$1(_extends$1({onClick:Hn},convertLegacyProps(sa)),{size:"small"}),ea);return createVNode("div",{class:`${Gn.value}-inner-content`},[createVNode("div",{class:`${Gn.value}-message`},[ia&&createVNode("span",{class:`${Gn.value}-message-icon`},[ia]),createVNode("div",{class:[`${Gn.value}-message-title`,{[`${Gn.value}-message-title-only`]:!!ga}]},[ua])]),ga&&createVNode("div",{class:`${Gn.value}-description`},[ga]),createVNode("div",{class:`${Gn.value}-buttons`},[fa?ma?ma(ba):createVNode(Button$1,ba,{default:()=>[aa||Jo.value.cancelText]}):null,ya?ya(Ia):createVNode(ActionButton,{buttonProps:_extends$1(_extends$1({size:"small"},convertLegacyProps(sa)),ea),actionFn:Hn,close:Bn,prefixCls:Yo.value,quitOnNullishReturnValue:!0,emitEvent:!0},{default:()=>[ca||Jo.value.okText]})])])};return()=>{var rr;const{placement:nr,overlayClassName:ta,trigger:oa="click"}=$n,ra=__rest$p($n,["placement","overlayClassName","trigger"]),ea=omit$1(ra,["title","content","cancelText","okText","onUpdate:open","onConfirm","onCancel","prefixCls"]),la=classNames(Gn.value,ta);return qo(createVNode(Popover$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},ea),Nn),{},{trigger:oa,placement:nr,onOpenChange:Yn,open:Dn.value,overlayClassName:la,transitionName:getTransitionName$1(Xn.value,"zoom-big",$n.transitionName),ref:Rn,"data-popover-inject":!0}),{default:()=>[cloneVNodes(((rr=_n.default)===null||rr===void 0?void 0:rr.call(_n))||[],{onKeydown:ua=>{Wn(ua)}},!1)],content:Zo}))}}}),index$f=withInstall(Popconfirm),progressStatuses=["normal","exception","active","success"],progressProps=()=>({prefixCls:String,type:stringType(),percent:Number,format:functionType(),status:stringType(),showInfo:booleanType(),strokeWidth:Number,strokeLinecap:stringType(),strokeColor:anyType(),trailColor:String,width:Number,success:objectType(),gapDegree:Number,gapPosition:stringType(),size:someType([String,Number,Array]),steps:Number,successPercent:Number,title:String,progressStatus:stringType()});function validProgress($n){return!$n||$n<0?0:$n>100?100:$n}function getSuccessPercent($n){let{success:Cn,successPercent:_n}=$n,Pn=_n;return Cn&&"progress"in Cn&&(devWarning(!1,"Progress","`success.progress` is deprecated. Please use `success.percent` instead."),Pn=Cn.progress),Cn&&"percent"in Cn&&(Pn=Cn.percent),Pn}function getPercentage($n){let{percent:Cn,success:_n,successPercent:Pn}=$n;const In=validProgress(getSuccessPercent({success:_n,successPercent:Pn}));return[In,validProgress(validProgress(Cn)-In)]}function getStrokeColor($n){let{success:Cn={},strokeColor:_n}=$n;const{strokeColor:Pn}=Cn;return[Pn||presetPrimaryColors.green,_n||null]}const getSize=($n,Cn,_n)=>{var Pn,In,Nn,Rn;let Dn=-1,Ln=-1;if(Cn==="step"){const Fn=_n.steps,Bn=_n.strokeWidth;typeof $n=="string"||typeof $n>"u"?(Dn=$n==="small"?2:14,Ln=Bn??8):typeof $n=="number"?[Dn,Ln]=[$n,$n]:[Dn=14,Ln=8]=$n,Dn*=Fn}else if(Cn==="line"){const Fn=_n==null?void 0:_n.strokeWidth;typeof $n=="string"||typeof $n>"u"?Ln=Fn||($n==="small"?6:8):typeof $n=="number"?[Dn,Ln]=[$n,$n]:[Dn=-1,Ln=8]=$n}else(Cn==="circle"||Cn==="dashboard")&&(typeof $n=="string"||typeof $n>"u"?[Dn,Ln]=$n==="small"?[60,60]:[120,120]:typeof $n=="number"?[Dn,Ln]=[$n,$n]:(Dn=(In=(Pn=$n[0])!==null&&Pn!==void 0?Pn:$n[1])!==null&&In!==void 0?In:120,Ln=(Rn=(Nn=$n[0])!==null&&Nn!==void 0?Nn:$n[1])!==null&&Rn!==void 0?Rn:120));return{width:Dn,height:Ln}};var __rest$o=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In_extends$1(_extends$1({},progressProps()),{strokeColor:anyType(),direction:stringType()}),sortGradient=$n=>{let Cn=[];return Object.keys($n).forEach(_n=>{const Pn=parseFloat(_n.replace(/%/g,""));isNaN(Pn)||Cn.push({key:Pn,value:$n[_n]})}),Cn=Cn.sort((_n,Pn)=>_n.key-Pn.key),Cn.map(_n=>{let{key:Pn,value:In}=_n;return`${In} ${Pn}%`}).join(", ")},handleGradient=($n,Cn)=>{const{from:_n=presetPrimaryColors.blue,to:Pn=presetPrimaryColors.blue,direction:In=Cn==="rtl"?"to left":"to right"}=$n,Nn=__rest$o($n,["from","to","direction"]);if(Object.keys(Nn).length!==0){const Rn=sortGradient(Nn);return{backgroundImage:`linear-gradient(${In}, ${Rn})`}}return{backgroundImage:`linear-gradient(${In}, ${_n}, ${Pn})`}},Line=defineComponent({compatConfig:{MODE:3},name:"ProgressLine",inheritAttrs:!1,props:lineProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=computed(()=>{const{strokeColor:Wn,direction:Yn}=$n;return Wn&&typeof Wn!="string"?handleGradient(Wn,Yn):{backgroundColor:Wn}}),Nn=computed(()=>$n.strokeLinecap==="square"||$n.strokeLinecap==="butt"?0:void 0),Rn=computed(()=>$n.trailColor?{backgroundColor:$n.trailColor}:void 0),Dn=computed(()=>{var Wn;return(Wn=$n.size)!==null&&Wn!==void 0?Wn:[-1,$n.strokeWidth||($n.size==="small"?6:8)]}),Ln=computed(()=>getSize(Dn.value,"line",{strokeWidth:$n.strokeWidth})),Fn=computed(()=>{const{percent:Wn}=$n;return _extends$1({width:`${validProgress(Wn)}%`,height:`${Ln.value.height}px`,borderRadius:Nn.value},In.value)}),Bn=computed(()=>getSuccessPercent($n)),Hn=computed(()=>{const{success:Wn}=$n;return{width:`${validProgress(Bn.value)}%`,height:`${Ln.value.height}px`,borderRadius:Nn.value,backgroundColor:Wn==null?void 0:Wn.strokeColor}}),zn={width:Ln.value.width<0?"100%":Ln.value.width,height:`${Ln.value.height}px`};return()=>{var Wn;return createVNode(Fragment,null,[createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[`${$n.prefixCls}-outer`,Pn.class],style:[Pn.style,zn]}),[createVNode("div",{class:`${$n.prefixCls}-inner`,style:Rn.value},[createVNode("div",{class:`${$n.prefixCls}-bg`,style:Fn.value},null),Bn.value!==void 0?createVNode("div",{class:`${$n.prefixCls}-success-bg`,style:Hn.value},null):null])]),(Wn=_n.default)===null||Wn===void 0?void 0:Wn.call(_n)])}}}),defaultProps={percent:0,prefixCls:"vc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1},useTransitionDuration=$n=>{const Cn=ref(null);return onUpdated(()=>{const _n=Date.now();let Pn=!1;$n.value.forEach(In=>{const Nn=(In==null?void 0:In.$el)||In;if(!Nn)return;Pn=!0;const Rn=Nn.style;Rn.transitionDuration=".3s, .3s, .3s, .06s",Cn.value&&_n-Cn.value<100&&(Rn.transitionDuration="0s, 0s")}),Pn&&(Cn.value=Date.now())}),$n},propTypes={gapDegree:Number,gapPosition:{type:String},percent:{type:[Array,Number]},prefixCls:String,strokeColor:{type:[Object,String,Array]},strokeLinecap:{type:String},strokeWidth:Number,trailColor:String,trailWidth:Number,transition:String};var __rest$n=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In4&&arguments[4]!==void 0?arguments[4]:0,Nn=arguments.length>5?arguments[5]:void 0;const Rn=50-Pn/2;let Dn=0,Ln=-Rn,Fn=0,Bn=-2*Rn;switch(Nn){case"left":Dn=-Rn,Ln=0,Fn=2*Rn,Bn=0;break;case"right":Dn=Rn,Ln=0,Fn=-2*Rn,Bn=0;break;case"bottom":Ln=Rn,Bn=2*Rn;break}const Hn=`M 50,50 m ${Dn},${Ln} - a ${Rn},${Rn} 0 1 1 ${Fn},${-Bn} - a ${Rn},${Rn} 0 1 1 ${-Fn},${Bn}`,zn=Math.PI*2*Rn,Wn={stroke:_n,strokeDasharray:`${Cn/100*(zn-In)}px ${zn}px`,strokeDashoffset:`-${In/2+$n/100*(zn-In)}px`,transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s"};return{pathString:Hn,pathStyle:Wn}}const VCCircle=defineComponent({compatConfig:{MODE:3},name:"VCCircle",props:initDefaultProps(propTypes,defaultProps),setup($n){gradientSeed+=1;const Cn=ref(gradientSeed),_n=computed(()=>toArray$2($n.percent)),Pn=computed(()=>toArray$2($n.strokeColor)),[In,Nn]=useRefs();useTransitionDuration(Nn);const Rn=()=>{const{prefixCls:Dn,strokeWidth:Ln,strokeLinecap:Fn,gapDegree:Bn,gapPosition:Hn}=$n;let zn=0;return _n.value.map((Wn,Yn)=>{const Gn=Pn.value[Yn]||Pn.value[Pn.value.length-1],Go=Object.prototype.toString.call(Gn)==="[object Object]"?`url(#${Dn}-gradient-${Cn.value})`:"",{pathString:Xn,pathStyle:Yo}=getPathStyles(zn,Wn,Gn,Ln,Bn,Hn);zn+=Wn;const qo={key:Yn,d:Xn,stroke:Go,"stroke-linecap":Fn,"stroke-width":Ln,opacity:Wn===0?0:1,"fill-opacity":"0",class:`${Dn}-circle-path`,style:Yo};return createVNode("path",_objectSpread2$1({ref:In(Yn)},qo),null)})};return()=>{const{prefixCls:Dn,strokeWidth:Ln,trailWidth:Fn,gapDegree:Bn,gapPosition:Hn,trailColor:zn,strokeLinecap:Wn,strokeColor:Yn}=$n,Gn=__rest$n($n,["prefixCls","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","strokeColor"]),{pathString:Go,pathStyle:Xn}=getPathStyles(0,100,zn,Ln,Bn,Hn);delete Gn.percent;const Yo=Pn.value.find(Jo=>Object.prototype.toString.call(Jo)==="[object Object]"),qo={d:Go,stroke:zn,"stroke-linecap":Wn,"stroke-width":Fn||Ln,"fill-opacity":"0",class:`${Dn}-circle-trail`,style:Xn};return createVNode("svg",_objectSpread2$1({class:`${Dn}-circle`,viewBox:"0 0 100 100"},Gn),[Yo&&createVNode("defs",null,[createVNode("linearGradient",{id:`${Dn}-gradient-${Cn.value}`,x1:"100%",y1:"0%",x2:"0%",y2:"0%"},[Object.keys(Yo).sort((Jo,Zo)=>stripPercentToNumber(Jo)-stripPercentToNumber(Zo)).map((Jo,Zo)=>createVNode("stop",{key:Zo,offset:Jo,"stop-color":Yo[Jo]},null))])]),createVNode("path",qo,null),Rn().reverse()])}}}),circleProps=()=>_extends$1(_extends$1({},progressProps()),{strokeColor:anyType()}),CIRCLE_MIN_STROKE_WIDTH=3,getMinPercent=$n=>CIRCLE_MIN_STROKE_WIDTH/$n*100,Circle=defineComponent({compatConfig:{MODE:3},name:"ProgressCircle",inheritAttrs:!1,props:initDefaultProps(circleProps(),{trailColor:null}),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=computed(()=>{var Gn;return(Gn=$n.width)!==null&&Gn!==void 0?Gn:120}),Nn=computed(()=>{var Gn;return(Gn=$n.size)!==null&&Gn!==void 0?Gn:[In.value,In.value]}),Rn=computed(()=>getSize(Nn.value,"circle")),Dn=computed(()=>{if($n.gapDegree||$n.gapDegree===0)return $n.gapDegree;if($n.type==="dashboard")return 75}),Ln=computed(()=>({width:`${Rn.value.width}px`,height:`${Rn.value.height}px`,fontSize:`${Rn.value.width*.15+6}px`})),Fn=computed(()=>{var Gn;return(Gn=$n.strokeWidth)!==null&&Gn!==void 0?Gn:Math.max(getMinPercent(Rn.value.width),6)}),Bn=computed(()=>$n.gapPosition||$n.type==="dashboard"&&"bottom"||void 0),Hn=computed(()=>getPercentage($n)),zn=computed(()=>Object.prototype.toString.call($n.strokeColor)==="[object Object]"),Wn=computed(()=>getStrokeColor({success:$n.success,strokeColor:$n.strokeColor})),Yn=computed(()=>({[`${$n.prefixCls}-inner`]:!0,[`${$n.prefixCls}-circle-gradient`]:zn.value}));return()=>{var Gn;const Go=createVNode(VCCircle,{percent:Hn.value,strokeWidth:Fn.value,trailWidth:Fn.value,strokeColor:Wn.value,strokeLinecap:$n.strokeLinecap,trailColor:$n.trailColor,prefixCls:$n.prefixCls,gapDegree:Dn.value,gapPosition:Bn.value},null);return createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Yn.value,Pn.class],style:[Pn.style,Ln.value]}),[Rn.value.width<=20?createVNode(Tooltip,null,{default:()=>[createVNode("span",null,[Go])],title:_n.default}):createVNode(Fragment,null,[Go,(Gn=_n.default)===null||Gn===void 0?void 0:Gn.call(_n)])])}}}),stepsProps$1=()=>_extends$1(_extends$1({},progressProps()),{steps:Number,strokeColor:someType(),trailColor:String}),Steps$4=defineComponent({compatConfig:{MODE:3},name:"Steps",props:stepsProps$1(),setup($n,Cn){let{slots:_n}=Cn;const Pn=computed(()=>Math.round($n.steps*(($n.percent||0)/100))),In=computed(()=>{var Dn;return(Dn=$n.size)!==null&&Dn!==void 0?Dn:[$n.size==="small"?2:14,$n.strokeWidth||8]}),Nn=computed(()=>getSize(In.value,"step",{steps:$n.steps,strokeWidth:$n.strokeWidth||8})),Rn=computed(()=>{const{steps:Dn,strokeColor:Ln,trailColor:Fn,prefixCls:Bn}=$n,Hn=[];for(let zn=0;zn{var Dn;return createVNode("div",{class:`${$n.prefixCls}-steps-outer`},[Rn.value,(Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n)])}}}),antProgressActive=new Keyframes("antProgressActive",{"0%":{transform:"translateX(-100%) scaleX(0)",opacity:.1},"20%":{transform:"translateX(-100%) scaleX(0)",opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}}),genBaseStyle$7=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:$n.fontSize,marginInlineEnd:$n.marginXS,marginBottom:$n.marginXS},[`${Cn}-outer`]:{display:"inline-block",width:"100%"},[`&${Cn}-show-info`]:{[`${Cn}-outer`]:{marginInlineEnd:`calc(-2em - ${$n.marginXS}px)`,paddingInlineEnd:`calc(2em + ${$n.paddingXS}px)`}},[`${Cn}-inner`]:{position:"relative",display:"inline-block",width:"100%",overflow:"hidden",verticalAlign:"middle",backgroundColor:$n.progressRemainingColor,borderRadius:$n.progressLineRadius},[`${Cn}-inner:not(${Cn}-circle-gradient)`]:{[`${Cn}-circle-path`]:{stroke:$n.colorInfo}},[`${Cn}-success-bg, ${Cn}-bg`]:{position:"relative",backgroundColor:$n.colorInfo,borderRadius:$n.progressLineRadius,transition:`all ${$n.motionDurationSlow} ${$n.motionEaseInOutCirc}`},[`${Cn}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:$n.colorSuccess},[`${Cn}-text`]:{display:"inline-block",width:"2em",marginInlineStart:$n.marginXS,color:$n.progressInfoTextColor,lineHeight:1,whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[_n]:{fontSize:$n.fontSize}},[`&${Cn}-status-active`]:{[`${Cn}-bg::before`]:{position:"absolute",inset:0,backgroundColor:$n.colorBgContainer,borderRadius:$n.progressLineRadius,opacity:0,animationName:antProgressActive,animationDuration:$n.progressActiveMotionDuration,animationTimingFunction:$n.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${Cn}-status-exception`]:{[`${Cn}-bg`]:{backgroundColor:$n.colorError},[`${Cn}-text`]:{color:$n.colorError}},[`&${Cn}-status-exception ${Cn}-inner:not(${Cn}-circle-gradient)`]:{[`${Cn}-circle-path`]:{stroke:$n.colorError}},[`&${Cn}-status-success`]:{[`${Cn}-bg`]:{backgroundColor:$n.colorSuccess},[`${Cn}-text`]:{color:$n.colorSuccess}},[`&${Cn}-status-success ${Cn}-inner:not(${Cn}-circle-gradient)`]:{[`${Cn}-circle-path`]:{stroke:$n.colorSuccess}}})}},genCircleStyle=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[Cn]:{[`${Cn}-circle-trail`]:{stroke:$n.progressRemainingColor},[`&${Cn}-circle ${Cn}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${Cn}-circle ${Cn}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:$n.colorText,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[_n]:{fontSize:`${$n.fontSize/$n.fontSizeSM}em`}},[`${Cn}-circle&-status-exception`]:{[`${Cn}-text`]:{color:$n.colorError}},[`${Cn}-circle&-status-success`]:{[`${Cn}-text`]:{color:$n.colorSuccess}}},[`${Cn}-inline-circle`]:{lineHeight:1,[`${Cn}-inner`]:{verticalAlign:"bottom"}}}},genStepStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{[`${Cn}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:$n.progressStepMinWidth,marginInlineEnd:$n.progressStepMarginInlineEnd,backgroundColor:$n.progressRemainingColor,transition:`all ${$n.motionDurationSlow}`,"&-active":{backgroundColor:$n.colorInfo}}}}}},genSmallLine=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[Cn]:{[`${Cn}-small&-line, ${Cn}-small&-line ${Cn}-text ${_n}`]:{fontSize:$n.fontSizeSM}}}},useStyle$g=genComponentStyleHook("Progress",$n=>{const Cn=$n.marginXXS/2,_n=merge$1($n,{progressLineRadius:100,progressInfoTextColor:$n.colorText,progressDefaultColor:$n.colorInfo,progressRemainingColor:$n.colorFillSecondary,progressStepMarginInlineEnd:Cn,progressStepMinWidth:Cn,progressActiveMotionDuration:"2.4s"});return[genBaseStyle$7(_n),genCircleStyle(_n),genStepStyle(_n),genSmallLine(_n)]});var __rest$m=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);InArray.isArray($n.strokeColor)?$n.strokeColor[0]:$n.strokeColor),Fn=computed(()=>{const{percent:Yn=0}=$n,Gn=getSuccessPercent($n);return parseInt(Gn!==void 0?Gn.toString():Yn.toString(),10)}),Bn=computed(()=>{const{status:Yn}=$n;return!progressStatuses.includes(Yn)&&Fn.value>=100?"success":Yn||"normal"}),Hn=computed(()=>{const{type:Yn,showInfo:Gn,size:Go}=$n,Xn=In.value;return{[Xn]:!0,[`${Xn}-inline-circle`]:Yn==="circle"&&getSize(Go,"circle").width<=20,[`${Xn}-${Yn==="dashboard"&&"circle"||Yn}`]:!0,[`${Xn}-status-${Bn.value}`]:!0,[`${Xn}-show-info`]:Gn,[`${Xn}-${Go}`]:Go,[`${Xn}-rtl`]:Nn.value==="rtl",[Dn.value]:!0}}),zn=computed(()=>typeof $n.strokeColor=="string"||Array.isArray($n.strokeColor)?$n.strokeColor:void 0),Wn=()=>{const{showInfo:Yn,format:Gn,type:Go,percent:Xn,title:Yo}=$n,qo=getSuccessPercent($n);if(!Yn)return null;let Jo;const Zo=Gn||(_n==null?void 0:_n.format)||(nr=>`${nr}%`),rr=Go==="line";return Gn||_n!=null&&_n.format||Bn.value!=="exception"&&Bn.value!=="success"?Jo=Zo(validProgress(Xn),validProgress(qo)):Bn.value==="exception"?Jo=createVNode(rr?CloseCircleFilled$1:CloseOutlined$1,null,null):Bn.value==="success"&&(Jo=createVNode(rr?CheckCircleFilled$1:CheckOutlined$1,null,null)),createVNode("span",{class:`${In.value}-text`,title:Yo===void 0&&typeof Jo=="string"?Jo:void 0},[Jo])};return()=>{const{type:Yn,steps:Gn,title:Go}=$n,{class:Xn}=Pn,Yo=__rest$m(Pn,["class"]),qo=Wn();let Jo;return Yn==="line"?Jo=Gn?createVNode(Steps$4,_objectSpread2$1(_objectSpread2$1({},$n),{},{strokeColor:zn.value,prefixCls:In.value,steps:Gn}),{default:()=>[qo]}):createVNode(Line,_objectSpread2$1(_objectSpread2$1({},$n),{},{strokeColor:Ln.value,prefixCls:In.value,direction:Nn.value}),{default:()=>[qo]}):(Yn==="circle"||Yn==="dashboard")&&(Jo=createVNode(Circle,_objectSpread2$1(_objectSpread2$1({},$n),{},{prefixCls:In.value,strokeColor:Ln.value,progressStatus:Bn.value}),{default:()=>[qo]})),Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({role:"progressbar"},Yo),{},{class:[Hn.value,Xn],title:Go}),[Jo]))}}}),Progress=withInstall(Progress$1);function getScroll($n){let Cn=$n.pageXOffset;const _n="scrollLeft";if(typeof Cn!="number"){const Pn=$n.document;Cn=Pn.documentElement[_n],typeof Cn!="number"&&(Cn=Pn.body[_n])}return Cn}function getClientPosition($n){let Cn,_n;const Pn=$n.ownerDocument,{body:In}=Pn,Nn=Pn&&Pn.documentElement,Rn=$n.getBoundingClientRect();return Cn=Rn.left,_n=Rn.top,Cn-=Nn.clientLeft||In.clientLeft||0,_n-=Nn.clientTop||In.clientTop||0,{left:Cn,top:_n}}function getOffsetLeft($n){const Cn=getClientPosition($n),_n=$n.ownerDocument,Pn=_n.defaultView||_n.parentWindow;return Cn.left+=getScroll(Pn),Cn.left}var StarFilled$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3z"}}]},name:"star",theme:"filled"};const StarFilledSvg=StarFilled$2;function _objectSpread$j($n){for(var Cn=1;Cn{const{index:Ln}=$n;_n("hover",Dn,Ln)},In=Dn=>{const{index:Ln}=$n;_n("click",Dn,Ln)},Nn=Dn=>{const{index:Ln}=$n;Dn.keyCode===13&&_n("click",Dn,Ln)},Rn=computed(()=>{const{prefixCls:Dn,index:Ln,value:Fn,allowHalf:Bn,focused:Hn}=$n,zn=Ln+1;let Wn=Dn;return Fn===0&&Ln===0&&Hn?Wn+=` ${Dn}-focused`:Bn&&Fn+.5>=zn&&Fn{const{disabled:Dn,prefixCls:Ln,characterRender:Fn,character:Bn,index:Hn,count:zn,value:Wn}=$n,Yn=typeof Bn=="function"?Bn({disabled:Dn,prefixCls:Ln,index:Hn,count:zn,value:Wn}):Bn;let Gn=createVNode("li",{class:Rn.value},[createVNode("div",{onClick:Dn?null:In,onKeydown:Dn?null:Nn,onMousemove:Dn?null:Pn,role:"radio","aria-checked":Wn>Hn?"true":"false","aria-posinset":Hn+1,"aria-setsize":zn,tabindex:Dn?-1:0},[createVNode("div",{class:`${Ln}-first`},[Yn]),createVNode("div",{class:`${Ln}-second`},[Yn])])]);return Fn&&(Gn=Fn(Gn,$n)),Gn}}}),genRateStarStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-star`]:{position:"relative",display:"inline-block",color:"inherit",cursor:"pointer","&:not(:last-child)":{marginInlineEnd:$n.marginXS},"> div":{transition:`all ${$n.motionDurationMid}, outline 0s`,"&:hover":{transform:$n.rateStarHoverScale},"&:focus":{outline:0},"&:focus-visible":{outline:`${$n.lineWidth}px dashed ${$n.rateStarColor}`,transform:$n.rateStarHoverScale}},"&-first, &-second":{color:$n.defaultColor,transition:`all ${$n.motionDurationMid}`,userSelect:"none",[$n.iconCls]:{verticalAlign:"middle"}},"&-first":{position:"absolute",top:0,insetInlineStart:0,width:"50%",height:"100%",overflow:"hidden",opacity:0},[`&-half ${Cn}-star-first, &-half ${Cn}-star-second`]:{opacity:1},[`&-half ${Cn}-star-first, &-full ${Cn}-star-second`]:{color:"inherit"}}}},genRateRtlStyle=$n=>({[`&-rtl${$n.componentCls}`]:{direction:"rtl"}}),genRateStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{display:"inline-block",margin:0,padding:0,color:$n.rateStarColor,fontSize:$n.rateStarSize,lineHeight:"unset",listStyle:"none",outline:"none",[`&-disabled${Cn} ${Cn}-star`]:{cursor:"default","&:hover":{transform:"scale(1)"}}}),genRateStarStyle($n)),{[`+ ${Cn}-text`]:{display:"inline-block",marginInlineStart:$n.marginXS,fontSize:$n.fontSize}}),genRateRtlStyle($n))}},useStyle$f=genComponentStyleHook("Rate",$n=>{const{colorFillContent:Cn}=$n,_n=merge$1($n,{rateStarColor:$n["yellow-6"],rateStarSize:$n.controlHeightLG*.5,rateStarHoverScale:"scale(1.1)",defaultColor:Cn});return[genRateStyle(_n)]}),rateProps=()=>({prefixCls:String,count:Number,value:Number,allowHalf:{type:Boolean,default:void 0},allowClear:{type:Boolean,default:void 0},tooltips:Array,disabled:{type:Boolean,default:void 0},character:PropTypes.any,autofocus:{type:Boolean,default:void 0},tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),direction:String,id:String,onChange:Function,onHoverChange:Function,"onUpdate:value":Function,onFocus:Function,onBlur:Function,onKeydown:Function}),Rate=defineComponent({compatConfig:{MODE:3},name:"ARate",inheritAttrs:!1,props:initDefaultProps(rateProps(),{value:0,count:5,allowHalf:!1,allowClear:!0,tabindex:0,direction:"ltr"}),setup($n,Cn){let{slots:_n,attrs:Pn,emit:In,expose:Nn}=Cn;const{prefixCls:Rn,direction:Dn}=useConfigInject("rate",$n),[Ln,Fn]=useStyle$f(Rn),Bn=useInjectFormItemContext(),Hn=ref(),[zn,Wn]=useRefs(),Yn=reactive({value:$n.value,focused:!1,cleanedValue:null,hoverValue:void 0});watch(()=>$n.value,()=>{Yn.value=$n.value});const Gn=ea=>findDOMNode(Wn.value.get(ea)),Go=(ea,la)=>{const ua=Dn.value==="rtl";let ga=ea+1;if($n.allowHalf){const aa=Gn(ea),ca=getOffsetLeft(aa),sa=aa.clientWidth;(ua&&la-ca>sa/2||!ua&&la-ca{$n.value===void 0&&(Yn.value=ea),In("update:value",ea),In("change",ea),Bn.onFieldChange()},Yo=(ea,la)=>{const ua=Go(la,ea.pageX);ua!==Yn.cleanedValue&&(Yn.hoverValue=ua,Yn.cleanedValue=null),In("hoverChange",ua)},qo=()=>{Yn.hoverValue=void 0,Yn.cleanedValue=null,In("hoverChange",void 0)},Jo=(ea,la)=>{const{allowClear:ua}=$n,ga=Go(la,ea.pageX);let aa=!1;ua&&(aa=ga===Yn.value),qo(),Xn(aa?0:ga),Yn.cleanedValue=aa?ga:null},Zo=ea=>{Yn.focused=!0,In("focus",ea)},rr=ea=>{Yn.focused=!1,In("blur",ea),Bn.onFieldBlur()},nr=ea=>{const{keyCode:la}=ea,{count:ua,allowHalf:ga}=$n,aa=Dn.value==="rtl";la===KeyCode$1.RIGHT&&Yn.value0&&!aa||la===KeyCode$1.RIGHT&&Yn.value>0&&aa?(ga?Yn.value-=.5:Yn.value-=1,Xn(Yn.value),ea.preventDefault()):la===KeyCode$1.LEFT&&Yn.value{$n.disabled||Hn.value.focus()};Nn({focus:ta,blur:()=>{$n.disabled||Hn.value.blur()}}),onMounted(()=>{const{autofocus:ea,disabled:la}=$n;ea&&!la&&ta()});const ra=(ea,la)=>{let{index:ua}=la;const{tooltips:ga}=$n;return ga?createVNode(Tooltip,{title:ga[ua]},{default:()=>[ea]}):ea};return()=>{const{count:ea,allowHalf:la,disabled:ua,tabindex:ga,id:aa=Bn.id.value}=$n,{class:ca,style:sa}=Pn,ia=[],fa=ua?`${Rn.value}-disabled`:"",ma=$n.character||_n.character||(()=>createVNode(StarFilled$1,null,null));for(let ba=0;bacreateVNode("svg",{width:"252",height:"294"},[createVNode("defs",null,[createVNode("path",{d:"M0 .387h251.772v251.772H0z"},null)]),createVNode("g",{fill:"none","fill-rule":"evenodd"},[createVNode("g",{transform:"translate(0 .012)"},[createVNode("mask",{fill:"#fff"},null),createVNode("path",{d:"M0 127.32v-2.095C0 56.279 55.892.387 124.838.387h2.096c68.946 0 124.838 55.892 124.838 124.838v2.096c0 68.946-55.892 124.838-124.838 124.838h-2.096C55.892 252.16 0 196.267 0 127.321",fill:"#E4EBF7",mask:"url(#b)"},null)]),createVNode("path",{d:"M39.755 130.84a8.276 8.276 0 1 1-16.468-1.66 8.276 8.276 0 0 1 16.468 1.66",fill:"#FFF"},null),createVNode("path",{d:"M36.975 134.297l10.482 5.943M48.373 146.508l-12.648 10.788",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{d:"M39.875 159.352a5.667 5.667 0 1 1-11.277-1.136 5.667 5.667 0 0 1 11.277 1.136M57.588 143.247a5.708 5.708 0 1 1-11.358-1.145 5.708 5.708 0 0 1 11.358 1.145M99.018 26.875l29.82-.014a4.587 4.587 0 1 0-.003-9.175l-29.82.013a4.587 4.587 0 1 0 .003 9.176M110.424 45.211l29.82-.013a4.588 4.588 0 0 0-.004-9.175l-29.82.013a4.587 4.587 0 1 0 .004 9.175",fill:"#FFF"},null),createVNode("path",{d:"M112.798 26.861v-.002l15.784-.006a4.588 4.588 0 1 0 .003 9.175l-15.783.007v-.002a4.586 4.586 0 0 0-.004-9.172M184.523 135.668c-.553 5.485-5.447 9.483-10.931 8.93-5.485-.553-9.483-5.448-8.93-10.932.552-5.485 5.447-9.483 10.932-8.93 5.485.553 9.483 5.447 8.93 10.932",fill:"#FFF"},null),createVNode("path",{d:"M179.26 141.75l12.64 7.167M193.006 156.477l-15.255 13.011",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{d:"M184.668 170.057a6.835 6.835 0 1 1-13.6-1.372 6.835 6.835 0 0 1 13.6 1.372M203.34 153.325a6.885 6.885 0 1 1-13.7-1.382 6.885 6.885 0 0 1 13.7 1.382",fill:"#FFF"},null),createVNode("path",{d:"M151.931 192.324a2.222 2.222 0 1 1-4.444 0 2.222 2.222 0 0 1 4.444 0zM225.27 116.056a2.222 2.222 0 1 1-4.445 0 2.222 2.222 0 0 1 4.444 0zM216.38 151.08a2.223 2.223 0 1 1-4.446-.001 2.223 2.223 0 0 1 4.446 0zM176.917 107.636a2.223 2.223 0 1 1-4.445 0 2.223 2.223 0 0 1 4.445 0zM195.291 92.165a2.223 2.223 0 1 1-4.445 0 2.223 2.223 0 0 1 4.445 0zM202.058 180.711a2.223 2.223 0 1 1-4.446 0 2.223 2.223 0 0 1 4.446 0z",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{stroke:"#FFF","stroke-width":"2",d:"M214.404 153.302l-1.912 20.184-10.928 5.99M173.661 174.792l-6.356 9.814h-11.36l-4.508 6.484M174.941 125.168v-15.804M220.824 117.25l-12.84 7.901-15.31-7.902V94.39"},null),createVNode("path",{d:"M166.588 65.936h-3.951a4.756 4.756 0 0 1-4.743-4.742 4.756 4.756 0 0 1 4.743-4.743h3.951a4.756 4.756 0 0 1 4.743 4.743 4.756 4.756 0 0 1-4.743 4.742",fill:"#FFF"},null),createVNode("path",{d:"M174.823 30.03c0-16.281 13.198-29.48 29.48-29.48 16.28 0 29.48 13.199 29.48 29.48 0 16.28-13.2 29.48-29.48 29.48-16.282 0-29.48-13.2-29.48-29.48",fill:"#1890FF"},null),createVNode("path",{d:"M205.952 38.387c.5.5.785 1.142.785 1.928s-.286 1.465-.785 1.964c-.572.5-1.214.75-2 .75-.785 0-1.429-.285-1.929-.785-.572-.5-.82-1.143-.82-1.929s.248-1.428.82-1.928c.5-.5 1.144-.75 1.93-.75.785 0 1.462.25 1.999.75m4.285-19.463c1.428 1.249 2.143 2.963 2.143 5.142 0 1.712-.427 3.13-1.219 4.25-.067.096-.137.18-.218.265-.416.429-1.41 1.346-2.956 2.699a5.07 5.07 0 0 0-1.428 1.75 5.207 5.207 0 0 0-.536 2.357v.5h-4.107v-.5c0-1.357.215-2.536.714-3.5.464-.964 1.857-2.464 4.178-4.536l.43-.5c.643-.785.964-1.643.964-2.535 0-1.18-.358-2.108-1-2.785-.678-.68-1.643-1.001-2.858-1.001-1.536 0-2.642.464-3.357 1.43-.37.5-.621 1.135-.76 1.904a1.999 1.999 0 0 1-1.971 1.63h-.004c-1.277 0-2.257-1.183-1.98-2.43.337-1.518 1.02-2.78 2.073-3.784 1.536-1.5 3.607-2.25 6.25-2.25 2.32 0 4.214.607 5.642 1.894",fill:"#FFF"},null),createVNode("path",{d:"M52.04 76.131s21.81 5.36 27.307 15.945c5.575 10.74-6.352 9.26-15.73 4.935-10.86-5.008-24.7-11.822-11.577-20.88",fill:"#FFB594"},null),createVNode("path",{d:"M90.483 67.504l-.449 2.893c-.753.49-4.748-2.663-4.748-2.663l-1.645.748-1.346-5.684s6.815-4.589 8.917-5.018c2.452-.501 9.884.94 10.7 2.278 0 0 1.32.486-2.227.69-3.548.203-5.043.447-6.79 3.132-1.747 2.686-2.412 3.624-2.412 3.624",fill:"#FFC6A0"},null),createVNode("path",{d:"M128.055 111.367c-2.627-7.724-6.15-13.18-8.917-15.478-3.5-2.906-9.34-2.225-11.366-4.187-1.27-1.231-3.215-1.197-3.215-1.197s-14.98-3.158-16.828-3.479c-2.37-.41-2.124-.714-6.054-1.405-1.57-1.907-2.917-1.122-2.917-1.122l-7.11-1.383c-.853-1.472-2.423-1.023-2.423-1.023l-2.468-.897c-1.645 9.976-7.74 13.796-7.74 13.796 1.795 1.122 15.703 8.3 15.703 8.3l5.107 37.11s-3.321 5.694 1.346 9.109c0 0 19.883-3.743 34.921-.329 0 0 3.047-2.546.972-8.806.523-3.01 1.394-8.263 1.736-11.622.385.772 2.019 1.918 3.14 3.477 0 0 9.407-7.365 11.052-14.012-.832-.723-1.598-1.585-2.267-2.453-.567-.736-.358-2.056-.765-2.717-.669-1.084-1.804-1.378-1.907-1.682",fill:"#FFF"},null),createVNode("path",{d:"M101.09 289.998s4.295 2.041 7.354 1.021c2.821-.94 4.53.668 7.08 1.178 2.55.51 6.874 1.1 11.686-1.26-.103-5.51-6.889-3.98-11.96-6.713-2.563-1.38-3.784-4.722-3.598-8.799h-9.402s-1.392 10.52-1.16 14.573",fill:"#CBD1D1"},null),createVNode("path",{d:"M101.067 289.826s2.428 1.271 6.759.653c3.058-.437 3.712.481 7.423 1.031 3.712.55 10.724-.069 11.823-.894.413 1.1-.343 2.063-.343 2.063s-1.512.603-4.812.824c-2.03.136-5.8.291-7.607-.503-1.787-1.375-5.247-1.903-5.728-.241-3.918.95-7.355-.286-7.355-.286l-.16-2.647z",fill:"#2B0849"},null),createVNode("path",{d:"M108.341 276.044h3.094s-.103 6.702 4.536 8.558c-4.64.618-8.558-2.303-7.63-8.558",fill:"#A4AABA"},null),createVNode("path",{d:"M57.542 272.401s-2.107 7.416-4.485 12.306c-1.798 3.695-4.225 7.492 5.465 7.492 6.648 0 8.953-.48 7.423-6.599-1.53-6.12.266-13.199.266-13.199h-8.669z",fill:"#CBD1D1"},null),createVNode("path",{d:"M51.476 289.793s2.097 1.169 6.633 1.169c6.083 0 8.249-1.65 8.249-1.65s.602 1.114-.619 2.165c-.993.855-3.597 1.591-7.39 1.546-4.145-.048-5.832-.566-6.736-1.168-.825-.55-.687-1.58-.137-2.062",fill:"#2B0849"},null),createVNode("path",{d:"M58.419 274.304s.033 1.519-.314 2.93c-.349 1.42-1.078 3.104-1.13 4.139-.058 1.151 4.537 1.58 5.155.034.62-1.547 1.294-6.427 1.913-7.252.619-.825-4.903-2.119-5.624.15",fill:"#A4AABA"},null),createVNode("path",{d:"M99.66 278.514l13.378.092s1.298-54.52 1.853-64.403c.554-9.882 3.776-43.364 1.002-63.128l-12.547-.644-22.849.78s-.434 3.966-1.195 9.976c-.063.496-.682.843-.749 1.365-.075.585.423 1.354.32 1.966-2.364 14.08-6.377 33.104-8.744 46.677-.116.666-1.234 1.009-1.458 2.691-.04.302.211 1.525.112 1.795-6.873 18.744-10.949 47.842-14.277 61.885l14.607-.014s2.197-8.57 4.03-16.97c2.811-12.886 23.111-85.01 23.111-85.01l3.016-.521 1.043 46.35s-.224 1.234.337 2.02c.56.785-.56 1.123-.392 2.244l.392 1.794s-.449 7.178-.898 11.89c-.448 4.71-.092 39.165-.092 39.165",fill:"#7BB2F9"},null),createVNode("path",{d:"M76.085 221.626c1.153.094 4.038-2.019 6.955-4.935M106.36 225.142s2.774-1.11 6.103-3.883",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M107.275 222.1s2.773-1.11 6.102-3.884",stroke:"#648BD8","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M74.74 224.767s2.622-.591 6.505-3.365M86.03 151.634c-.27 3.106.3 8.525-4.336 9.123M103.625 149.88s.11 14.012-1.293 15.065c-2.219 1.664-2.99 1.944-2.99 1.944M99.79 150.438s.035 12.88-1.196 24.377M93.673 175.911s7.212-1.664 9.431-1.664M74.31 205.861a212.013 212.013 0 0 1-.979 4.56s-1.458 1.832-1.009 3.776c.449 1.944-.947 2.045-4.985 15.355-1.696 5.59-4.49 18.591-6.348 27.597l-.231 1.12M75.689 197.807a320.934 320.934 0 0 1-.882 4.754M82.591 152.233L81.395 162.7s-1.097.15-.5 2.244c.113 1.346-2.674 15.775-5.18 30.43M56.12 274.418h13.31",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M116.241 148.22s-17.047-3.104-35.893.2c.158 2.514-.003 4.15-.003 4.15s14.687-2.818 35.67-.312c.252-2.355.226-4.038.226-4.038",fill:"#192064"},null),createVNode("path",{d:"M106.322 151.165l.003-4.911a.81.81 0 0 0-.778-.815c-2.44-.091-5.066-.108-7.836-.014a.818.818 0 0 0-.789.815l-.003 4.906a.81.81 0 0 0 .831.813c2.385-.06 4.973-.064 7.73.017a.815.815 0 0 0 .842-.81",fill:"#FFF"},null),createVNode("path",{d:"M105.207 150.233l.002-3.076a.642.642 0 0 0-.619-.646 94.321 94.321 0 0 0-5.866-.01.65.65 0 0 0-.63.647v3.072a.64.64 0 0 0 .654.644 121.12 121.12 0 0 1 5.794.011c.362.01.665-.28.665-.642",fill:"#192064"},null),createVNode("path",{d:"M100.263 275.415h12.338M101.436 270.53c.006 3.387.042 5.79.111 6.506M101.451 264.548a915.75 915.75 0 0 0-.015 4.337M100.986 174.965l.898 44.642s.673 1.57-.225 2.692c-.897 1.122 2.468.673.898 2.243-1.57 1.57.897 1.122 0 3.365-.596 1.489-.994 21.1-1.096 35.146",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M46.876 83.427s-.516 6.045 7.223 5.552c11.2-.712 9.218-9.345 31.54-21.655-.786-2.708-2.447-4.744-2.447-4.744s-11.068 3.11-22.584 8.046c-6.766 2.9-13.395 6.352-13.732 12.801M104.46 91.057l.941-5.372-8.884-11.43-5.037 5.372-1.74 7.834a.321.321 0 0 0 .108.32c.965.8 6.5 5.013 14.347 3.544a.332.332 0 0 0 .264-.268",fill:"#FFC6A0"},null),createVNode("path",{d:"M93.942 79.387s-4.533-2.853-2.432-6.855c1.623-3.09 4.513 1.133 4.513 1.133s.52-3.642 3.121-3.642c.52-1.04 1.561-4.162 1.561-4.162s11.445 2.601 13.526 3.121c0 5.203-2.304 19.424-7.84 19.861-8.892.703-12.449-9.456-12.449-9.456",fill:"#FFC6A0"},null),createVNode("path",{d:"M113.874 73.446c2.601-2.081 3.47-9.722 3.47-9.722s-2.479-.49-6.64-2.05c-4.683-2.081-12.798-4.747-17.48.976-9.668 3.223-2.05 19.823-2.05 19.823l2.713-3.021s-3.935-3.287-2.08-6.243c2.17-3.462 3.92 1.073 3.92 1.073s.637-2.387 3.581-3.342c.355-.71 1.036-2.674 1.432-3.85a1.073 1.073 0 0 1 1.263-.704c2.4.558 8.677 2.019 11.356 2.662.522.125.871.615.82 1.15l-.305 3.248z",fill:"#520038"},null),createVNode("path",{d:"M104.977 76.064c-.103.61-.582 1.038-1.07.956-.489-.083-.801-.644-.698-1.254.103-.61.582-1.038 1.07-.956.488.082.8.644.698 1.254M112.132 77.694c-.103.61-.582 1.038-1.07.956-.488-.083-.8-.644-.698-1.254.103-.61.582-1.038 1.07-.956.488.082.8.643.698 1.254",fill:"#552950"},null),createVNode("path",{stroke:"#DB836E","stroke-width":"1.118","stroke-linecap":"round","stroke-linejoin":"round",d:"M110.13 74.84l-.896 1.61-.298 4.357h-2.228"},null),createVNode("path",{d:"M110.846 74.481s1.79-.716 2.506.537",stroke:"#5C2552","stroke-width":"1.118","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M92.386 74.282s.477-1.114 1.113-.716c.637.398 1.274 1.433.558 1.99-.717.556.159 1.67.159 1.67",stroke:"#DB836E","stroke-width":"1.118","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M103.287 72.93s1.83 1.113 4.137.954",stroke:"#5C2552","stroke-width":"1.118","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M103.685 81.762s2.227 1.193 4.376 1.193M104.64 84.308s.954.398 1.511.318M94.693 81.205s2.308 7.4 10.424 7.639",stroke:"#DB836E","stroke-width":"1.118","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M81.45 89.384s.45 5.647-4.935 12.787M69 82.654s-.726 9.282-8.204 14.206",stroke:"#E4EBF7","stroke-width":"1.101","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M129.405 122.865s-5.272 7.403-9.422 10.768",stroke:"#E4EBF7","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M119.306 107.329s.452 4.366-2.127 32.062",stroke:"#E4EBF7","stroke-width":"1.101","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M150.028 151.232h-49.837a1.01 1.01 0 0 1-1.01-1.01v-31.688c0-.557.452-1.01 1.01-1.01h49.837c.558 0 1.01.453 1.01 1.01v31.688a1.01 1.01 0 0 1-1.01 1.01",fill:"#F2D7AD"},null),createVNode("path",{d:"M150.29 151.232h-19.863v-33.707h20.784v32.786a.92.92 0 0 1-.92.92",fill:"#F4D19D"},null),createVNode("path",{d:"M123.554 127.896H92.917a.518.518 0 0 1-.425-.816l6.38-9.113c.193-.277.51-.442.85-.442h31.092l-7.26 10.371z",fill:"#F2D7AD"},null),createVNode("path",{fill:"#CC9B6E",d:"M123.689 128.447H99.25v-.519h24.169l7.183-10.26.424.298z"},null),createVNode("path",{d:"M158.298 127.896h-18.669a2.073 2.073 0 0 1-1.659-.83l-7.156-9.541h19.965c.49 0 .95.23 1.244.622l6.69 8.92a.519.519 0 0 1-.415.83",fill:"#F4D19D"},null),createVNode("path",{fill:"#CC9B6E",d:"M157.847 128.479h-19.384l-7.857-10.475.415-.31 7.7 10.266h19.126zM130.554 150.685l-.032-8.177.519-.002.032 8.177z"},null),createVNode("path",{fill:"#CC9B6E",d:"M130.511 139.783l-.08-21.414.519-.002.08 21.414zM111.876 140.932l-.498-.143 1.479-5.167.498.143zM108.437 141.06l-2.679-2.935 2.665-3.434.41.318-2.397 3.089 2.384 2.612zM116.607 141.06l-.383-.35 2.383-2.612-2.397-3.089.41-.318 2.665 3.434z"},null),createVNode("path",{d:"M154.316 131.892l-3.114-1.96.038 3.514-1.043.092c-1.682.115-3.634.23-4.789.23-1.902 0-2.693 2.258 2.23 2.648l-2.645-.596s-2.168 1.317.504 2.3c0 0-1.58 1.217.561 2.58-.584 3.504 5.247 4.058 7.122 3.59 1.876-.47 4.233-2.359 4.487-5.16.28-3.085-.89-5.432-3.35-7.238",fill:"#FFC6A0"},null),createVNode("path",{d:"M153.686 133.577s-6.522.47-8.36.372c-1.836-.098-1.904 2.19 2.359 2.264 3.739.15 5.451-.044 5.451-.044",stroke:"#DB836E","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M145.16 135.877c-1.85 1.346.561 2.355.561 2.355s3.478.898 6.73.617",stroke:"#DB836E","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M151.89 141.71s-6.28.111-6.73-2.132c-.223-1.346.45-1.402.45-1.402M146.114 140.868s-1.103 3.16 5.44 3.533M151.202 129.932v3.477M52.838 89.286c3.533-.337 8.423-1.248 13.582-7.754",stroke:"#DB836E","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M168.567 248.318a6.647 6.647 0 0 1-6.647-6.647v-66.466a6.647 6.647 0 1 1 13.294 0v66.466a6.647 6.647 0 0 1-6.647 6.647",fill:"#5BA02E"},null),createVNode("path",{d:"M176.543 247.653a6.647 6.647 0 0 1-6.646-6.647v-33.232a6.647 6.647 0 1 1 13.293 0v33.232a6.647 6.647 0 0 1-6.647 6.647",fill:"#92C110"},null),createVNode("path",{d:"M186.443 293.613H158.92a3.187 3.187 0 0 1-3.187-3.187v-46.134a3.187 3.187 0 0 1 3.187-3.187h27.524a3.187 3.187 0 0 1 3.187 3.187v46.134a3.187 3.187 0 0 1-3.187 3.187",fill:"#F2D7AD"},null),createVNode("path",{d:"M88.979 89.48s7.776 5.384 16.6 2.842",stroke:"#E4EBF7","stroke-width":"1.101","stroke-linecap":"round","stroke-linejoin":"round"},null)])]),noFound=NoFound,ServerError=()=>createVNode("svg",{width:"254",height:"294"},[createVNode("defs",null,[createVNode("path",{d:"M0 .335h253.49v253.49H0z"},null),createVNode("path",{d:"M0 293.665h253.49V.401H0z"},null)]),createVNode("g",{fill:"none","fill-rule":"evenodd"},[createVNode("g",{transform:"translate(0 .067)"},[createVNode("mask",{fill:"#fff"},null),createVNode("path",{d:"M0 128.134v-2.11C0 56.608 56.273.334 125.69.334h2.11c69.416 0 125.69 56.274 125.69 125.69v2.11c0 69.417-56.274 125.69-125.69 125.69h-2.11C56.273 253.824 0 197.551 0 128.134",fill:"#E4EBF7",mask:"url(#b)"},null)]),createVNode("path",{d:"M39.989 132.108a8.332 8.332 0 1 1-16.581-1.671 8.332 8.332 0 0 1 16.58 1.671",fill:"#FFF"},null),createVNode("path",{d:"M37.19 135.59l10.553 5.983M48.665 147.884l-12.734 10.861",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{d:"M40.11 160.816a5.706 5.706 0 1 1-11.354-1.145 5.706 5.706 0 0 1 11.354 1.145M57.943 144.6a5.747 5.747 0 1 1-11.436-1.152 5.747 5.747 0 0 1 11.436 1.153M99.656 27.434l30.024-.013a4.619 4.619 0 1 0-.004-9.238l-30.024.013a4.62 4.62 0 0 0 .004 9.238M111.14 45.896l30.023-.013a4.62 4.62 0 1 0-.004-9.238l-30.024.013a4.619 4.619 0 1 0 .004 9.238",fill:"#FFF"},null),createVNode("path",{d:"M113.53 27.421v-.002l15.89-.007a4.619 4.619 0 1 0 .005 9.238l-15.892.007v-.002a4.618 4.618 0 0 0-.004-9.234M150.167 70.091h-3.979a4.789 4.789 0 0 1-4.774-4.775 4.788 4.788 0 0 1 4.774-4.774h3.979a4.789 4.789 0 0 1 4.775 4.774 4.789 4.789 0 0 1-4.775 4.775",fill:"#FFF"},null),createVNode("path",{d:"M171.687 30.234c0-16.392 13.289-29.68 29.681-29.68 16.392 0 29.68 13.288 29.68 29.68 0 16.393-13.288 29.681-29.68 29.681s-29.68-13.288-29.68-29.68",fill:"#FF603B"},null),createVNode("path",{d:"M203.557 19.435l-.676 15.035a1.514 1.514 0 0 1-3.026 0l-.675-15.035a2.19 2.19 0 1 1 4.377 0m-.264 19.378c.513.477.77 1.1.77 1.87s-.257 1.393-.77 1.907c-.55.476-1.21.733-1.943.733a2.545 2.545 0 0 1-1.87-.77c-.55-.514-.806-1.136-.806-1.87 0-.77.256-1.393.806-1.87.513-.513 1.137-.733 1.87-.733.77 0 1.43.22 1.943.733",fill:"#FFF"},null),createVNode("path",{d:"M119.3 133.275c4.426-.598 3.612-1.204 4.079-4.778.675-5.18-3.108-16.935-8.262-25.118-1.088-10.72-12.598-11.24-12.598-11.24s4.312 4.895 4.196 16.199c1.398 5.243.804 14.45.804 14.45s5.255 11.369 11.78 10.487",fill:"#FFB594"},null),createVNode("path",{d:"M100.944 91.61s1.463-.583 3.211.582c8.08 1.398 10.368 6.706 11.3 11.368 1.864 1.282 1.864 2.33 1.864 3.496.365.777 1.515 3.03 1.515 3.03s-7.225 1.748-10.954 6.758c-1.399-6.41-6.936-25.235-6.936-25.235",fill:"#FFF"},null),createVNode("path",{d:"M94.008 90.5l1.019-5.815-9.23-11.874-5.233 5.581-2.593 9.863s8.39 5.128 16.037 2.246",fill:"#FFB594"},null),createVNode("path",{d:"M82.931 78.216s-4.557-2.868-2.445-6.892c1.632-3.107 4.537 1.139 4.537 1.139s.524-3.662 3.139-3.662c.523-1.046 1.569-4.184 1.569-4.184s11.507 2.615 13.6 3.138c-.001 5.23-2.317 19.529-7.884 19.969-8.94.706-12.516-9.508-12.516-9.508",fill:"#FFC6A0"},null),createVNode("path",{d:"M102.971 72.243c2.616-2.093 3.489-9.775 3.489-9.775s-2.492-.492-6.676-2.062c-4.708-2.092-12.867-4.771-17.575.982-9.54 4.41-2.062 19.93-2.062 19.93l2.729-3.037s-3.956-3.304-2.092-6.277c2.183-3.48 3.943 1.08 3.943 1.08s.64-2.4 3.6-3.36c.356-.714 1.04-2.69 1.44-3.872a1.08 1.08 0 0 1 1.27-.707c2.41.56 8.723 2.03 11.417 2.676.524.126.876.619.825 1.156l-.308 3.266z",fill:"#520038"},null),createVNode("path",{d:"M101.22 76.514c-.104.613-.585 1.044-1.076.96-.49-.082-.805-.646-.702-1.26.104-.613.585-1.044 1.076-.961.491.083.805.647.702 1.26M94.26 75.074c-.104.613-.585 1.044-1.076.96-.49-.082-.805-.646-.702-1.26.104-.613.585-1.044 1.076-.96.491.082.805.646.702 1.26",fill:"#552950"},null),createVNode("path",{stroke:"#DB836E","stroke-width":"1.063","stroke-linecap":"round","stroke-linejoin":"round",d:"M99.206 73.644l-.9 1.62-.3 4.38h-2.24"},null),createVNode("path",{d:"M99.926 73.284s1.8-.72 2.52.54",stroke:"#5C2552","stroke-width":"1.117","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M81.367 73.084s.48-1.12 1.12-.72c.64.4 1.28 1.44.56 2s.16 1.68.16 1.68",stroke:"#DB836E","stroke-width":"1.117","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M92.326 71.724s1.84 1.12 4.16.96",stroke:"#5C2552","stroke-width":"1.117","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M92.726 80.604s2.24 1.2 4.4 1.2M93.686 83.164s.96.4 1.52.32M83.687 80.044s1.786 6.547 9.262 7.954",stroke:"#DB836E","stroke-width":"1.063","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M95.548 91.663s-1.068 2.821-8.298 2.105c-7.23-.717-10.29-5.044-10.29-5.044",stroke:"#E4EBF7","stroke-width":"1.136","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M78.126 87.478s6.526 4.972 16.47 2.486c0 0 9.577 1.02 11.536 5.322 5.36 11.77.543 36.835 0 39.962 3.496 4.055-.466 8.483-.466 8.483-15.624-3.548-35.81-.6-35.81-.6-4.849-3.546-1.223-9.044-1.223-9.044L62.38 110.32c-2.485-15.227.833-19.803 3.549-20.743 3.03-1.049 8.04-1.282 8.04-1.282.496-.058 1.08-.076 1.37-.233 2.36-1.282 2.787-.583 2.787-.583",fill:"#FFF"},null),createVNode("path",{d:"M65.828 89.81s-6.875.465-7.59 8.156c-.466 8.857 3.03 10.954 3.03 10.954s6.075 22.102 16.796 22.957c8.39-2.176 4.758-6.702 4.661-11.42-.233-11.304-7.108-16.897-7.108-16.897s-4.212-13.75-9.789-13.75",fill:"#FFC6A0"},null),createVNode("path",{d:"M71.716 124.225s.855 11.264 9.828 6.486c4.765-2.536 7.581-13.828 9.789-22.568 1.456-5.768 2.58-12.197 2.58-12.197l-4.973-1.709s-2.408 5.516-7.769 12.275c-4.335 5.467-9.144 11.11-9.455 17.713",fill:"#FFC6A0"},null),createVNode("path",{d:"M108.463 105.191s1.747 2.724-2.331 30.535c2.376 2.216 1.053 6.012-.233 7.51",stroke:"#E4EBF7","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M123.262 131.527s-.427 2.732-11.77 1.981c-15.187-1.006-25.326-3.25-25.326-3.25l.933-5.8s.723.215 9.71-.068c11.887-.373 18.714-6.07 24.964-1.022 4.039 3.263 1.489 8.16 1.489 8.16",fill:"#FFC6A0"},null),createVNode("path",{d:"M70.24 90.974s-5.593-4.739-11.054 2.68c-3.318 7.223.517 15.284 2.664 19.578-.31 3.729 2.33 4.311 2.33 4.311s.108.895 1.516 2.68c4.078-7.03 6.72-9.166 13.711-12.546-.328-.656-1.877-3.265-1.825-3.767.175-1.69-1.282-2.623-1.282-2.623s-.286-.156-1.165-2.738c-.788-2.313-2.036-5.177-4.895-7.575",fill:"#FFF"},null),createVNode("path",{d:"M90.232 288.027s4.855 2.308 8.313 1.155c3.188-1.063 5.12.755 8.002 1.331 2.881.577 7.769 1.243 13.207-1.424-.117-6.228-7.786-4.499-13.518-7.588-2.895-1.56-4.276-5.336-4.066-9.944H91.544s-1.573 11.89-1.312 16.47",fill:"#CBD1D1"},null),createVNode("path",{d:"M90.207 287.833s2.745 1.437 7.639.738c3.456-.494 3.223.66 7.418 1.282 4.195.621 13.092-.194 14.334-1.126.466 1.242-.388 2.33-.388 2.33s-1.709.682-5.438.932c-2.295.154-8.098.276-10.14-.621-2.02-1.554-4.894-1.515-6.06-.234-4.427 1.075-7.184-.31-7.184-.31l-.181-2.991z",fill:"#2B0849"},null),createVNode("path",{d:"M98.429 272.257h3.496s-.117 7.574 5.127 9.671c-5.244.7-9.672-2.602-8.623-9.671",fill:"#A4AABA"},null),createVNode("path",{d:"M44.425 272.046s-2.208 7.774-4.702 12.899c-1.884 3.874-4.428 7.854 5.729 7.854 6.97 0 9.385-.503 7.782-6.917-1.604-6.415.279-13.836.279-13.836h-9.088z",fill:"#CBD1D1"},null),createVNode("path",{d:"M38.066 290.277s2.198 1.225 6.954 1.225c6.376 0 8.646-1.73 8.646-1.73s.63 1.168-.649 2.27c-1.04.897-3.77 1.668-7.745 1.621-4.347-.05-6.115-.593-7.062-1.224-.864-.577-.72-1.657-.144-2.162",fill:"#2B0849"},null),createVNode("path",{d:"M45.344 274.041s.035 1.592-.329 3.07c-.365 1.49-1.13 3.255-1.184 4.34-.061 1.206 4.755 1.657 5.403.036.65-1.622 1.357-6.737 2.006-7.602.648-.865-5.14-2.222-5.896.156",fill:"#A4AABA"},null),createVNode("path",{d:"M89.476 277.57l13.899.095s1.349-56.643 1.925-66.909c.576-10.267 3.923-45.052 1.042-65.585l-13.037-.669-23.737.81s-.452 4.12-1.243 10.365c-.065.515-.708.874-.777 1.417-.078.608.439 1.407.332 2.044-2.455 14.627-5.797 32.736-8.256 46.837-.121.693-1.282 1.048-1.515 2.796-.042.314.22 1.584.116 1.865-7.14 19.473-12.202 52.601-15.66 67.19l15.176-.015s2.282-10.145 4.185-18.871c2.922-13.389 24.012-88.32 24.012-88.32l3.133-.954-.158 48.568s-.233 1.282.35 2.098c.583.815-.581 1.167-.408 2.331l.408 1.864s-.466 7.458-.932 12.352c-.467 4.895 1.145 40.69 1.145 40.69",fill:"#7BB2F9"},null),createVNode("path",{d:"M64.57 218.881c1.197.099 4.195-2.097 7.225-5.127M96.024 222.534s2.881-1.152 6.34-4.034",stroke:"#648BD8","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M96.973 219.373s2.882-1.153 6.34-4.034",stroke:"#648BD8","stroke-width":"1.032","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M63.172 222.144s2.724-.614 6.759-3.496M74.903 146.166c-.281 3.226.31 8.856-4.506 9.478M93.182 144.344s.115 14.557-1.344 15.65c-2.305 1.73-3.107 2.02-3.107 2.02M89.197 144.923s.269 13.144-1.01 25.088M83.525 170.71s6.81-1.051 9.116-1.051M46.026 270.045l-.892 4.538M46.937 263.289l-.815 4.157M62.725 202.503c-.33 1.618-.102 1.904-.449 3.438 0 0-2.756 1.903-2.29 3.923.466 2.02-.31 3.424-4.505 17.252-1.762 5.807-4.233 18.922-6.165 28.278-.03.144-.521 2.646-1.14 5.8M64.158 194.136c-.295 1.658-.6 3.31-.917 4.938M71.33 146.787l-1.244 10.877s-1.14.155-.519 2.33c.117 1.399-2.778 16.39-5.382 31.615M44.242 273.727H58.07",stroke:"#648BD8","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M106.18 142.117c-3.028-.489-18.825-2.744-36.219.2a.625.625 0 0 0-.518.644c.063 1.307.044 2.343.015 2.995a.617.617 0 0 0 .716.636c3.303-.534 17.037-2.412 35.664-.266.347.04.66-.214.692-.56.124-1.347.16-2.425.17-3.029a.616.616 0 0 0-.52-.62",fill:"#192064"},null),createVNode("path",{d:"M96.398 145.264l.003-5.102a.843.843 0 0 0-.809-.847 114.104 114.104 0 0 0-8.141-.014.85.85 0 0 0-.82.847l-.003 5.097c0 .476.388.857.864.845 2.478-.064 5.166-.067 8.03.017a.848.848 0 0 0 .876-.843",fill:"#FFF"},null),createVNode("path",{d:"M95.239 144.296l.002-3.195a.667.667 0 0 0-.643-.672c-1.9-.061-3.941-.073-6.094-.01a.675.675 0 0 0-.654.672l-.002 3.192c0 .376.305.677.68.669 1.859-.042 3.874-.043 6.02.012.376.01.69-.291.691-.668",fill:"#192064"},null),createVNode("path",{d:"M90.102 273.522h12.819M91.216 269.761c.006 3.519-.072 5.55 0 6.292M90.923 263.474c-.009 1.599-.016 2.558-.016 4.505M90.44 170.404l.932 46.38s.7 1.631-.233 2.796c-.932 1.166 2.564.7.932 2.33-1.63 1.633.933 1.166 0 3.497-.618 1.546-1.031 21.921-1.138 36.513",stroke:"#648BD8","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M73.736 98.665l2.214 4.312s2.098.816 1.865 2.68l.816 2.214M64.297 116.611c.233-.932 2.176-7.147 12.585-10.488M77.598 90.042s7.691 6.137 16.547 2.72",stroke:"#E4EBF7","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M91.974 86.954s5.476-.816 7.574-4.545c1.297-.345.72 2.212-.33 3.671-.7.971-1.01 1.554-1.01 1.554s.194.31.155.816c-.053.697-.175.653-.272 1.048-.081.335.108.657 0 1.049-.046.17-.198.5-.382.878-.12.249-.072.687-.2.948-.231.469-1.562 1.87-2.622 2.855-3.826 3.554-5.018 1.644-6.001-.408-.894-1.865-.661-5.127-.874-6.875-.35-2.914-2.622-3.03-1.923-4.429.343-.685 2.87.69 3.263 1.748.757 2.04 2.952 1.807 2.622 1.69",fill:"#FFC6A0"},null),createVNode("path",{d:"M99.8 82.429c-.465.077-.35.272-.97 1.243-.622.971-4.817 2.932-6.39 3.224-2.589.48-2.278-1.56-4.254-2.855-1.69-1.107-3.562-.638-1.398 1.398.99.932.932 1.107 1.398 3.205.335 1.506-.64 3.67.7 5.593",stroke:"#DB836E","stroke-width":".774","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M79.543 108.673c-2.1 2.926-4.266 6.175-5.557 8.762",stroke:"#E59788","stroke-width":".774","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M87.72 124.768s-2.098-1.942-5.127-2.719c-3.03-.777-3.574-.155-5.516.078-1.942.233-3.885-.932-3.652.7.233 1.63 5.05 1.01 5.206 2.097.155 1.087-6.37 2.796-8.313 2.175-.777.777.466 1.864 2.02 2.175.233 1.554 2.253 1.554 2.253 1.554s.699 1.01 2.641 1.088c2.486 1.32 8.934-.7 10.954-1.554 2.02-.855-.466-5.594-.466-5.594",fill:"#FFC6A0"},null),createVNode("path",{d:"M73.425 122.826s.66 1.127 3.167 1.418c2.315.27 2.563.583 2.563.583s-2.545 2.894-9.07 2.272M72.416 129.274s3.826.097 4.933-.718M74.98 130.75s1.961.136 3.36-.505M77.232 131.916s1.748.019 2.914-.505M73.328 122.321s-.595-1.032 1.262-.427c1.671.544 2.833.055 5.128.155 1.389.061 3.067-.297 3.982.15 1.606.784 3.632 2.181 3.632 2.181s10.526 1.204 19.033-1.127M78.864 108.104s-8.39 2.758-13.168 12.12",stroke:"#E59788","stroke-width":".774","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M109.278 112.533s3.38-3.613 7.575-4.662",stroke:"#E4EBF7","stroke-width":"1.085","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M107.375 123.006s9.697-2.745 11.445-.88",stroke:"#E59788","stroke-width":".774","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M194.605 83.656l3.971-3.886M187.166 90.933l3.736-3.655M191.752 84.207l-4.462-4.56M198.453 91.057l-4.133-4.225M129.256 163.074l3.718-3.718M122.291 170.039l3.498-3.498M126.561 163.626l-4.27-4.27M132.975 170.039l-3.955-3.955",stroke:"#BFCDDD","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M190.156 211.779h-1.604a4.023 4.023 0 0 1-4.011-4.011V175.68a4.023 4.023 0 0 1 4.01-4.01h1.605a4.023 4.023 0 0 1 4.011 4.01v32.088a4.023 4.023 0 0 1-4.01 4.01",fill:"#A3B4C6"},null),createVNode("path",{d:"M237.824 212.977a4.813 4.813 0 0 1-4.813 4.813h-86.636a4.813 4.813 0 0 1 0-9.626h86.636a4.813 4.813 0 0 1 4.813 4.813",fill:"#A3B4C6"},null),createVNode("mask",{fill:"#fff"},null),createVNode("path",{fill:"#A3B4C6",mask:"url(#d)",d:"M154.098 190.096h70.513v-84.617h-70.513z"},null),createVNode("path",{d:"M224.928 190.096H153.78a3.219 3.219 0 0 1-3.208-3.209V167.92a3.219 3.219 0 0 1 3.208-3.21h71.148a3.219 3.219 0 0 1 3.209 3.21v18.967a3.219 3.219 0 0 1-3.21 3.209M224.928 130.832H153.78a3.218 3.218 0 0 1-3.208-3.208v-18.968a3.219 3.219 0 0 1 3.208-3.209h71.148a3.219 3.219 0 0 1 3.209 3.21v18.967a3.218 3.218 0 0 1-3.21 3.208",fill:"#BFCDDD",mask:"url(#d)"},null),createVNode("path",{d:"M159.563 120.546a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M166.98 120.546a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M174.397 120.546a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M222.539 120.546h-22.461a.802.802 0 0 1-.802-.802v-3.208c0-.443.359-.803.802-.803h22.46c.444 0 .803.36.803.803v3.208c0 .443-.36.802-.802.802",fill:"#FFF",mask:"url(#d)"},null),createVNode("path",{d:"M224.928 160.464H153.78a3.218 3.218 0 0 1-3.208-3.209v-18.967a3.219 3.219 0 0 1 3.208-3.209h71.148a3.219 3.219 0 0 1 3.209 3.209v18.967a3.218 3.218 0 0 1-3.21 3.209",fill:"#BFCDDD",mask:"url(#d)"},null),createVNode("path",{d:"M173.455 130.832h49.301M164.984 130.832h6.089M155.952 130.832h6.75M173.837 160.613h49.3M165.365 160.613h6.089M155.57 160.613h6.751",stroke:"#7C90A5","stroke-width":"1.124","stroke-linecap":"round","stroke-linejoin":"round",mask:"url(#d)"},null),createVNode("path",{d:"M159.563 151.038a2.407 2.407 0 1 1 0-4.814 2.407 2.407 0 0 1 0 4.814M166.98 151.038a2.407 2.407 0 1 1 0-4.814 2.407 2.407 0 0 1 0 4.814M174.397 151.038a2.407 2.407 0 1 1 .001-4.814 2.407 2.407 0 0 1 0 4.814M222.539 151.038h-22.461a.802.802 0 0 1-.802-.802v-3.209c0-.443.359-.802.802-.802h22.46c.444 0 .803.36.803.802v3.209c0 .443-.36.802-.802.802M159.563 179.987a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M166.98 179.987a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M174.397 179.987a2.407 2.407 0 1 1 0-4.813 2.407 2.407 0 0 1 0 4.813M222.539 179.987h-22.461a.802.802 0 0 1-.802-.802v-3.209c0-.443.359-.802.802-.802h22.46c.444 0 .803.36.803.802v3.209c0 .443-.36.802-.802.802",fill:"#FFF",mask:"url(#d)"},null),createVNode("path",{d:"M203.04 221.108h-27.372a2.413 2.413 0 0 1-2.406-2.407v-11.448a2.414 2.414 0 0 1 2.406-2.407h27.372a2.414 2.414 0 0 1 2.407 2.407V218.7a2.413 2.413 0 0 1-2.407 2.407",fill:"#BFCDDD",mask:"url(#d)"},null),createVNode("path",{d:"M177.259 207.217v11.52M201.05 207.217v11.52",stroke:"#A3B4C6","stroke-width":"1.124","stroke-linecap":"round","stroke-linejoin":"round",mask:"url(#d)"},null),createVNode("path",{d:"M162.873 267.894a9.422 9.422 0 0 1-9.422-9.422v-14.82a9.423 9.423 0 0 1 18.845 0v14.82a9.423 9.423 0 0 1-9.423 9.422",fill:"#5BA02E",mask:"url(#d)"},null),createVNode("path",{d:"M171.22 267.83a9.422 9.422 0 0 1-9.422-9.423v-3.438a9.423 9.423 0 0 1 18.845 0v3.438a9.423 9.423 0 0 1-9.422 9.423",fill:"#92C110",mask:"url(#d)"},null),createVNode("path",{d:"M181.31 293.666h-27.712a3.209 3.209 0 0 1-3.209-3.21V269.79a3.209 3.209 0 0 1 3.209-3.21h27.711a3.209 3.209 0 0 1 3.209 3.21v20.668a3.209 3.209 0 0 1-3.209 3.209",fill:"#F2D7AD",mask:"url(#d)"},null)])]),serverError=ServerError,Unauthorized=()=>createVNode("svg",{width:"251",height:"294"},[createVNode("g",{fill:"none","fill-rule":"evenodd"},[createVNode("path",{d:"M0 129.023v-2.084C0 58.364 55.591 2.774 124.165 2.774h2.085c68.574 0 124.165 55.59 124.165 124.165v2.084c0 68.575-55.59 124.166-124.165 124.166h-2.085C55.591 253.189 0 197.598 0 129.023",fill:"#E4EBF7"},null),createVNode("path",{d:"M41.417 132.92a8.231 8.231 0 1 1-16.38-1.65 8.231 8.231 0 0 1 16.38 1.65",fill:"#FFF"},null),createVNode("path",{d:"M38.652 136.36l10.425 5.91M49.989 148.505l-12.58 10.73",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{d:"M41.536 161.28a5.636 5.636 0 1 1-11.216-1.13 5.636 5.636 0 0 1 11.216 1.13M59.154 145.261a5.677 5.677 0 1 1-11.297-1.138 5.677 5.677 0 0 1 11.297 1.138M100.36 29.516l29.66-.013a4.562 4.562 0 1 0-.004-9.126l-29.66.013a4.563 4.563 0 0 0 .005 9.126M111.705 47.754l29.659-.013a4.563 4.563 0 1 0-.004-9.126l-29.66.013a4.563 4.563 0 1 0 .005 9.126",fill:"#FFF"},null),createVNode("path",{d:"M114.066 29.503V29.5l15.698-.007a4.563 4.563 0 1 0 .004 9.126l-15.698.007v-.002a4.562 4.562 0 0 0-.004-9.122M185.405 137.723c-.55 5.455-5.418 9.432-10.873 8.882-5.456-.55-9.432-5.418-8.882-10.873.55-5.455 5.418-9.432 10.873-8.882 5.455.55 9.432 5.418 8.882 10.873",fill:"#FFF"},null),createVNode("path",{d:"M180.17 143.772l12.572 7.129M193.841 158.42L178.67 171.36",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{d:"M185.55 171.926a6.798 6.798 0 1 1-13.528-1.363 6.798 6.798 0 0 1 13.527 1.363M204.12 155.285a6.848 6.848 0 1 1-13.627-1.375 6.848 6.848 0 0 1 13.626 1.375",fill:"#FFF"},null),createVNode("path",{d:"M152.988 194.074a2.21 2.21 0 1 1-4.42 0 2.21 2.21 0 0 1 4.42 0zM225.931 118.217a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.421 0zM217.09 153.051a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.42 0zM177.84 109.842a2.21 2.21 0 1 1-4.422 0 2.21 2.21 0 0 1 4.421 0zM196.114 94.454a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.421 0zM202.844 182.523a2.21 2.21 0 1 1-4.42 0 2.21 2.21 0 0 1 4.42 0z",stroke:"#FFF","stroke-width":"2"},null),createVNode("path",{stroke:"#FFF","stroke-width":"2",d:"M215.125 155.262l-1.902 20.075-10.87 5.958M174.601 176.636l-6.322 9.761H156.98l-4.484 6.449M175.874 127.28V111.56M221.51 119.404l-12.77 7.859-15.228-7.86V96.668"},null),createVNode("path",{d:"M180.68 29.32C180.68 13.128 193.806 0 210 0c16.193 0 29.32 13.127 29.32 29.32 0 16.194-13.127 29.322-29.32 29.322-16.193 0-29.32-13.128-29.32-29.321",fill:"#A26EF4"},null),createVNode("path",{d:"M221.45 41.706l-21.563-.125a1.744 1.744 0 0 1-1.734-1.754l.071-12.23a1.744 1.744 0 0 1 1.754-1.734l21.562.125c.964.006 1.74.791 1.735 1.755l-.071 12.229a1.744 1.744 0 0 1-1.754 1.734",fill:"#FFF"},null),createVNode("path",{d:"M215.106 29.192c-.015 2.577-2.049 4.654-4.543 4.64-2.494-.014-4.504-2.115-4.489-4.693l.04-6.925c.016-2.577 2.05-4.654 4.543-4.64 2.494.015 4.504 2.116 4.49 4.693l-.04 6.925zm-4.53-14.074a6.877 6.877 0 0 0-6.916 6.837l-.043 7.368a6.877 6.877 0 0 0 13.754.08l.042-7.368a6.878 6.878 0 0 0-6.837-6.917zM167.566 68.367h-3.93a4.73 4.73 0 0 1-4.717-4.717 4.73 4.73 0 0 1 4.717-4.717h3.93a4.73 4.73 0 0 1 4.717 4.717 4.73 4.73 0 0 1-4.717 4.717",fill:"#FFF"},null),createVNode("path",{d:"M168.214 248.838a6.611 6.611 0 0 1-6.61-6.611v-66.108a6.611 6.611 0 0 1 13.221 0v66.108a6.611 6.611 0 0 1-6.61 6.61",fill:"#5BA02E"},null),createVNode("path",{d:"M176.147 248.176a6.611 6.611 0 0 1-6.61-6.61v-33.054a6.611 6.611 0 1 1 13.221 0v33.053a6.611 6.611 0 0 1-6.61 6.611",fill:"#92C110"},null),createVNode("path",{d:"M185.994 293.89h-27.376a3.17 3.17 0 0 1-3.17-3.17v-45.887a3.17 3.17 0 0 1 3.17-3.17h27.376a3.17 3.17 0 0 1 3.17 3.17v45.886a3.17 3.17 0 0 1-3.17 3.17",fill:"#F2D7AD"},null),createVNode("path",{d:"M81.972 147.673s6.377-.927 17.566-1.28c11.729-.371 17.57 1.086 17.57 1.086s3.697-3.855.968-8.424c1.278-12.077 5.982-32.827.335-48.273-1.116-1.339-3.743-1.512-7.536-.62-1.337.315-7.147-.149-7.983-.1l-15.311-.347s-3.487-.17-8.035-.508c-1.512-.113-4.227-1.683-5.458-.338-.406.443-2.425 5.669-1.97 16.077l8.635 35.642s-3.141 3.61 1.219 7.085",fill:"#FFF"},null),createVNode("path",{d:"M75.768 73.325l-.9-6.397 11.982-6.52s7.302-.118 8.038 1.205c.737 1.324-5.616.993-5.616.993s-1.836 1.388-2.615 2.5c-1.654 2.363-.986 6.471-8.318 5.986-1.708.284-2.57 2.233-2.57 2.233",fill:"#FFC6A0"},null),createVNode("path",{d:"M52.44 77.672s14.217 9.406 24.973 14.444c1.061.497-2.094 16.183-11.892 11.811-7.436-3.318-20.162-8.44-21.482-14.496-.71-3.258 2.543-7.643 8.401-11.76M141.862 80.113s-6.693 2.999-13.844 6.876c-3.894 2.11-10.137 4.704-12.33 7.988-6.224 9.314 3.536 11.22 12.947 7.503 6.71-2.651 28.999-12.127 13.227-22.367",fill:"#FFB594"},null),createVNode("path",{d:"M76.166 66.36l3.06 3.881s-2.783 2.67-6.31 5.747c-7.103 6.195-12.803 14.296-15.995 16.44-3.966 2.662-9.754 3.314-12.177-.118-3.553-5.032.464-14.628 31.422-25.95",fill:"#FFC6A0"},null),createVNode("path",{d:"M64.674 85.116s-2.34 8.413-8.912 14.447c.652.548 18.586 10.51 22.144 10.056 5.238-.669 6.417-18.968 1.145-20.531-.702-.208-5.901-1.286-8.853-2.167-.87-.26-1.611-1.71-3.545-.936l-1.98-.869zM128.362 85.826s5.318 1.956 7.325 13.734c-.546.274-17.55 12.35-21.829 7.805-6.534-6.94-.766-17.393 4.275-18.61 4.646-1.121 5.03-1.37 10.23-2.929",fill:"#FFF"},null),createVNode("path",{d:"M78.18 94.656s.911 7.41-4.914 13.078",stroke:"#E4EBF7","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M87.397 94.68s3.124 2.572 10.263 2.572c7.14 0 9.074-3.437 9.074-3.437",stroke:"#E4EBF7","stroke-width":".932","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M117.184 68.639l-6.781-6.177s-5.355-4.314-9.223-.893c-3.867 3.422 4.463 2.083 5.653 4.165 1.19 2.082.848 1.143-2.083.446-5.603-1.331-2.082.893 2.975 5.355 2.091 1.845 6.992.955 6.992.955l2.467-3.851z",fill:"#FFC6A0"},null),createVNode("path",{d:"M105.282 91.315l-.297-10.937-15.918-.027-.53 10.45c-.026.403.17.788.515.999 2.049 1.251 9.387 5.093 15.799.424.287-.21.443-.554.431-.91",fill:"#FFB594"},null),createVNode("path",{d:"M107.573 74.24c.817-1.147.982-9.118 1.015-11.928a1.046 1.046 0 0 0-.965-1.055l-4.62-.365c-7.71-1.044-17.071.624-18.253 6.346-5.482 5.813-.421 13.244-.421 13.244s1.963 3.566 4.305 6.791c.756 1.041.398-3.731 3.04-5.929 5.524-4.594 15.899-7.103 15.899-7.103",fill:"#5C2552"},null),createVNode("path",{d:"M88.426 83.206s2.685 6.202 11.602 6.522c7.82.28 8.973-7.008 7.434-17.505l-.909-5.483c-6.118-2.897-15.478.54-15.478.54s-.576 2.044-.19 5.504c-2.276 2.066-1.824 5.618-1.824 5.618s-.905-1.922-1.98-2.321c-.86-.32-1.897.089-2.322 1.98-1.04 4.632 3.667 5.145 3.667 5.145",fill:"#FFC6A0"},null),createVNode("path",{stroke:"#DB836E","stroke-width":"1.145","stroke-linecap":"round","stroke-linejoin":"round",d:"M100.843 77.099l1.701-.928-1.015-4.324.674-1.406"},null),createVNode("path",{d:"M105.546 74.092c-.022.713-.452 1.279-.96 1.263-.51-.016-.904-.607-.882-1.32.021-.713.452-1.278.96-1.263.51.016.904.607.882 1.32M97.592 74.349c-.022.713-.452 1.278-.961 1.263-.509-.016-.904-.607-.882-1.32.022-.713.452-1.279.961-1.263.51.016.904.606.882 1.32",fill:"#552950"},null),createVNode("path",{d:"M91.132 86.786s5.269 4.957 12.679 2.327",stroke:"#DB836E","stroke-width":"1.145","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M99.776 81.903s-3.592.232-1.44-2.79c1.59-1.496 4.897-.46 4.897-.46s1.156 3.906-3.457 3.25",fill:"#DB836E"},null),createVNode("path",{d:"M102.88 70.6s2.483.84 3.402.715M93.883 71.975s2.492-1.144 4.778-1.073",stroke:"#5C2552","stroke-width":"1.526","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M86.32 77.374s.961.879 1.458 2.106c-.377.48-1.033 1.152-.236 1.809M99.337 83.719s1.911.151 2.509-.254",stroke:"#DB836E","stroke-width":"1.145","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M87.782 115.821l15.73-3.012M100.165 115.821l10.04-2.008",stroke:"#E4EBF7","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M66.508 86.763s-1.598 8.83-6.697 14.078",stroke:"#E4EBF7","stroke-width":"1.114","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M128.31 87.934s3.013 4.121 4.06 11.785",stroke:"#E4EBF7","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M64.09 84.816s-6.03 9.912-13.607 9.903",stroke:"#DB836E","stroke-width":".795","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M112.366 65.909l-.142 5.32s5.993 4.472 11.945 9.202c4.482 3.562 8.888 7.455 10.985 8.662 4.804 2.766 8.9 3.355 11.076 1.808 4.071-2.894 4.373-9.878-8.136-15.263-4.271-1.838-16.144-6.36-25.728-9.73",fill:"#FFC6A0"},null),createVNode("path",{d:"M130.532 85.488s4.588 5.757 11.619 6.214",stroke:"#DB836E","stroke-width":".75","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M121.708 105.73s-.393 8.564-1.34 13.612",stroke:"#E4EBF7","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M115.784 161.512s-3.57-1.488-2.678-7.14",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M101.52 290.246s4.326 2.057 7.408 1.03c2.842-.948 4.564.673 7.132 1.186 2.57.514 6.925 1.108 11.772-1.269-.104-5.551-6.939-4.01-12.048-6.763-2.582-1.39-3.812-4.757-3.625-8.863h-9.471s-1.402 10.596-1.169 14.68",fill:"#CBD1D1"},null),createVNode("path",{d:"M101.496 290.073s2.447 1.281 6.809.658c3.081-.44 3.74.485 7.479 1.039 3.739.554 10.802-.07 11.91-.9.415 1.108-.347 2.077-.347 2.077s-1.523.608-4.847.831c-2.045.137-5.843.293-7.663-.507-1.8-1.385-5.286-1.917-5.77-.243-3.947.958-7.41-.288-7.41-.288l-.16-2.667z",fill:"#2B0849"},null),createVNode("path",{d:"M108.824 276.19h3.116s-.103 6.751 4.57 8.62c-4.673.624-8.62-2.32-7.686-8.62",fill:"#A4AABA"},null),createVNode("path",{d:"M57.65 272.52s-2.122 7.47-4.518 12.396c-1.811 3.724-4.255 7.548 5.505 7.548 6.698 0 9.02-.483 7.479-6.648-1.541-6.164.268-13.296.268-13.296H57.65z",fill:"#CBD1D1"},null),createVNode("path",{d:"M51.54 290.04s2.111 1.178 6.682 1.178c6.128 0 8.31-1.662 8.31-1.662s.605 1.122-.624 2.18c-1 .862-3.624 1.603-7.444 1.559-4.177-.049-5.876-.57-6.786-1.177-.831-.554-.692-1.593-.138-2.078",fill:"#2B0849"},null),createVNode("path",{d:"M58.533 274.438s.034 1.529-.315 2.95c-.352 1.431-1.087 3.127-1.139 4.17-.058 1.16 4.57 1.592 5.194.035.623-1.559 1.303-6.475 1.927-7.306.622-.831-4.94-2.135-5.667.15",fill:"#A4AABA"},null),createVNode("path",{d:"M100.885 277.015l13.306.092s1.291-54.228 1.843-64.056c.552-9.828 3.756-43.13.997-62.788l-12.48-.64-22.725.776s-.433 3.944-1.19 9.921c-.062.493-.677.838-.744 1.358-.075.582.42 1.347.318 1.956-2.35 14.003-6.343 32.926-8.697 46.425-.116.663-1.227 1.004-1.45 2.677-.04.3.21 1.516.112 1.785-6.836 18.643-10.89 47.584-14.2 61.551l14.528-.014s2.185-8.524 4.008-16.878c2.796-12.817 22.987-84.553 22.987-84.553l3-.517 1.037 46.1s-.223 1.228.334 2.008c.558.782-.556 1.117-.39 2.233l.39 1.784s-.446 7.14-.892 11.826c-.446 4.685-.092 38.954-.092 38.954",fill:"#7BB2F9"},null),createVNode("path",{d:"M77.438 220.434c1.146.094 4.016-2.008 6.916-4.91M107.55 223.931s2.758-1.103 6.069-3.862",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M108.459 220.905s2.759-1.104 6.07-3.863",stroke:"#648BD8","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M76.099 223.557s2.608-.587 6.47-3.346M87.33 150.82c-.27 3.088.297 8.478-4.315 9.073M104.829 149.075s.11 13.936-1.286 14.983c-2.207 1.655-2.975 1.934-2.975 1.934M101.014 149.63s.035 12.81-1.19 24.245M94.93 174.965s7.174-1.655 9.38-1.655M75.671 204.754c-.316 1.55-.64 3.067-.973 4.535 0 0-1.45 1.822-1.003 3.756.446 1.934-.943 2.034-4.96 15.273-1.686 5.559-4.464 18.49-6.313 27.447-.078.38-4.018 18.06-4.093 18.423M77.043 196.743a313.269 313.269 0 0 1-.877 4.729M83.908 151.414l-1.19 10.413s-1.091.148-.496 2.23c.111 1.34-2.66 15.692-5.153 30.267M57.58 272.94h13.238",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null),createVNode("path",{d:"M117.377 147.423s-16.955-3.087-35.7.199c.157 2.501-.002 4.128-.002 4.128s14.607-2.802 35.476-.31c.251-2.342.226-4.017.226-4.017",fill:"#192064"},null),createVNode("path",{d:"M107.511 150.353l.004-4.885a.807.807 0 0 0-.774-.81c-2.428-.092-5.04-.108-7.795-.014a.814.814 0 0 0-.784.81l-.003 4.88c0 .456.371.82.827.808a140.76 140.76 0 0 1 7.688.017.81.81 0 0 0 .837-.806",fill:"#FFF"},null),createVNode("path",{d:"M106.402 149.426l.002-3.06a.64.64 0 0 0-.616-.643 94.135 94.135 0 0 0-5.834-.009.647.647 0 0 0-.626.643l-.001 3.056c0 .36.291.648.651.64 1.78-.04 3.708-.041 5.762.012.36.009.662-.279.662-.64",fill:"#192064"},null),createVNode("path",{d:"M101.485 273.933h12.272M102.652 269.075c.006 3.368.04 5.759.11 6.47M102.667 263.125c-.009 1.53-.015 2.98-.016 4.313M102.204 174.024l.893 44.402s.669 1.561-.224 2.677c-.892 1.116 2.455.67.893 2.231-1.562 1.562.893 1.116 0 3.347-.592 1.48-.988 20.987-1.09 34.956",stroke:"#648BD8","stroke-width":"1.051","stroke-linecap":"round","stroke-linejoin":"round"},null)])]),unauthorized=Unauthorized,genBaseStyle$6=$n=>{const{componentCls:Cn,lineHeightHeading3:_n,iconCls:Pn,padding:In,paddingXL:Nn,paddingXS:Rn,paddingLG:Dn,marginXS:Ln,lineHeight:Fn}=$n;return{[Cn]:{padding:`${Dn*2}px ${Nn}px`,"&-rtl":{direction:"rtl"}},[`${Cn} ${Cn}-image`]:{width:$n.imageWidth,height:$n.imageHeight,margin:"auto"},[`${Cn} ${Cn}-icon`]:{marginBottom:Dn,textAlign:"center",[`& > ${Pn}`]:{fontSize:$n.resultIconFontSize}},[`${Cn} ${Cn}-title`]:{color:$n.colorTextHeading,fontSize:$n.resultTitleFontSize,lineHeight:_n,marginBlock:Ln,textAlign:"center"},[`${Cn} ${Cn}-subtitle`]:{color:$n.colorTextDescription,fontSize:$n.resultSubtitleFontSize,lineHeight:Fn,textAlign:"center"},[`${Cn} ${Cn}-content`]:{marginTop:Dn,padding:`${Dn}px ${In*2.5}px`,backgroundColor:$n.colorFillAlter},[`${Cn} ${Cn}-extra`]:{margin:$n.resultExtraMargin,textAlign:"center","& > *":{marginInlineEnd:Rn,"&:last-child":{marginInlineEnd:0}}}}},genStatusIconStyle=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[`${Cn}-success ${Cn}-icon > ${_n}`]:{color:$n.resultSuccessIconColor},[`${Cn}-error ${Cn}-icon > ${_n}`]:{color:$n.resultErrorIconColor},[`${Cn}-info ${Cn}-icon > ${_n}`]:{color:$n.resultInfoIconColor},[`${Cn}-warning ${Cn}-icon > ${_n}`]:{color:$n.resultWarningIconColor}}},genResultStyle=$n=>[genBaseStyle$6($n),genStatusIconStyle($n)],getStyle=$n=>genResultStyle($n),useStyle$e=genComponentStyleHook("Result",$n=>{const{paddingLG:Cn,fontSizeHeading3:_n}=$n,Pn=$n.fontSize,In=`${Cn}px 0 0 0`,Nn=$n.colorInfo,Rn=$n.colorError,Dn=$n.colorSuccess,Ln=$n.colorWarning,Fn=merge$1($n,{resultTitleFontSize:_n,resultSubtitleFontSize:Pn,resultIconFontSize:_n*3,resultExtraMargin:In,resultInfoIconColor:Nn,resultErrorIconColor:Rn,resultSuccessIconColor:Dn,resultWarningIconColor:Ln});return[getStyle(Fn)]},{imageWidth:250,imageHeight:295}),IconMap={success:CheckCircleFilled$1,error:CloseCircleFilled$1,info:ExclamationCircleFilled$1,warning:WarningFilled$1},ExceptionMap={404:noFound,500:serverError,403:unauthorized},ExceptionStatus=Object.keys(ExceptionMap),resultProps=()=>({prefixCls:String,icon:PropTypes.any,status:{type:[Number,String],default:"info"},title:PropTypes.any,subTitle:PropTypes.any,extra:PropTypes.any}),renderIcon=($n,Cn)=>{let{status:_n,icon:Pn}=Cn;if(ExceptionStatus.includes(`${_n}`)){const Rn=ExceptionMap[_n];return createVNode("div",{class:`${$n}-icon ${$n}-image`},[createVNode(Rn,null,null)])}const In=IconMap[_n],Nn=Pn||createVNode(In,null,null);return createVNode("div",{class:`${$n}-icon`},[Nn])},renderExtra=($n,Cn)=>Cn&&createVNode("div",{class:`${$n}-extra`},[Cn]),Result=defineComponent({compatConfig:{MODE:3},name:"AResult",inheritAttrs:!1,props:resultProps(),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("result",$n),[Rn,Dn]=useStyle$e(In),Ln=computed(()=>classNames(In.value,Dn.value,`${In.value}-${$n.status}`,{[`${In.value}-rtl`]:Nn.value==="rtl"}));return()=>{var Fn,Bn,Hn,zn,Wn,Yn,Gn,Go;const Xn=(Fn=$n.title)!==null&&Fn!==void 0?Fn:(Bn=_n.title)===null||Bn===void 0?void 0:Bn.call(_n),Yo=(Hn=$n.subTitle)!==null&&Hn!==void 0?Hn:(zn=_n.subTitle)===null||zn===void 0?void 0:zn.call(_n),qo=(Wn=$n.icon)!==null&&Wn!==void 0?Wn:(Yn=_n.icon)===null||Yn===void 0?void 0:Yn.call(_n),Jo=(Gn=$n.extra)!==null&&Gn!==void 0?Gn:(Go=_n.extra)===null||Go===void 0?void 0:Go.call(_n),Zo=In.value;return Rn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:[Ln.value,Pn.class]}),[renderIcon(Zo,{status:$n.status,icon:qo}),createVNode("div",{class:`${Zo}-title`},[Xn]),Yo&&createVNode("div",{class:`${Zo}-subtitle`},[Yo]),renderExtra(Zo,Jo),_n.default&&createVNode("div",{class:`${Zo}-content`},[_n.default()])]))}}});Result.PRESENTED_IMAGE_403=ExceptionMap[403];Result.PRESENTED_IMAGE_404=ExceptionMap[404];Result.PRESENTED_IMAGE_500=ExceptionMap[500];Result.install=function($n){return $n.component(Result.name,Result),$n};const Result$1=Result,index$d=withInstall(Row$2),Track=($n,Cn)=>{let{attrs:_n}=Cn;const{included:Pn,vertical:In,style:Nn,class:Rn}=_n;let{length:Dn,offset:Ln,reverse:Fn}=_n;Dn<0&&(Fn=!Fn,Dn=Math.abs(Dn),Ln=100-Ln);const Bn=In?{[Fn?"top":"bottom"]:`${Ln}%`,[Fn?"bottom":"top"]:"auto",height:`${Dn}%`}:{[Fn?"right":"left"]:`${Ln}%`,[Fn?"left":"right"]:"auto",width:`${Dn}%`},Hn=_extends$1(_extends$1({},Nn),Bn);return Pn?createVNode("div",{class:Rn,style:Hn},null):null};Track.inheritAttrs=!1;const Track$1=Track,calcPoints=($n,Cn,_n,Pn,In,Nn)=>{warning$3();const Rn=Object.keys(Cn).map(parseFloat).sort((Dn,Ln)=>Dn-Ln);if(_n&&Pn)for(let Dn=In;Dn<=Nn;Dn+=Pn)Rn.indexOf(Dn)===-1&&Rn.push(Dn);return Rn},Steps$2=($n,Cn)=>{let{attrs:_n}=Cn;const{prefixCls:Pn,vertical:In,reverse:Nn,marks:Rn,dots:Dn,step:Ln,included:Fn,lowerBound:Bn,upperBound:Hn,max:zn,min:Wn,dotStyle:Yn,activeDotStyle:Gn}=_n,Go=zn-Wn,Xn=calcPoints(In,Rn,Dn,Ln,Wn,zn).map(Yo=>{const qo=`${Math.abs(Yo-Wn)/Go*100}%`,Jo=!Fn&&Yo===Hn||Fn&&Yo<=Hn&&Yo>=Bn;let Zo=In?_extends$1(_extends$1({},Yn),{[Nn?"top":"bottom"]:qo}):_extends$1(_extends$1({},Yn),{[Nn?"right":"left"]:qo});Jo&&(Zo=_extends$1(_extends$1({},Zo),Gn));const rr=classNames({[`${Pn}-dot`]:!0,[`${Pn}-dot-active`]:Jo,[`${Pn}-dot-reverse`]:Nn});return createVNode("span",{class:rr,style:Zo,key:Yo},null)});return createVNode("div",{class:`${Pn}-step`},[Xn])};Steps$2.inheritAttrs=!1;const Steps$3=Steps$2,Marks=($n,Cn)=>{let{attrs:_n,slots:Pn}=Cn;const{class:In,vertical:Nn,reverse:Rn,marks:Dn,included:Ln,upperBound:Fn,lowerBound:Bn,max:Hn,min:zn,onClickLabel:Wn}=_n,Yn=Object.keys(Dn),Gn=Pn.mark,Go=Hn-zn,Xn=Yn.map(parseFloat).sort((Yo,qo)=>Yo-qo).map(Yo=>{const qo=typeof Dn[Yo]=="function"?Dn[Yo]():Dn[Yo],Jo=typeof qo=="object"&&!isValidElement(qo);let Zo=Jo?qo.label:qo;if(!Zo&&Zo!==0)return null;Gn&&(Zo=Gn({point:Yo,label:Zo}));const rr=!Ln&&Yo===Fn||Ln&&Yo<=Fn&&Yo>=Bn,nr=classNames({[`${In}-text`]:!0,[`${In}-text-active`]:rr}),ta={marginBottom:"-50%",[Rn?"top":"bottom"]:`${(Yo-zn)/Go*100}%`},oa={transform:`translateX(${Rn?"50%":"-50%"})`,msTransform:`translateX(${Rn?"50%":"-50%"})`,[Rn?"right":"left"]:`${(Yo-zn)/Go*100}%`},ra=Nn?ta:oa,ea=Jo?_extends$1(_extends$1({},ra),qo.style):ra,la={[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]:ua=>Wn(ua,Yo)};return createVNode("span",_objectSpread2$1({class:nr,style:ea,key:Yo,onMousedown:ua=>Wn(ua,Yo)},la),[Zo])});return createVNode("div",{class:In},[Xn])};Marks.inheritAttrs=!1;const Marks$1=Marks,VcHandle=defineComponent({compatConfig:{MODE:3},name:"Handle",inheritAttrs:!1,props:{prefixCls:String,vertical:{type:Boolean,default:void 0},offset:Number,disabled:{type:Boolean,default:void 0},min:Number,max:Number,value:Number,tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),reverse:{type:Boolean,default:void 0},ariaLabel:String,ariaLabelledBy:String,ariaValueTextFormatter:Function,onMouseenter:{type:Function},onMouseleave:{type:Function},onMousedown:{type:Function}},setup($n,Cn){let{attrs:_n,emit:Pn,expose:In}=Cn;const Nn=shallowRef(!1),Rn=shallowRef(),Dn=()=>{document.activeElement===Rn.value&&(Nn.value=!0)},Ln=Go=>{Nn.value=!1,Pn("blur",Go)},Fn=()=>{Nn.value=!1},Bn=()=>{var Go;(Go=Rn.value)===null||Go===void 0||Go.focus()},Hn=()=>{var Go;(Go=Rn.value)===null||Go===void 0||Go.blur()},zn=()=>{Nn.value=!0,Bn()},Wn=Go=>{Go.preventDefault(),Bn(),Pn("mousedown",Go)};In({focus:Bn,blur:Hn,clickFocus:zn,ref:Rn});let Yn=null;onMounted(()=>{Yn=addEventListenerWrap(document,"mouseup",Dn)}),onBeforeUnmount(()=>{Yn==null||Yn.remove()});const Gn=computed(()=>{const{vertical:Go,offset:Xn,reverse:Yo}=$n;return Go?{[Yo?"top":"bottom"]:`${Xn}%`,[Yo?"bottom":"top"]:"auto",transform:Yo?null:"translateY(+50%)"}:{[Yo?"right":"left"]:`${Xn}%`,[Yo?"left":"right"]:"auto",transform:`translateX(${Yo?"+":"-"}50%)`}});return()=>{const{prefixCls:Go,disabled:Xn,min:Yo,max:qo,value:Jo,tabindex:Zo,ariaLabel:rr,ariaLabelledBy:nr,ariaValueTextFormatter:ta,onMouseenter:oa,onMouseleave:ra}=$n,ea=classNames(_n.class,{[`${Go}-handle-click-focused`]:Nn.value}),la={"aria-valuemin":Yo,"aria-valuemax":qo,"aria-valuenow":Jo,"aria-disabled":!!Xn},ua=[_n.style,Gn.value];let ga=Zo||0;(Xn||Zo===null)&&(ga=null);let aa;ta&&(aa=ta(Jo));const ca=_extends$1(_extends$1(_extends$1(_extends$1({},_n),{role:"slider",tabindex:ga}),la),{class:ea,onBlur:Ln,onKeydown:Fn,onMousedown:Wn,onMouseenter:oa,onMouseleave:ra,ref:Rn,style:ua});return createVNode("div",_objectSpread2$1(_objectSpread2$1({},ca),{},{"aria-label":rr,"aria-labelledby":nr,"aria-valuetext":aa}),null)}}});function isEventFromHandle($n,Cn){try{return Object.keys(Cn).some(_n=>$n.target===Cn[_n].ref)}catch{return!1}}function isValueOutOfRange($n,Cn){let{min:_n,max:Pn}=Cn;return $n<_n||$n>Pn}function isNotTouchEvent($n){return $n.touches.length>1||$n.type.toLowerCase()==="touchend"&&$n.touches.length>0}function getClosestPoint($n,Cn){let{marks:_n,step:Pn,min:In,max:Nn}=Cn;const Rn=Object.keys(_n).map(parseFloat);if(Pn!==null){const Ln=Math.pow(10,getPrecision(Pn)),Fn=Math.floor((Nn*Ln-In*Ln)/(Pn*Ln)),Bn=Math.min(($n-In)/Pn,Fn),Hn=Math.round(Bn)*Pn+In;Rn.push(Hn)}const Dn=Rn.map(Ln=>Math.abs($n-Ln));return Rn[Dn.indexOf(Math.min(...Dn))]}function getPrecision($n){const Cn=$n.toString();let _n=0;return Cn.indexOf(".")>=0&&(_n=Cn.length-Cn.indexOf(".")-1),_n}function getMousePosition($n,Cn){let _n=1;return window.visualViewport&&(_n=+(window.visualViewport.width/document.body.getBoundingClientRect().width).toFixed(2)),($n?Cn.clientY:Cn.pageX)/_n}function getTouchPosition($n,Cn){let _n=1;return window.visualViewport&&(_n=+(window.visualViewport.width/document.body.getBoundingClientRect().width).toFixed(2)),($n?Cn.touches[0].clientY:Cn.touches[0].pageX)/_n}function getHandleCenterPosition($n,Cn){const _n=Cn.getBoundingClientRect();return $n?_n.top+_n.height*.5:window.pageXOffset+_n.left+_n.width*.5}function ensureValueInRange($n,Cn){let{max:_n,min:Pn}=Cn;return $n<=Pn?Pn:$n>=_n?_n:$n}function ensureValuePrecision($n,Cn){const{step:_n}=Cn,Pn=isFinite(getClosestPoint($n,Cn))?getClosestPoint($n,Cn):0;return _n===null?Pn:parseFloat(Pn.toFixed(getPrecision(_n)))}function pauseEvent($n){$n.stopPropagation(),$n.preventDefault()}function calculateNextValue($n,Cn,_n){const Pn={increase:(Rn,Dn)=>Rn+Dn,decrease:(Rn,Dn)=>Rn-Dn},In=Pn[$n](Object.keys(_n.marks).indexOf(JSON.stringify(Cn)),1),Nn=Object.keys(_n.marks)[In];return _n.step?Pn[$n](Cn,_n.step):Object.keys(_n.marks).length&&_n.marks[Nn]?_n.marks[Nn]:Cn}function getKeyboardValueMutator($n,Cn,_n){const Pn="increase",In="decrease";let Nn=Pn;switch($n.keyCode){case KeyCode$1.UP:Nn=Cn&&_n?In:Pn;break;case KeyCode$1.RIGHT:Nn=!Cn&&_n?In:Pn;break;case KeyCode$1.DOWN:Nn=Cn&&_n?Pn:In;break;case KeyCode$1.LEFT:Nn=!Cn&&_n?Pn:In;break;case KeyCode$1.END:return(Rn,Dn)=>Dn.max;case KeyCode$1.HOME:return(Rn,Dn)=>Dn.min;case KeyCode$1.PAGE_UP:return(Rn,Dn)=>Rn+Dn.step*2;case KeyCode$1.PAGE_DOWN:return(Rn,Dn)=>Rn-Dn.step*2;default:return}return(Rn,Dn)=>calculateNextValue(Nn,Rn,Dn)}var __rest$l=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{this.document=this.sliderRef&&this.sliderRef.ownerDocument;const{autofocus:_n,disabled:Pn}=this;_n&&!Pn&&this.focus()})},beforeUnmount(){this.$nextTick(()=>{this.removeDocumentEvents()})},methods:{defaultHandle(_n){var{index:Pn,directives:In,className:Nn,style:Rn}=_n,Dn=__rest$l(_n,["index","directives","className","style"]);if(delete Dn.dragging,Dn.value===null)return null;const Ln=_extends$1(_extends$1({},Dn),{class:Nn,style:Rn,key:Pn});return createVNode(VcHandle,Ln,null)},onDown(_n,Pn){let In=Pn;const{draggableTrack:Nn,vertical:Rn}=this.$props,{bounds:Dn}=this.$data,Ln=Nn&&this.positionGetValue?this.positionGetValue(In)||[]:[],Fn=isEventFromHandle(_n,this.handlesRefs);if(this.dragTrack=Nn&&Dn.length>=2&&!Fn&&!Ln.map((Bn,Hn)=>{const zn=Hn?!0:Bn>=Dn[Hn];return Hn===Ln.length-1?Bn<=Dn[Hn]:zn}).some(Bn=>!Bn),this.dragTrack)this.dragOffset=In,this.startBounds=[...Dn];else{if(!Fn)this.dragOffset=0;else{const Bn=getHandleCenterPosition(Rn,_n.target);this.dragOffset=In-Bn,In=Bn}this.onStart(In)}},onMouseDown(_n){if(_n.button!==0)return;this.removeDocumentEvents();const Pn=this.$props.vertical,In=getMousePosition(Pn,_n);this.onDown(_n,In),this.addDocumentMouseEvents()},onTouchStart(_n){if(isNotTouchEvent(_n))return;const Pn=this.vertical,In=getTouchPosition(Pn,_n);this.onDown(_n,In),this.addDocumentTouchEvents(),pauseEvent(_n)},onFocus(_n){const{vertical:Pn}=this;if(isEventFromHandle(_n,this.handlesRefs)&&!this.dragTrack){const In=getHandleCenterPosition(Pn,_n.target);this.dragOffset=0,this.onStart(In),pauseEvent(_n),this.$emit("focus",_n)}},onBlur(_n){this.dragTrack||this.onEnd(),this.$emit("blur",_n)},onMouseUp(){this.handlesRefs[this.prevMovedHandleIndex]&&this.handlesRefs[this.prevMovedHandleIndex].clickFocus()},onMouseMove(_n){if(!this.sliderRef){this.onEnd();return}const Pn=getMousePosition(this.vertical,_n);this.onMove(_n,Pn-this.dragOffset,this.dragTrack,this.startBounds)},onTouchMove(_n){if(isNotTouchEvent(_n)||!this.sliderRef){this.onEnd();return}const Pn=getTouchPosition(this.vertical,_n);this.onMove(_n,Pn-this.dragOffset,this.dragTrack,this.startBounds)},onKeyDown(_n){this.sliderRef&&isEventFromHandle(_n,this.handlesRefs)&&this.onKeyboard(_n)},onClickMarkLabel(_n,Pn){_n.stopPropagation(),this.onChange({sValue:Pn}),this.setState({sValue:Pn},()=>this.onEnd(!0))},getSliderStart(){const _n=this.sliderRef,{vertical:Pn,reverse:In}=this,Nn=_n.getBoundingClientRect();return Pn?In?Nn.bottom:Nn.top:window.pageXOffset+(In?Nn.right:Nn.left)},getSliderLength(){const _n=this.sliderRef;if(!_n)return 0;const Pn=_n.getBoundingClientRect();return this.vertical?Pn.height:Pn.width},addDocumentTouchEvents(){this.onTouchMoveListener=addEventListenerWrap(this.document,"touchmove",this.onTouchMove),this.onTouchUpListener=addEventListenerWrap(this.document,"touchend",this.onEnd)},addDocumentMouseEvents(){this.onMouseMoveListener=addEventListenerWrap(this.document,"mousemove",this.onMouseMove),this.onMouseUpListener=addEventListenerWrap(this.document,"mouseup",this.onEnd)},removeDocumentEvents(){this.onTouchMoveListener&&this.onTouchMoveListener.remove(),this.onTouchUpListener&&this.onTouchUpListener.remove(),this.onMouseMoveListener&&this.onMouseMoveListener.remove(),this.onMouseUpListener&&this.onMouseUpListener.remove()},focus(){var _n;this.$props.disabled||(_n=this.handlesRefs[0])===null||_n===void 0||_n.focus()},blur(){this.$props.disabled||Object.keys(this.handlesRefs).forEach(_n=>{var Pn,In;(In=(Pn=this.handlesRefs[_n])===null||Pn===void 0?void 0:Pn.blur)===null||In===void 0||In.call(Pn)})},calcValue(_n){const{vertical:Pn,min:In,max:Nn}=this,Rn=Math.abs(Math.max(_n,0)/this.getSliderLength());return Pn?(1-Rn)*(Nn-In)+In:Rn*(Nn-In)+In},calcValueByPos(_n){const In=(this.reverse?-1:1)*(_n-this.getSliderStart());return this.trimAlignValue(this.calcValue(In))},calcOffset(_n){const{min:Pn,max:In}=this,Nn=(_n-Pn)/(In-Pn);return Math.max(0,Nn*100)},saveSlider(_n){this.sliderRef=_n},saveHandle(_n,Pn){this.handlesRefs[_n]=Pn}},render(){const{prefixCls:_n,marks:Pn,dots:In,step:Nn,included:Rn,disabled:Dn,vertical:Ln,reverse:Fn,min:Bn,max:Hn,maximumTrackStyle:zn,railStyle:Wn,dotStyle:Yn,activeDotStyle:Gn,id:Go}=this,{class:Xn,style:Yo}=this.$attrs,{tracks:qo,handles:Jo}=this.renderSlider(),Zo=classNames(_n,Xn,{[`${_n}-with-marks`]:Object.keys(Pn).length,[`${_n}-disabled`]:Dn,[`${_n}-vertical`]:Ln,[`${_n}-horizontal`]:!Ln}),rr={vertical:Ln,marks:Pn,included:Rn,lowerBound:this.getLowerBound(),upperBound:this.getUpperBound(),max:Hn,min:Bn,reverse:Fn,class:`${_n}-mark`,onClickLabel:Dn?noop$6:this.onClickMarkLabel},nr={[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]:Dn?noop$6:this.onTouchStart};return createVNode("div",_objectSpread2$1(_objectSpread2$1({id:Go,ref:this.saveSlider,tabindex:"-1",class:Zo},nr),{},{onMousedown:Dn?noop$6:this.onMouseDown,onMouseup:Dn?noop$6:this.onMouseUp,onKeydown:Dn?noop$6:this.onKeyDown,onFocus:Dn?noop$6:this.onFocus,onBlur:Dn?noop$6:this.onBlur,style:Yo}),[createVNode("div",{class:`${_n}-rail`,style:_extends$1(_extends$1({},zn),Wn)},null),qo,createVNode(Steps$3,{prefixCls:_n,vertical:Ln,reverse:Fn,marks:Pn,dots:In,step:Nn,included:Rn,lowerBound:this.getLowerBound(),upperBound:this.getUpperBound(),max:Hn,min:Bn,dotStyle:Yn,activeDotStyle:Gn},null),Jo,createVNode(Marks$1,rr,{mark:this.$slots.mark}),getSlot(this)])}})}const Slider$1=defineComponent({compatConfig:{MODE:3},name:"Slider",mixins:[BaseMixin],inheritAttrs:!1,props:{defaultValue:Number,value:Number,disabled:{type:Boolean,default:void 0},autofocus:{type:Boolean,default:void 0},tabindex:PropTypes.oneOfType([PropTypes.number,PropTypes.string]),reverse:{type:Boolean,default:void 0},min:Number,max:Number,ariaLabelForHandle:String,ariaLabelledByForHandle:String,ariaValueTextFormatterForHandle:String,startPoint:Number},emits:["beforeChange","afterChange","change"],data(){const $n=this.defaultValue!==void 0?this.defaultValue:this.min,Cn=this.value!==void 0?this.value:$n;return{sValue:this.trimAlignValue(Cn),dragging:!1}},watch:{value:{handler($n){this.setChangeValue($n)},deep:!0},min(){const{sValue:$n}=this;this.setChangeValue($n)},max(){const{sValue:$n}=this;this.setChangeValue($n)}},methods:{setChangeValue($n){const Cn=$n!==void 0?$n:this.sValue,_n=this.trimAlignValue(Cn,this.$props);_n!==this.sValue&&(this.setState({sValue:_n}),isValueOutOfRange(Cn,this.$props)&&this.$emit("change",_n))},onChange($n){const Cn=!hasProp(this,"value"),_n=$n.sValue>this.max?_extends$1(_extends$1({},$n),{sValue:this.max}):$n;Cn&&this.setState(_n);const Pn=_n.sValue;this.$emit("change",Pn)},onStart($n){this.setState({dragging:!0});const{sValue:Cn}=this;this.$emit("beforeChange",Cn);const _n=this.calcValueByPos($n);this.startValue=_n,this.startPosition=$n,_n!==Cn&&(this.prevMovedHandleIndex=0,this.onChange({sValue:_n}))},onEnd($n){const{dragging:Cn}=this;this.removeDocumentEvents(),(Cn||$n)&&this.$emit("afterChange",this.sValue),this.setState({dragging:!1})},onMove($n,Cn){pauseEvent($n);const{sValue:_n}=this,Pn=this.calcValueByPos(Cn);Pn!==_n&&this.onChange({sValue:Pn})},onKeyboard($n){const{reverse:Cn,vertical:_n}=this.$props,Pn=getKeyboardValueMutator($n,_n,Cn);if(Pn){pauseEvent($n);const{sValue:In}=this,Nn=Pn(In,this.$props),Rn=this.trimAlignValue(Nn);if(Rn===In)return;this.onChange({sValue:Rn}),this.$emit("afterChange",Rn),this.onEnd()}},getLowerBound(){const $n=this.$props.startPoint||this.$props.min;return this.$data.sValue>$n?$n:this.$data.sValue},getUpperBound(){return this.$data.sValue1&&arguments[1]!==void 0?arguments[1]:{};if($n===null)return null;const _n=_extends$1(_extends$1({},this.$props),Cn),Pn=ensureValueInRange($n,_n);return ensureValuePrecision(Pn,_n)},getTrack($n){let{prefixCls:Cn,reverse:_n,vertical:Pn,included:In,minimumTrackStyle:Nn,mergedTrackStyle:Rn,length:Dn,offset:Ln}=$n;return createVNode(Track$1,{class:`${Cn}-track`,vertical:Pn,included:In,offset:Ln,reverse:_n,length:Dn,style:_extends$1(_extends$1({},Nn),Rn)},null)},renderSlider(){const{prefixCls:$n,vertical:Cn,included:_n,disabled:Pn,minimumTrackStyle:In,trackStyle:Nn,handleStyle:Rn,tabindex:Dn,ariaLabelForHandle:Ln,ariaLabelledByForHandle:Fn,ariaValueTextFormatterForHandle:Bn,min:Hn,max:zn,startPoint:Wn,reverse:Yn,handle:Gn,defaultHandle:Go}=this,Xn=Gn||Go,{sValue:Yo,dragging:qo}=this,Jo=this.calcOffset(Yo),Zo=Xn({class:`${$n}-handle`,prefixCls:$n,vertical:Cn,offset:Jo,value:Yo,dragging:qo,disabled:Pn,min:Hn,max:zn,reverse:Yn,index:0,tabindex:Dn,ariaLabel:Ln,ariaLabelledBy:Fn,ariaValueTextFormatter:Bn,style:Rn[0]||Rn,ref:ta=>this.saveHandle(0,ta),onFocus:this.onFocus,onBlur:this.onBlur}),rr=Wn!==void 0?this.calcOffset(Wn):0,nr=Nn[0]||Nn;return{tracks:this.getTrack({prefixCls:$n,reverse:Yn,vertical:Cn,included:_n,offset:rr,minimumTrackStyle:In,mergedTrackStyle:nr,length:Jo-rr}),handles:Zo}}}}),VcSlider=createSlider(Slider$1),trimAlignValue=$n=>{let{value:Cn,handle:_n,bounds:Pn,props:In}=$n;const{allowCross:Nn,pushable:Rn}=In,Dn=Number(Rn),Ln=ensureValueInRange(Cn,In);let Fn=Ln;return!Nn&&_n!=null&&Pn!==void 0&&(_n>0&&Ln<=Pn[_n-1]+Dn&&(Fn=Pn[_n-1]+Dn),_n=Pn[_n+1]-Dn&&(Fn=Pn[_n+1]-Dn)),ensureValuePrecision(Fn,In)},rangeProps={defaultValue:PropTypes.arrayOf(PropTypes.number),value:PropTypes.arrayOf(PropTypes.number),count:Number,pushable:withUndefined(PropTypes.oneOfType([PropTypes.looseBool,PropTypes.number])),allowCross:{type:Boolean,default:void 0},disabled:{type:Boolean,default:void 0},reverse:{type:Boolean,default:void 0},tabindex:PropTypes.arrayOf(PropTypes.number),prefixCls:String,min:Number,max:Number,autofocus:{type:Boolean,default:void 0},ariaLabelGroupForHandles:Array,ariaLabelledByGroupForHandles:Array,ariaValueTextFormatterGroupForHandles:Array,draggableTrack:{type:Boolean,default:void 0}},Range=defineComponent({compatConfig:{MODE:3},name:"Range",mixins:[BaseMixin],inheritAttrs:!1,props:initDefaultProps(rangeProps,{count:1,allowCross:!0,pushable:!1,tabindex:[],draggableTrack:!1,ariaLabelGroupForHandles:[],ariaLabelledByGroupForHandles:[],ariaValueTextFormatterGroupForHandles:[]}),emits:["beforeChange","afterChange","change"],displayName:"Range",data(){const{count:$n,min:Cn,max:_n}=this,Pn=Array(...Array($n+1)).map(()=>Cn),In=hasProp(this,"defaultValue")?this.defaultValue:Pn;let{value:Nn}=this;Nn===void 0&&(Nn=In);const Rn=Nn.map((Ln,Fn)=>trimAlignValue({value:Ln,handle:Fn,props:this.$props}));return{sHandle:null,recent:Rn[0]===_n?0:Rn.length-1,bounds:Rn}},watch:{value:{handler($n){const{bounds:Cn}=this;this.setChangeValue($n||Cn)},deep:!0},min(){const{value:$n}=this;this.setChangeValue($n||this.bounds)},max(){const{value:$n}=this;this.setChangeValue($n||this.bounds)}},methods:{setChangeValue($n){const{bounds:Cn}=this;let _n=$n.map((Pn,In)=>trimAlignValue({value:Pn,handle:In,bounds:Cn,props:this.$props}));if(Cn.length===_n.length){if(_n.every((Pn,In)=>Pn===Cn[In]))return null}else _n=$n.map((Pn,In)=>trimAlignValue({value:Pn,handle:In,props:this.$props}));if(this.setState({bounds:_n}),$n.some(Pn=>isValueOutOfRange(Pn,this.$props))){const Pn=$n.map(In=>ensureValueInRange(In,this.$props));this.$emit("change",Pn)}},onChange($n){if(!hasProp(this,"value"))this.setState($n);else{const In={};["sHandle","recent"].forEach(Nn=>{$n[Nn]!==void 0&&(In[Nn]=$n[Nn])}),Object.keys(In).length&&this.setState(In)}const Pn=_extends$1(_extends$1({},this.$data),$n).bounds;this.$emit("change",Pn)},positionGetValue($n){const Cn=this.getValue(),_n=this.calcValueByPos($n),Pn=this.getClosestBound(_n),In=this.getBoundNeedMoving(_n,Pn),Nn=Cn[In];if(_n===Nn)return null;const Rn=[...Cn];return Rn[In]=_n,Rn},onStart($n){const{bounds:Cn}=this;this.$emit("beforeChange",Cn);const _n=this.calcValueByPos($n);this.startValue=_n,this.startPosition=$n;const Pn=this.getClosestBound(_n);this.prevMovedHandleIndex=this.getBoundNeedMoving(_n,Pn),this.setState({sHandle:this.prevMovedHandleIndex,recent:this.prevMovedHandleIndex});const In=Cn[this.prevMovedHandleIndex];if(_n===In)return;const Nn=[...Cn];Nn[this.prevMovedHandleIndex]=_n,this.onChange({bounds:Nn})},onEnd($n){const{sHandle:Cn}=this;this.removeDocumentEvents(),Cn||(this.dragTrack=!1),(Cn!==null||$n)&&this.$emit("afterChange",this.bounds),this.setState({sHandle:null})},onMove($n,Cn,_n,Pn){pauseEvent($n);const{$data:In,$props:Nn}=this,Rn=Nn.max||100,Dn=Nn.min||0;if(_n){let zn=Nn.vertical?-Cn:Cn;zn=Nn.reverse?-zn:zn;const Wn=Rn-Math.max(...Pn),Yn=Dn-Math.min(...Pn),Gn=Math.min(Math.max(zn/(this.getSliderLength()/100),Yn),Wn),Go=Pn.map(Xn=>Math.floor(Math.max(Math.min(Xn+Gn,Rn),Dn)));In.bounds.map((Xn,Yo)=>Xn===Go[Yo]).some(Xn=>!Xn)&&this.onChange({bounds:Go});return}const{bounds:Ln,sHandle:Fn}=this,Bn=this.calcValueByPos(Cn),Hn=Ln[Fn];Bn!==Hn&&this.moveTo(Bn)},onKeyboard($n){const{reverse:Cn,vertical:_n}=this.$props,Pn=getKeyboardValueMutator($n,_n,Cn);if(Pn){pauseEvent($n);const{bounds:In,sHandle:Nn}=this,Rn=In[Nn===null?this.recent:Nn],Dn=Pn(Rn,this.$props),Ln=trimAlignValue({value:Dn,handle:Nn,bounds:In,props:this.$props});if(Ln===Rn)return;this.moveTo(Ln,!0)}},getClosestBound($n){const{bounds:Cn}=this;let _n=0;for(let Pn=1;Pn=Cn[Pn]&&(_n=Pn);return Math.abs(Cn[_n+1]-$n)Dn-Ln),this.internalPointsCache={marks:$n,step:Cn,points:Rn}}return this.internalPointsCache.points},moveTo($n,Cn){const _n=[...this.bounds],{sHandle:Pn,recent:In}=this,Nn=Pn===null?In:Pn;_n[Nn]=$n;let Rn=Nn;this.$props.pushable!==!1?this.pushSurroundingHandles(_n,Rn):this.$props.allowCross&&(_n.sort((Dn,Ln)=>Dn-Ln),Rn=_n.indexOf($n)),this.onChange({recent:Rn,sHandle:Rn,bounds:_n}),Cn&&(this.$emit("afterChange",_n),this.setState({},()=>{this.handlesRefs[Rn].focus()}),this.onEnd())},pushSurroundingHandles($n,Cn){const _n=$n[Cn],{pushable:Pn}=this,In=Number(Pn);let Nn=0;if($n[Cn+1]-_n=Pn.length||Nn<0)return!1;const Rn=Cn+_n,Dn=Pn[Nn],{pushable:Ln}=this,Fn=Number(Ln),Bn=_n*($n[Rn]-Dn);return this.pushHandle($n,Rn,_n,Fn-Bn)?($n[Cn]=Dn,!0):!1},trimAlignValue($n){const{sHandle:Cn,bounds:_n}=this;return trimAlignValue({value:$n,handle:Cn,bounds:_n,props:this.$props})},ensureValueNotConflict($n,Cn,_n){let{allowCross:Pn,pushable:In}=_n;const Nn=this.$data||{},{bounds:Rn}=Nn;if($n=$n===void 0?Nn.sHandle:$n,In=Number(In),!Pn&&$n!=null&&Rn!==void 0){if($n>0&&Cn<=Rn[$n-1]+In)return Rn[$n-1]+In;if($n=Rn[$n+1]-In)return Rn[$n+1]-In}return Cn},getTrack($n){let{bounds:Cn,prefixCls:_n,reverse:Pn,vertical:In,included:Nn,offsets:Rn,trackStyle:Dn}=$n;return Cn.slice(0,-1).map((Ln,Fn)=>{const Bn=Fn+1,Hn=classNames({[`${_n}-track`]:!0,[`${_n}-track-${Bn}`]:!0});return createVNode(Track$1,{class:Hn,vertical:In,reverse:Pn,included:Nn,offset:Rn[Bn-1],length:Rn[Bn]-Rn[Bn-1],style:Dn[Fn],key:Bn},null)})},renderSlider(){const{sHandle:$n,bounds:Cn,prefixCls:_n,vertical:Pn,included:In,disabled:Nn,min:Rn,max:Dn,reverse:Ln,handle:Fn,defaultHandle:Bn,trackStyle:Hn,handleStyle:zn,tabindex:Wn,ariaLabelGroupForHandles:Yn,ariaLabelledByGroupForHandles:Gn,ariaValueTextFormatterGroupForHandles:Go}=this,Xn=Fn||Bn,Yo=Cn.map(Zo=>this.calcOffset(Zo)),qo=`${_n}-handle`,Jo=Cn.map((Zo,rr)=>{let nr=Wn[rr]||0;(Nn||Wn[rr]===null)&&(nr=null);const ta=$n===rr;return Xn({class:classNames({[qo]:!0,[`${qo}-${rr+1}`]:!0,[`${qo}-dragging`]:ta}),prefixCls:_n,vertical:Pn,dragging:ta,offset:Yo[rr],value:Zo,index:rr,tabindex:nr,min:Rn,max:Dn,reverse:Ln,disabled:Nn,style:zn[rr],ref:oa=>this.saveHandle(rr,oa),onFocus:this.onFocus,onBlur:this.onBlur,ariaLabel:Yn[rr],ariaLabelledBy:Gn[rr],ariaValueTextFormatter:Go[rr]})});return{tracks:this.getTrack({bounds:Cn,prefixCls:_n,reverse:Ln,vertical:Pn,included:In,offsets:Yo,trackStyle:Hn}),handles:Jo}}}}),VcRange=createSlider(Range),SliderTooltip=defineComponent({compatConfig:{MODE:3},name:"SliderTooltip",inheritAttrs:!1,props:tooltipProps(),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=ref(null),Nn=ref(null);function Rn(){wrapperRaf.cancel(Nn.value),Nn.value=null}function Dn(){Nn.value=wrapperRaf(()=>{var Fn;(Fn=In.value)===null||Fn===void 0||Fn.forcePopupAlign(),Nn.value=null})}const Ln=()=>{Rn(),$n.open&&Dn()};return watch([()=>$n.open,()=>$n.title],()=>{Ln()},{flush:"post",immediate:!0}),onActivated(()=>{Ln()}),onBeforeUnmount(()=>{Rn()}),()=>createVNode(Tooltip,_objectSpread2$1(_objectSpread2$1({ref:In},$n),_n),Pn)}}),genBaseStyle$5=$n=>{const{componentCls:Cn,controlSize:_n,dotSize:Pn,marginFull:In,marginPart:Nn,colorFillContentHover:Rn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",height:_n,margin:`${Nn}px ${In}px`,padding:0,cursor:"pointer",touchAction:"none","&-vertical":{margin:`${In}px ${Nn}px`},[`${Cn}-rail`]:{position:"absolute",backgroundColor:$n.colorFillTertiary,borderRadius:$n.borderRadiusXS,transition:`background-color ${$n.motionDurationMid}`},[`${Cn}-track`]:{position:"absolute",backgroundColor:$n.colorPrimaryBorder,borderRadius:$n.borderRadiusXS,transition:`background-color ${$n.motionDurationMid}`},"&:hover":{[`${Cn}-rail`]:{backgroundColor:$n.colorFillSecondary},[`${Cn}-track`]:{backgroundColor:$n.colorPrimaryBorderHover},[`${Cn}-dot`]:{borderColor:Rn},[`${Cn}-handle::after`]:{boxShadow:`0 0 0 ${$n.handleLineWidth}px ${$n.colorPrimaryBorderHover}`},[`${Cn}-dot-active`]:{borderColor:$n.colorPrimary}},[`${Cn}-handle`]:{position:"absolute",width:$n.handleSize,height:$n.handleSize,outline:"none",[`${Cn}-dragging`]:{zIndex:1},"&::before":{content:'""',position:"absolute",insetInlineStart:-$n.handleLineWidth,insetBlockStart:-$n.handleLineWidth,width:$n.handleSize+$n.handleLineWidth*2,height:$n.handleSize+$n.handleLineWidth*2,backgroundColor:"transparent"},"&::after":{content:'""',position:"absolute",insetBlockStart:0,insetInlineStart:0,width:$n.handleSize,height:$n.handleSize,backgroundColor:$n.colorBgElevated,boxShadow:`0 0 0 ${$n.handleLineWidth}px ${$n.colorPrimaryBorder}`,borderRadius:"50%",cursor:"pointer",transition:` - inset-inline-start ${$n.motionDurationMid}, - inset-block-start ${$n.motionDurationMid}, - width ${$n.motionDurationMid}, - height ${$n.motionDurationMid}, - box-shadow ${$n.motionDurationMid} - `},"&:hover, &:active, &:focus":{"&::before":{insetInlineStart:-(($n.handleSizeHover-$n.handleSize)/2+$n.handleLineWidthHover),insetBlockStart:-(($n.handleSizeHover-$n.handleSize)/2+$n.handleLineWidthHover),width:$n.handleSizeHover+$n.handleLineWidthHover*2,height:$n.handleSizeHover+$n.handleLineWidthHover*2},"&::after":{boxShadow:`0 0 0 ${$n.handleLineWidthHover}px ${$n.colorPrimary}`,width:$n.handleSizeHover,height:$n.handleSizeHover,insetInlineStart:($n.handleSize-$n.handleSizeHover)/2,insetBlockStart:($n.handleSize-$n.handleSizeHover)/2}}},[`${Cn}-mark`]:{position:"absolute",fontSize:$n.fontSize},[`${Cn}-mark-text`]:{position:"absolute",display:"inline-block",color:$n.colorTextDescription,textAlign:"center",wordBreak:"keep-all",cursor:"pointer",userSelect:"none","&-active":{color:$n.colorText}},[`${Cn}-step`]:{position:"absolute",background:"transparent",pointerEvents:"none"},[`${Cn}-dot`]:{position:"absolute",width:Pn,height:Pn,backgroundColor:$n.colorBgElevated,border:`${$n.handleLineWidth}px solid ${$n.colorBorderSecondary}`,borderRadius:"50%",cursor:"pointer",transition:`border-color ${$n.motionDurationSlow}`,"&-active":{borderColor:$n.colorPrimaryBorder}},[`&${Cn}-disabled`]:{cursor:"not-allowed",[`${Cn}-rail`]:{backgroundColor:`${$n.colorFillSecondary} !important`},[`${Cn}-track`]:{backgroundColor:`${$n.colorTextDisabled} !important`},[` - ${Cn}-dot - `]:{backgroundColor:$n.colorBgElevated,borderColor:$n.colorTextDisabled,boxShadow:"none",cursor:"not-allowed"},[`${Cn}-handle::after`]:{backgroundColor:$n.colorBgElevated,cursor:"not-allowed",width:$n.handleSize,height:$n.handleSize,boxShadow:`0 0 0 ${$n.handleLineWidth}px ${new TinyColor($n.colorTextDisabled).onBackground($n.colorBgContainer).toHexString()}`,insetInlineStart:0,insetBlockStart:0},[` - ${Cn}-mark-text, - ${Cn}-dot - `]:{cursor:"not-allowed !important"}}})}},genDirectionStyle=($n,Cn)=>{const{componentCls:_n,railSize:Pn,handleSize:In,dotSize:Nn}=$n,Rn=Cn?"paddingBlock":"paddingInline",Dn=Cn?"width":"height",Ln=Cn?"height":"width",Fn=Cn?"insetBlockStart":"insetInlineStart",Bn=Cn?"top":"insetInlineStart";return{[Rn]:Pn,[Ln]:Pn*3,[`${_n}-rail`]:{[Dn]:"100%",[Ln]:Pn},[`${_n}-track`]:{[Ln]:Pn},[`${_n}-handle`]:{[Fn]:(Pn*3-In)/2},[`${_n}-mark`]:{insetInlineStart:0,top:0,[Bn]:In,[Dn]:"100%"},[`${_n}-step`]:{insetInlineStart:0,top:0,[Bn]:Pn,[Dn]:"100%",[Ln]:Pn},[`${_n}-dot`]:{position:"absolute",[Fn]:(Pn-Nn)/2}}},genHorizontalStyle=$n=>{const{componentCls:Cn,marginPartWithMark:_n}=$n;return{[`${Cn}-horizontal`]:_extends$1(_extends$1({},genDirectionStyle($n,!0)),{[`&${Cn}-with-marks`]:{marginBottom:_n}})}},genVerticalStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-vertical`]:_extends$1(_extends$1({},genDirectionStyle($n,!1)),{height:"100%"})}},useStyle$d=genComponentStyleHook("Slider",$n=>{const Cn=merge$1($n,{marginPart:($n.controlHeight-$n.controlSize)/2,marginFull:$n.controlSize/2,marginPartWithMark:$n.controlHeightLG-$n.controlSize});return[genBaseStyle$5(Cn),genHorizontalStyle(Cn),genVerticalStyle(Cn)]},$n=>{const _n=$n.controlHeightLG/4,Pn=$n.controlHeightSM/2,In=$n.lineWidth+1,Nn=$n.lineWidth+1*3;return{controlSize:_n,railSize:4,handleSize:_n,handleSizeHover:Pn,dotSize:8,handleLineWidth:In,handleLineWidthHover:Nn}});var __rest$k=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);Intypeof $n=="number"?$n.toString():"",sliderProps=()=>({id:String,prefixCls:String,tooltipPrefixCls:String,range:someType([Boolean,Object]),reverse:booleanType(),min:Number,max:Number,step:someType([Object,Number]),marks:objectType(),dots:booleanType(),value:someType([Array,Number]),defaultValue:someType([Array,Number]),included:booleanType(),disabled:booleanType(),vertical:booleanType(),tipFormatter:someType([Function,Object],()=>defaultTipFormatter),tooltipOpen:booleanType(),tooltipVisible:booleanType(),tooltipPlacement:stringType(),getTooltipPopupContainer:functionType(),autofocus:booleanType(),handleStyle:someType([Array,Object]),trackStyle:someType([Array,Object]),onChange:functionType(),onAfterChange:functionType(),onFocus:functionType(),onBlur:functionType(),"onUpdate:value":functionType()}),Slider=defineComponent({compatConfig:{MODE:3},name:"ASlider",inheritAttrs:!1,props:sliderProps(),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In,expose:Nn}=Cn;const{prefixCls:Rn,rootPrefixCls:Dn,direction:Ln,getPopupContainer:Fn,configProvider:Bn}=useConfigInject("slider",$n),[Hn,zn]=useStyle$d(Rn),Wn=useInjectFormItemContext(),Yn=ref(),Gn=ref({}),Go=(nr,ta)=>{Gn.value[nr]=ta},Xn=computed(()=>$n.tooltipPlacement?$n.tooltipPlacement:$n.vertical?Ln.value==="rtl"?"left":"right":"top"),Yo=()=>{var nr;(nr=Yn.value)===null||nr===void 0||nr.focus()},qo=()=>{var nr;(nr=Yn.value)===null||nr===void 0||nr.blur()},Jo=nr=>{In("update:value",nr),In("change",nr),Wn.onFieldChange()},Zo=nr=>{In("blur",nr)};Nn({focus:Yo,blur:qo});const rr=nr=>{var{tooltipPrefixCls:ta}=nr,oa=nr.info,{value:ra,dragging:ea,index:la}=oa,ua=__rest$k(oa,["value","dragging","index"]);const{tipFormatter:ga,tooltipOpen:aa=$n.tooltipVisible,getTooltipPopupContainer:ca}=$n,sa=ga?Gn.value[la]||ea:!1,ia=aa||aa===void 0&&sa;return createVNode(SliderTooltip,{prefixCls:ta,title:ga?ga(ra):"",open:ia,placement:Xn.value,transitionName:`${Dn.value}-zoom-down`,key:la,overlayClassName:`${Rn.value}-tooltip`,getPopupContainer:ca||(Fn==null?void 0:Fn.value)},{default:()=>[createVNode(VcHandle,_objectSpread2$1(_objectSpread2$1({},ua),{},{value:ra,onMouseenter:()=>Go(la,!0),onMouseleave:()=>Go(la,!1)}),null)]})};return()=>{const{tooltipPrefixCls:nr,range:ta,id:oa=Wn.id.value}=$n,ra=__rest$k($n,["tooltipPrefixCls","range","id"]),ea=Bn.getPrefixCls("tooltip",nr),la=classNames(_n.class,{[`${Rn.value}-rtl`]:Ln.value==="rtl"},zn.value);Ln.value==="rtl"&&!ra.vertical&&(ra.reverse=!ra.reverse);let ua;return typeof ta=="object"&&(ua=ta.draggableTrack),Hn(ta?createVNode(VcRange,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),ra),{},{step:ra.step,draggableTrack:ua,class:la,ref:Yn,handle:ga=>rr({tooltipPrefixCls:ea,prefixCls:Rn.value,info:ga}),prefixCls:Rn.value,onChange:Jo,onBlur:Zo}),{mark:Pn.mark}):createVNode(VcSlider,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),ra),{},{id:oa,step:ra.step,class:la,ref:Yn,handle:ga=>rr({tooltipPrefixCls:ea,prefixCls:Rn.value,info:ga}),prefixCls:Rn.value,onChange:Jo,onBlur:Zo}),{mark:Pn.mark}))}}}),index$c=withInstall(Slider);function isString$2($n){return typeof $n=="string"}function noop$5(){}const VcStepProps=()=>({prefixCls:String,itemWidth:String,active:{type:Boolean,default:void 0},disabled:{type:Boolean,default:void 0},status:stringType(),iconPrefix:String,icon:PropTypes.any,adjustMarginRight:String,stepNumber:Number,stepIndex:Number,description:PropTypes.any,title:PropTypes.any,subTitle:PropTypes.any,progressDot:withUndefined(PropTypes.oneOfType([PropTypes.looseBool,PropTypes.func])),tailContent:PropTypes.any,icons:PropTypes.shape({finish:PropTypes.any,error:PropTypes.any}).loose,onClick:functionType(),onStepClick:functionType(),stepIcon:functionType(),itemRender:functionType(),__legacy:booleanType()}),VcStep=defineComponent({compatConfig:{MODE:3},name:"Step",inheritAttrs:!1,props:VcStepProps(),setup($n,Cn){let{slots:_n,emit:Pn,attrs:In}=Cn;const Nn=Dn=>{Pn("click",Dn),Pn("stepClick",$n.stepIndex)},Rn=Dn=>{let{icon:Ln,title:Fn,description:Bn}=Dn;const{prefixCls:Hn,stepNumber:zn,status:Wn,iconPrefix:Yn,icons:Gn,progressDot:Go=_n.progressDot,stepIcon:Xn=_n.stepIcon}=$n;let Yo;const qo=classNames(`${Hn}-icon`,`${Yn}icon`,{[`${Yn}icon-${Ln}`]:Ln&&isString$2(Ln),[`${Yn}icon-check`]:!Ln&&Wn==="finish"&&(Gn&&!Gn.finish||!Gn),[`${Yn}icon-cross`]:!Ln&&Wn==="error"&&(Gn&&!Gn.error||!Gn)}),Jo=createVNode("span",{class:`${Hn}-icon-dot`},null);return Go?typeof Go=="function"?Yo=createVNode("span",{class:`${Hn}-icon`},[Go({iconDot:Jo,index:zn-1,status:Wn,title:Fn,description:Bn,prefixCls:Hn})]):Yo=createVNode("span",{class:`${Hn}-icon`},[Jo]):Ln&&!isString$2(Ln)?Yo=createVNode("span",{class:`${Hn}-icon`},[Ln]):Gn&&Gn.finish&&Wn==="finish"?Yo=createVNode("span",{class:`${Hn}-icon`},[Gn.finish]):Gn&&Gn.error&&Wn==="error"?Yo=createVNode("span",{class:`${Hn}-icon`},[Gn.error]):Ln||Wn==="finish"||Wn==="error"?Yo=createVNode("span",{class:qo},null):Yo=createVNode("span",{class:`${Hn}-icon`},[zn]),Xn&&(Yo=Xn({index:zn-1,status:Wn,title:Fn,description:Bn,node:Yo})),Yo};return()=>{var Dn,Ln,Fn,Bn;const{prefixCls:Hn,itemWidth:zn,active:Wn,status:Yn="wait",tailContent:Gn,adjustMarginRight:Go,disabled:Xn,title:Yo=(Dn=_n.title)===null||Dn===void 0?void 0:Dn.call(_n),description:qo=(Ln=_n.description)===null||Ln===void 0?void 0:Ln.call(_n),subTitle:Jo=(Fn=_n.subTitle)===null||Fn===void 0?void 0:Fn.call(_n),icon:Zo=(Bn=_n.icon)===null||Bn===void 0?void 0:Bn.call(_n),onClick:rr,onStepClick:nr}=$n,ta=Yn||"wait",oa=classNames(`${Hn}-item`,`${Hn}-item-${ta}`,{[`${Hn}-item-custom`]:Zo,[`${Hn}-item-active`]:Wn,[`${Hn}-item-disabled`]:Xn===!0}),ra={};zn&&(ra.width=zn),Go&&(ra.marginRight=Go);const ea={onClick:rr||noop$5};nr&&!Xn&&(ea.role="button",ea.tabindex=0,ea.onClick=Nn);const la=createVNode("div",_objectSpread2$1(_objectSpread2$1({},omit$1(In,["__legacy"])),{},{class:[oa,In.class],style:[In.style,ra]}),[createVNode("div",_objectSpread2$1(_objectSpread2$1({},ea),{},{class:`${Hn}-item-container`}),[createVNode("div",{class:`${Hn}-item-tail`},[Gn]),createVNode("div",{class:`${Hn}-item-icon`},[Rn({icon:Zo,title:Yo,description:qo})]),createVNode("div",{class:`${Hn}-item-content`},[createVNode("div",{class:`${Hn}-item-title`},[Yo,Jo&&createVNode("div",{title:typeof Jo=="string"?Jo:void 0,class:`${Hn}-item-subtitle`},[Jo])]),qo&&createVNode("div",{class:`${Hn}-item-description`},[qo])])])]);return $n.itemRender?$n.itemRender(la):la}}});var __rest$j=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In[]),icons:PropTypes.shape({finish:PropTypes.any,error:PropTypes.any}).loose,stepIcon:functionType(),isInline:PropTypes.looseBool,itemRender:functionType()},emits:["change"],setup($n,Cn){let{slots:_n,emit:Pn}=Cn;const In=Dn=>{const{current:Ln}=$n;Ln!==Dn&&Pn("change",Dn)},Nn=(Dn,Ln,Fn)=>{const{prefixCls:Bn,iconPrefix:Hn,status:zn,current:Wn,initial:Yn,icons:Gn,stepIcon:Go=_n.stepIcon,isInline:Xn,itemRender:Yo,progressDot:qo=_n.progressDot}=$n,Jo=Xn||qo,Zo=_extends$1(_extends$1({},Dn),{class:""}),rr=Yn+Ln,nr={active:rr===Wn,stepNumber:rr+1,stepIndex:rr,key:rr,prefixCls:Bn,iconPrefix:Hn,progressDot:Jo,stepIcon:Go,icons:Gn,onStepClick:In};return zn==="error"&&Ln===Wn-1&&(Zo.class=`${Bn}-next-error`),Zo.status||(rr===Wn?Zo.status=zn:rrYo(Zo,ta)),createVNode(VcStep,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Zo),nr),{},{__legacy:!1}),null))},Rn=(Dn,Ln)=>Nn(_extends$1({},Dn.props),Ln,Fn=>cloneElement(Dn,Fn));return()=>{var Dn;const{prefixCls:Ln,direction:Fn,type:Bn,labelPlacement:Hn,iconPrefix:zn,status:Wn,size:Yn,current:Gn,progressDot:Go=_n.progressDot,initial:Xn,icons:Yo,items:qo,isInline:Jo,itemRender:Zo}=$n,rr=__rest$j($n,["prefixCls","direction","type","labelPlacement","iconPrefix","status","size","current","progressDot","initial","icons","items","isInline","itemRender"]),nr=Bn==="navigation",ta=Jo||Go,oa=Jo?"horizontal":Fn,ra=Jo?void 0:Yn,ea=ta?"vertical":Hn,la=classNames(Ln,`${Ln}-${Fn}`,{[`${Ln}-${ra}`]:ra,[`${Ln}-label-${ea}`]:oa==="horizontal",[`${Ln}-dot`]:!!ta,[`${Ln}-navigation`]:nr,[`${Ln}-inline`]:Jo});return createVNode("div",_objectSpread2$1({class:la},rr),[qo.filter(ua=>ua).map((ua,ga)=>Nn(ua,ga)),filterEmpty((Dn=_n.default)===null||Dn===void 0?void 0:Dn.call(_n)).map(Rn)])}}}),genStepsCustomIconStyle=$n=>{const{componentCls:Cn,stepsIconCustomTop:_n,stepsIconCustomSize:Pn,stepsIconCustomFontSize:In}=$n;return{[`${Cn}-item-custom`]:{[`> ${Cn}-item-container > ${Cn}-item-icon`]:{height:"auto",background:"none",border:0,[`> ${Cn}-icon`]:{top:_n,width:Pn,height:Pn,fontSize:In,lineHeight:`${Pn}px`}}},[`&:not(${Cn}-vertical)`]:{[`${Cn}-item-custom`]:{[`${Cn}-item-icon`]:{width:"auto",background:"none"}}}}},genStepsLabelPlacementStyle=$n=>{const{componentCls:Cn,stepsIconSize:_n,lineHeight:Pn,stepsSmallIconSize:In}=$n;return{[`&${Cn}-label-vertical`]:{[`${Cn}-item`]:{overflow:"visible","&-tail":{marginInlineStart:_n/2+$n.controlHeightLG,padding:`${$n.paddingXXS}px ${$n.paddingLG}px`},"&-content":{display:"block",width:(_n/2+$n.controlHeightLG)*2,marginTop:$n.marginSM,textAlign:"center"},"&-icon":{display:"inline-block",marginInlineStart:$n.controlHeightLG},"&-title":{paddingInlineEnd:0,paddingInlineStart:0,"&::after":{display:"none"}},"&-subtitle":{display:"block",marginBottom:$n.marginXXS,marginInlineStart:0,lineHeight:Pn}},[`&${Cn}-small:not(${Cn}-dot)`]:{[`${Cn}-item`]:{"&-icon":{marginInlineStart:$n.controlHeightLG+(_n-In)/2}}}}}},genStepsNavStyle=$n=>{const{componentCls:Cn,stepsNavContentMaxWidth:_n,stepsNavArrowColor:Pn,stepsNavActiveColor:In,motionDurationSlow:Nn}=$n;return{[`&${Cn}-navigation`]:{paddingTop:$n.paddingSM,[`&${Cn}-small`]:{[`${Cn}-item`]:{"&-container":{marginInlineStart:-$n.marginSM}}},[`${Cn}-item`]:{overflow:"visible",textAlign:"center","&-container":{display:"inline-block",height:"100%",marginInlineStart:-$n.margin,paddingBottom:$n.paddingSM,textAlign:"start",transition:`opacity ${Nn}`,[`${Cn}-item-content`]:{maxWidth:_n},[`${Cn}-item-title`]:_extends$1(_extends$1({maxWidth:"100%",paddingInlineEnd:0},textEllipsis),{"&::after":{display:"none"}})},[`&:not(${Cn}-item-active)`]:{[`${Cn}-item-container[role='button']`]:{cursor:"pointer","&:hover":{opacity:.85}}},"&:last-child":{flex:1,"&::after":{display:"none"}},"&::after":{position:"absolute",top:`calc(50% - ${$n.paddingSM/2}px)`,insetInlineStart:"100%",display:"inline-block",width:$n.fontSizeIcon,height:$n.fontSizeIcon,borderTop:`${$n.lineWidth}px ${$n.lineType} ${Pn}`,borderBottom:"none",borderInlineStart:"none",borderInlineEnd:`${$n.lineWidth}px ${$n.lineType} ${Pn}`,transform:"translateY(-50%) translateX(-50%) rotate(45deg)",content:'""'},"&::before":{position:"absolute",bottom:0,insetInlineStart:"50%",display:"inline-block",width:0,height:$n.lineWidthBold,backgroundColor:In,transition:`width ${Nn}, inset-inline-start ${Nn}`,transitionTimingFunction:"ease-out",content:'""'}},[`${Cn}-item${Cn}-item-active::before`]:{insetInlineStart:0,width:"100%"}},[`&${Cn}-navigation${Cn}-vertical`]:{[`> ${Cn}-item`]:{marginInlineEnd:0,"&::before":{display:"none"},[`&${Cn}-item-active::before`]:{top:0,insetInlineEnd:0,insetInlineStart:"unset",display:"block",width:$n.lineWidth*3,height:`calc(100% - ${$n.marginLG}px)`},"&::after":{position:"relative",insetInlineStart:"50%",display:"block",width:$n.controlHeight*.25,height:$n.controlHeight*.25,marginBottom:$n.marginXS,textAlign:"center",transform:"translateY(-50%) translateX(-50%) rotate(135deg)"},[`> ${Cn}-item-container > ${Cn}-item-tail`]:{visibility:"hidden"}}},[`&${Cn}-navigation${Cn}-horizontal`]:{[`> ${Cn}-item > ${Cn}-item-container > ${Cn}-item-tail`]:{visibility:"hidden"}}}},genStepsProgressStyle=$n=>{const{antCls:Cn,componentCls:_n}=$n;return{[`&${_n}-with-progress`]:{[`${_n}-item`]:{paddingTop:$n.paddingXXS,[`&-process ${_n}-item-container ${_n}-item-icon ${_n}-icon`]:{color:$n.processIconColor}},[`&${_n}-vertical > ${_n}-item `]:{paddingInlineStart:$n.paddingXXS,[`> ${_n}-item-container > ${_n}-item-tail`]:{top:$n.marginXXS,insetInlineStart:$n.stepsIconSize/2-$n.lineWidth+$n.paddingXXS}},[`&, &${_n}-small`]:{[`&${_n}-horizontal ${_n}-item:first-child`]:{paddingBottom:$n.paddingXXS,paddingInlineStart:$n.paddingXXS}},[`&${_n}-small${_n}-vertical > ${_n}-item > ${_n}-item-container > ${_n}-item-tail`]:{insetInlineStart:$n.stepsSmallIconSize/2-$n.lineWidth+$n.paddingXXS},[`&${_n}-label-vertical`]:{[`${_n}-item ${_n}-item-tail`]:{top:$n.margin-2*$n.lineWidth}},[`${_n}-item-icon`]:{position:"relative",[`${Cn}-progress`]:{position:"absolute",insetBlockStart:($n.stepsIconSize-$n.stepsProgressSize-$n.lineWidth*2)/2,insetInlineStart:($n.stepsIconSize-$n.stepsProgressSize-$n.lineWidth*2)/2}}}}},genStepsProgressDotStyle=$n=>{const{componentCls:Cn,descriptionWidth:_n,lineHeight:Pn,stepsCurrentDotSize:In,stepsDotSize:Nn,motionDurationSlow:Rn}=$n;return{[`&${Cn}-dot, &${Cn}-dot${Cn}-small`]:{[`${Cn}-item`]:{"&-title":{lineHeight:Pn},"&-tail":{top:Math.floor(($n.stepsDotSize-$n.lineWidth*3)/2),width:"100%",marginTop:0,marginBottom:0,marginInline:`${_n/2}px 0`,padding:0,"&::after":{width:`calc(100% - ${$n.marginSM*2}px)`,height:$n.lineWidth*3,marginInlineStart:$n.marginSM}},"&-icon":{width:Nn,height:Nn,marginInlineStart:($n.descriptionWidth-Nn)/2,paddingInlineEnd:0,lineHeight:`${Nn}px`,background:"transparent",border:0,[`${Cn}-icon-dot`]:{position:"relative",float:"left",width:"100%",height:"100%",borderRadius:100,transition:`all ${Rn}`,"&::after":{position:"absolute",top:-$n.marginSM,insetInlineStart:(Nn-$n.controlHeightLG*1.5)/2,width:$n.controlHeightLG*1.5,height:$n.controlHeight,background:"transparent",content:'""'}}},"&-content":{width:_n},[`&-process ${Cn}-item-icon`]:{position:"relative",top:(Nn-In)/2,width:In,height:In,lineHeight:`${In}px`,background:"none",marginInlineStart:($n.descriptionWidth-In)/2},[`&-process ${Cn}-icon`]:{[`&:first-child ${Cn}-icon-dot`]:{insetInlineStart:0}}}},[`&${Cn}-vertical${Cn}-dot`]:{[`${Cn}-item-icon`]:{marginTop:($n.controlHeight-Nn)/2,marginInlineStart:0,background:"none"},[`${Cn}-item-process ${Cn}-item-icon`]:{marginTop:($n.controlHeight-In)/2,top:0,insetInlineStart:(Nn-In)/2,marginInlineStart:0},[`${Cn}-item > ${Cn}-item-container > ${Cn}-item-tail`]:{top:($n.controlHeight-Nn)/2,insetInlineStart:0,margin:0,padding:`${Nn+$n.paddingXS}px 0 ${$n.paddingXS}px`,"&::after":{marginInlineStart:(Nn-$n.lineWidth)/2}},[`&${Cn}-small`]:{[`${Cn}-item-icon`]:{marginTop:($n.controlHeightSM-Nn)/2},[`${Cn}-item-process ${Cn}-item-icon`]:{marginTop:($n.controlHeightSM-In)/2},[`${Cn}-item > ${Cn}-item-container > ${Cn}-item-tail`]:{top:($n.controlHeightSM-Nn)/2}},[`${Cn}-item:first-child ${Cn}-icon-dot`]:{insetInlineStart:0},[`${Cn}-item-content`]:{width:"inherit"}}}},genStepsRTLStyle=$n=>{const{componentCls:Cn}=$n;return{[`&${Cn}-rtl`]:{direction:"rtl",[`${Cn}-item`]:{"&-subtitle":{float:"left"}},[`&${Cn}-navigation`]:{[`${Cn}-item::after`]:{transform:"rotate(-45deg)"}},[`&${Cn}-vertical`]:{[`> ${Cn}-item`]:{"&::after":{transform:"rotate(225deg)"},[`${Cn}-item-icon`]:{float:"right"}}},[`&${Cn}-dot`]:{[`${Cn}-item-icon ${Cn}-icon-dot, &${Cn}-small ${Cn}-item-icon ${Cn}-icon-dot`]:{float:"right"}}}}},genStepsSmallStyle=$n=>{const{componentCls:Cn,stepsSmallIconSize:_n,fontSizeSM:Pn,fontSize:In,colorTextDescription:Nn}=$n;return{[`&${Cn}-small`]:{[`&${Cn}-horizontal:not(${Cn}-label-vertical) ${Cn}-item`]:{paddingInlineStart:$n.paddingSM,"&:first-child":{paddingInlineStart:0}},[`${Cn}-item-icon`]:{width:_n,height:_n,marginTop:0,marginBottom:0,marginInline:`0 ${$n.marginXS}px`,fontSize:Pn,lineHeight:`${_n}px`,textAlign:"center",borderRadius:_n},[`${Cn}-item-title`]:{paddingInlineEnd:$n.paddingSM,fontSize:In,lineHeight:`${_n}px`,"&::after":{top:_n/2}},[`${Cn}-item-description`]:{color:Nn,fontSize:In},[`${Cn}-item-tail`]:{top:_n/2-$n.paddingXXS},[`${Cn}-item-custom ${Cn}-item-icon`]:{width:"inherit",height:"inherit",lineHeight:"inherit",background:"none",border:0,borderRadius:0,[`> ${Cn}-icon`]:{fontSize:_n,lineHeight:`${_n}px`,transform:"none"}}}}},genStepsVerticalStyle=$n=>{const{componentCls:Cn,stepsSmallIconSize:_n,stepsIconSize:Pn}=$n;return{[`&${Cn}-vertical`]:{display:"flex",flexDirection:"column",[`> ${Cn}-item`]:{display:"block",flex:"1 0 auto",paddingInlineStart:0,overflow:"visible",[`${Cn}-item-icon`]:{float:"left",marginInlineEnd:$n.margin},[`${Cn}-item-content`]:{display:"block",minHeight:$n.controlHeight*1.5,overflow:"hidden"},[`${Cn}-item-title`]:{lineHeight:`${Pn}px`},[`${Cn}-item-description`]:{paddingBottom:$n.paddingSM}},[`> ${Cn}-item > ${Cn}-item-container > ${Cn}-item-tail`]:{position:"absolute",top:0,insetInlineStart:$n.stepsIconSize/2-$n.lineWidth,width:$n.lineWidth,height:"100%",padding:`${Pn+$n.marginXXS*1.5}px 0 ${$n.marginXXS*1.5}px`,"&::after":{width:$n.lineWidth,height:"100%"}},[`> ${Cn}-item:not(:last-child) > ${Cn}-item-container > ${Cn}-item-tail`]:{display:"block"},[` > ${Cn}-item > ${Cn}-item-container > ${Cn}-item-content > ${Cn}-item-title`]:{"&::after":{display:"none"}},[`&${Cn}-small ${Cn}-item-container`]:{[`${Cn}-item-tail`]:{position:"absolute",top:0,insetInlineStart:$n.stepsSmallIconSize/2-$n.lineWidth,padding:`${_n+$n.marginXXS*1.5}px 0 ${$n.marginXXS*1.5}px`},[`${Cn}-item-title`]:{lineHeight:`${_n}px`}}}}},genStepsInlineStyle=$n=>{const{componentCls:Cn,inlineDotSize:_n,inlineTitleColor:Pn,inlineTailColor:In}=$n,Nn=$n.paddingXS+$n.lineWidth,Rn={[`${Cn}-item-container ${Cn}-item-content ${Cn}-item-title`]:{color:Pn}};return{[`&${Cn}-inline`]:{width:"auto",display:"inline-flex",[`${Cn}-item`]:{flex:"none","&-container":{padding:`${Nn}px ${$n.paddingXXS}px 0`,margin:`0 ${$n.marginXXS/2}px`,borderRadius:$n.borderRadiusSM,cursor:"pointer",transition:`background-color ${$n.motionDurationMid}`,"&:hover":{background:$n.controlItemBgHover},"&[role='button']:hover":{opacity:1}},"&-icon":{width:_n,height:_n,marginInlineStart:`calc(50% - ${_n/2}px)`,[`> ${Cn}-icon`]:{top:0},[`${Cn}-icon-dot`]:{borderRadius:$n.fontSizeSM/4}},"&-content":{width:"auto",marginTop:$n.marginXS-$n.lineWidth},"&-title":{color:Pn,fontSize:$n.fontSizeSM,lineHeight:$n.lineHeightSM,fontWeight:"normal",marginBottom:$n.marginXXS/2},"&-description":{display:"none"},"&-tail":{marginInlineStart:0,top:Nn+_n/2,transform:"translateY(-50%)","&:after":{width:"100%",height:$n.lineWidth,borderRadius:0,marginInlineStart:0,background:In}},[`&:first-child ${Cn}-item-tail`]:{width:"50%",marginInlineStart:"50%"},[`&:last-child ${Cn}-item-tail`]:{display:"block",width:"50%"},"&-wait":_extends$1({[`${Cn}-item-icon ${Cn}-icon ${Cn}-icon-dot`]:{backgroundColor:$n.colorBorderBg,border:`${$n.lineWidth}px ${$n.lineType} ${In}`}},Rn),"&-finish":_extends$1({[`${Cn}-item-tail::after`]:{backgroundColor:In},[`${Cn}-item-icon ${Cn}-icon ${Cn}-icon-dot`]:{backgroundColor:In,border:`${$n.lineWidth}px ${$n.lineType} ${In}`}},Rn),"&-error":Rn,"&-active, &-process":_extends$1({[`${Cn}-item-icon`]:{width:_n,height:_n,marginInlineStart:`calc(50% - ${_n/2}px)`,top:0}},Rn),[`&:not(${Cn}-item-active) > ${Cn}-item-container[role='button']:hover`]:{[`${Cn}-item-title`]:{color:Pn}}}}}};var StepItemStatusEnum;(function($n){$n.wait="wait",$n.process="process",$n.finish="finish",$n.error="error"})(StepItemStatusEnum||(StepItemStatusEnum={}));const genStepsItemStatusStyle=($n,Cn)=>{const _n=`${Cn.componentCls}-item`,Pn=`${$n}IconColor`,In=`${$n}TitleColor`,Nn=`${$n}DescriptionColor`,Rn=`${$n}TailColor`,Dn=`${$n}IconBgColor`,Ln=`${$n}IconBorderColor`,Fn=`${$n}DotColor`;return{[`${_n}-${$n} ${_n}-icon`]:{backgroundColor:Cn[Dn],borderColor:Cn[Ln],[`> ${Cn.componentCls}-icon`]:{color:Cn[Pn],[`${Cn.componentCls}-icon-dot`]:{background:Cn[Fn]}}},[`${_n}-${$n}${_n}-custom ${_n}-icon`]:{[`> ${Cn.componentCls}-icon`]:{color:Cn[Fn]}},[`${_n}-${$n} > ${_n}-container > ${_n}-content > ${_n}-title`]:{color:Cn[In],"&::after":{backgroundColor:Cn[Rn]}},[`${_n}-${$n} > ${_n}-container > ${_n}-content > ${_n}-description`]:{color:Cn[Nn]},[`${_n}-${$n} > ${_n}-container > ${_n}-tail::after`]:{backgroundColor:Cn[Rn]}}},genStepsItemStyle=$n=>{const{componentCls:Cn,motionDurationSlow:_n}=$n,Pn=`${Cn}-item`;return _extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({[Pn]:{position:"relative",display:"inline-block",flex:1,overflow:"hidden",verticalAlign:"top","&:last-child":{flex:"none",[`> ${Pn}-container > ${Pn}-tail, > ${Pn}-container > ${Pn}-content > ${Pn}-title::after`]:{display:"none"}}},[`${Pn}-container`]:{outline:"none"},[`${Pn}-icon, ${Pn}-content`]:{display:"inline-block",verticalAlign:"top"},[`${Pn}-icon`]:{width:$n.stepsIconSize,height:$n.stepsIconSize,marginTop:0,marginBottom:0,marginInlineStart:0,marginInlineEnd:$n.marginXS,fontSize:$n.stepsIconFontSize,fontFamily:$n.fontFamily,lineHeight:`${$n.stepsIconSize}px`,textAlign:"center",borderRadius:$n.stepsIconSize,border:`${$n.lineWidth}px ${$n.lineType} transparent`,transition:`background-color ${_n}, border-color ${_n}`,[`${Cn}-icon`]:{position:"relative",top:$n.stepsIconTop,color:$n.colorPrimary,lineHeight:1}},[`${Pn}-tail`]:{position:"absolute",top:$n.stepsIconSize/2-$n.paddingXXS,insetInlineStart:0,width:"100%","&::after":{display:"inline-block",width:"100%",height:$n.lineWidth,background:$n.colorSplit,borderRadius:$n.lineWidth,transition:`background ${_n}`,content:'""'}},[`${Pn}-title`]:{position:"relative",display:"inline-block",paddingInlineEnd:$n.padding,color:$n.colorText,fontSize:$n.fontSizeLG,lineHeight:`${$n.stepsTitleLineHeight}px`,"&::after":{position:"absolute",top:$n.stepsTitleLineHeight/2,insetInlineStart:"100%",display:"block",width:9999,height:$n.lineWidth,background:$n.processTailColor,content:'""'}},[`${Pn}-subtitle`]:{display:"inline",marginInlineStart:$n.marginXS,color:$n.colorTextDescription,fontWeight:"normal",fontSize:$n.fontSize},[`${Pn}-description`]:{color:$n.colorTextDescription,fontSize:$n.fontSize}},genStepsItemStatusStyle(StepItemStatusEnum.wait,$n)),genStepsItemStatusStyle(StepItemStatusEnum.process,$n)),{[`${Pn}-process > ${Pn}-container > ${Pn}-title`]:{fontWeight:$n.fontWeightStrong}}),genStepsItemStatusStyle(StepItemStatusEnum.finish,$n)),genStepsItemStatusStyle(StepItemStatusEnum.error,$n)),{[`${Pn}${Cn}-next-error > ${Cn}-item-title::after`]:{background:$n.colorError},[`${Pn}-disabled`]:{cursor:"not-allowed"}})},genStepsClickableStyle=$n=>{const{componentCls:Cn,motionDurationSlow:_n}=$n;return{[`& ${Cn}-item`]:{[`&:not(${Cn}-item-active)`]:{[`& > ${Cn}-item-container[role='button']`]:{cursor:"pointer",[`${Cn}-item`]:{[`&-title, &-subtitle, &-description, &-icon ${Cn}-icon`]:{transition:`color ${_n}`}},"&:hover":{[`${Cn}-item`]:{"&-title, &-subtitle, &-description":{color:$n.colorPrimary}}}},[`&:not(${Cn}-item-process)`]:{[`& > ${Cn}-item-container[role='button']:hover`]:{[`${Cn}-item`]:{"&-icon":{borderColor:$n.colorPrimary,[`${Cn}-icon`]:{color:$n.colorPrimary}}}}}}},[`&${Cn}-horizontal:not(${Cn}-label-vertical)`]:{[`${Cn}-item`]:{paddingInlineStart:$n.padding,whiteSpace:"nowrap","&:first-child":{paddingInlineStart:0},[`&:last-child ${Cn}-item-title`]:{paddingInlineEnd:0},"&-tail":{display:"none"},"&-description":{maxWidth:$n.descriptionWidth,whiteSpace:"normal"}}}}},genStepsStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{display:"flex",width:"100%",fontSize:0,textAlign:"initial"}),genStepsItemStyle($n)),genStepsClickableStyle($n)),genStepsCustomIconStyle($n)),genStepsSmallStyle($n)),genStepsVerticalStyle($n)),genStepsLabelPlacementStyle($n)),genStepsProgressDotStyle($n)),genStepsNavStyle($n)),genStepsRTLStyle($n)),genStepsProgressStyle($n)),genStepsInlineStyle($n))}},useStyle$c=genComponentStyleHook("Steps",$n=>{const{wireframe:Cn,colorTextDisabled:_n,fontSizeHeading3:Pn,fontSize:In,controlHeight:Nn,controlHeightLG:Rn,colorTextLightSolid:Dn,colorText:Ln,colorPrimary:Fn,colorTextLabel:Bn,colorTextDescription:Hn,colorTextQuaternary:zn,colorFillContent:Wn,controlItemBgActive:Yn,colorError:Gn,colorBgContainer:Go,colorBorderSecondary:Xn}=$n,Yo=$n.controlHeight,qo=$n.colorSplit,Jo=merge$1($n,{processTailColor:qo,stepsNavArrowColor:_n,stepsIconSize:Yo,stepsIconCustomSize:Yo,stepsIconCustomTop:0,stepsIconCustomFontSize:Rn/2,stepsIconTop:-.5,stepsIconFontSize:In,stepsTitleLineHeight:Nn,stepsSmallIconSize:Pn,stepsDotSize:Nn/4,stepsCurrentDotSize:Rn/4,stepsNavContentMaxWidth:"auto",processIconColor:Dn,processTitleColor:Ln,processDescriptionColor:Ln,processIconBgColor:Fn,processIconBorderColor:Fn,processDotColor:Fn,waitIconColor:Cn?_n:Bn,waitTitleColor:Hn,waitDescriptionColor:Hn,waitTailColor:qo,waitIconBgColor:Cn?Go:Wn,waitIconBorderColor:Cn?_n:"transparent",waitDotColor:_n,finishIconColor:Fn,finishTitleColor:Ln,finishDescriptionColor:Hn,finishTailColor:Fn,finishIconBgColor:Cn?Go:Yn,finishIconBorderColor:Cn?Fn:Yn,finishDotColor:Fn,errorIconColor:Dn,errorTitleColor:Gn,errorDescriptionColor:Gn,errorTailColor:qo,errorIconBgColor:Gn,errorIconBorderColor:Gn,errorDotColor:Gn,stepsNavActiveColor:Fn,stepsProgressSize:Rn,inlineDotSize:6,inlineTitleColor:zn,inlineTailColor:Xn});return[genStepsStyle(Jo)]},{descriptionWidth:140}),stepsProps=()=>({prefixCls:String,iconPrefix:String,current:Number,initial:Number,percent:Number,responsive:booleanType(),items:arrayType(),labelPlacement:stringType(),status:stringType(),size:stringType(),direction:stringType(),progressDot:someType([Boolean,Function]),type:stringType(),onChange:functionType(),"onUpdate:current":functionType()}),Steps=defineComponent({compatConfig:{MODE:3},name:"ASteps",inheritAttrs:!1,props:initDefaultProps(stepsProps(),{current:0,responsive:!0,labelPlacement:"horizontal"}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const{prefixCls:Nn,direction:Rn,configProvider:Dn}=useConfigInject("steps",$n),[Ln,Fn]=useStyle$c(Nn),[,Bn]=useToken(),Hn=useBreakpoint(),zn=computed(()=>$n.responsive&&Hn.value.xs?"vertical":$n.direction),Wn=computed(()=>Dn.getPrefixCls("",$n.iconPrefix)),Yn=qo=>{In("update:current",qo),In("change",qo)},Gn=computed(()=>$n.type==="inline"),Go=computed(()=>Gn.value?void 0:$n.percent),Xn=qo=>{let{node:Jo,status:Zo}=qo;if(Zo==="process"&&$n.percent!==void 0){const rr=$n.size==="small"?Bn.value.controlHeight:Bn.value.controlHeightLG;return createVNode("div",{class:`${Nn.value}-progress-icon`},[createVNode(Progress,{type:"circle",percent:Go.value,size:rr,strokeWidth:4,format:()=>null},null),Jo])}return Jo},Yo=computed(()=>({finish:createVNode(CheckOutlined$1,{class:`${Nn.value}-finish-icon`},null),error:createVNode(CloseOutlined$1,{class:`${Nn.value}-error-icon`},null)}));return()=>{const qo=classNames({[`${Nn.value}-rtl`]:Rn.value==="rtl",[`${Nn.value}-with-progress`]:Go.value!==void 0},_n.class,Fn.value),Jo=(Zo,rr)=>Zo.description?createVNode(Tooltip,{title:Zo.description},{default:()=>[rr]}):rr;return Ln(createVNode(Steps$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({icons:Yo.value},_n),omit$1($n,["percent","responsive"])),{},{items:$n.items,direction:zn.value,prefixCls:Nn.value,iconPrefix:Wn.value,class:qo,onChange:Yn,isInline:Gn.value,itemRender:Gn.value?Jo:void 0}),_extends$1({stepIcon:Xn},Pn)))}}}),Step=defineComponent(_extends$1(_extends$1({compatConfig:{MODE:3}},VcStep),{name:"AStep",props:VcStepProps()})),index$b=_extends$1(Steps,{Step,install:$n=>($n.component(Steps.name,Steps),$n.component(Step.name,Step),$n)}),genSwitchSmallStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-inner`;return{[Cn]:{[`&${Cn}-small`]:{minWidth:$n.switchMinWidthSM,height:$n.switchHeightSM,lineHeight:`${$n.switchHeightSM}px`,[`${Cn}-inner`]:{paddingInlineStart:$n.switchInnerMarginMaxSM,paddingInlineEnd:$n.switchInnerMarginMinSM,[`${_n}-checked`]:{marginInlineStart:`calc(-100% + ${$n.switchPinSizeSM+$n.switchPadding*2}px - ${$n.switchInnerMarginMaxSM*2}px)`,marginInlineEnd:`calc(100% - ${$n.switchPinSizeSM+$n.switchPadding*2}px + ${$n.switchInnerMarginMaxSM*2}px)`},[`${_n}-unchecked`]:{marginTop:-$n.switchHeightSM,marginInlineStart:0,marginInlineEnd:0}},[`${Cn}-handle`]:{width:$n.switchPinSizeSM,height:$n.switchPinSizeSM},[`${Cn}-loading-icon`]:{top:($n.switchPinSizeSM-$n.switchLoadingIconSize)/2,fontSize:$n.switchLoadingIconSize},[`&${Cn}-checked`]:{[`${Cn}-inner`]:{paddingInlineStart:$n.switchInnerMarginMinSM,paddingInlineEnd:$n.switchInnerMarginMaxSM,[`${_n}-checked`]:{marginInlineStart:0,marginInlineEnd:0},[`${_n}-unchecked`]:{marginInlineStart:`calc(100% - ${$n.switchPinSizeSM+$n.switchPadding*2}px + ${$n.switchInnerMarginMaxSM*2}px)`,marginInlineEnd:`calc(-100% + ${$n.switchPinSizeSM+$n.switchPadding*2}px - ${$n.switchInnerMarginMaxSM*2}px)`}},[`${Cn}-handle`]:{insetInlineStart:`calc(100% - ${$n.switchPinSizeSM+$n.switchPadding}px)`}},[`&:not(${Cn}-disabled):active`]:{[`&:not(${Cn}-checked) ${_n}`]:{[`${_n}-unchecked`]:{marginInlineStart:$n.marginXXS/2,marginInlineEnd:-$n.marginXXS/2}},[`&${Cn}-checked ${_n}`]:{[`${_n}-checked`]:{marginInlineStart:-$n.marginXXS/2,marginInlineEnd:$n.marginXXS/2}}}}}}},genSwitchLoadingStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{[`${Cn}-loading-icon${$n.iconCls}`]:{position:"relative",top:($n.switchPinSize-$n.fontSize)/2,color:$n.switchLoadingIconColor,verticalAlign:"top"},[`&${Cn}-checked ${Cn}-loading-icon`]:{color:$n.switchColor}}}},genSwitchHandleStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-handle`;return{[Cn]:{[_n]:{position:"absolute",top:$n.switchPadding,insetInlineStart:$n.switchPadding,width:$n.switchPinSize,height:$n.switchPinSize,transition:`all ${$n.switchDuration} ease-in-out`,"&::before":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,backgroundColor:$n.colorWhite,borderRadius:$n.switchPinSize/2,boxShadow:$n.switchHandleShadow,transition:`all ${$n.switchDuration} ease-in-out`,content:'""'}},[`&${Cn}-checked ${_n}`]:{insetInlineStart:`calc(100% - ${$n.switchPinSize+$n.switchPadding}px)`},[`&:not(${Cn}-disabled):active`]:{[`${_n}::before`]:{insetInlineEnd:$n.switchHandleActiveInset,insetInlineStart:0},[`&${Cn}-checked ${_n}::before`]:{insetInlineEnd:0,insetInlineStart:$n.switchHandleActiveInset}}}}},genSwitchInnerStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-inner`;return{[Cn]:{[_n]:{display:"block",overflow:"hidden",borderRadius:100,height:"100%",paddingInlineStart:$n.switchInnerMarginMax,paddingInlineEnd:$n.switchInnerMarginMin,transition:`padding-inline-start ${$n.switchDuration} ease-in-out, padding-inline-end ${$n.switchDuration} ease-in-out`,[`${_n}-checked, ${_n}-unchecked`]:{display:"block",color:$n.colorTextLightSolid,fontSize:$n.fontSizeSM,transition:`margin-inline-start ${$n.switchDuration} ease-in-out, margin-inline-end ${$n.switchDuration} ease-in-out`,pointerEvents:"none"},[`${_n}-checked`]:{marginInlineStart:`calc(-100% + ${$n.switchPinSize+$n.switchPadding*2}px - ${$n.switchInnerMarginMax*2}px)`,marginInlineEnd:`calc(100% - ${$n.switchPinSize+$n.switchPadding*2}px + ${$n.switchInnerMarginMax*2}px)`},[`${_n}-unchecked`]:{marginTop:-$n.switchHeight,marginInlineStart:0,marginInlineEnd:0}},[`&${Cn}-checked ${_n}`]:{paddingInlineStart:$n.switchInnerMarginMin,paddingInlineEnd:$n.switchInnerMarginMax,[`${_n}-checked`]:{marginInlineStart:0,marginInlineEnd:0},[`${_n}-unchecked`]:{marginInlineStart:`calc(100% - ${$n.switchPinSize+$n.switchPadding*2}px + ${$n.switchInnerMarginMax*2}px)`,marginInlineEnd:`calc(-100% + ${$n.switchPinSize+$n.switchPadding*2}px - ${$n.switchInnerMarginMax*2}px)`}},[`&:not(${Cn}-disabled):active`]:{[`&:not(${Cn}-checked) ${_n}`]:{[`${_n}-unchecked`]:{marginInlineStart:$n.switchPadding*2,marginInlineEnd:-$n.switchPadding*2}},[`&${Cn}-checked ${_n}`]:{[`${_n}-checked`]:{marginInlineStart:-$n.switchPadding*2,marginInlineEnd:$n.switchPadding*2}}}}}},genSwitchStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"inline-block",boxSizing:"border-box",minWidth:$n.switchMinWidth,height:$n.switchHeight,lineHeight:`${$n.switchHeight}px`,verticalAlign:"middle",background:$n.colorTextQuaternary,border:"0",borderRadius:100,cursor:"pointer",transition:`all ${$n.motionDurationMid}`,userSelect:"none",[`&:hover:not(${Cn}-disabled)`]:{background:$n.colorTextTertiary}}),genFocusStyle($n)),{[`&${Cn}-checked`]:{background:$n.switchColor,[`&:hover:not(${Cn}-disabled)`]:{background:$n.colorPrimaryHover}},[`&${Cn}-loading, &${Cn}-disabled`]:{cursor:"not-allowed",opacity:$n.switchDisabledOpacity,"*":{boxShadow:"none",cursor:"not-allowed"}},[`&${Cn}-rtl`]:{direction:"rtl"}})}},useStyle$b=genComponentStyleHook("Switch",$n=>{const Cn=$n.fontSize*$n.lineHeight,_n=$n.controlHeight/2,Pn=2,In=Cn-Pn*2,Nn=_n-Pn*2,Rn=merge$1($n,{switchMinWidth:In*2+Pn*4,switchHeight:Cn,switchDuration:$n.motionDurationMid,switchColor:$n.colorPrimary,switchDisabledOpacity:$n.opacityLoading,switchInnerMarginMin:In/2,switchInnerMarginMax:In+Pn+Pn*2,switchPadding:Pn,switchPinSize:In,switchBg:$n.colorBgContainer,switchMinWidthSM:Nn*2+Pn*2,switchHeightSM:_n,switchInnerMarginMinSM:Nn/2,switchInnerMarginMaxSM:Nn+Pn+Pn*2,switchPinSizeSM:Nn,switchHandleShadow:`0 2px 4px 0 ${new TinyColor("#00230b").setAlpha(.2).toRgbString()}`,switchLoadingIconSize:$n.fontSizeIcon*.75,switchLoadingIconColor:`rgba(0, 0, 0, ${$n.opacityLoading})`,switchHandleActiveInset:"-30%"});return[genSwitchStyle(Rn),genSwitchInnerStyle(Rn),genSwitchHandleStyle(Rn),genSwitchLoadingStyle(Rn),genSwitchSmallStyle(Rn)]}),SwitchSizes=tuple$1("small","default"),switchProps=()=>({id:String,prefixCls:String,size:PropTypes.oneOf(SwitchSizes),disabled:{type:Boolean,default:void 0},checkedChildren:PropTypes.any,unCheckedChildren:PropTypes.any,tabindex:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),autofocus:{type:Boolean,default:void 0},loading:{type:Boolean,default:void 0},checked:PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.looseBool]),checkedValue:PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.looseBool]).def(!0),unCheckedValue:PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.looseBool]).def(!1),onChange:{type:Function},onClick:{type:Function},onKeydown:{type:Function},onMouseup:{type:Function},"onUpdate:checked":{type:Function},onBlur:Function,onFocus:Function}),Switch=defineComponent({compatConfig:{MODE:3},name:"ASwitch",__ANT_SWITCH:!0,inheritAttrs:!1,props:switchProps(),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,expose:In,emit:Nn}=Cn;const Rn=useInjectFormItemContext(),Dn=useInjectDisabled(),Ln=computed(()=>{var oa;return(oa=$n.disabled)!==null&&oa!==void 0?oa:Dn.value});onBeforeMount(()=>{warning$3(),warning$3()});const Fn=ref($n.checked!==void 0?$n.checked:_n.defaultChecked),Bn=computed(()=>Fn.value===$n.checkedValue);watch(()=>$n.checked,()=>{Fn.value=$n.checked});const{prefixCls:Hn,direction:zn,size:Wn}=useConfigInject("switch",$n),[Yn,Gn]=useStyle$b(Hn),Go=ref(),Xn=()=>{var oa;(oa=Go.value)===null||oa===void 0||oa.focus()};In({focus:Xn,blur:()=>{var oa;(oa=Go.value)===null||oa===void 0||oa.blur()}}),onMounted(()=>{nextTick(()=>{$n.autofocus&&!Ln.value&&Go.value.focus()})});const qo=(oa,ra)=>{Ln.value||(Nn("update:checked",oa),Nn("change",oa,ra),Rn.onFieldChange())},Jo=oa=>{Nn("blur",oa)},Zo=oa=>{Xn();const ra=Bn.value?$n.unCheckedValue:$n.checkedValue;qo(ra,oa),Nn("click",ra,oa)},rr=oa=>{oa.keyCode===KeyCode$1.LEFT?qo($n.unCheckedValue,oa):oa.keyCode===KeyCode$1.RIGHT&&qo($n.checkedValue,oa),Nn("keydown",oa)},nr=oa=>{var ra;(ra=Go.value)===null||ra===void 0||ra.blur(),Nn("mouseup",oa)},ta=computed(()=>({[`${Hn.value}-small`]:Wn.value==="small",[`${Hn.value}-loading`]:$n.loading,[`${Hn.value}-checked`]:Bn.value,[`${Hn.value}-disabled`]:Ln.value,[Hn.value]:!0,[`${Hn.value}-rtl`]:zn.value==="rtl",[Gn.value]:!0}));return()=>{var oa;return Yn(createVNode(Wave,null,{default:()=>[createVNode("button",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},omit$1($n,["prefixCls","checkedChildren","unCheckedChildren","checked","autofocus","checkedValue","unCheckedValue","id","onChange","onUpdate:checked"])),_n),{},{id:(oa=$n.id)!==null&&oa!==void 0?oa:Rn.id.value,onKeydown:rr,onClick:Zo,onBlur:Jo,onMouseup:nr,type:"button",role:"switch","aria-checked":Fn.value,disabled:Ln.value||$n.loading,class:[_n.class,ta.value],ref:Go}),[createVNode("div",{class:`${Hn.value}-handle`},[$n.loading?createVNode(LoadingOutlined$1,{class:`${Hn.value}-loading-icon`},null):null]),createVNode("span",{class:`${Hn.value}-inner`},[createVNode("span",{class:`${Hn.value}-inner-checked`},[getPropsSlot(Pn,$n,"checkedChildren")]),createVNode("span",{class:`${Hn.value}-inner-unchecked`},[getPropsSlot(Pn,$n,"unCheckedChildren")])])])]}))}}}),index$a=withInstall(Switch),TableContextKey=Symbol("TableContextProps"),useProvideTable=$n=>{provide(TableContextKey,$n)},useInjectTable=()=>inject(TableContextKey,{}),INTERNAL_KEY_PREFIX="RC_TABLE_KEY";function toArray$1($n){return $n==null?[]:Array.isArray($n)?$n:[$n]}function getPathValue($n,Cn){if(!Cn&&typeof Cn!="number")return $n;const _n=toArray$1(Cn);let Pn=$n;for(let In=0;In<_n.length;In+=1){if(!Pn)return null;const Nn=_n[In];Pn=Pn[Nn]}return Pn}function getColumnsKey($n){const Cn=[],_n={};return $n.forEach(Pn=>{const{key:In,dataIndex:Nn}=Pn||{};let Rn=In||toArray$1(Nn).join("-")||INTERNAL_KEY_PREFIX;for(;_n[Rn];)Rn=`${Rn}_next`;_n[Rn]=!0,Cn.push(Rn)}),Cn}function mergeObject(){const $n={};function Cn(Nn,Rn){Rn&&Object.keys(Rn).forEach(Dn=>{const Ln=Rn[Dn];Ln&&typeof Ln=="object"?(Nn[Dn]=Nn[Dn]||{},Cn(Nn[Dn],Ln)):Nn[Dn]=Ln})}for(var _n=arguments.length,Pn=new Array(_n),In=0;In<_n;In++)Pn[In]=arguments[In];return Pn.forEach(Nn=>{Cn($n,Nn)}),$n}function validateValue($n){return $n!=null}const SlotsContextKey=Symbol("SlotsContextProps"),useProvideSlots=$n=>{provide(SlotsContextKey,$n)},useInjectSlots=()=>inject(SlotsContextKey,computed(()=>({}))),ContextKey=Symbol("ContextProps"),useProvideTableContext=$n=>{provide(ContextKey,$n)},useInjectTableContext=()=>inject(ContextKey,{onResizeColumn:()=>{}}),INTERNAL_COL_DEFINE="RC_TABLE_INTERNAL_COL_DEFINE",HoverContextKey=Symbol("HoverContextProps"),useProvideHover=$n=>{provide(HoverContextKey,$n)},useInjectHover=()=>inject(HoverContextKey,{startRow:shallowRef(-1),endRow:shallowRef(-1),onHover(){}}),supportSticky=shallowRef(!1),useProvideSticky=()=>{onMounted(()=>{supportSticky.value=supportSticky.value||isStyleSupport("position","sticky")})},useInjectSticky=()=>supportSticky;var __rest$i=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In=_n}function isRenderCell($n){return $n&&typeof $n=="object"&&!Array.isArray($n)&&!isVNode$1($n)}const Cell=defineComponent({name:"Cell",props:["prefixCls","record","index","renderIndex","dataIndex","customRender","component","colSpan","rowSpan","fixLeft","fixRight","firstFixLeft","lastFixLeft","firstFixRight","lastFixRight","appendNode","additionalProps","ellipsis","align","rowType","isSticky","column","cellType","transformCellText"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectSlots(),{onHover:In,startRow:Nn,endRow:Rn}=useInjectHover(),Dn=computed(()=>{var Yn,Gn,Go,Xn;return(Go=(Yn=$n.colSpan)!==null&&Yn!==void 0?Yn:(Gn=$n.additionalProps)===null||Gn===void 0?void 0:Gn.colSpan)!==null&&Go!==void 0?Go:(Xn=$n.additionalProps)===null||Xn===void 0?void 0:Xn.colspan}),Ln=computed(()=>{var Yn,Gn,Go,Xn;return(Go=(Yn=$n.rowSpan)!==null&&Yn!==void 0?Yn:(Gn=$n.additionalProps)===null||Gn===void 0?void 0:Gn.rowSpan)!==null&&Go!==void 0?Go:(Xn=$n.additionalProps)===null||Xn===void 0?void 0:Xn.rowspan}),Fn=eagerComputed(()=>{const{index:Yn}=$n;return inHoverRange(Yn,Ln.value||1,Nn.value,Rn.value)}),Bn=useInjectSticky(),Hn=(Yn,Gn)=>{var Go;const{record:Xn,index:Yo,additionalProps:qo}=$n;Xn&&In(Yo,Yo+Gn-1),(Go=qo==null?void 0:qo.onMouseenter)===null||Go===void 0||Go.call(qo,Yn)},zn=Yn=>{var Gn;const{record:Go,additionalProps:Xn}=$n;Go&&In(-1,-1),(Gn=Xn==null?void 0:Xn.onMouseleave)===null||Gn===void 0||Gn.call(Xn,Yn)},Wn=Yn=>{const Gn=filterEmpty(Yn)[0];return isVNode$1(Gn)?Gn.type===Text$2?Gn.children:Array.isArray(Gn.children)?Wn(Gn.children):void 0:Gn};return()=>{var Yn,Gn,Go,Xn,Yo,qo;const{prefixCls:Jo,record:Zo,index:rr,renderIndex:nr,dataIndex:ta,customRender:oa,component:ra="td",fixLeft:ea,fixRight:la,firstFixLeft:ua,lastFixLeft:ga,firstFixRight:aa,lastFixRight:ca,appendNode:sa=(Yn=_n.appendNode)===null||Yn===void 0?void 0:Yn.call(_n),additionalProps:ia={},ellipsis:fa,align:ma,rowType:ya,isSticky:ba,column:Ia={},cellType:Ea}=$n,xa=`${Jo}-cell`;let Ta,wa;const La=(Gn=_n.default)===null||Gn===void 0?void 0:Gn.call(_n);if(validateValue(La)||Ea==="header")wa=La;else{const Xa=getPathValue(Zo,ta);if(wa=Xa,oa){const Oa=oa({text:Xa,value:Xa,record:Zo,index:rr,renderIndex:nr,column:Ia.__originColumn__});isRenderCell(Oa)?(wa=Oa.children,Ta=Oa.props):wa=Oa}if(!(INTERNAL_COL_DEFINE in Ia)&&Ea==="body"&&Pn.value.bodyCell&&!(!((Go=Ia.slots)===null||Go===void 0)&&Go.customRender)){const Oa=customRenderSlot(Pn.value,"bodyCell",{text:Xa,value:Xa,record:Zo,index:rr,column:Ia.__originColumn__},()=>{const Ma=wa===void 0?Xa:wa;return[typeof Ma=="object"&&isValidElement(Ma)||typeof Ma!="object"?Ma:null]});wa=flattenChildren(Oa)}$n.transformCellText&&(wa=$n.transformCellText({text:wa,record:Zo,index:rr,column:Ia.__originColumn__}))}typeof wa=="object"&&!Array.isArray(wa)&&!isVNode$1(wa)&&(wa=null),fa&&(ga||aa)&&(wa=createVNode("span",{class:`${xa}-content`},[wa])),Array.isArray(wa)&&wa.length===1&&(wa=wa[0]);const Na=Ta||{},{colSpan:$a,rowSpan:ka,style:Ha,class:da}=Na,pa=__rest$i(Na,["colSpan","rowSpan","style","class"]),Sa=(Xn=$a!==void 0?$a:Dn.value)!==null&&Xn!==void 0?Xn:1,Aa=(Yo=ka!==void 0?ka:Ln.value)!==null&&Yo!==void 0?Yo:1;if(Sa===0||Aa===0)return null;const Ra={},Fa=typeof ea=="number"&&Bn.value,za=typeof la=="number"&&Bn.value;Fa&&(Ra.position="sticky",Ra.left=`${ea}px`),za&&(Ra.position="sticky",Ra.right=`${la}px`);const Wa={};ma&&(Wa.textAlign=ma);let Ya;const ja=fa===!0?{showTitle:!0}:fa;ja&&(ja.showTitle||ya==="header")&&(typeof wa=="string"||typeof wa=="number"?Ya=wa.toString():isVNode$1(wa)&&(Ya=Wn([wa])));const qa=_extends$1(_extends$1(_extends$1({title:Ya},pa),ia),{colSpan:Sa!==1?Sa:null,rowSpan:Aa!==1?Aa:null,class:classNames(xa,{[`${xa}-fix-left`]:Fa&&Bn.value,[`${xa}-fix-left-first`]:ua&&Bn.value,[`${xa}-fix-left-last`]:ga&&Bn.value,[`${xa}-fix-right`]:za&&Bn.value,[`${xa}-fix-right-first`]:aa&&Bn.value,[`${xa}-fix-right-last`]:ca&&Bn.value,[`${xa}-ellipsis`]:fa,[`${xa}-with-append`]:sa,[`${xa}-fix-sticky`]:(Fa||za)&&ba&&Bn.value,[`${xa}-row-hover`]:!Ta&&Fn.value},ia.class,da),onMouseenter:Xa=>{Hn(Xa,Aa)},onMouseleave:zn,style:[ia.style,Wa,Ra,Ha]});return createVNode(ra,qa,{default:()=>[sa,wa,(qo=_n.dragHandle)===null||qo===void 0?void 0:qo.call(_n)]})}}});function getCellFixedInfo($n,Cn,_n,Pn,In){const Nn=_n[$n]||{},Rn=_n[Cn]||{};let Dn,Ln;Nn.fixed==="left"?Dn=Pn.left[$n]:Rn.fixed==="right"&&(Ln=Pn.right[Cn]);let Fn=!1,Bn=!1,Hn=!1,zn=!1;const Wn=_n[Cn+1],Yn=_n[$n-1];return In==="rtl"?Dn!==void 0?zn=!(Yn&&Yn.fixed==="left"):Ln!==void 0&&(Hn=!(Wn&&Wn.fixed==="right")):Dn!==void 0?Fn=!(Wn&&Wn.fixed==="left"):Ln!==void 0&&(Bn=!(Yn&&Yn.fixed==="right")),{fixLeft:Dn,fixRight:Ln,lastFixLeft:Fn,firstFixRight:Bn,lastFixRight:Hn,firstFixLeft:zn,isSticky:Pn.isSticky}}const events={mouse:{start:"mousedown",move:"mousemove",stop:"mouseup"},touch:{start:"touchstart",move:"touchmove",stop:"touchend"}},defaultMinWidth=50,DragHandleVue=defineComponent({compatConfig:{MODE:3},name:"DragHandle",props:{prefixCls:String,width:{type:Number,required:!0},minWidth:{type:Number,default:defaultMinWidth},maxWidth:{type:Number,default:1/0},column:{type:Object,default:void 0}},setup($n){let Cn=0,_n={remove:()=>{}},Pn={remove:()=>{}};const In=()=>{_n.remove(),Pn.remove()};onUnmounted(()=>{In()}),watchEffect(()=>{devWarning(!isNaN($n.width),"Table","width must be a number when use resizable")});const{onResizeColumn:Nn}=useInjectTableContext(),Rn=computed(()=>typeof $n.minWidth=="number"&&!isNaN($n.minWidth)?$n.minWidth:defaultMinWidth),Dn=computed(()=>typeof $n.maxWidth=="number"&&!isNaN($n.maxWidth)?$n.maxWidth:1/0),Ln=getCurrentInstance();let Fn=0;const Bn=shallowRef(!1);let Hn;const zn=qo=>{let Jo=0;qo.touches?qo.touches.length?Jo=qo.touches[0].pageX:Jo=qo.changedTouches[0].pageX:Jo=qo.pageX;const Zo=Cn-Jo;let rr=Math.max(Fn-Zo,Rn.value);rr=Math.min(rr,Dn.value),wrapperRaf.cancel(Hn),Hn=wrapperRaf(()=>{Nn(rr,$n.column.__originColumn__)})},Wn=qo=>{zn(qo)},Yn=qo=>{Bn.value=!1,zn(qo),In()},Gn=(qo,Jo)=>{Bn.value=!0,In(),Fn=Ln.vnode.el.parentNode.getBoundingClientRect().width,!(qo instanceof MouseEvent&&qo.which!==1)&&(qo.stopPropagation&&qo.stopPropagation(),Cn=qo.touches?qo.touches[0].pageX:qo.pageX,_n=addEventListenerWrap(document.documentElement,Jo.move,Wn),Pn=addEventListenerWrap(document.documentElement,Jo.stop,Yn))},Go=qo=>{qo.stopPropagation(),qo.preventDefault(),Gn(qo,events.mouse)},Xn=qo=>{qo.stopPropagation(),qo.preventDefault(),Gn(qo,events.touch)},Yo=qo=>{qo.stopPropagation(),qo.preventDefault()};return()=>{const{prefixCls:qo}=$n,Jo={[supportsPassive$1?"onTouchstartPassive":"onTouchstart"]:Zo=>Xn(Zo)};return createVNode("div",_objectSpread2$1(_objectSpread2$1({class:`${qo}-resize-handle ${Bn.value?"dragging":""}`,onMousedown:Go},Jo),{},{onClick:Yo}),[createVNode("div",{class:`${qo}-resize-handle-line`},null)])}}}),HeaderRow=defineComponent({name:"HeaderRow",props:["cells","stickyOffsets","flattenColumns","rowComponent","cellComponent","index","customHeaderRow"],setup($n){const Cn=useInjectTable();return()=>{const{prefixCls:_n,direction:Pn}=Cn,{cells:In,stickyOffsets:Nn,flattenColumns:Rn,rowComponent:Dn,cellComponent:Ln,customHeaderRow:Fn,index:Bn}=$n;let Hn;Fn&&(Hn=Fn(In.map(Wn=>Wn.column),Bn));const zn=getColumnsKey(In.map(Wn=>Wn.column));return createVNode(Dn,Hn,{default:()=>[In.map((Wn,Yn)=>{const{column:Gn}=Wn,Go=getCellFixedInfo(Wn.colStart,Wn.colEnd,Rn,Nn,Pn);let Xn;Gn&&Gn.customHeaderCell&&(Xn=Wn.column.customHeaderCell(Gn));const Yo=Gn;return createVNode(Cell,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Wn),{},{cellType:"header",ellipsis:Gn.ellipsis,align:Gn.align,component:Ln,prefixCls:_n,key:zn[Yn]},Go),{},{additionalProps:Xn,rowType:"header",column:Gn}),{default:()=>Gn.title,dragHandle:()=>Yo.resizable?createVNode(DragHandleVue,{prefixCls:_n,width:Yo.width,minWidth:Yo.minWidth,maxWidth:Yo.maxWidth,column:Yo},null):null})})]})}}});function parseHeaderRows($n){const Cn=[];function _n(In,Nn){let Rn=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0;Cn[Rn]=Cn[Rn]||[];let Dn=Nn;return In.filter(Boolean).map(Fn=>{const Bn={key:Fn.key,class:classNames(Fn.className,Fn.class),column:Fn,colStart:Dn};let Hn=1;const zn=Fn.children;return zn&&zn.length>0&&(Hn=_n(zn,Dn,Rn+1).reduce((Wn,Yn)=>Wn+Yn,0),Bn.hasSubColumns=!0),"colSpan"in Fn&&({colSpan:Hn}=Fn),"rowSpan"in Fn&&(Bn.rowSpan=Fn.rowSpan),Bn.colSpan=Hn,Bn.colEnd=Bn.colStart+Hn-1,Cn[Rn].push(Bn),Dn+=Hn,Hn})}_n($n,0);const Pn=Cn.length;for(let In=0;In{!("rowSpan"in Nn)&&!Nn.hasSubColumns&&(Nn.rowSpan=Pn-In)});return Cn}const Header=defineComponent({name:"TableHeader",inheritAttrs:!1,props:["columns","flattenColumns","stickyOffsets","customHeaderRow"],setup($n){const Cn=useInjectTable(),_n=computed(()=>parseHeaderRows($n.columns));return()=>{const{prefixCls:Pn,getComponent:In}=Cn,{stickyOffsets:Nn,flattenColumns:Rn,customHeaderRow:Dn}=$n,Ln=In(["header","wrapper"],"thead"),Fn=In(["header","row"],"tr"),Bn=In(["header","cell"],"th");return createVNode(Ln,{class:`${Pn}-thead`},{default:()=>[_n.value.map((Hn,zn)=>createVNode(HeaderRow,{key:zn,flattenColumns:Rn,cells:Hn,stickyOffsets:Nn,rowComponent:Fn,cellComponent:Bn,customHeaderRow:Dn,index:zn},null))]})}}}),ExpandedRowContextKey=Symbol("ExpandedRowProps"),useProvideExpandedRow=$n=>{provide(ExpandedRowContextKey,$n)},useInjectExpandedRow=()=>inject(ExpandedRowContextKey,{}),ExpandedRow=defineComponent({name:"ExpandedRow",inheritAttrs:!1,props:["prefixCls","component","cellComponent","expanded","colSpan","isEmpty"],setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const In=useInjectTable(),Nn=useInjectExpandedRow(),{fixHeader:Rn,fixColumn:Dn,componentWidth:Ln,horizonScroll:Fn}=Nn;return()=>{const{prefixCls:Bn,component:Hn,cellComponent:zn,expanded:Wn,colSpan:Yn,isEmpty:Gn}=$n;return createVNode(Hn,{class:Pn.class,style:{display:Wn?null:"none"}},{default:()=>[createVNode(Cell,{component:zn,prefixCls:Bn,colSpan:Yn},{default:()=>{var Go;let Xn=(Go=_n.default)===null||Go===void 0?void 0:Go.call(_n);return(Gn?Fn.value:Dn.value)&&(Xn=createVNode("div",{style:{width:`${Ln.value-(Rn.value?In.scrollbarSize:0)}px`,position:"sticky",left:0,overflow:"hidden"},class:`${Bn}-expanded-row-fixed`},[Xn])),Xn}})]})}}}),MeasureCell=defineComponent({name:"MeasureCell",props:["columnKey"],setup($n,Cn){let{emit:_n}=Cn;const Pn=ref();return onMounted(()=>{Pn.value&&_n("columnResize",$n.columnKey,Pn.value.offsetWidth)}),()=>createVNode(ResizeObserver$1,{onResize:In=>{let{offsetWidth:Nn}=In;_n("columnResize",$n.columnKey,Nn)}},{default:()=>[createVNode("td",{ref:Pn,style:{padding:0,border:0,height:0}},[createVNode("div",{style:{height:0,overflow:"hidden"}},[createTextVNode(" ")])])]})}}),BodyContextKey=Symbol("BodyContextProps"),useProvideBody=$n=>{provide(BodyContextKey,$n)},useInjectBody=()=>inject(BodyContextKey,{}),BodyRow=defineComponent({name:"BodyRow",inheritAttrs:!1,props:["record","index","renderIndex","recordKey","expandedKeys","rowComponent","cellComponent","customRow","rowExpandable","indent","rowKey","getRowKey","childrenColumnName"],setup($n,Cn){let{attrs:_n}=Cn;const Pn=useInjectTable(),In=useInjectBody(),Nn=shallowRef(!1),Rn=computed(()=>$n.expandedKeys&&$n.expandedKeys.has($n.recordKey));watchEffect(()=>{Rn.value&&(Nn.value=!0)});const Dn=computed(()=>In.expandableType==="row"&&(!$n.rowExpandable||$n.rowExpandable($n.record))),Ln=computed(()=>In.expandableType==="nest"),Fn=computed(()=>$n.childrenColumnName&&$n.record&&$n.record[$n.childrenColumnName]),Bn=computed(()=>Dn.value||Ln.value),Hn=(Go,Xn)=>{In.onTriggerExpand(Go,Xn)},zn=computed(()=>{var Go;return((Go=$n.customRow)===null||Go===void 0?void 0:Go.call($n,$n.record,$n.index))||{}}),Wn=function(Go){var Xn,Yo;In.expandRowByClick&&Bn.value&&Hn($n.record,Go);for(var qo=arguments.length,Jo=new Array(qo>1?qo-1:0),Zo=1;Zo{const{record:Go,index:Xn,indent:Yo}=$n,{rowClassName:qo}=In;return typeof qo=="string"?qo:typeof qo=="function"?qo(Go,Xn,Yo):""}),Gn=computed(()=>getColumnsKey(In.flattenColumns));return()=>{const{class:Go,style:Xn}=_n,{record:Yo,index:qo,rowKey:Jo,indent:Zo=0,rowComponent:rr,cellComponent:nr}=$n,{prefixCls:ta,fixedInfoList:oa,transformCellText:ra}=Pn,{flattenColumns:ea,expandedRowClassName:la,indentSize:ua,expandIcon:ga,expandedRowRender:aa,expandIconColumnIndex:ca}=In,sa=createVNode(rr,_objectSpread2$1(_objectSpread2$1({},zn.value),{},{"data-row-key":Jo,class:classNames(Go,`${ta}-row`,`${ta}-row-level-${Zo}`,Yn.value,zn.value.class),style:[Xn,zn.value.style],onClick:Wn}),{default:()=>[ea.map((fa,ma)=>{const{customRender:ya,dataIndex:ba,className:Ia}=fa,Ea=Gn[ma],xa=oa[ma];let Ta;fa.customCell&&(Ta=fa.customCell(Yo,qo,fa));const wa=ma===(ca||0)&&Ln.value?createVNode(Fragment,null,[createVNode("span",{style:{paddingLeft:`${ua*Zo}px`},class:`${ta}-row-indent indent-level-${Zo}`},null),ga({prefixCls:ta,expanded:Rn.value,expandable:Fn.value,record:Yo,onExpand:Hn})]):null;return createVNode(Cell,_objectSpread2$1(_objectSpread2$1({cellType:"body",class:Ia,ellipsis:fa.ellipsis,align:fa.align,component:nr,prefixCls:ta,key:Ea,record:Yo,index:qo,renderIndex:$n.renderIndex,dataIndex:ba,customRender:ya},xa),{},{additionalProps:Ta,column:fa,transformCellText:ra,appendNode:wa}),null)})]});let ia;if(Dn.value&&(Nn.value||Rn.value)){const fa=aa({record:Yo,index:qo,indent:Zo+1,expanded:Rn.value}),ma=la&&la(Yo,qo,Zo);ia=createVNode(ExpandedRow,{expanded:Rn.value,class:classNames(`${ta}-expanded-row`,`${ta}-expanded-row-level-${Zo+1}`,ma),prefixCls:ta,component:rr,cellComponent:nr,colSpan:ea.length,isEmpty:!1},{default:()=>[fa]})}return createVNode(Fragment,null,[sa,ia])}}});function flatRecord($n,Cn,_n,Pn,In,Nn){const Rn=[];Rn.push({record:$n,indent:Cn,index:Nn});const Dn=In($n),Ln=Pn==null?void 0:Pn.has(Dn);if($n&&Array.isArray($n[_n])&&Ln)for(let Fn=0;Fn<$n[_n].length;Fn+=1){const Bn=flatRecord($n[_n][Fn],Cn+1,_n,Pn,In,Fn);Rn.push(...Bn)}return Rn}function useFlattenRecords($n,Cn,_n,Pn){return computed(()=>{const Nn=Cn.value,Rn=_n.value,Dn=$n.value;if(Rn!=null&&Rn.size){const Ln=[];for(let Fn=0;Fn<(Dn==null?void 0:Dn.length);Fn+=1){const Bn=Dn[Fn];Ln.push(...flatRecord(Bn,0,Nn,Rn,Pn.value,Fn))}return Ln}return Dn==null?void 0:Dn.map((Ln,Fn)=>({record:Ln,indent:0,index:Fn}))})}const ResizeContextKey=Symbol("ResizeContextProps"),useProvideResize=$n=>{provide(ResizeContextKey,$n)},useInjectResize=()=>inject(ResizeContextKey,{onColumnResize:()=>{}}),Body=defineComponent({name:"TableBody",props:["data","getRowKey","measureColumnWidth","expandedKeys","customRow","rowExpandable","childrenColumnName"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectResize(),In=useInjectTable(),Nn=useInjectBody(),Rn=useFlattenRecords(toRef($n,"data"),toRef($n,"childrenColumnName"),toRef($n,"expandedKeys"),toRef($n,"getRowKey")),Dn=shallowRef(-1),Ln=shallowRef(-1);let Fn;return useProvideHover({startRow:Dn,endRow:Ln,onHover:(Bn,Hn)=>{clearTimeout(Fn),Fn=setTimeout(()=>{Dn.value=Bn,Ln.value=Hn},100)}}),()=>{var Bn;const{data:Hn,getRowKey:zn,measureColumnWidth:Wn,expandedKeys:Yn,customRow:Gn,rowExpandable:Go,childrenColumnName:Xn}=$n,{onColumnResize:Yo}=Pn,{prefixCls:qo,getComponent:Jo}=In,{flattenColumns:Zo}=Nn,rr=Jo(["body","wrapper"],"tbody"),nr=Jo(["body","row"],"tr"),ta=Jo(["body","cell"],"td");let oa;Hn.length?oa=Rn.value.map((ea,la)=>{const{record:ua,indent:ga,index:aa}=ea,ca=zn(ua,la);return createVNode(BodyRow,{key:ca,rowKey:ca,record:ua,recordKey:ca,index:la,renderIndex:aa,rowComponent:nr,cellComponent:ta,expandedKeys:Yn,customRow:Gn,getRowKey:zn,rowExpandable:Go,childrenColumnName:Xn,indent:ga},null)}):oa=createVNode(ExpandedRow,{expanded:!0,class:`${qo}-placeholder`,prefixCls:qo,component:nr,cellComponent:ta,colSpan:Zo.length,isEmpty:!0},{default:()=>[(Bn=_n.emptyNode)===null||Bn===void 0?void 0:Bn.call(_n)]});const ra=getColumnsKey(Zo);return createVNode(rr,{class:`${qo}-tbody`},{default:()=>[Wn&&createVNode("tr",{"aria-hidden":"true",class:`${qo}-measure-row`,style:{height:0,fontSize:0}},[ra.map(ea=>createVNode(MeasureCell,{key:ea,columnKey:ea,onColumnResize:Yo},null))]),oa]})}}}),EXPAND_COLUMN={};var __rest$h=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const{fixed:Pn}=_n,In=Pn===!0?"left":Pn,Nn=_n.children;return Nn&&Nn.length>0?[...Cn,...flatColumns(Nn).map(Rn=>_extends$1({fixed:In},Rn))]:[...Cn,_extends$1(_extends$1({},_n),{fixed:In})]},[])}function revertForRtl($n){return $n.map(Cn=>{const{fixed:_n}=Cn,Pn=__rest$h(Cn,["fixed"]);let In=_n;return _n==="left"?In="right":_n==="right"&&(In="left"),_extends$1({fixed:In},Pn)})}function useColumns$1($n,Cn){let{prefixCls:_n,columns:Pn,expandable:In,expandedKeys:Nn,getRowKey:Rn,onTriggerExpand:Dn,expandIcon:Ln,rowExpandable:Fn,expandIconColumnIndex:Bn,direction:Hn,expandRowByClick:zn,expandColumnWidth:Wn,expandFixed:Yn}=$n;const Gn=useInjectSlots(),Go=computed(()=>{if(In.value){let qo=Pn.value.slice();if(!qo.includes(EXPAND_COLUMN)){const ua=Bn.value||0;ua>=0&&qo.splice(ua,0,EXPAND_COLUMN)}const Jo=qo.indexOf(EXPAND_COLUMN);qo=qo.filter((ua,ga)=>ua!==EXPAND_COLUMN||ga===Jo);const Zo=Pn.value[Jo];let rr;(Yn.value==="left"||Yn.value)&&!Bn.value?rr="left":(Yn.value==="right"||Yn.value)&&Bn.value===Pn.value.length?rr="right":rr=Zo?Zo.fixed:null;const nr=Nn.value,ta=Fn.value,oa=Ln.value,ra=_n.value,ea=zn.value,la={[INTERNAL_COL_DEFINE]:{class:`${_n.value}-expand-icon-col`,columnType:"EXPAND_COLUMN"},title:customRenderSlot(Gn.value,"expandColumnTitle",{},()=>[""]),fixed:rr,class:`${_n.value}-row-expand-icon-cell`,width:Wn.value,customRender:ua=>{let{record:ga,index:aa}=ua;const ca=Rn.value(ga,aa),sa=nr.has(ca),ia=ta?ta(ga):!0,fa=oa({prefixCls:ra,expanded:sa,expandable:ia,record:ga,onExpand:Dn});return ea?createVNode("span",{onClick:ma=>ma.stopPropagation()},[fa]):fa}};return qo.map(ua=>ua===EXPAND_COLUMN?la:ua)}return Pn.value.filter(qo=>qo!==EXPAND_COLUMN)}),Xn=computed(()=>{let qo=Go.value;return Cn.value&&(qo=Cn.value(qo)),qo.length||(qo=[{customRender:()=>null}]),qo}),Yo=computed(()=>Hn.value==="rtl"?revertForRtl(flatColumns(Xn.value)):flatColumns(Xn.value));return[Xn,Yo]}function useLayoutState($n){const Cn=shallowRef($n);let _n;const Pn=shallowRef([]);function In(Nn){Pn.value.push(Nn),wrapperRaf.cancel(_n),_n=wrapperRaf(()=>{const Rn=Pn.value;Pn.value=[],Rn.forEach(Dn=>{Cn.value=Dn(Cn.value)})})}return onBeforeUnmount(()=>{wrapperRaf.cancel(_n)}),[Cn,In]}function useTimeoutLock($n){const Cn=ref($n||null),_n=ref();function Pn(){clearTimeout(_n.value)}function In(Rn){Cn.value=Rn,Pn(),_n.value=setTimeout(()=>{Cn.value=null,_n.value=void 0},100)}function Nn(){return Cn.value}return onBeforeUnmount(()=>{Pn()}),[In,Nn]}function useStickyOffsets($n,Cn,_n){return computed(()=>{const In=[],Nn=[];let Rn=0,Dn=0;const Ln=$n.value,Fn=Cn.value,Bn=_n.value;for(let Hn=0;Hn=0;Dn-=1){const Ln=Cn[Dn],Fn=_n&&_n[Dn],Bn=Fn&&Fn[INTERNAL_COL_DEFINE];if(Ln||Bn||Rn){const Hn=Bn||{},zn=__rest$g(Hn,["columnType"]);In.unshift(createVNode("col",_objectSpread2$1({key:Dn,style:{width:typeof Ln=="number"?`${Ln}px`:Ln}},zn),null)),Rn=!0}}return createVNode("colgroup",null,[In])}function Panel($n,Cn){let{slots:_n}=Cn;var Pn;return createVNode("div",null,[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)])}Panel.displayName="Panel";let indexGuid=0;const Summary=defineComponent({name:"TableSummary",props:["fixed"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectTable(),In=`table-summary-uni-key-${++indexGuid}`,Nn=computed(()=>$n.fixed===""||$n.fixed);return watchEffect(()=>{Pn.summaryCollect(In,Nn.value)}),onBeforeUnmount(()=>{Pn.summaryCollect(In,!1)}),()=>{var Rn;return(Rn=_n.default)===null||Rn===void 0?void 0:Rn.call(_n)}}}),Summary$1=Summary,SummaryRow=defineComponent({compatConfig:{MODE:3},name:"ATableSummaryRow",setup($n,Cn){let{slots:_n}=Cn;return()=>{var Pn;return createVNode("tr",null,[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)])}}}),SummaryContextKey=Symbol("SummaryContextProps"),useProvideSummary=$n=>{provide(SummaryContextKey,$n)},useInjectSummary=()=>inject(SummaryContextKey,{}),SummaryCell=defineComponent({name:"ATableSummaryCell",props:["index","colSpan","rowSpan","align"],setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=useInjectTable(),Nn=useInjectSummary();return()=>{const{index:Rn,colSpan:Dn=1,rowSpan:Ln,align:Fn}=$n,{prefixCls:Bn,direction:Hn}=In,{scrollColumnIndex:zn,stickyOffsets:Wn,flattenColumns:Yn}=Nn,Go=Rn+Dn-1+1===zn?Dn+1:Dn,Xn=getCellFixedInfo(Rn,Rn+Go-1,Yn,Wn,Hn);return createVNode(Cell,_objectSpread2$1({class:_n.class,index:Rn,component:"td",prefixCls:Bn,record:null,dataIndex:null,align:Fn,colSpan:Go,rowSpan:Ln,customRender:()=>{var Yo;return(Yo=Pn.default)===null||Yo===void 0?void 0:Yo.call(Pn)}},Xn),null)}}}),Footer=defineComponent({name:"TableFooter",inheritAttrs:!1,props:["stickyOffsets","flattenColumns"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectTable();return useProvideSummary(reactive({stickyOffsets:toRef($n,"stickyOffsets"),flattenColumns:toRef($n,"flattenColumns"),scrollColumnIndex:computed(()=>{const In=$n.flattenColumns.length-1,Nn=$n.flattenColumns[In];return Nn!=null&&Nn.scrollbar?In:null})})),()=>{var In;const{prefixCls:Nn}=Pn;return createVNode("tfoot",{class:`${Nn}-summary`},[(In=_n.default)===null||In===void 0?void 0:In.call(_n)])}}}),FooterComponents=Summary$1;function renderExpandIcon$1($n){let{prefixCls:Cn,record:_n,onExpand:Pn,expanded:In,expandable:Nn}=$n;const Rn=`${Cn}-row-expand-icon`;if(!Nn)return createVNode("span",{class:[Rn,`${Cn}-row-spaced`]},null);const Dn=Ln=>{Pn(_n,Ln),Ln.stopPropagation()};return createVNode("span",{class:{[Rn]:!0,[`${Cn}-row-expanded`]:In,[`${Cn}-row-collapsed`]:!In},onClick:Dn},null)}function findAllChildrenKeys($n,Cn,_n){const Pn=[];function In(Nn){(Nn||[]).forEach((Rn,Dn)=>{Pn.push(Cn(Rn,Dn)),In(Rn[_n])})}return In($n),Pn}const StickyScrollBar=defineComponent({name:"StickyScrollBar",inheritAttrs:!1,props:["offsetScroll","container","scrollBodyRef","scrollBodySizeInfo"],emits:["scroll"],setup($n,Cn){let{emit:_n,expose:Pn}=Cn;const In=useInjectTable(),Nn=shallowRef(0),Rn=shallowRef(0),Dn=shallowRef(0);watchEffect(()=>{Nn.value=$n.scrollBodySizeInfo.scrollWidth||0,Rn.value=$n.scrollBodySizeInfo.clientWidth||0,Dn.value=Nn.value&&Rn.value*(Rn.value/Nn.value)},{flush:"post"});const Ln=shallowRef(),[Fn,Bn]=useLayoutState({scrollLeft:0,isHiddenScrollBar:!0}),Hn=ref({delta:0,x:0}),zn=shallowRef(!1),Wn=()=>{zn.value=!1},Yn=nr=>{Hn.value={delta:nr.pageX-Fn.value.scrollLeft,x:0},zn.value=!0,nr.preventDefault()},Gn=nr=>{const{buttons:ta}=nr||(window==null?void 0:window.event);if(!zn.value||ta===0){zn.value&&(zn.value=!1);return}let oa=Hn.value.x+nr.pageX-Hn.value.x-Hn.value.delta;oa<=0&&(oa=0),oa+Dn.value>=Rn.value&&(oa=Rn.value-Dn.value),_n("scroll",{scrollLeft:oa/Rn.value*(Nn.value+2)}),Hn.value.x=nr.pageX},Go=()=>{if(!$n.scrollBodyRef.value)return;const nr=getOffset($n.scrollBodyRef.value).top,ta=nr+$n.scrollBodyRef.value.offsetHeight,oa=$n.container===window?document.documentElement.scrollTop+window.innerHeight:getOffset($n.container).top+$n.container.clientHeight;ta-getScrollBarSize()<=oa||nr>=oa-$n.offsetScroll?Bn(ra=>_extends$1(_extends$1({},ra),{isHiddenScrollBar:!0})):Bn(ra=>_extends$1(_extends$1({},ra),{isHiddenScrollBar:!1}))};Pn({setScrollLeft:nr=>{Bn(ta=>_extends$1(_extends$1({},ta),{scrollLeft:nr/Nn.value*Rn.value||0}))}});let Yo=null,qo=null,Jo=null,Zo=null;onMounted(()=>{Yo=addEventListenerWrap(document.body,"mouseup",Wn,!1),qo=addEventListenerWrap(document.body,"mousemove",Gn,!1),Jo=addEventListenerWrap(window,"resize",Go,!1)}),onActivated(()=>{nextTick(()=>{Go()})}),onMounted(()=>{setTimeout(()=>{watch([Dn,zn],()=>{Go()},{immediate:!0,flush:"post"})})}),watch(()=>$n.container,()=>{Zo==null||Zo.remove(),Zo=addEventListenerWrap($n.container,"scroll",Go,!1)},{immediate:!0,flush:"post"}),onBeforeUnmount(()=>{Yo==null||Yo.remove(),qo==null||qo.remove(),Zo==null||Zo.remove(),Jo==null||Jo.remove()}),watch(()=>_extends$1({},Fn.value),(nr,ta)=>{nr.isHiddenScrollBar!==(ta==null?void 0:ta.isHiddenScrollBar)&&!nr.isHiddenScrollBar&&Bn(oa=>{const ra=$n.scrollBodyRef.value;return ra?_extends$1(_extends$1({},oa),{scrollLeft:ra.scrollLeft/ra.scrollWidth*ra.clientWidth}):oa})},{immediate:!0});const rr=getScrollBarSize();return()=>{if(Nn.value<=Rn.value||!Dn.value||Fn.value.isHiddenScrollBar)return null;const{prefixCls:nr}=In;return createVNode("div",{style:{height:`${rr}px`,width:`${Rn.value}px`,bottom:`${$n.offsetScroll}px`},class:`${nr}-sticky-scroll`},[createVNode("div",{onMousedown:Yn,ref:Ln,class:classNames(`${nr}-sticky-scroll-bar`,{[`${nr}-sticky-scroll-bar-active`]:zn.value}),style:{width:`${Dn.value}px`,transform:`translate3d(${Fn.value.scrollLeft}px, 0, 0)`}},null)])}}}),defaultContainer=canUseDom$1()?window:null;function useSticky($n,Cn){return computed(()=>{const{offsetHeader:_n=0,offsetSummary:Pn=0,offsetScroll:In=0,getContainer:Nn=()=>defaultContainer}=typeof $n.value=="object"?$n.value:{},Rn=Nn()||defaultContainer,Dn=!!$n.value;return{isSticky:Dn,stickyClassName:Dn?`${Cn.value}-sticky-holder`:"",offsetHeader:_n,offsetSummary:Pn,offsetScroll:In,container:Rn}})}function useColumnWidth($n,Cn){return computed(()=>{const _n=[],Pn=$n.value,In=Cn.value;for(let Nn=0;NnNn.isSticky&&!$n.fixHeader?0:Nn.scrollbarSize),Dn=ref(),Ln=Gn=>{const{currentTarget:Go,deltaX:Xn}=Gn;Xn&&(In("scroll",{currentTarget:Go,scrollLeft:Go.scrollLeft+Xn}),Gn.preventDefault())},Fn=ref();onMounted(()=>{nextTick(()=>{Fn.value=addEventListenerWrap(Dn.value,"wheel",Ln)})}),onBeforeUnmount(()=>{var Gn;(Gn=Fn.value)===null||Gn===void 0||Gn.remove()});const Bn=computed(()=>$n.flattenColumns.every(Gn=>Gn.width&&Gn.width!==0&&Gn.width!=="0px")),Hn=ref([]),zn=ref([]);watchEffect(()=>{const Gn=$n.flattenColumns[$n.flattenColumns.length-1],Go={fixed:Gn?Gn.fixed:null,scrollbar:!0,customHeaderCell:()=>({class:`${Nn.prefixCls}-cell-scrollbar`})};Hn.value=Rn.value?[...$n.columns,Go]:$n.columns,zn.value=Rn.value?[...$n.flattenColumns,Go]:$n.flattenColumns});const Wn=computed(()=>{const{stickyOffsets:Gn,direction:Go}=$n,{right:Xn,left:Yo}=Gn;return _extends$1(_extends$1({},Gn),{left:Go==="rtl"?[...Yo.map(qo=>qo+Rn.value),0]:Yo,right:Go==="rtl"?Xn:[...Xn.map(qo=>qo+Rn.value),0],isSticky:Nn.isSticky})}),Yn=useColumnWidth(toRef($n,"colWidths"),toRef($n,"columCount"));return()=>{var Gn;const{noData:Go,columCount:Xn,stickyTopOffset:Yo,stickyBottomOffset:qo,stickyClassName:Jo,maxContentScroll:Zo}=$n,{isSticky:rr}=Nn;return createVNode("div",{style:_extends$1({overflow:"hidden"},rr?{top:`${Yo}px`,bottom:`${qo}px`}:{}),ref:Dn,class:classNames(_n.class,{[Jo]:!!Jo})},[createVNode("table",{style:{tableLayout:"fixed",visibility:Go||Yn.value?null:"hidden"}},[(!Go||!Zo||Bn.value)&&createVNode(ColGroup,{colWidths:Yn.value?[...Yn.value,Rn.value]:[],columCount:Xn+1,columns:zn.value},null),(Gn=Pn.default)===null||Gn===void 0?void 0:Gn.call(Pn,_extends$1(_extends$1({},$n),{stickyOffsets:Wn.value,columns:Hn.value,flattenColumns:zn.value}))])])}}});function reactivePick($n){for(var Cn=arguments.length,_n=new Array(Cn>1?Cn-1:0),Pn=1;Pn[In,toRef($n,In)])))}const EMPTY_DATA=[],EMPTY_SCROLL_TARGET={},INTERNAL_HOOKS="rc-table-internal-hook",Table$2=defineComponent({name:"VcTable",inheritAttrs:!1,props:["prefixCls","data","columns","rowKey","tableLayout","scroll","rowClassName","title","footer","id","showHeader","components","customRow","customHeaderRow","direction","expandFixed","expandColumnWidth","expandedRowKeys","defaultExpandedRowKeys","expandedRowRender","expandRowByClick","expandIcon","onExpand","onExpandedRowsChange","onUpdate:expandedRowKeys","defaultExpandAllRows","indentSize","expandIconColumnIndex","expandedRowClassName","childrenColumnName","rowExpandable","sticky","transformColumns","internalHooks","internalRefs","canExpandable","onUpdateInternalRefs","transformCellText"],emits:["expand","expandedRowsChange","updateInternalRefs","update:expandedRowKeys"],setup($n,Cn){let{attrs:_n,slots:Pn,emit:In}=Cn;const Nn=computed(()=>$n.data||EMPTY_DATA),Rn=computed(()=>!!Nn.value.length),Dn=computed(()=>mergeObject($n.components,{})),Ln=(Ma,Ua)=>getPathValue(Dn.value,Ma)||Ua,Fn=computed(()=>{const Ma=$n.rowKey;return typeof Ma=="function"?Ma:Ua=>Ua&&Ua[Ma]}),Bn=computed(()=>$n.expandIcon||renderExpandIcon$1),Hn=computed(()=>$n.childrenColumnName||"children"),zn=computed(()=>$n.expandedRowRender?"row":$n.canExpandable||Nn.value.some(Ma=>Ma&&typeof Ma=="object"&&Ma[Hn.value])?"nest":!1),Wn=shallowRef([]);watchEffect(()=>{$n.defaultExpandedRowKeys&&(Wn.value=$n.defaultExpandedRowKeys),$n.defaultExpandAllRows&&(Wn.value=findAllChildrenKeys(Nn.value,Fn.value,Hn.value))})();const Gn=computed(()=>new Set($n.expandedRowKeys||Wn.value||[])),Go=Ma=>{const Ua=Fn.value(Ma,Nn.value.indexOf(Ma));let Qa;const ri=Gn.value.has(Ua);ri?(Gn.value.delete(Ua),Qa=[...Gn.value]):Qa=[...Gn.value,Ua],Wn.value=Qa,In("expand",!ri,Ma),In("update:expandedRowKeys",Qa),In("expandedRowsChange",Qa)},Xn=ref(0),[Yo,qo]=useColumns$1(_extends$1(_extends$1({},toRefs($n)),{expandable:computed(()=>!!$n.expandedRowRender),expandedKeys:Gn,getRowKey:Fn,onTriggerExpand:Go,expandIcon:Bn}),computed(()=>$n.internalHooks===INTERNAL_HOOKS?$n.transformColumns:null)),Jo=computed(()=>({columns:Yo.value,flattenColumns:qo.value})),Zo=ref(),rr=ref(),nr=ref(),ta=ref({scrollWidth:0,clientWidth:0}),oa=ref(),[ra,ea]=useState(!1),[la,ua]=useState(!1),[ga,aa]=useLayoutState(new Map),ca=computed(()=>getColumnsKey(qo.value)),sa=computed(()=>ca.value.map(Ma=>ga.value.get(Ma))),ia=computed(()=>qo.value.length),fa=useStickyOffsets(sa,ia,toRef($n,"direction")),ma=computed(()=>$n.scroll&&validateValue($n.scroll.y)),ya=computed(()=>$n.scroll&&validateValue($n.scroll.x)||!!$n.expandFixed),ba=computed(()=>ya.value&&qo.value.some(Ma=>{let{fixed:Ua}=Ma;return Ua})),Ia=ref(),Ea=useSticky(toRef($n,"sticky"),toRef($n,"prefixCls")),xa=reactive({}),Ta=computed(()=>{const Ma=Object.values(xa)[0];return(ma.value||Ea.value.isSticky)&&Ma}),wa=(Ma,Ua)=>{Ua?xa[Ma]=Ua:delete xa[Ma]},La=ref({}),Na=ref({}),$a=ref({});watchEffect(()=>{ma.value&&(Na.value={overflowY:"scroll",maxHeight:toPx($n.scroll.y)}),ya.value&&(La.value={overflowX:"auto"},ma.value||(Na.value={overflowY:"hidden"}),$a.value={width:$n.scroll.x===!0?"auto":toPx($n.scroll.x),minWidth:"100%"})});const ka=(Ma,Ua)=>{isVisible(Zo.value)&&aa(Qa=>{if(Qa.get(Ma)!==Ua){const ri=new Map(Qa);return ri.set(Ma,Ua),ri}return Qa})},[Ha,da]=useTimeoutLock(null);function pa(Ma,Ua){if(!Ua)return;if(typeof Ua=="function"){Ua(Ma);return}const Qa=Ua.$el||Ua;Qa.scrollLeft!==Ma&&(Qa.scrollLeft=Ma)}const Sa=Ma=>{let{currentTarget:Ua,scrollLeft:Qa}=Ma;var ri;const fi=$n.direction==="rtl",ei=typeof Qa=="number"?Qa:Ua.scrollLeft,ti=Ua||EMPTY_SCROLL_TARGET;if((!da()||da()===ti)&&(Ha(ti),pa(ei,rr.value),pa(ei,nr.value),pa(ei,oa.value),pa(ei,(ri=Ia.value)===null||ri===void 0?void 0:ri.setScrollLeft)),Ua){const{scrollWidth:ni,clientWidth:ui}=Ua;fi?(ea(-ei0)):(ea(ei>0),ua(ei{ya.value&&nr.value?Sa({currentTarget:nr.value}):(ea(!1),ua(!1))};let Ra;const Fa=Ma=>{Ma!==Xn.value&&(Aa(),Xn.value=Zo.value?Zo.value.offsetWidth:Ma)},za=Ma=>{let{width:Ua}=Ma;if(clearTimeout(Ra),Xn.value===0){Fa(Ua);return}Ra=setTimeout(()=>{Fa(Ua)},100)};watch([ya,()=>$n.data,()=>$n.columns],()=>{ya.value&&Aa()},{flush:"post"});const[Wa,Ya]=useState(0);useProvideSticky(),onMounted(()=>{nextTick(()=>{var Ma,Ua;Aa(),Ya(getTargetScrollBarSize(nr.value).width),ta.value={scrollWidth:((Ma=nr.value)===null||Ma===void 0?void 0:Ma.scrollWidth)||0,clientWidth:((Ua=nr.value)===null||Ua===void 0?void 0:Ua.clientWidth)||0}})}),onUpdated(()=>{nextTick(()=>{var Ma,Ua;const Qa=((Ma=nr.value)===null||Ma===void 0?void 0:Ma.scrollWidth)||0,ri=((Ua=nr.value)===null||Ua===void 0?void 0:Ua.clientWidth)||0;(ta.value.scrollWidth!==Qa||ta.value.clientWidth!==ri)&&(ta.value={scrollWidth:Qa,clientWidth:ri})})}),watchEffect(()=>{$n.internalHooks===INTERNAL_HOOKS&&$n.internalRefs&&$n.onUpdateInternalRefs({body:nr.value?nr.value.$el||nr.value:null})},{flush:"post"});const ja=computed(()=>$n.tableLayout?$n.tableLayout:ba.value?$n.scroll.x==="max-content"?"auto":"fixed":ma.value||Ea.value.isSticky||qo.value.some(Ma=>{let{ellipsis:Ua}=Ma;return Ua})?"fixed":"auto"),qa=()=>{var Ma;return Rn.value?null:((Ma=Pn.emptyText)===null||Ma===void 0?void 0:Ma.call(Pn))||"No Data"};useProvideTable(reactive(_extends$1(_extends$1({},toRefs(reactivePick($n,"prefixCls","direction","transformCellText"))),{getComponent:Ln,scrollbarSize:Wa,fixedInfoList:computed(()=>qo.value.map((Ma,Ua)=>getCellFixedInfo(Ua,Ua,qo.value,fa.value,$n.direction))),isSticky:computed(()=>Ea.value.isSticky),summaryCollect:wa}))),useProvideBody(reactive(_extends$1(_extends$1({},toRefs(reactivePick($n,"rowClassName","expandedRowClassName","expandRowByClick","expandedRowRender","expandIconColumnIndex","indentSize"))),{columns:Yo,flattenColumns:qo,tableLayout:ja,expandIcon:Bn,expandableType:zn,onTriggerExpand:Go}))),useProvideResize({onColumnResize:ka}),useProvideExpandedRow({componentWidth:Xn,fixHeader:ma,fixColumn:ba,horizonScroll:ya});const Xa=()=>createVNode(Body,{data:Nn.value,measureColumnWidth:ma.value||ya.value||Ea.value.isSticky,expandedKeys:Gn.value,rowExpandable:$n.rowExpandable,getRowKey:Fn.value,customRow:$n.customRow,childrenColumnName:Hn.value},{emptyNode:qa}),Oa=()=>createVNode(ColGroup,{colWidths:qo.value.map(Ma=>{let{width:Ua}=Ma;return Ua}),columns:qo.value},null);return()=>{var Ma;const{prefixCls:Ua,scroll:Qa,tableLayout:ri,direction:fi,title:ei=Pn.title,footer:ti=Pn.footer,id:ni,showHeader:ui,customHeaderRow:mi}=$n,{isSticky:di,offsetHeader:gi,offsetSummary:wi,offsetScroll:Ti,stickyClassName:Ei,container:Ni}=Ea.value,Ri=Ln(["table"],"table"),Zi=Ln(["body"]),Qi=(Ma=Pn.summary)===null||Ma===void 0?void 0:Ma.call(Pn,{pageData:Nn.value});let Ji=()=>null;const Yi={colWidths:sa.value,columCount:qo.value.length,stickyOffsets:fa.value,customHeaderRow:mi,fixHeader:ma.value,scroll:Qa};if(ma.value||di){let il=()=>null;typeof Zi=="function"?(il=()=>Zi(Nn.value,{scrollbarSize:Wa.value,ref:nr,onScroll:Sa}),Yi.colWidths=qo.value.map((ul,ts)=>{let{width:ci}=ul;const Ci=ts===Yo.value.length-1?ci-Wa.value:ci;return typeof Ci=="number"&&!Number.isNaN(Ci)?Ci:0})):il=()=>createVNode("div",{style:_extends$1(_extends$1({},La.value),Na.value),onScroll:Sa,ref:nr,class:classNames(`${Ua}-body`)},[createVNode(Ri,{style:_extends$1(_extends$1({},$a.value),{tableLayout:ja.value})},{default:()=>[Oa(),Xa(),!Ta.value&&Qi&&createVNode(Footer,{stickyOffsets:fa.value,flattenColumns:qo.value},{default:()=>[Qi]})]})]);const Tl=_extends$1(_extends$1(_extends$1({noData:!Nn.value.length,maxContentScroll:ya.value&&Qa.x==="max-content"},Yi),Jo.value),{direction:fi,stickyClassName:Ei,onScroll:Sa});Ji=()=>createVNode(Fragment,null,[ui!==!1&&createVNode(FixedHolder,_objectSpread2$1(_objectSpread2$1({},Tl),{},{stickyTopOffset:gi,class:`${Ua}-header`,ref:rr}),{default:ul=>createVNode(Fragment,null,[createVNode(Header,ul,null),Ta.value==="top"&&createVNode(Footer,ul,{default:()=>[Qi]})])}),il(),Ta.value&&Ta.value!=="top"&&createVNode(FixedHolder,_objectSpread2$1(_objectSpread2$1({},Tl),{},{stickyBottomOffset:wi,class:`${Ua}-summary`,ref:oa}),{default:ul=>createVNode(Footer,ul,{default:()=>[Qi]})}),di&&nr.value&&createVNode(StickyScrollBar,{ref:Ia,offsetScroll:Ti,scrollBodyRef:nr,onScroll:Sa,container:Ni,scrollBodySizeInfo:ta.value},null)])}else Ji=()=>createVNode("div",{style:_extends$1(_extends$1({},La.value),Na.value),class:classNames(`${Ua}-content`),onScroll:Sa,ref:nr},[createVNode(Ri,{style:_extends$1(_extends$1({},$a.value),{tableLayout:ja.value})},{default:()=>[Oa(),ui!==!1&&createVNode(Header,_objectSpread2$1(_objectSpread2$1({},Yi),Jo.value),null),Xa(),Qi&&createVNode(Footer,{stickyOffsets:fa.value,flattenColumns:qo.value},{default:()=>[Qi]})]})]);const rl=pickAttrs(_n,{aria:!0,data:!0}),yi=()=>createVNode("div",_objectSpread2$1(_objectSpread2$1({},rl),{},{class:classNames(Ua,{[`${Ua}-rtl`]:fi==="rtl",[`${Ua}-ping-left`]:ra.value,[`${Ua}-ping-right`]:la.value,[`${Ua}-layout-fixed`]:ri==="fixed",[`${Ua}-fixed-header`]:ma.value,[`${Ua}-fixed-column`]:ba.value,[`${Ua}-scroll-horizontal`]:ya.value,[`${Ua}-has-fix-left`]:qo.value[0]&&qo.value[0].fixed,[`${Ua}-has-fix-right`]:qo.value[ia.value-1]&&qo.value[ia.value-1].fixed==="right",[_n.class]:_n.class}),style:_n.style,id:ni,ref:Zo}),[ei&&createVNode(Panel,{class:`${Ua}-title`},{default:()=>[ei(Nn.value)]}),createVNode("div",{class:`${Ua}-container`},[Ji()]),ti&&createVNode(Panel,{class:`${Ua}-footer`},{default:()=>[ti(Nn.value)]})]);return ya.value?createVNode(ResizeObserver$1,{onResize:za},{default:yi}):yi()}}});function extendsObject(){const $n=_extends$1({},arguments.length<=0?void 0:arguments[0]);for(let Cn=1;Cn{const In=_n[Pn];In!==void 0&&($n[Pn]=In)})}return $n}const DEFAULT_PAGE_SIZE=10;function getPaginationParam($n,Cn){const _n={current:$n.current,pageSize:$n.pageSize};return Object.keys(Cn&&typeof Cn=="object"?Cn:{}).forEach(In=>{const Nn=$n[In];typeof Nn!="function"&&(_n[In]=Nn)}),_n}function usePagination($n,Cn,_n){const Pn=computed(()=>Cn.value&&typeof Cn.value=="object"?Cn.value:{}),In=computed(()=>Pn.value.total||0),[Nn,Rn]=useState(()=>({current:"defaultCurrent"in Pn.value?Pn.value.defaultCurrent:1,pageSize:"defaultPageSize"in Pn.value?Pn.value.defaultPageSize:DEFAULT_PAGE_SIZE})),Dn=computed(()=>{const Bn=extendsObject(Nn.value,Pn.value,{total:In.value>0?In.value:$n.value}),Hn=Math.ceil((In.value||$n.value)/Bn.pageSize);return Bn.current>Hn&&(Bn.current=Hn||1),Bn}),Ln=(Bn,Hn)=>{Cn.value!==!1&&Rn({current:Bn??1,pageSize:Hn||Dn.value.pageSize})},Fn=(Bn,Hn)=>{var zn,Wn;Cn.value&&((Wn=(zn=Pn.value).onChange)===null||Wn===void 0||Wn.call(zn,Bn,Hn)),Ln(Bn,Hn),_n(Bn,Hn||Dn.value.pageSize)};return[computed(()=>Cn.value===!1?{}:_extends$1(_extends$1({},Dn.value),{onChange:Fn})),Ln]}function useLazyKVMap($n,Cn,_n){const Pn=shallowRef({});watch([$n,Cn,_n],()=>{const Nn=new Map,Rn=_n.value,Dn=Cn.value;function Ln(Fn){Fn.forEach((Bn,Hn)=>{const zn=Rn(Bn,Hn);Nn.set(zn,Bn),Bn&&typeof Bn=="object"&&Dn in Bn&&Ln(Bn[Dn]||[])})}Ln($n.value),Pn.value={kvMap:Nn}},{deep:!0,immediate:!0});function In(Nn){return Pn.value.kvMap.get(Nn)}return[In]}const SELECTION_COLUMN={},SELECTION_ALL="SELECT_ALL",SELECTION_INVERT="SELECT_INVERT",SELECTION_NONE="SELECT_NONE",EMPTY_LIST$1=[];function flattenData($n,Cn){let _n=[];return(Cn||[]).forEach(Pn=>{_n.push(Pn),Pn&&typeof Pn=="object"&&$n in Pn&&(_n=[..._n,...flattenData($n,Pn[$n])])}),_n}function useSelection($n,Cn){const _n=computed(()=>{const oa=$n.value||{},{checkStrictly:ra=!0}=oa;return _extends$1(_extends$1({},oa),{checkStrictly:ra})}),[Pn,In]=useMergedState(_n.value.selectedRowKeys||_n.value.defaultSelectedRowKeys||EMPTY_LIST$1,{value:computed(()=>_n.value.selectedRowKeys)}),Nn=shallowRef(new Map),Rn=oa=>{if(_n.value.preserveSelectedRowKeys){const ra=new Map;oa.forEach(ea=>{let la=Cn.getRecordByKey(ea);!la&&Nn.value.has(ea)&&(la=Nn.value.get(ea)),ra.set(ea,la)}),Nn.value=ra}};watchEffect(()=>{Rn(Pn.value)});const Dn=computed(()=>_n.value.checkStrictly?null:convertDataToEntities(Cn.data.value,{externalGetKey:Cn.getRowKey.value,childrenPropName:Cn.childrenColumnName.value}).keyEntities),Ln=computed(()=>flattenData(Cn.childrenColumnName.value,Cn.pageData.value)),Fn=computed(()=>{const oa=new Map,ra=Cn.getRowKey.value,ea=_n.value.getCheckboxProps;return Ln.value.forEach((la,ua)=>{const ga=ra(la,ua),aa=(ea?ea(la):null)||{};oa.set(ga,aa)}),oa}),{maxLevel:Bn,levelEntities:Hn}=useMaxLevel(Dn),zn=oa=>{var ra;return!!(!((ra=Fn.value.get(Cn.getRowKey.value(oa)))===null||ra===void 0)&&ra.disabled)},Wn=computed(()=>{if(_n.value.checkStrictly)return[Pn.value||[],[]];const{checkedKeys:oa,halfCheckedKeys:ra}=conductCheck(Pn.value,!0,Dn.value,Bn.value,Hn.value,zn);return[oa||[],ra]}),Yn=computed(()=>Wn.value[0]),Gn=computed(()=>Wn.value[1]),Go=computed(()=>{const oa=_n.value.type==="radio"?Yn.value.slice(0,1):Yn.value;return new Set(oa)}),Xn=computed(()=>_n.value.type==="radio"?new Set:new Set(Gn.value)),[Yo,qo]=useState(null),Jo=oa=>{let ra,ea;Rn(oa);const{preserveSelectedRowKeys:la,onChange:ua}=_n.value,{getRecordByKey:ga}=Cn;la?(ra=oa,ea=oa.map(aa=>Nn.value.get(aa))):(ra=[],ea=[],oa.forEach(aa=>{const ca=ga(aa);ca!==void 0&&(ra.push(aa),ea.push(ca))})),In(ra),ua==null||ua(ra,ea)},Zo=(oa,ra,ea,la)=>{const{onSelect:ua}=_n.value,{getRecordByKey:ga}=Cn||{};if(ua){const aa=ea.map(ca=>ga(ca));ua(ga(oa),ra,aa,la)}Jo(ea)},rr=computed(()=>{const{onSelectInvert:oa,onSelectNone:ra,selections:ea,hideSelectAll:la}=_n.value,{data:ua,pageData:ga,getRowKey:aa,locale:ca}=Cn;return!ea||la?null:(ea===!0?[SELECTION_ALL,SELECTION_INVERT,SELECTION_NONE]:ea).map(ia=>ia===SELECTION_ALL?{key:"all",text:ca.value.selectionAll,onSelect(){Jo(ua.value.map((fa,ma)=>aa.value(fa,ma)).filter(fa=>{const ma=Fn.value.get(fa);return!(ma!=null&&ma.disabled)||Go.value.has(fa)}))}}:ia===SELECTION_INVERT?{key:"invert",text:ca.value.selectInvert,onSelect(){const fa=new Set(Go.value);ga.value.forEach((ya,ba)=>{const Ia=aa.value(ya,ba),Ea=Fn.value.get(Ia);Ea!=null&&Ea.disabled||(fa.has(Ia)?fa.delete(Ia):fa.add(Ia))});const ma=Array.from(fa);oa&&(devWarning(!1,"Table","`onSelectInvert` will be removed in future. Please use `onChange` instead."),oa(ma)),Jo(ma)}}:ia===SELECTION_NONE?{key:"none",text:ca.value.selectNone,onSelect(){ra==null||ra(),Jo(Array.from(Go.value).filter(fa=>{const ma=Fn.value.get(fa);return ma==null?void 0:ma.disabled}))}}:ia)}),nr=computed(()=>Ln.value.length);return[oa=>{var ra;const{onSelectAll:ea,onSelectMultiple:la,columnWidth:ua,type:ga,fixed:aa,renderCell:ca,hideSelectAll:sa,checkStrictly:ia}=_n.value,{prefixCls:fa,getRecordByKey:ma,getRowKey:ya,expandType:ba,getPopupContainer:Ia}=Cn;if(!$n.value)return oa.filter(Fa=>Fa!==SELECTION_COLUMN);let Ea=oa.slice();const xa=new Set(Go.value),Ta=Ln.value.map(ya.value).filter(Fa=>!Fn.value.get(Fa).disabled),wa=Ta.every(Fa=>xa.has(Fa)),La=Ta.some(Fa=>xa.has(Fa)),Na=()=>{const Fa=[];wa?Ta.forEach(Wa=>{xa.delete(Wa),Fa.push(Wa)}):Ta.forEach(Wa=>{xa.has(Wa)||(xa.add(Wa),Fa.push(Wa))});const za=Array.from(xa);ea==null||ea(!wa,za.map(Wa=>ma(Wa)),Fa.map(Wa=>ma(Wa))),Jo(za)};let $a;if(ga!=="radio"){let Fa;if(rr.value){const qa=createVNode(Menu,{getPopupContainer:Ia.value},{default:()=>[rr.value.map((Xa,Oa)=>{const{key:Ma,text:Ua,onSelect:Qa}=Xa;return createVNode(Menu.Item,{key:Ma||Oa,onClick:()=>{Qa==null||Qa(Ta)}},{default:()=>[Ua]})})]});Fa=createVNode("div",{class:`${fa.value}-selection-extra`},[createVNode(Dropdown$1,{overlay:qa,getPopupContainer:Ia.value},{default:()=>[createVNode("span",null,[createVNode(DownOutlined$1,null,null)])]})])}const za=Ln.value.map((qa,Xa)=>{const Oa=ya.value(qa,Xa),Ma=Fn.value.get(Oa)||{};return _extends$1({checked:xa.has(Oa)},Ma)}).filter(qa=>{let{disabled:Xa}=qa;return Xa}),Wa=!!za.length&&za.length===nr.value,Ya=Wa&&za.every(qa=>{let{checked:Xa}=qa;return Xa}),ja=Wa&&za.some(qa=>{let{checked:Xa}=qa;return Xa});$a=!sa&&createVNode("div",{class:`${fa.value}-selection`},[createVNode(Checkbox,{checked:Wa?Ya:!!nr.value&&wa,indeterminate:Wa?!Ya&&ja:!wa&&La,onChange:Na,disabled:nr.value===0||Wa,"aria-label":Fa?"Custom selection":"Select all",skipGroup:!0},null),Fa])}let ka;ga==="radio"?ka=Fa=>{let{record:za,index:Wa}=Fa;const Ya=ya.value(za,Wa),ja=xa.has(Ya);return{node:createVNode(Radio,_objectSpread2$1(_objectSpread2$1({},Fn.value.get(Ya)),{},{checked:ja,onClick:qa=>qa.stopPropagation(),onChange:qa=>{xa.has(Ya)||Zo(Ya,!0,[Ya],qa.nativeEvent)}}),null),checked:ja}}:ka=Fa=>{let{record:za,index:Wa}=Fa;var Ya;const ja=ya.value(za,Wa),qa=xa.has(ja),Xa=Xn.value.has(ja),Oa=Fn.value.get(ja);let Ma;return ba.value==="nest"?(Ma=Xa,devWarning(typeof(Oa==null?void 0:Oa.indeterminate)!="boolean","Table","set `indeterminate` using `rowSelection.getCheckboxProps` is not allowed with tree structured dataSource.")):Ma=(Ya=Oa==null?void 0:Oa.indeterminate)!==null&&Ya!==void 0?Ya:Xa,{node:createVNode(Checkbox,_objectSpread2$1(_objectSpread2$1({},Oa),{},{indeterminate:Ma,checked:qa,skipGroup:!0,onClick:Ua=>Ua.stopPropagation(),onChange:Ua=>{let{nativeEvent:Qa}=Ua;const{shiftKey:ri}=Qa;let fi=-1,ei=-1;if(ri&&ia){const ti=new Set([Yo.value,ja]);Ta.some((ni,ui)=>{if(ti.has(ni))if(fi===-1)fi=ui;else return ei=ui,!0;return!1})}if(ei!==-1&&fi!==ei&&ia){const ti=Ta.slice(fi,ei+1),ni=[];qa?ti.forEach(mi=>{xa.has(mi)&&(ni.push(mi),xa.delete(mi))}):ti.forEach(mi=>{xa.has(mi)||(ni.push(mi),xa.add(mi))});const ui=Array.from(xa);la==null||la(!qa,ui.map(mi=>ma(mi)),ni.map(mi=>ma(mi))),Jo(ui)}else{const ti=Yn.value;if(ia){const ni=qa?arrDel(ti,ja):arrAdd(ti,ja);Zo(ja,!qa,ni,Qa)}else{const ni=conductCheck([...ti,ja],!0,Dn.value,Bn.value,Hn.value,zn),{checkedKeys:ui,halfCheckedKeys:mi}=ni;let di=ui;if(qa){const gi=new Set(ui);gi.delete(ja),di=conductCheck(Array.from(gi),{checked:!1,halfCheckedKeys:mi},Dn.value,Bn.value,Hn.value,zn).checkedKeys}Zo(ja,!qa,di,Qa)}}qo(ja)}}),null),checked:qa}};const Ha=Fa=>{let{record:za,index:Wa}=Fa;const{node:Ya,checked:ja}=ka({record:za,index:Wa});return ca?ca(ja,za,Wa,Ya):Ya};if(!Ea.includes(SELECTION_COLUMN))if(Ea.findIndex(Fa=>{var za;return((za=Fa[INTERNAL_COL_DEFINE])===null||za===void 0?void 0:za.columnType)==="EXPAND_COLUMN"})===0){const[Fa,...za]=Ea;Ea=[Fa,SELECTION_COLUMN,...za]}else Ea=[SELECTION_COLUMN,...Ea];const da=Ea.indexOf(SELECTION_COLUMN);Ea=Ea.filter((Fa,za)=>Fa!==SELECTION_COLUMN||za===da);const pa=Ea[da-1],Sa=Ea[da+1];let Aa=aa;Aa===void 0&&((Sa==null?void 0:Sa.fixed)!==void 0?Aa=Sa.fixed:(pa==null?void 0:pa.fixed)!==void 0&&(Aa=pa.fixed)),Aa&&pa&&((ra=pa[INTERNAL_COL_DEFINE])===null||ra===void 0?void 0:ra.columnType)==="EXPAND_COLUMN"&&pa.fixed===void 0&&(pa.fixed=Aa);const Ra={fixed:Aa,width:ua,className:`${fa.value}-selection-column`,title:_n.value.columnTitle||$a,customRender:Ha,[INTERNAL_COL_DEFINE]:{class:`${fa.value}-selection-col`}};return Ea.map(Fa=>Fa===SELECTION_COLUMN?Ra:Fa)},Go]}var CaretDownOutlined$2={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"}}]},name:"caret-down",theme:"outlined"};const CaretDownOutlinedSvg=CaretDownOutlined$2;function _objectSpread$h($n){for(var Cn=1;Cn0&&arguments[0]!==void 0?arguments[0]:[];const Cn=flattenChildren($n),_n=[];return Cn.forEach(Pn=>{var In,Nn,Rn,Dn;if(!Pn)return;const Ln=Pn.key,Fn=((In=Pn.props)===null||In===void 0?void 0:In.style)||{},Bn=((Nn=Pn.props)===null||Nn===void 0?void 0:Nn.class)||"",Hn=Pn.props||{};for(const[Go,Xn]of Object.entries(Hn))Hn[camelize(Go)]=Xn;const zn=Pn.children||{},{default:Wn}=zn,Yn=__rest$f(zn,["default"]),Gn=_extends$1(_extends$1(_extends$1({},Yn),Hn),{style:Fn,class:Bn});if(Ln&&(Gn.key=Ln),!((Rn=Pn.type)===null||Rn===void 0)&&Rn.__ANT_TABLE_COLUMN_GROUP)Gn.children=convertChildrenToColumns(typeof Wn=="function"?Wn():Wn);else{const Go=(Dn=Pn.children)===null||Dn===void 0?void 0:Dn.default;Gn.customRender=Gn.customRender||Go}_n.push(Gn)}),_n}const ASCEND="ascend",DESCEND="descend";function getMultiplePriority($n){return typeof $n.sorter=="object"&&typeof $n.sorter.multiple=="number"?$n.sorter.multiple:!1}function getSortFunction($n){return typeof $n=="function"?$n:$n&&typeof $n=="object"&&$n.compare?$n.compare:!1}function nextSortDirection($n,Cn){return Cn?$n[$n.indexOf(Cn)+1]:$n[0]}function collectSortStates($n,Cn,_n){let Pn=[];function In(Nn,Rn){Pn.push({column:Nn,key:getColumnKey(Nn,Rn),multiplePriority:getMultiplePriority(Nn),sortOrder:Nn.sortOrder})}return($n||[]).forEach((Nn,Rn)=>{const Dn=getColumnPos(Rn,_n);Nn.children?("sortOrder"in Nn&&In(Nn,Dn),Pn=[...Pn,...collectSortStates(Nn.children,Cn,Dn)]):Nn.sorter&&("sortOrder"in Nn?In(Nn,Dn):Cn&&Nn.defaultSortOrder&&Pn.push({column:Nn,key:getColumnKey(Nn,Dn),multiplePriority:getMultiplePriority(Nn),sortOrder:Nn.defaultSortOrder}))}),Pn}function injectSorter($n,Cn,_n,Pn,In,Nn,Rn,Dn){return(Cn||[]).map((Ln,Fn)=>{const Bn=getColumnPos(Fn,Dn);let Hn=Ln;if(Hn.sorter){const zn=Hn.sortDirections||In,Wn=Hn.showSorterTooltip===void 0?Rn:Hn.showSorterTooltip,Yn=getColumnKey(Hn,Bn),Gn=_n.find(oa=>{let{key:ra}=oa;return ra===Yn}),Go=Gn?Gn.sortOrder:null,Xn=nextSortDirection(zn,Go),Yo=zn.includes(ASCEND)&&createVNode(CaretUpOutlined$1,{class:classNames(`${$n}-column-sorter-up`,{active:Go===ASCEND}),role:"presentation"},null),qo=zn.includes(DESCEND)&&createVNode(CaretDownOutlined$1,{role:"presentation",class:classNames(`${$n}-column-sorter-down`,{active:Go===DESCEND})},null),{cancelSort:Jo,triggerAsc:Zo,triggerDesc:rr}=Nn||{};let nr=Jo;Xn===DESCEND?nr=rr:Xn===ASCEND&&(nr=Zo);const ta=typeof Wn=="object"?Wn:{title:nr};Hn=_extends$1(_extends$1({},Hn),{className:classNames(Hn.className,{[`${$n}-column-sort`]:Go}),title:oa=>{const ra=createVNode("div",{class:`${$n}-column-sorters`},[createVNode("span",{class:`${$n}-column-title`},[renderColumnTitle(Ln.title,oa)]),createVNode("span",{class:classNames(`${$n}-column-sorter`,{[`${$n}-column-sorter-full`]:!!(Yo&&qo)})},[createVNode("span",{class:`${$n}-column-sorter-inner`},[Yo,qo])])]);return Wn?createVNode(Tooltip,ta,{default:()=>[ra]}):ra},customHeaderCell:oa=>{const ra=Ln.customHeaderCell&&Ln.customHeaderCell(oa)||{},ea=ra.onClick,la=ra.onKeydown;return ra.onClick=ua=>{Pn({column:Ln,key:Yn,sortOrder:Xn,multiplePriority:getMultiplePriority(Ln)}),ea&&ea(ua)},ra.onKeydown=ua=>{ua.keyCode===KeyCode$1.ENTER&&(Pn({column:Ln,key:Yn,sortOrder:Xn,multiplePriority:getMultiplePriority(Ln)}),la==null||la(ua))},Go&&(ra["aria-sort"]=Go==="ascend"?"ascending":"descending"),ra.class=classNames(ra.class,`${$n}-column-has-sorters`),ra.tabindex=0,ra}})}return"children"in Hn&&(Hn=_extends$1(_extends$1({},Hn),{children:injectSorter($n,Hn.children,_n,Pn,In,Nn,Rn,Bn)})),Hn})}function stateToInfo($n){const{column:Cn,sortOrder:_n}=$n;return{column:Cn,order:_n,field:Cn.dataIndex,columnKey:Cn.key}}function generateSorterInfo($n){const Cn=$n.filter(_n=>{let{sortOrder:Pn}=_n;return Pn}).map(stateToInfo);return Cn.length===0&&$n.length?_extends$1(_extends$1({},stateToInfo($n[$n.length-1])),{column:void 0}):Cn.length<=1?Cn[0]||{}:Cn}function getSortData($n,Cn,_n){const Pn=Cn.slice().sort((Rn,Dn)=>Dn.multiplePriority-Rn.multiplePriority),In=$n.slice(),Nn=Pn.filter(Rn=>{let{column:{sorter:Dn},sortOrder:Ln}=Rn;return getSortFunction(Dn)&&Ln});return Nn.length?In.sort((Rn,Dn)=>{for(let Ln=0;Ln{const Dn=Rn[_n];return Dn?_extends$1(_extends$1({},Rn),{[_n]:getSortData(Dn,Cn,_n)}):Rn}):In}function useFilterSorter($n){let{prefixCls:Cn,mergedColumns:_n,onSorterChange:Pn,sortDirections:In,tableLocale:Nn,showSorterTooltip:Rn}=$n;const[Dn,Ln]=useState(collectSortStates(_n.value,!0)),Fn=computed(()=>{let Yn=!0;const Gn=collectSortStates(_n.value,!1);if(!Gn.length)return Dn.value;const Go=[];function Xn(qo){Yn?Go.push(qo):Go.push(_extends$1(_extends$1({},qo),{sortOrder:null}))}let Yo=null;return Gn.forEach(qo=>{Yo===null?(Xn(qo),qo.sortOrder&&(qo.multiplePriority===!1?Yn=!1:Yo=!0)):(Yo&&qo.multiplePriority!==!1||(Yn=!1),Xn(qo))}),Go}),Bn=computed(()=>{const Yn=Fn.value.map(Gn=>{let{column:Go,sortOrder:Xn}=Gn;return{column:Go,order:Xn}});return{sortColumns:Yn,sortColumn:Yn[0]&&Yn[0].column,sortOrder:Yn[0]&&Yn[0].order}});function Hn(Yn){let Gn;Yn.multiplePriority===!1||!Fn.value.length||Fn.value[0].multiplePriority===!1?Gn=[Yn]:Gn=[...Fn.value.filter(Go=>{let{key:Xn}=Go;return Xn!==Yn.key}),Yn],Ln(Gn),Pn(generateSorterInfo(Gn),Gn)}const zn=Yn=>injectSorter(Cn.value,Yn,Fn.value,Hn,In.value,Nn.value,Rn.value),Wn=computed(()=>generateSorterInfo(Fn.value));return[zn,Fn,Bn,Wn]}var FilterFilled$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"}}]},name:"filter",theme:"filled"};const FilterFilledSvg=FilterFilled$2;function _objectSpread$f($n){for(var Cn=1;Cn{const{keyCode:Cn}=$n;Cn===KeyCode$1.ENTER&&$n.stopPropagation()},FilterDropdownMenuWrapper=($n,Cn)=>{let{slots:_n}=Cn;var Pn;return createVNode("div",{onClick:In=>In.stopPropagation(),onKeydown:onKeyDown},[(Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n)])},FilterDropdownMenuWrapper$1=FilterDropdownMenuWrapper,FilterSearch=defineComponent({compatConfig:{MODE:3},name:"FilterSearch",inheritAttrs:!1,props:{value:stringType(),onChange:functionType(),filterSearch:someType([Boolean,Function]),tablePrefixCls:stringType(),locale:objectType()},setup($n){return()=>{const{value:Cn,onChange:_n,filterSearch:Pn,tablePrefixCls:In,locale:Nn}=$n;return Pn?createVNode("div",{class:`${In}-filter-dropdown-search`},[createVNode(Input,{placeholder:Nn.filterSearchPlaceholder,onChange:_n,value:Cn,htmlSize:1,class:`${In}-filter-dropdown-search-input`},{prefix:()=>createVNode(SearchOutlined$1,null,null)})]):null}}});var __rest$e=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In$n.motion?$n.motion:collapseMotion$1()),Ln=(Fn,Bn)=>{var Hn,zn,Wn,Yn;Bn==="appear"?(zn=(Hn=Dn.value)===null||Hn===void 0?void 0:Hn.onAfterEnter)===null||zn===void 0||zn.call(Hn,Fn):Bn==="leave"&&((Yn=(Wn=Dn.value)===null||Wn===void 0?void 0:Wn.onAfterLeave)===null||Yn===void 0||Yn.call(Wn,Fn)),Rn.value||$n.onMotionEnd(),Rn.value=!0};return watch(()=>$n.motionNodes,()=>{$n.motionNodes&&$n.motionType==="hide"&&In.value&&nextTick(()=>{In.value=!1})},{immediate:!0,flush:"post"}),onMounted(()=>{$n.motionNodes&&$n.onMotionStart()}),onBeforeUnmount(()=>{$n.motionNodes&&Ln()}),()=>{const{motion:Fn,motionNodes:Bn,motionType:Hn,active:zn,eventKey:Wn}=$n,Yn=__rest$e($n,["motion","motionNodes","motionType","active","eventKey"]);return Bn?createVNode(Transition,_objectSpread2$1(_objectSpread2$1({},Dn.value),{},{appear:Hn==="show",onAfterAppear:Gn=>Ln(Gn,"appear"),onAfterLeave:Gn=>Ln(Gn,"leave")}),{default:()=>[withDirectives(createVNode("div",{class:`${Nn.value.prefixCls}-treenode-motion`},[Bn.map(Gn=>{const Go=__rest$e(Gn.data,[]),{title:Xn,key:Yo,isStart:qo,isEnd:Jo}=Gn;return delete Go.children,createVNode(VcTreeNode,_objectSpread2$1(_objectSpread2$1({},Go),{},{title:Xn,active:zn,data:Gn.data,key:Yo,eventKey:Yo,isStart:qo,isEnd:Jo}),Pn)})]),[[vShow,In.value]])]}):createVNode(VcTreeNode,_objectSpread2$1(_objectSpread2$1({class:_n.class,style:_n.style},Yn),{},{active:zn,eventKey:Wn}),Pn)}}});function findExpandedKeys(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],Cn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[];const _n=$n.length,Pn=Cn.length;if(Math.abs(_n-Pn)!==1)return{add:!1,key:null};function In(Nn,Rn){const Dn=new Map;Nn.forEach(Fn=>{Dn.set(Fn,!0)});const Ln=Rn.filter(Fn=>!Dn.has(Fn));return Ln.length===1?Ln[0]:null}return _nRn.key===_n),In=$n[Pn+1],Nn=Cn.findIndex(Rn=>Rn.key===_n);if(In){const Rn=Cn.findIndex(Dn=>Dn.key===In.key);return Cn.slice(Nn+1,Rn)}return Cn.slice(Nn+1)}var __rest$d=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{},MOTION_KEY=`RC_TREE_MOTION_${Math.random()}`,MotionNode={key:MOTION_KEY},MotionEntity={key:MOTION_KEY,level:0,index:0,pos:"0",node:MotionNode,nodes:[MotionNode]},MotionFlattenData={parent:null,children:[],pos:MotionEntity.pos,data:MotionNode,title:null,key:MOTION_KEY,isStart:[],isEnd:[]};function getMinimumRangeTransitionRange($n,Cn,_n,Pn){return Cn===!1||!_n?$n:$n.slice(0,Math.ceil(_n/Pn)+1)}function itemKey($n){const{key:Cn,pos:_n}=$n;return getKey(Cn,_n)}function getAccessibilityPath($n){let Cn=String($n.key),_n=$n;for(;_n.parent;)_n=_n.parent,Cn=`${_n.key} > ${Cn}`;return Cn}const NodeList=defineComponent({compatConfig:{MODE:3},name:"NodeList",inheritAttrs:!1,props:nodeListProps,setup($n,Cn){let{expose:_n,attrs:Pn}=Cn;const In=ref(),Nn=ref(),{expandedKeys:Rn,flattenNodes:Dn}=useInjectKeysState();_n({scrollTo:Gn=>{In.value.scrollTo(Gn)},getIndentWidth:()=>Nn.value.offsetWidth});const Ln=shallowRef(Dn.value),Fn=shallowRef([]),Bn=ref(null);function Hn(){Ln.value=Dn.value,Fn.value=[],Bn.value=null,$n.onListChangeEnd()}const zn=useInjectTreeContext();watch([()=>Rn.value.slice(),Dn],(Gn,Go)=>{let[Xn,Yo]=Gn,[qo,Jo]=Go;const Zo=findExpandedKeys(qo,Xn);if(Zo.key!==null){const{virtual:rr,height:nr,itemHeight:ta}=$n;if(Zo.add){const oa=Jo.findIndex(la=>{let{key:ua}=la;return ua===Zo.key}),ra=getMinimumRangeTransitionRange(getExpandRange(Jo,Yo,Zo.key),rr,nr,ta),ea=Jo.slice();ea.splice(oa+1,0,MotionFlattenData),Ln.value=ea,Fn.value=ra,Bn.value="show"}else{const oa=Yo.findIndex(la=>{let{key:ua}=la;return ua===Zo.key}),ra=getMinimumRangeTransitionRange(getExpandRange(Yo,Jo,Zo.key),rr,nr,ta),ea=Yo.slice();ea.splice(oa+1,0,MotionFlattenData),Ln.value=ea,Fn.value=ra,Bn.value="hide"}}else Jo!==Yo&&(Ln.value=Yo)}),watch(()=>zn.value.dragging,Gn=>{Gn||Hn()});const Wn=computed(()=>$n.motion===void 0?Ln.value:Dn.value),Yn=()=>{$n.onActiveChange(null)};return()=>{const Gn=_extends$1(_extends$1({},$n),Pn),{prefixCls:Go,selectable:Xn,checkable:Yo,disabled:qo,motion:Jo,height:Zo,itemHeight:rr,virtual:nr,focusable:ta,activeItem:oa,focused:ra,tabindex:ea,onKeydown:la,onFocus:ua,onBlur:ga,onListChangeStart:aa,onListChangeEnd:ca}=Gn,sa=__rest$d(Gn,["prefixCls","selectable","checkable","disabled","motion","height","itemHeight","virtual","focusable","activeItem","focused","tabindex","onKeydown","onFocus","onBlur","onListChangeStart","onListChangeEnd"]);return createVNode(Fragment,null,[ra&&oa&&createVNode("span",{style:HIDDEN_STYLE$1,"aria-live":"assertive"},[getAccessibilityPath(oa)]),createVNode("div",null,[createVNode("input",{style:HIDDEN_STYLE$1,disabled:ta===!1||qo,tabindex:ta!==!1?ea:null,onKeydown:la,onFocus:ua,onBlur:ga,value:"",onChange:noop$4,"aria-label":"for screen reader"},null)]),createVNode("div",{class:`${Go}-treenode`,"aria-hidden":!0,style:{position:"absolute",pointerEvents:"none",visibility:"hidden",height:0,overflow:"hidden"}},[createVNode("div",{class:`${Go}-indent`},[createVNode("div",{ref:Nn,class:`${Go}-indent-unit`},null)])]),createVNode(List$4,_objectSpread2$1(_objectSpread2$1({},omit$1(sa,["onActiveChange"])),{},{data:Wn.value,itemKey,height:Zo,fullHeight:!1,virtual:nr,itemHeight:rr,prefixCls:`${Go}-list`,ref:In,onVisibleChange:(ia,fa)=>{const ma=new Set(ia);fa.filter(ba=>!ma.has(ba)).some(ba=>itemKey(ba)===MOTION_KEY)&&Hn()}}),{default:ia=>{const{pos:fa}=ia,ma=__rest$d(ia.data,[]),{title:ya,key:ba,isStart:Ia,isEnd:Ea}=ia,xa=getKey(ba,fa);return delete ma.key,delete ma.children,createVNode(MotionTreeNode,_objectSpread2$1(_objectSpread2$1({},ma),{},{eventKey:xa,title:ya,active:!!oa&&ba===oa.key,data:ia.data,isStart:Ia,isEnd:Ea,motion:Jo,motionNodes:ba===MOTION_KEY?Fn.value:null,motionType:Bn.value,onMotionStart:aa,onMotionEnd:Hn,onMousemove:Yn}),null)}})])}}});function DropIndicator($n){let{dropPosition:Cn,dropLevelOffset:_n,indent:Pn}=$n;const In={pointerEvents:"none",position:"absolute",right:0,backgroundColor:"red",height:"2px"};switch(Cn){case-1:In.top=0,In.left=`${-_n*Pn}px`;break;case 1:In.bottom=0,In.left=`${-_n*Pn}px`;break;case 0:In.bottom=0,In.left=`${Pn}`;break}return createVNode("div",{style:In},null)}const MAX_RETRY_TIMES=10,Tree$2=defineComponent({compatConfig:{MODE:3},name:"Tree",inheritAttrs:!1,props:initDefaultProps(treeProps$1(),{prefixCls:"vc-tree",showLine:!1,showIcon:!0,selectable:!0,multiple:!1,checkable:!1,disabled:!1,checkStrictly:!1,draggable:!1,expandAction:!1,defaultExpandParent:!0,autoExpandParent:!1,defaultExpandAll:!1,defaultExpandedKeys:[],defaultCheckedKeys:[],defaultSelectedKeys:[],dropIndicatorRender:DropIndicator,allowDrop:()=>!0}),setup($n,Cn){let{attrs:_n,slots:Pn,expose:In}=Cn;const Nn=shallowRef(!1);let Rn={};const Dn=shallowRef(),Ln=shallowRef([]),Fn=shallowRef([]),Bn=shallowRef([]),Hn=shallowRef([]),zn=shallowRef([]),Wn=shallowRef([]),Yn={},Gn=reactive({draggingNodeKey:null,dragChildrenKeys:[],dropTargetKey:null,dropPosition:null,dropContainerKey:null,dropLevelOffset:null,dropTargetPos:null,dropAllowed:!0,dragOverNodeKey:null}),Go=shallowRef([]);watch([()=>$n.treeData,()=>$n.children],()=>{Go.value=$n.treeData!==void 0?toRaw($n.treeData).slice():convertTreeToData(toRaw($n.children))},{immediate:!0,deep:!0});const Xn=shallowRef({}),Yo=shallowRef(!1),qo=shallowRef(null),Jo=shallowRef(!1),Zo=computed(()=>fillFieldNames$1($n.fieldNames)),rr=shallowRef();let nr=null,ta=null,oa=null;const ra=computed(()=>({expandedKeysSet:ea.value,selectedKeysSet:la.value,loadedKeysSet:ua.value,loadingKeysSet:ga.value,checkedKeysSet:aa.value,halfCheckedKeysSet:ca.value,dragOverNodeKey:Gn.dragOverNodeKey,dropPosition:Gn.dropPosition,keyEntities:Xn.value})),ea=computed(()=>new Set(Wn.value)),la=computed(()=>new Set(Ln.value)),ua=computed(()=>new Set(Hn.value)),ga=computed(()=>new Set(zn.value)),aa=computed(()=>new Set(Fn.value)),ca=computed(()=>new Set(Bn.value));watchEffect(()=>{if(Go.value){const ei=convertDataToEntities(Go.value,{fieldNames:Zo.value});Xn.value=_extends$1({[MOTION_KEY]:MotionEntity},ei.keyEntities)}});let sa=!1;watch([()=>$n.expandedKeys,()=>$n.autoExpandParent,Xn],(ei,ti)=>{let[ni,ui]=ei,[mi,di]=ti,gi=Wn.value;if($n.expandedKeys!==void 0||sa&&ui!==di)gi=$n.autoExpandParent||!sa&&$n.defaultExpandParent?conductExpandParent($n.expandedKeys,Xn.value):$n.expandedKeys;else if(!sa&&$n.defaultExpandAll){const wi=_extends$1({},Xn.value);delete wi[MOTION_KEY],gi=Object.keys(wi).map(Ti=>wi[Ti].key)}else!sa&&$n.defaultExpandedKeys&&(gi=$n.autoExpandParent||$n.defaultExpandParent?conductExpandParent($n.defaultExpandedKeys,Xn.value):$n.defaultExpandedKeys);gi&&(Wn.value=gi),sa=!0},{immediate:!0});const ia=shallowRef([]);watchEffect(()=>{ia.value=flattenTreeData(Go.value,Wn.value,Zo.value)}),watchEffect(()=>{$n.selectable&&($n.selectedKeys!==void 0?Ln.value=calcSelectedKeys($n.selectedKeys,$n):!sa&&$n.defaultSelectedKeys&&(Ln.value=calcSelectedKeys($n.defaultSelectedKeys,$n)))});const{maxLevel:fa,levelEntities:ma}=useMaxLevel(Xn);watchEffect(()=>{if($n.checkable){let ei;if($n.checkedKeys!==void 0?ei=parseCheckedKeys($n.checkedKeys)||{}:!sa&&$n.defaultCheckedKeys?ei=parseCheckedKeys($n.defaultCheckedKeys)||{}:Go.value&&(ei=parseCheckedKeys($n.checkedKeys)||{checkedKeys:Fn.value,halfCheckedKeys:Bn.value}),ei){let{checkedKeys:ti=[],halfCheckedKeys:ni=[]}=ei;$n.checkStrictly||({checkedKeys:ti,halfCheckedKeys:ni}=conductCheck(ti,!0,Xn.value,fa.value,ma.value)),Fn.value=ti,Bn.value=ni}}}),watchEffect(()=>{$n.loadedKeys&&(Hn.value=$n.loadedKeys)});const ya=()=>{_extends$1(Gn,{dragOverNodeKey:null,dropPosition:null,dropLevelOffset:null,dropTargetKey:null,dropContainerKey:null,dropTargetPos:null,dropAllowed:!1})},ba=ei=>{rr.value.scrollTo(ei)};watch(()=>$n.activeKey,()=>{$n.activeKey!==void 0&&(qo.value=$n.activeKey)},{immediate:!0}),watch(qo,ei=>{nextTick(()=>{ei!==null&&ba({key:ei})})},{immediate:!0,flush:"post"});const Ia=ei=>{$n.expandedKeys===void 0&&(Wn.value=ei)},Ea=()=>{Gn.draggingNodeKey!==null&&_extends$1(Gn,{draggingNodeKey:null,dropPosition:null,dropContainerKey:null,dropTargetKey:null,dropLevelOffset:null,dropAllowed:!0,dragOverNodeKey:null}),nr=null,oa=null},xa=(ei,ti)=>{const{onDragend:ni}=$n;Gn.dragOverNodeKey=null,Ea(),ni==null||ni({event:ei,node:ti.eventData}),ta=null},Ta=ei=>{xa(ei,null),window.removeEventListener("dragend",Ta)},wa=(ei,ti)=>{const{onDragstart:ni}=$n,{eventKey:ui,eventData:mi}=ti;ta=ti,nr={x:ei.clientX,y:ei.clientY};const di=arrDel(Wn.value,ui);Gn.draggingNodeKey=ui,Gn.dragChildrenKeys=getDragChildrenKeys(ui,Xn.value),Dn.value=rr.value.getIndentWidth(),Ia(di),window.addEventListener("dragend",Ta),ni&&ni({event:ei,node:mi})},La=(ei,ti)=>{const{onDragenter:ni,onExpand:ui,allowDrop:mi,direction:di}=$n,{pos:gi,eventKey:wi}=ti;if(oa!==wi&&(oa=wi),!ta){ya();return}const{dropPosition:Ti,dropLevelOffset:Ei,dropTargetKey:Ni,dropContainerKey:Ri,dropTargetPos:Zi,dropAllowed:Qi,dragOverNodeKey:Ji}=calcDropPosition(ei,ta,ti,Dn.value,nr,mi,ia.value,Xn.value,ea.value,di);if(Gn.dragChildrenKeys.indexOf(Ni)!==-1||!Qi){ya();return}if(Rn||(Rn={}),Object.keys(Rn).forEach(Yi=>{clearTimeout(Rn[Yi])}),ta.eventKey!==ti.eventKey&&(Rn[gi]=window.setTimeout(()=>{if(Gn.draggingNodeKey===null)return;let Yi=Wn.value.slice();const rl=Xn.value[ti.eventKey];rl&&(rl.children||[]).length&&(Yi=arrAdd(Wn.value,ti.eventKey)),Ia(Yi),ui&&ui(Yi,{node:ti.eventData,expanded:!0,nativeEvent:ei})},800)),ta.eventKey===Ni&&Ei===0){ya();return}_extends$1(Gn,{dragOverNodeKey:Ji,dropPosition:Ti,dropLevelOffset:Ei,dropTargetKey:Ni,dropContainerKey:Ri,dropTargetPos:Zi,dropAllowed:Qi}),ni&&ni({event:ei,node:ti.eventData,expandedKeys:Wn.value})},Na=(ei,ti)=>{const{onDragover:ni,allowDrop:ui,direction:mi}=$n;if(!ta)return;const{dropPosition:di,dropLevelOffset:gi,dropTargetKey:wi,dropContainerKey:Ti,dropAllowed:Ei,dropTargetPos:Ni,dragOverNodeKey:Ri}=calcDropPosition(ei,ta,ti,Dn.value,nr,ui,ia.value,Xn.value,ea.value,mi);Gn.dragChildrenKeys.indexOf(wi)!==-1||!Ei||(ta.eventKey===wi&&gi===0?Gn.dropPosition===null&&Gn.dropLevelOffset===null&&Gn.dropTargetKey===null&&Gn.dropContainerKey===null&&Gn.dropTargetPos===null&&Gn.dropAllowed===!1&&Gn.dragOverNodeKey===null||ya():di===Gn.dropPosition&&gi===Gn.dropLevelOffset&&wi===Gn.dropTargetKey&&Ti===Gn.dropContainerKey&&Ni===Gn.dropTargetPos&&Ei===Gn.dropAllowed&&Ri===Gn.dragOverNodeKey||_extends$1(Gn,{dropPosition:di,dropLevelOffset:gi,dropTargetKey:wi,dropContainerKey:Ti,dropTargetPos:Ni,dropAllowed:Ei,dragOverNodeKey:Ri}),ni&&ni({event:ei,node:ti.eventData}))},$a=(ei,ti)=>{oa===ti.eventKey&&!ei.currentTarget.contains(ei.relatedTarget)&&(ya(),oa=null);const{onDragleave:ni}=$n;ni&&ni({event:ei,node:ti.eventData})},ka=function(ei,ti){let ni=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;var ui;const{dragChildrenKeys:mi,dropPosition:di,dropTargetKey:gi,dropTargetPos:wi,dropAllowed:Ti}=Gn;if(!Ti)return;const{onDrop:Ei}=$n;if(Gn.dragOverNodeKey=null,Ea(),gi===null)return;const Ni=_extends$1(_extends$1({},getTreeNodeProps(gi,toRaw(ra.value))),{active:((ui=Ua.value)===null||ui===void 0?void 0:ui.key)===gi,data:Xn.value[gi].node});mi.indexOf(gi);const Ri=posToArr(wi),Zi={event:ei,node:convertNodePropsToEventData(Ni),dragNode:ta?ta.eventData:null,dragNodesKeys:[ta.eventKey].concat(mi),dropToGap:di!==0,dropPosition:di+Number(Ri[Ri.length-1])};ni||Ei==null||Ei(Zi),ta=null},Ha=(ei,ti)=>{const{expanded:ni,key:ui}=ti,mi=ia.value.filter(gi=>gi.key===ui)[0],di=convertNodePropsToEventData(_extends$1(_extends$1({},getTreeNodeProps(ui,ra.value)),{data:mi.data}));Ia(ni?arrDel(Wn.value,ui):arrAdd(Wn.value,ui)),qa(ei,di)},da=(ei,ti)=>{const{onClick:ni,expandAction:ui}=$n;ui==="click"&&Ha(ei,ti),ni&&ni(ei,ti)},pa=(ei,ti)=>{const{onDblclick:ni,expandAction:ui}=$n;(ui==="doubleclick"||ui==="dblclick")&&Ha(ei,ti),ni&&ni(ei,ti)},Sa=(ei,ti)=>{let ni=Ln.value;const{onSelect:ui,multiple:mi}=$n,{selected:di}=ti,gi=ti[Zo.value.key],wi=!di;wi?mi?ni=arrAdd(ni,gi):ni=[gi]:ni=arrDel(ni,gi);const Ti=Xn.value,Ei=ni.map(Ni=>{const Ri=Ti[Ni];return Ri?Ri.node:null}).filter(Ni=>Ni);$n.selectedKeys===void 0&&(Ln.value=ni),ui&&ui(ni,{event:"select",selected:wi,node:ti,selectedNodes:Ei,nativeEvent:ei})},Aa=(ei,ti,ni)=>{const{checkStrictly:ui,onCheck:mi}=$n,di=ti[Zo.value.key];let gi;const wi={event:"check",node:ti,checked:ni,nativeEvent:ei},Ti=Xn.value;if(ui){const Ei=ni?arrAdd(Fn.value,di):arrDel(Fn.value,di),Ni=arrDel(Bn.value,di);gi={checked:Ei,halfChecked:Ni},wi.checkedNodes=Ei.map(Ri=>Ti[Ri]).filter(Ri=>Ri).map(Ri=>Ri.node),$n.checkedKeys===void 0&&(Fn.value=Ei)}else{let{checkedKeys:Ei,halfCheckedKeys:Ni}=conductCheck([...Fn.value,di],!0,Ti,fa.value,ma.value);if(!ni){const Ri=new Set(Ei);Ri.delete(di),{checkedKeys:Ei,halfCheckedKeys:Ni}=conductCheck(Array.from(Ri),{checked:!1,halfCheckedKeys:Ni},Ti,fa.value,ma.value)}gi=Ei,wi.checkedNodes=[],wi.checkedNodesPositions=[],wi.halfCheckedKeys=Ni,Ei.forEach(Ri=>{const Zi=Ti[Ri];if(!Zi)return;const{node:Qi,pos:Ji}=Zi;wi.checkedNodes.push(Qi),wi.checkedNodesPositions.push({node:Qi,pos:Ji})}),$n.checkedKeys===void 0&&(Fn.value=Ei,Bn.value=Ni)}mi&&mi(gi,wi)},Ra=ei=>{const ti=ei[Zo.value.key],ni=new Promise((ui,mi)=>{const{loadData:di,onLoad:gi}=$n;if(!di||ua.value.has(ti)||ga.value.has(ti))return null;di(ei).then(()=>{const Ti=arrAdd(Hn.value,ti),Ei=arrDel(zn.value,ti);gi&&gi(Ti,{event:"load",node:ei}),$n.loadedKeys===void 0&&(Hn.value=Ti),zn.value=Ei,ui()}).catch(Ti=>{const Ei=arrDel(zn.value,ti);if(zn.value=Ei,Yn[ti]=(Yn[ti]||0)+1,Yn[ti]>=MAX_RETRY_TIMES){const Ni=arrAdd(Hn.value,ti);$n.loadedKeys===void 0&&(Hn.value=Ni),ui()}mi(Ti)}),zn.value=arrAdd(zn.value,ti)});return ni.catch(()=>{}),ni},Fa=(ei,ti)=>{const{onMouseenter:ni}=$n;ni&&ni({event:ei,node:ti})},za=(ei,ti)=>{const{onMouseleave:ni}=$n;ni&&ni({event:ei,node:ti})},Wa=(ei,ti)=>{const{onRightClick:ni}=$n;ni&&(ei.preventDefault(),ni({event:ei,node:ti}))},Ya=ei=>{const{onFocus:ti}=$n;Yo.value=!0,ti&&ti(ei)},ja=ei=>{const{onBlur:ti}=$n;Yo.value=!1,Ma(null),ti&&ti(ei)},qa=(ei,ti)=>{let ni=Wn.value;const{onExpand:ui,loadData:mi}=$n,{expanded:di}=ti,gi=ti[Zo.value.key];if(Jo.value)return;ni.indexOf(gi);const wi=!di;if(wi?ni=arrAdd(ni,gi):ni=arrDel(ni,gi),Ia(ni),ui&&ui(ni,{node:ti,expanded:wi,nativeEvent:ei}),wi&&mi){const Ti=Ra(ti);Ti&&Ti.then(()=>{}).catch(Ei=>{const Ni=arrDel(Wn.value,gi);Ia(Ni),Promise.reject(Ei)})}},Xa=()=>{Jo.value=!0},Oa=()=>{setTimeout(()=>{Jo.value=!1})},Ma=ei=>{const{onActiveChange:ti}=$n;qo.value!==ei&&($n.activeKey!==void 0&&(qo.value=ei),ei!==null&&ba({key:ei}),ti&&ti(ei))},Ua=computed(()=>qo.value===null?null:ia.value.find(ei=>{let{key:ti}=ei;return ti===qo.value})||null),Qa=ei=>{let ti=ia.value.findIndex(ui=>{let{key:mi}=ui;return mi===qo.value});ti===-1&&ei<0&&(ti=ia.value.length),ti=(ti+ei+ia.value.length)%ia.value.length;const ni=ia.value[ti];if(ni){const{key:ui}=ni;Ma(ui)}else Ma(null)},ri=computed(()=>convertNodePropsToEventData(_extends$1(_extends$1({},getTreeNodeProps(qo.value,ra.value)),{data:Ua.value.data,active:!0}))),fi=ei=>{const{onKeydown:ti,checkable:ni,selectable:ui}=$n;switch(ei.which){case KeyCode$1.UP:{Qa(-1),ei.preventDefault();break}case KeyCode$1.DOWN:{Qa(1),ei.preventDefault();break}}const mi=Ua.value;if(mi&&mi.data){const di=mi.data.isLeaf===!1||!!(mi.data.children||[]).length,gi=ri.value;switch(ei.which){case KeyCode$1.LEFT:{di&&ea.value.has(qo.value)?qa({},gi):mi.parent&&Ma(mi.parent.key),ei.preventDefault();break}case KeyCode$1.RIGHT:{di&&!ea.value.has(qo.value)?qa({},gi):mi.children&&mi.children.length&&Ma(mi.children[0].key),ei.preventDefault();break}case KeyCode$1.ENTER:case KeyCode$1.SPACE:{ni&&!gi.disabled&&gi.checkable!==!1&&!gi.disableCheckbox?Aa({},gi,!aa.value.has(qo.value)):!ni&&ui&&!gi.disabled&&gi.selectable!==!1&&Sa({},gi);break}}}ti&&ti(ei)};return In({onNodeExpand:qa,scrollTo:ba,onKeydown:fi,selectedKeys:computed(()=>Ln.value),checkedKeys:computed(()=>Fn.value),halfCheckedKeys:computed(()=>Bn.value),loadedKeys:computed(()=>Hn.value),loadingKeys:computed(()=>zn.value),expandedKeys:computed(()=>Wn.value)}),onUnmounted(()=>{window.removeEventListener("dragend",Ta),Nn.value=!0}),useProvideKeysState({expandedKeys:Wn,selectedKeys:Ln,loadedKeys:Hn,loadingKeys:zn,checkedKeys:Fn,halfCheckedKeys:Bn,expandedKeysSet:ea,selectedKeysSet:la,loadedKeysSet:ua,loadingKeysSet:ga,checkedKeysSet:aa,halfCheckedKeysSet:ca,flattenNodes:ia}),()=>{const{draggingNodeKey:ei,dropLevelOffset:ti,dropContainerKey:ni,dropTargetKey:ui,dropPosition:mi,dragOverNodeKey:di}=Gn,{prefixCls:gi,showLine:wi,focusable:Ti,tabindex:Ei=0,selectable:Ni,showIcon:Ri,icon:Zi=Pn.icon,switcherIcon:Qi,draggable:Ji,checkable:Yi,checkStrictly:rl,disabled:yi,motion:il,loadData:Tl,filterTreeNode:ul,height:ts,itemHeight:ci,virtual:Ci,dropIndicatorRender:bi,onContextmenu:Bi,onScroll:nl,direction:el,rootClassName:gl,rootStyle:ll}=$n,{class:Rl,style:ml}=_n,hl=pickAttrs(_extends$1(_extends$1({},$n),_n),{aria:!0,data:!0});let zi;return Ji?typeof Ji=="object"?zi=Ji:typeof Ji=="function"?zi={nodeDraggable:Ji}:zi={}:zi=!1,createVNode(TreeContext,{value:{prefixCls:gi,selectable:Ni,showIcon:Ri,icon:Zi,switcherIcon:Qi,draggable:zi,draggingNodeKey:ei,checkable:Yi,customCheckable:Pn.checkable,checkStrictly:rl,disabled:yi,keyEntities:Xn.value,dropLevelOffset:ti,dropContainerKey:ni,dropTargetKey:ui,dropPosition:mi,dragOverNodeKey:di,dragging:ei!==null,indent:Dn.value,direction:el,dropIndicatorRender:bi,loadData:Tl,filterTreeNode:ul,onNodeClick:da,onNodeDoubleClick:pa,onNodeExpand:qa,onNodeSelect:Sa,onNodeCheck:Aa,onNodeLoad:Ra,onNodeMouseEnter:Fa,onNodeMouseLeave:za,onNodeContextMenu:Wa,onNodeDragStart:wa,onNodeDragEnter:La,onNodeDragOver:Na,onNodeDragLeave:$a,onNodeDragEnd:xa,onNodeDrop:ka,slots:Pn}},{default:()=>[createVNode("div",{role:"tree",class:classNames(gi,Rl,gl,{[`${gi}-show-line`]:wi,[`${gi}-focused`]:Yo.value,[`${gi}-active-focused`]:qo.value!==null}),style:ll},[createVNode(NodeList,_objectSpread2$1({ref:rr,prefixCls:gi,style:ml,disabled:yi,selectable:Ni,checkable:!!Yi,motion:il,height:ts,itemHeight:ci,virtual:Ci,focusable:Ti,focused:Yo.value,tabindex:Ei,activeItem:Ua.value,onFocus:Ya,onBlur:ja,onKeydown:fi,onActiveChange:Ma,onListChangeStart:Xa,onListChangeEnd:Oa,onContextmenu:Bi,onScroll:nl},hl),null)])]})}}});var FileOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"}}]},name:"file",theme:"outlined"};const FileOutlinedSvg=FileOutlined$2;function _objectSpread$e($n){for(var Cn=1;Cn({[`.${$n}-switcher-icon`]:{display:"inline-block",fontSize:10,verticalAlign:"baseline",svg:{transition:`transform ${Cn.motionDurationSlow}`}}}),getDropIndicatorStyle=($n,Cn)=>({[`.${$n}-drop-indicator`]:{position:"absolute",zIndex:1,height:2,backgroundColor:Cn.colorPrimary,borderRadius:1,pointerEvents:"none","&:after":{position:"absolute",top:-3,insetInlineStart:-6,width:8,height:8,backgroundColor:"transparent",border:`${Cn.lineWidthBold}px solid ${Cn.colorPrimary}`,borderRadius:"50%",content:'""'}}}),genBaseStyle$4=($n,Cn)=>{const{treeCls:_n,treeNodeCls:Pn,treeNodePadding:In,treeTitleHeight:Nn}=Cn,Rn=(Nn-Cn.fontSizeLG)/2,Dn=Cn.paddingXS;return{[_n]:_extends$1(_extends$1({},resetComponent(Cn)),{background:Cn.colorBgContainer,borderRadius:Cn.borderRadius,transition:`background-color ${Cn.motionDurationSlow}`,[`&${_n}-rtl`]:{[`${_n}-switcher`]:{"&_close":{[`${_n}-switcher-icon`]:{svg:{transform:"rotate(90deg)"}}}}},[`&-focused:not(:hover):not(${_n}-active-focused)`]:_extends$1({},genFocusOutline(Cn)),[`${_n}-list-holder-inner`]:{alignItems:"flex-start"},[`&${_n}-block-node`]:{[`${_n}-list-holder-inner`]:{alignItems:"stretch",[`${_n}-node-content-wrapper`]:{flex:"auto"},[`${Pn}.dragging`]:{position:"relative","&:after":{position:"absolute",top:0,insetInlineEnd:0,bottom:In,insetInlineStart:0,border:`1px solid ${Cn.colorPrimary}`,opacity:0,animationName:treeNodeFX,animationDuration:Cn.motionDurationSlow,animationPlayState:"running",animationFillMode:"forwards",content:'""',pointerEvents:"none"}}}},[`${Pn}`]:{display:"flex",alignItems:"flex-start",padding:`0 0 ${In}px 0`,outline:"none","&-rtl":{direction:"rtl"},"&-disabled":{[`${_n}-node-content-wrapper`]:{color:Cn.colorTextDisabled,cursor:"not-allowed","&:hover":{background:"transparent"}}},[`&-active ${_n}-node-content-wrapper`]:_extends$1({},genFocusOutline(Cn)),[`&:not(${Pn}-disabled).filter-node ${_n}-title`]:{color:"inherit",fontWeight:500},"&-draggable":{[`${_n}-draggable-icon`]:{width:Nn,lineHeight:`${Nn}px`,textAlign:"center",visibility:"visible",opacity:.2,transition:`opacity ${Cn.motionDurationSlow}`,[`${Pn}:hover &`]:{opacity:.45}},[`&${Pn}-disabled`]:{[`${_n}-draggable-icon`]:{visibility:"hidden"}}}},[`${_n}-indent`]:{alignSelf:"stretch",whiteSpace:"nowrap",userSelect:"none","&-unit":{display:"inline-block",width:Nn}},[`${_n}-draggable-icon`]:{visibility:"hidden"},[`${_n}-switcher`]:_extends$1(_extends$1({},getSwitchStyle($n,Cn)),{position:"relative",flex:"none",alignSelf:"stretch",width:Nn,margin:0,lineHeight:`${Nn}px`,textAlign:"center",cursor:"pointer",userSelect:"none","&-noop":{cursor:"default"},"&_close":{[`${_n}-switcher-icon`]:{svg:{transform:"rotate(-90deg)"}}},"&-loading-icon":{color:Cn.colorPrimary},"&-leaf-line":{position:"relative",zIndex:1,display:"inline-block",width:"100%",height:"100%","&:before":{position:"absolute",top:0,insetInlineEnd:Nn/2,bottom:-In,marginInlineStart:-1,borderInlineEnd:`1px solid ${Cn.colorBorder}`,content:'""'},"&:after":{position:"absolute",width:Nn/2*.8,height:Nn/2,borderBottom:`1px solid ${Cn.colorBorder}`,content:'""'}}}),[`${_n}-checkbox`]:{top:"initial",marginInlineEnd:Dn,marginBlockStart:Rn},[`${_n}-node-content-wrapper, ${_n}-checkbox + span`]:{position:"relative",zIndex:"auto",minHeight:Nn,margin:0,padding:`0 ${Cn.paddingXS/2}px`,color:"inherit",lineHeight:`${Nn}px`,background:"transparent",borderRadius:Cn.borderRadius,cursor:"pointer",transition:`all ${Cn.motionDurationMid}, border 0s, line-height 0s, box-shadow 0s`,"&:hover":{backgroundColor:Cn.controlItemBgHover},[`&${_n}-node-selected`]:{backgroundColor:Cn.controlItemBgActive},[`${_n}-iconEle`]:{display:"inline-block",width:Nn,height:Nn,lineHeight:`${Nn}px`,textAlign:"center",verticalAlign:"top","&:empty":{display:"none"}}},[`${_n}-unselectable ${_n}-node-content-wrapper:hover`]:{backgroundColor:"transparent"},[`${_n}-node-content-wrapper`]:_extends$1({lineHeight:`${Nn}px`,userSelect:"none"},getDropIndicatorStyle($n,Cn)),[`${Pn}.drop-container`]:{"> [draggable]":{boxShadow:`0 0 0 2px ${Cn.colorPrimary}`}},"&-show-line":{[`${_n}-indent`]:{"&-unit":{position:"relative",height:"100%","&:before":{position:"absolute",top:0,insetInlineEnd:Nn/2,bottom:-In,borderInlineEnd:`1px solid ${Cn.colorBorder}`,content:'""'},"&-end":{"&:before":{display:"none"}}}},[`${_n}-switcher`]:{background:"transparent","&-line-icon":{verticalAlign:"-0.15em"}}},[`${Pn}-leaf-last`]:{[`${_n}-switcher`]:{"&-leaf-line":{"&:before":{top:"auto !important",bottom:"auto !important",height:`${Nn/2}px !important`}}}}})}},genDirectoryStyle=$n=>{const{treeCls:Cn,treeNodeCls:_n,treeNodePadding:Pn}=$n;return{[`${Cn}${Cn}-directory`]:{[_n]:{position:"relative","&:before":{position:"absolute",top:0,insetInlineEnd:0,bottom:Pn,insetInlineStart:0,transition:`background-color ${$n.motionDurationMid}`,content:'""',pointerEvents:"none"},"&:hover":{"&:before":{background:$n.controlItemBgHover}},"> *":{zIndex:1},[`${Cn}-switcher`]:{transition:`color ${$n.motionDurationMid}`},[`${Cn}-node-content-wrapper`]:{borderRadius:0,userSelect:"none","&:hover":{background:"transparent"},[`&${Cn}-node-selected`]:{color:$n.colorTextLightSolid,background:"transparent"}},"&-selected":{"\n &:hover::before,\n &::before\n ":{background:$n.colorPrimary},[`${Cn}-switcher`]:{color:$n.colorTextLightSolid},[`${Cn}-node-content-wrapper`]:{color:$n.colorTextLightSolid,background:"transparent"}}}}}},genTreeStyle=($n,Cn)=>{const _n=`.${$n}`,Pn=`${_n}-treenode`,In=Cn.paddingXS/2,Nn=Cn.controlHeightSM,Rn=merge$1(Cn,{treeCls:_n,treeNodeCls:Pn,treeNodePadding:In,treeTitleHeight:Nn});return[genBaseStyle$4($n,Rn),genDirectoryStyle(Rn)]},useStyle$a=genComponentStyleHook("Tree",($n,Cn)=>{let{prefixCls:_n}=Cn;return[{[$n.componentCls]:getStyle$2(`${_n}-checkbox`,$n)},genTreeStyle(_n,$n),genCollapseMotion$1($n)]}),treeProps=()=>{const $n=treeProps$1();return _extends$1(_extends$1({},$n),{showLine:someType([Boolean,Object]),multiple:booleanType(),autoExpandParent:booleanType(),checkStrictly:booleanType(),checkable:booleanType(),disabled:booleanType(),defaultExpandAll:booleanType(),defaultExpandParent:booleanType(),defaultExpandedKeys:arrayType(),expandedKeys:arrayType(),checkedKeys:someType([Array,Object]),defaultCheckedKeys:arrayType(),selectedKeys:arrayType(),defaultSelectedKeys:arrayType(),selectable:booleanType(),loadedKeys:arrayType(),draggable:booleanType(),showIcon:booleanType(),icon:functionType(),switcherIcon:PropTypes.any,prefixCls:String,replaceFields:objectType(),blockNode:booleanType(),openAnimation:PropTypes.any,onDoubleclick:$n.onDblclick,"onUpdate:selectedKeys":functionType(),"onUpdate:checkedKeys":functionType(),"onUpdate:expandedKeys":functionType()})},Tree$1=defineComponent({compatConfig:{MODE:3},name:"ATree",inheritAttrs:!1,props:initDefaultProps(treeProps(),{checkable:!1,selectable:!0,showIcon:!1,blockNode:!1}),slots:Object,setup($n,Cn){let{attrs:_n,expose:Pn,emit:In,slots:Nn}=Cn;$n.treeData===void 0&&Nn.default;const{prefixCls:Rn,direction:Dn,virtual:Ln}=useConfigInject("tree",$n),[Fn,Bn]=useStyle$a(Rn),Hn=ref();Pn({treeRef:Hn,onNodeExpand:function(){var Go;(Go=Hn.value)===null||Go===void 0||Go.onNodeExpand(...arguments)},scrollTo:Go=>{var Xn;(Xn=Hn.value)===null||Xn===void 0||Xn.scrollTo(Go)},selectedKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.selectedKeys}),checkedKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.checkedKeys}),halfCheckedKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.halfCheckedKeys}),loadedKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.loadedKeys}),loadingKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.loadingKeys}),expandedKeys:computed(()=>{var Go;return(Go=Hn.value)===null||Go===void 0?void 0:Go.expandedKeys})}),watchEffect(()=>{devWarning($n.replaceFields===void 0,"Tree","`replaceFields` is deprecated, please use fieldNames instead")});const Wn=(Go,Xn)=>{In("update:checkedKeys",Go),In("check",Go,Xn)},Yn=(Go,Xn)=>{In("update:expandedKeys",Go),In("expand",Go,Xn)},Gn=(Go,Xn)=>{In("update:selectedKeys",Go),In("select",Go,Xn)};return()=>{const{showIcon:Go,showLine:Xn,switcherIcon:Yo=Nn.switcherIcon,icon:qo=Nn.icon,blockNode:Jo,checkable:Zo,selectable:rr,fieldNames:nr=$n.replaceFields,motion:ta=$n.openAnimation,itemHeight:oa=28,onDoubleclick:ra,onDblclick:ea}=$n,la=_extends$1(_extends$1(_extends$1({},_n),omit$1($n,["onUpdate:checkedKeys","onUpdate:expandedKeys","onUpdate:selectedKeys","onDoubleclick"])),{showLine:!!Xn,dropIndicatorRender,fieldNames:nr,icon:qo,itemHeight:oa}),ua=Nn.default?filterEmpty(Nn.default()):void 0;return Fn(createVNode(Tree$2,_objectSpread2$1(_objectSpread2$1({},la),{},{virtual:Ln.value,motion:ta,ref:Hn,prefixCls:Rn.value,class:classNames({[`${Rn.value}-icon-hide`]:!Go,[`${Rn.value}-block-node`]:Jo,[`${Rn.value}-unselectable`]:!rr,[`${Rn.value}-rtl`]:Dn.value==="rtl"},_n.class,Bn.value),direction:Dn.value,checkable:Zo,selectable:rr,switcherIcon:ga=>renderSwitcherIcon(Rn.value,Yo,ga,Nn.leafIcon,Xn),onCheck:Wn,onExpand:Yn,onSelect:Gn,onDblclick:ea||ra,children:ua}),_extends$1(_extends$1({},Nn),{checkable:()=>createVNode("span",{class:`${Rn.value}-checkbox-inner`},null)})))}}});var FolderOpenOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 00-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"}}]},name:"folder-open",theme:"outlined"};const FolderOpenOutlinedSvg=FolderOpenOutlined$2;function _objectSpread$a($n){for(var Cn=1;Cn{if(Dn===Record.End)return!1;if(Ln(Fn)){if(Rn.push(Fn),Dn===Record.None)Dn=Record.Start;else if(Dn===Record.Start)return Dn=Record.End,!1}else Dn===Record.Start&&Rn.push(Fn);return _n.includes(Fn)}),Rn}function convertDirectoryKeysToNodes($n,Cn,_n){const Pn=[...Cn],In=[];return traverseNodesKey($n,_n,(Nn,Rn)=>{const Dn=Pn.indexOf(Nn);return Dn!==-1&&(In.push(Rn),Pn.splice(Dn,1)),!!Pn.length}),In}var __rest$c=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In_extends$1(_extends$1({},treeProps()),{expandAction:someType([Boolean,String])});function getIcon($n){const{isLeaf:Cn,expanded:_n}=$n;return createVNode(Cn?FileOutlined$1:_n?FolderOpenOutlined$1:FolderOutlined$1,null,null)}const DirectoryTree=defineComponent({compatConfig:{MODE:3},name:"ADirectoryTree",inheritAttrs:!1,props:initDefaultProps(directoryTreeProps(),{showIcon:!0,expandAction:"click"}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,emit:In,expose:Nn}=Cn;var Rn;const Dn=ref($n.treeData||convertTreeToData(filterEmpty((Rn=Pn.default)===null||Rn===void 0?void 0:Rn.call(Pn))));watch(()=>$n.treeData,()=>{Dn.value=$n.treeData}),onUpdated(()=>{nextTick(()=>{var oa;$n.treeData===void 0&&Pn.default&&(Dn.value=convertTreeToData(filterEmpty((oa=Pn.default)===null||oa===void 0?void 0:oa.call(Pn))))})});const Ln=ref(),Fn=ref(),Bn=computed(()=>fillFieldNames$1($n.fieldNames)),Hn=ref();Nn({scrollTo:oa=>{var ra;(ra=Hn.value)===null||ra===void 0||ra.scrollTo(oa)},selectedKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.selectedKeys}),checkedKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.checkedKeys}),halfCheckedKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.halfCheckedKeys}),loadedKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.loadedKeys}),loadingKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.loadingKeys}),expandedKeys:computed(()=>{var oa;return(oa=Hn.value)===null||oa===void 0?void 0:oa.expandedKeys})});const Wn=()=>{const{keyEntities:oa}=convertDataToEntities(Dn.value,{fieldNames:Bn.value});let ra;return $n.defaultExpandAll?ra=Object.keys(oa):$n.defaultExpandParent?ra=conductExpandParent($n.expandedKeys||$n.defaultExpandedKeys||[],oa):ra=$n.expandedKeys||$n.defaultExpandedKeys,ra},Yn=ref($n.selectedKeys||$n.defaultSelectedKeys||[]),Gn=ref(Wn());watch(()=>$n.selectedKeys,()=>{$n.selectedKeys!==void 0&&(Yn.value=$n.selectedKeys)},{immediate:!0}),watch(()=>$n.expandedKeys,()=>{$n.expandedKeys!==void 0&&(Gn.value=$n.expandedKeys)},{immediate:!0});const Xn=debounce$2((oa,ra)=>{const{isLeaf:ea}=ra;ea||oa.shiftKey||oa.metaKey||oa.ctrlKey||Hn.value.onNodeExpand(oa,ra)},200,{leading:!0}),Yo=(oa,ra)=>{$n.expandedKeys===void 0&&(Gn.value=oa),In("update:expandedKeys",oa),In("expand",oa,ra)},qo=(oa,ra)=>{const{expandAction:ea}=$n;ea==="click"&&Xn(oa,ra),In("click",oa,ra)},Jo=(oa,ra)=>{const{expandAction:ea}=$n;(ea==="dblclick"||ea==="doubleclick")&&Xn(oa,ra),In("doubleclick",oa,ra),In("dblclick",oa,ra)},Zo=(oa,ra)=>{const{multiple:ea}=$n,{node:la,nativeEvent:ua}=ra,ga=la[Bn.value.key],aa=_extends$1(_extends$1({},ra),{selected:!0}),ca=(ua==null?void 0:ua.ctrlKey)||(ua==null?void 0:ua.metaKey),sa=ua==null?void 0:ua.shiftKey;let ia;ea&&ca?(ia=oa,Ln.value=ga,Fn.value=ia,aa.selectedNodes=convertDirectoryKeysToNodes(Dn.value,ia,Bn.value)):ea&&sa?(ia=Array.from(new Set([...Fn.value||[],...calcRangeKeys({treeData:Dn.value,expandedKeys:Gn.value,startKey:ga,endKey:Ln.value,fieldNames:Bn.value})])),aa.selectedNodes=convertDirectoryKeysToNodes(Dn.value,ia,Bn.value)):(ia=[ga],Ln.value=ga,Fn.value=ia,aa.selectedNodes=convertDirectoryKeysToNodes(Dn.value,ia,Bn.value)),In("update:selectedKeys",ia),In("select",ia,aa),$n.selectedKeys===void 0&&(Yn.value=ia)},rr=(oa,ra)=>{In("update:checkedKeys",oa),In("check",oa,ra)},{prefixCls:nr,direction:ta}=useConfigInject("tree",$n);return()=>{const oa=classNames(`${nr.value}-directory`,{[`${nr.value}-directory-rtl`]:ta.value==="rtl"},_n.class),{icon:ra=Pn.icon,blockNode:ea=!0}=$n,la=__rest$c($n,["icon","blockNode"]);return createVNode(Tree$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),{},{icon:ra||getIcon,ref:Hn,blockNode:ea},la),{},{prefixCls:nr.value,class:oa,expandedKeys:Gn.value,selectedKeys:Yn.value,onSelect:Zo,onClick:qo,onDblclick:Jo,onExpand:Yo,onCheck:rr}),Pn)}}}),TreeNode$2=VcTreeNode,Tree=_extends$1(Tree$1,{DirectoryTree,TreeNode:TreeNode$2,install:$n=>($n.component(Tree$1.name,Tree$1),$n.component(TreeNode$2.name,TreeNode$2),$n.component(DirectoryTree.name,DirectoryTree),$n)});function isEqual($n,Cn){let _n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;const Pn=new Set;function In(Nn,Rn){let Dn=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1;const Ln=Pn.has(Nn);if(warningOnce(!Ln,"Warning: There may be circular references"),Ln)return!1;if(Nn===Rn)return!0;if(_n&&Dn>1)return!1;Pn.add(Nn);const Fn=Dn+1;if(Array.isArray(Nn)){if(!Array.isArray(Rn)||Nn.length!==Rn.length)return!1;for(let Bn=0;BnIn(Nn[Hn],Rn[Hn],Fn))}return!1}return In($n,Cn)}const{SubMenu,Item:MenuItem}=Menu;function hasSubMenu($n){return $n.some(Cn=>{let{children:_n}=Cn;return _n&&_n.length>0})}function searchValueMatched($n,Cn){return typeof Cn=="string"||typeof Cn=="number"?Cn==null?void 0:Cn.toString().toLowerCase().includes($n.trim().toLowerCase()):!1}function renderFilterItems($n){let{filters:Cn,prefixCls:_n,filteredKeys:Pn,filterMultiple:In,searchValue:Nn,filterSearch:Rn}=$n;return Cn.map((Dn,Ln)=>{const Fn=String(Dn.value);if(Dn.children)return createVNode(SubMenu,{key:Fn||Ln,title:Dn.text,popupClassName:`${_n}-dropdown-submenu`},{default:()=>[renderFilterItems({filters:Dn.children,prefixCls:_n,filteredKeys:Pn,filterMultiple:In,searchValue:Nn,filterSearch:Rn})]});const Bn=In?Checkbox:Radio,Hn=createVNode(MenuItem,{key:Dn.value!==void 0?Fn:Ln},{default:()=>[createVNode(Bn,{checked:Pn.includes(Fn)},null),createVNode("span",null,[Dn.text])]});return Nn.trim()?typeof Rn=="function"?Rn(Nn,Dn)?Hn:void 0:searchValueMatched(Nn,Dn.text)?Hn:void 0:Hn})}const FilterDropdown=defineComponent({name:"FilterDropdown",props:["tablePrefixCls","prefixCls","dropdownPrefixCls","column","filterState","filterMultiple","filterMode","filterSearch","columnKey","triggerFilter","locale","getPopupContainer"],setup($n,Cn){let{slots:_n}=Cn;const Pn=useInjectSlots(),In=computed(()=>{var ba;return(ba=$n.filterMode)!==null&&ba!==void 0?ba:"menu"}),Nn=computed(()=>{var ba;return(ba=$n.filterSearch)!==null&&ba!==void 0?ba:!1}),Rn=computed(()=>$n.column.filterDropdownOpen||$n.column.filterDropdownVisible),Dn=computed(()=>$n.column.onFilterDropdownOpenChange||$n.column.onFilterDropdownVisibleChange),Ln=shallowRef(!1),Fn=computed(()=>{var ba;return!!($n.filterState&&(!((ba=$n.filterState.filteredKeys)===null||ba===void 0)&&ba.length||$n.filterState.forceFiltered))}),Bn=computed(()=>{var ba;return flattenKeys((ba=$n.column)===null||ba===void 0?void 0:ba.filters)}),Hn=computed(()=>{const{filterDropdown:ba,slots:Ia={},customFilterDropdown:Ea}=$n.column;return ba||Ia.filterDropdown&&Pn.value[Ia.filterDropdown]||Ea&&Pn.value.customFilterDropdown}),zn=computed(()=>{const{filterIcon:ba,slots:Ia={}}=$n.column;return ba||Ia.filterIcon&&Pn.value[Ia.filterIcon]||Pn.value.customFilterIcon}),Wn=ba=>{var Ia;Ln.value=ba,(Ia=Dn.value)===null||Ia===void 0||Ia.call(Dn,ba)},Yn=computed(()=>typeof Rn.value=="boolean"?Rn.value:Ln.value),Gn=computed(()=>{var ba;return(ba=$n.filterState)===null||ba===void 0?void 0:ba.filteredKeys}),Go=shallowRef([]),Xn=ba=>{let{selectedKeys:Ia}=ba;Go.value=Ia},Yo=(ba,Ia)=>{let{node:Ea,checked:xa}=Ia;$n.filterMultiple?Xn({selectedKeys:ba}):Xn({selectedKeys:xa&&Ea.key?[Ea.key]:[]})};watch(Gn,()=>{Ln.value&&Xn({selectedKeys:Gn.value||[]})},{immediate:!0});const qo=shallowRef([]),Jo=shallowRef(),Zo=ba=>{Jo.value=setTimeout(()=>{qo.value=ba})},rr=()=>{clearTimeout(Jo.value)};onBeforeUnmount(()=>{clearTimeout(Jo.value)});const nr=shallowRef(""),ta=ba=>{const{value:Ia}=ba.target;nr.value=Ia};watch(Ln,()=>{Ln.value||(nr.value="")});const oa=ba=>{const{column:Ia,columnKey:Ea,filterState:xa}=$n,Ta=ba&&ba.length?ba:null;if(Ta===null&&(!xa||!xa.filteredKeys)||isEqual(Ta,xa==null?void 0:xa.filteredKeys,!0))return null;$n.triggerFilter({column:Ia,key:Ea,filteredKeys:Ta})},ra=()=>{Wn(!1),oa(Go.value)},ea=function(){let{confirm:ba,closeDropdown:Ia}=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{confirm:!1,closeDropdown:!1};ba&&oa([]),Ia&&Wn(!1),nr.value="",$n.column.filterResetToDefaultFilteredValue?Go.value=($n.column.defaultFilteredValue||[]).map(Ea=>String(Ea)):Go.value=[]},la=function(){let{closeDropdown:ba}=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{closeDropdown:!0};ba&&Wn(!1),oa(Go.value)},ua=ba=>{ba&&Gn.value!==void 0&&(Go.value=Gn.value||[]),Wn(ba),!ba&&!Hn.value&&ra()},{direction:ga}=useConfigInject("",$n),aa=ba=>{if(ba.target.checked){const Ia=Bn.value;Go.value=Ia}else Go.value=[]},ca=ba=>{let{filters:Ia}=ba;return(Ia||[]).map((Ea,xa)=>{const Ta=String(Ea.value),wa={title:Ea.text,key:Ea.value!==void 0?Ta:xa};return Ea.children&&(wa.children=ca({filters:Ea.children})),wa})},sa=ba=>{var Ia;return _extends$1(_extends$1({},ba),{text:ba.title,value:ba.key,children:((Ia=ba.children)===null||Ia===void 0?void 0:Ia.map(Ea=>sa(Ea)))||[]})},ia=computed(()=>ca({filters:$n.column.filters})),fa=computed(()=>classNames({[`${$n.dropdownPrefixCls}-menu-without-submenu`]:!hasSubMenu($n.column.filters||[])})),ma=()=>{const ba=Go.value,{column:Ia,locale:Ea,tablePrefixCls:xa,filterMultiple:Ta,dropdownPrefixCls:wa,getPopupContainer:La,prefixCls:Na}=$n;return(Ia.filters||[]).length===0?createVNode(Empty$1,{image:Empty$1.PRESENTED_IMAGE_SIMPLE,description:Ea.filterEmptyText,imageStyle:{height:24},style:{margin:0,padding:"16px 0"}},null):In.value==="tree"?createVNode(Fragment,null,[createVNode(FilterSearch,{filterSearch:Nn.value,value:nr.value,onChange:ta,tablePrefixCls:xa,locale:Ea},null),createVNode("div",{class:`${xa}-filter-dropdown-tree`},[Ta?createVNode(Checkbox,{class:`${xa}-filter-dropdown-checkall`,onChange:aa,checked:ba.length===Bn.value.length,indeterminate:ba.length>0&&ba.length[Ea.filterCheckall]}):null,createVNode(Tree,{checkable:!0,selectable:!1,blockNode:!0,multiple:Ta,checkStrictly:!Ta,class:`${wa}-menu`,onCheck:Yo,checkedKeys:ba,selectedKeys:ba,showIcon:!1,treeData:ia.value,autoExpandParent:!0,defaultExpandAll:!0,filterTreeNode:nr.value.trim()?$a=>typeof Nn.value=="function"?Nn.value(nr.value,sa($a)):searchValueMatched(nr.value,$a.title):void 0},null)])]):createVNode(Fragment,null,[createVNode(FilterSearch,{filterSearch:Nn.value,value:nr.value,onChange:ta,tablePrefixCls:xa,locale:Ea},null),createVNode(Menu,{multiple:Ta,prefixCls:`${wa}-menu`,class:fa.value,onClick:rr,onSelect:Xn,onDeselect:Xn,selectedKeys:ba,getPopupContainer:La,openKeys:qo.value,onOpenChange:Zo},{default:()=>renderFilterItems({filters:Ia.filters||[],filterSearch:Nn.value,prefixCls:Na,filteredKeys:Go.value,filterMultiple:Ta,searchValue:nr.value})})])},ya=computed(()=>{const ba=Go.value;return $n.column.filterResetToDefaultFilteredValue?isEqual(($n.column.defaultFilteredValue||[]).map(Ia=>String(Ia)),ba,!0):ba.length===0});return()=>{var ba;const{tablePrefixCls:Ia,prefixCls:Ea,column:xa,dropdownPrefixCls:Ta,locale:wa,getPopupContainer:La}=$n;let Na;typeof Hn.value=="function"?Na=Hn.value({prefixCls:`${Ta}-custom`,setSelectedKeys:Ha=>Xn({selectedKeys:Ha}),selectedKeys:Go.value,confirm:la,clearFilters:ea,filters:xa.filters,visible:Yn.value,column:xa.__originColumn__,close:()=>{Wn(!1)}}):Hn.value?Na=Hn.value:Na=createVNode(Fragment,null,[ma(),createVNode("div",{class:`${Ea}-dropdown-btns`},[createVNode(Button$1,{type:"link",size:"small",disabled:ya.value,onClick:()=>ea()},{default:()=>[wa.filterReset]}),createVNode(Button$1,{type:"primary",size:"small",onClick:ra},{default:()=>[wa.filterConfirm]})])]);const $a=createVNode(FilterDropdownMenuWrapper$1,{class:`${Ea}-dropdown`},{default:()=>[Na]});let ka;return typeof zn.value=="function"?ka=zn.value({filtered:Fn.value,column:xa.__originColumn__}):zn.value?ka=zn.value:ka=createVNode(FilterFilled$1,null,null),createVNode("div",{class:`${Ea}-column`},[createVNode("span",{class:`${Ia}-column-title`},[(ba=_n.default)===null||ba===void 0?void 0:ba.call(_n)]),createVNode(Dropdown$1,{overlay:$a,trigger:["click"],open:Yn.value,onOpenChange:ua,getPopupContainer:La,placement:ga.value==="rtl"?"bottomLeft":"bottomRight"},{default:()=>[createVNode("span",{role:"button",tabindex:-1,class:classNames(`${Ea}-trigger`,{active:Fn.value}),onClick:Ha=>{Ha.stopPropagation()}},[ka])]})])}}});function collectFilterStates($n,Cn,_n){let Pn=[];return($n||[]).forEach((In,Nn)=>{var Rn,Dn;const Ln=getColumnPos(Nn,_n),Fn=In.filterDropdown||((Rn=In==null?void 0:In.slots)===null||Rn===void 0?void 0:Rn.filterDropdown)||In.customFilterDropdown;if(In.filters||Fn||"onFilter"in In)if("filteredValue"in In){let Bn=In.filteredValue;Fn||(Bn=(Dn=Bn==null?void 0:Bn.map(String))!==null&&Dn!==void 0?Dn:Bn),Pn.push({column:In,key:getColumnKey(In,Ln),filteredKeys:Bn,forceFiltered:In.filtered})}else Pn.push({column:In,key:getColumnKey(In,Ln),filteredKeys:Cn&&In.defaultFilteredValue?In.defaultFilteredValue:void 0,forceFiltered:In.filtered});"children"in In&&(Pn=[...Pn,...collectFilterStates(In.children,Cn,Ln)])}),Pn}function injectFilter($n,Cn,_n,Pn,In,Nn,Rn,Dn){return _n.map((Ln,Fn)=>{var Bn;const Hn=getColumnPos(Fn,Dn),{filterMultiple:zn=!0,filterMode:Wn,filterSearch:Yn}=Ln;let Gn=Ln;const Go=Ln.filterDropdown||((Bn=Ln==null?void 0:Ln.slots)===null||Bn===void 0?void 0:Bn.filterDropdown)||Ln.customFilterDropdown;if(Gn.filters||Go){const Xn=getColumnKey(Gn,Hn),Yo=Pn.find(qo=>{let{key:Jo}=qo;return Xn===Jo});Gn=_extends$1(_extends$1({},Gn),{title:qo=>createVNode(FilterDropdown,{tablePrefixCls:$n,prefixCls:`${$n}-filter`,dropdownPrefixCls:Cn,column:Gn,columnKey:Xn,filterState:Yo,filterMultiple:zn,filterMode:Wn,filterSearch:Yn,triggerFilter:Nn,locale:In,getPopupContainer:Rn},{default:()=>[renderColumnTitle(Ln.title,qo)]})})}return"children"in Gn&&(Gn=_extends$1(_extends$1({},Gn),{children:injectFilter($n,Cn,Gn.children,Pn,In,Nn,Rn,Hn)})),Gn})}function flattenKeys($n){let Cn=[];return($n||[]).forEach(_n=>{let{value:Pn,children:In}=_n;Cn.push(Pn),In&&(Cn=[...Cn,...flattenKeys(In)])}),Cn}function generateFilterInfo($n){const Cn={};return $n.forEach(_n=>{let{key:Pn,filteredKeys:In,column:Nn}=_n;var Rn;const Dn=Nn.filterDropdown||((Rn=Nn==null?void 0:Nn.slots)===null||Rn===void 0?void 0:Rn.filterDropdown)||Nn.customFilterDropdown,{filters:Ln}=Nn;if(Dn)Cn[Pn]=In||null;else if(Array.isArray(In)){const Fn=flattenKeys(Ln);Cn[Pn]=Fn.filter(Bn=>In.includes(String(Bn)))}else Cn[Pn]=null}),Cn}function getFilterData($n,Cn){return Cn.reduce((_n,Pn)=>{const{column:{onFilter:In,filters:Nn},filteredKeys:Rn}=Pn;return In&&Rn&&Rn.length?_n.filter(Dn=>Rn.some(Ln=>{const Fn=flattenKeys(Nn),Bn=Fn.findIndex(zn=>String(zn)===String(Ln)),Hn=Bn!==-1?Fn[Bn]:Ln;return In(Hn,Dn)})):_n},$n)}function getMergedColumns($n){return $n.flatMap(Cn=>"children"in Cn?[Cn,...getMergedColumns(Cn.children||[])]:[Cn])}function useFilter($n){let{prefixCls:Cn,dropdownPrefixCls:_n,mergedColumns:Pn,locale:In,onFilterChange:Nn,getPopupContainer:Rn}=$n;const Dn=computed(()=>getMergedColumns(Pn.value)),[Ln,Fn]=useState(collectFilterStates(Dn.value,!0)),Bn=computed(()=>{const Yn=collectFilterStates(Dn.value,!1);if(Yn.length===0)return Yn;let Gn=!0,Go=!0;if(Yn.forEach(Xn=>{let{filteredKeys:Yo}=Xn;Yo!==void 0?Gn=!1:Go=!1}),Gn){const Xn=(Dn.value||[]).map((Yo,qo)=>getColumnKey(Yo,getColumnPos(qo)));return Ln.value.filter(Yo=>{let{key:qo}=Yo;return Xn.includes(qo)}).map(Yo=>{const qo=Dn.value[Xn.findIndex(Jo=>Jo===Yo.key)];return _extends$1(_extends$1({},Yo),{column:_extends$1(_extends$1({},Yo.column),qo),forceFiltered:qo.filtered})})}return devWarning(Go,"Table","Columns should all contain `filteredValue` or not contain `filteredValue`."),Yn}),Hn=computed(()=>generateFilterInfo(Bn.value)),zn=Yn=>{const Gn=Bn.value.filter(Go=>{let{key:Xn}=Go;return Xn!==Yn.key});Gn.push(Yn),Fn(Gn),Nn(generateFilterInfo(Gn),Gn)};return[Yn=>injectFilter(Cn.value,_n.value,Yn,Bn.value,In.value,zn,Rn.value),Bn,Hn]}function fillTitle($n,Cn){return $n.map(_n=>{const Pn=_extends$1({},_n);return Pn.title=renderColumnTitle(Pn.title,Cn),"children"in Pn&&(Pn.children=fillTitle(Pn.children,Cn)),Pn})}function useTitleColumns($n){return[_n=>fillTitle(_n,$n.value)]}function renderExpandIcon($n){return function(_n){let{prefixCls:Pn,onExpand:In,record:Nn,expanded:Rn,expandable:Dn}=_n;const Ln=`${Pn}-row-expand-icon`;return createVNode("button",{type:"button",onClick:Fn=>{In(Nn,Fn),Fn.stopPropagation()},class:classNames(Ln,{[`${Ln}-spaced`]:!Dn,[`${Ln}-expanded`]:Dn&&Rn,[`${Ln}-collapsed`]:Dn&&!Rn}),"aria-label":Rn?$n.collapse:$n.expand,"aria-expanded":Rn},null)}}function fillSlots($n,Cn){const _n=Cn.value;return $n.map(Pn=>{var In;if(Pn===SELECTION_COLUMN||Pn===EXPAND_COLUMN)return Pn;const Nn=_extends$1({},Pn),{slots:Rn={}}=Nn;return Nn.__originColumn__=Pn,devWarning(!("slots"in Nn),"Table","`column.slots` is deprecated. Please use `v-slot:headerCell` `v-slot:bodyCell` instead."),Object.keys(Rn).forEach(Dn=>{const Ln=Rn[Dn];Nn[Dn]===void 0&&_n[Ln]&&(Nn[Dn]=_n[Ln])}),Cn.value.headerCell&&!(!((In=Pn.slots)===null||In===void 0)&&In.title)&&(Nn.title=customRenderSlot(Cn.value,"headerCell",{title:Pn.title,column:Pn},()=>[Pn.title])),"children"in Nn&&Array.isArray(Nn.children)&&(Nn.children=fillSlots(Nn.children,Cn)),Nn})}function useColumns($n){return[_n=>fillSlots(_n,$n)]}const genBorderedStyle=$n=>{const{componentCls:Cn}=$n,_n=`${$n.lineWidth}px ${$n.lineType} ${$n.tableBorderColor}`,Pn=(In,Nn,Rn)=>({[`&${Cn}-${In}`]:{[`> ${Cn}-container`]:{[`> ${Cn}-content, > ${Cn}-body`]:{"> table > tbody > tr > td":{[`> ${Cn}-expanded-row-fixed`]:{margin:`-${Nn}px -${Rn+$n.lineWidth}px`}}}}}});return{[`${Cn}-wrapper`]:{[`${Cn}${Cn}-bordered`]:_extends$1(_extends$1(_extends$1({[`> ${Cn}-title`]:{border:_n,borderBottom:0},[`> ${Cn}-container`]:{borderInlineStart:_n,[` - > ${Cn}-content, - > ${Cn}-header, - > ${Cn}-body, - > ${Cn}-summary - `]:{"> table":{"\n > thead > tr > th,\n > tbody > tr > td,\n > tfoot > tr > th,\n > tfoot > tr > td\n ":{borderInlineEnd:_n},"> thead":{"> tr:not(:last-child) > th":{borderBottom:_n},"> tr > th::before":{backgroundColor:"transparent !important"}},"\n > thead > tr,\n > tbody > tr,\n > tfoot > tr\n ":{[`> ${Cn}-cell-fix-right-first::after`]:{borderInlineEnd:_n}},"> tbody > tr > td":{[`> ${Cn}-expanded-row-fixed`]:{margin:`-${$n.tablePaddingVertical}px -${$n.tablePaddingHorizontal+$n.lineWidth}px`,"&::after":{position:"absolute",top:0,insetInlineEnd:$n.lineWidth,bottom:0,borderInlineEnd:_n,content:'""'}}}}},[` - > ${Cn}-content, - > ${Cn}-header - `]:{"> table":{borderTop:_n}}},[`&${Cn}-scroll-horizontal`]:{[`> ${Cn}-container > ${Cn}-body`]:{"> table > tbody":{[` - > tr${Cn}-expanded-row, - > tr${Cn}-placeholder - `]:{"> td":{borderInlineEnd:0}}}}}},Pn("middle",$n.tablePaddingVerticalMiddle,$n.tablePaddingHorizontalMiddle)),Pn("small",$n.tablePaddingVerticalSmall,$n.tablePaddingHorizontalSmall)),{[`> ${Cn}-footer`]:{border:_n,borderTop:0}}),[`${Cn}-cell`]:{[`${Cn}-container:first-child`]:{borderTop:0},"&-scrollbar:not([rowspan])":{boxShadow:`0 ${$n.lineWidth}px 0 ${$n.lineWidth}px ${$n.tableHeaderBg}`}}}}},genBorderedStyle$1=genBorderedStyle,genEllipsisStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-cell-ellipsis`]:_extends$1(_extends$1({},textEllipsis),{wordBreak:"keep-all",[` - &${Cn}-cell-fix-left-last, - &${Cn}-cell-fix-right-first - `]:{overflow:"visible",[`${Cn}-cell-content`]:{display:"block",overflow:"hidden",textOverflow:"ellipsis"}},[`${Cn}-column-title`]:{overflow:"hidden",textOverflow:"ellipsis",wordBreak:"keep-all"}})}}},genEllipsisStyle$1=genEllipsisStyle,genEmptyStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-tbody > tr${Cn}-placeholder`]:{textAlign:"center",color:$n.colorTextDisabled,"&:hover > td":{background:$n.colorBgContainer}}}}},genEmptyStyle$1=genEmptyStyle,genExpandStyle=$n=>{const{componentCls:Cn,antCls:_n,controlInteractiveSize:Pn,motionDurationSlow:In,lineWidth:Nn,paddingXS:Rn,lineType:Dn,tableBorderColor:Ln,tableExpandIconBg:Fn,tableExpandColumnWidth:Bn,borderRadius:Hn,fontSize:zn,fontSizeSM:Wn,lineHeight:Yn,tablePaddingVertical:Gn,tablePaddingHorizontal:Go,tableExpandedRowBg:Xn,paddingXXS:Yo}=$n,qo=Pn/2-Nn,Jo=qo*2+Nn*3,Zo=`${Nn}px ${Dn} ${Ln}`,rr=Yo-Nn;return{[`${Cn}-wrapper`]:{[`${Cn}-expand-icon-col`]:{width:Bn},[`${Cn}-row-expand-icon-cell`]:{textAlign:"center",[`${Cn}-row-expand-icon`]:{display:"inline-flex",float:"none",verticalAlign:"sub"}},[`${Cn}-row-indent`]:{height:1,float:"left"},[`${Cn}-row-expand-icon`]:_extends$1(_extends$1({},operationUnit($n)),{position:"relative",float:"left",boxSizing:"border-box",width:Jo,height:Jo,padding:0,color:"inherit",lineHeight:`${Jo}px`,background:Fn,border:Zo,borderRadius:Hn,transform:`scale(${Pn/Jo})`,transition:`all ${In}`,userSelect:"none","&:focus, &:hover, &:active":{borderColor:"currentcolor"},"&::before, &::after":{position:"absolute",background:"currentcolor",transition:`transform ${In} ease-out`,content:'""'},"&::before":{top:qo,insetInlineEnd:rr,insetInlineStart:rr,height:Nn},"&::after":{top:rr,bottom:rr,insetInlineStart:qo,width:Nn,transform:"rotate(90deg)"},"&-collapsed::before":{transform:"rotate(-180deg)"},"&-collapsed::after":{transform:"rotate(0deg)"},"&-spaced":{"&::before, &::after":{display:"none",content:"none"},background:"transparent",border:0,visibility:"hidden"}}),[`${Cn}-row-indent + ${Cn}-row-expand-icon`]:{marginTop:(zn*Yn-Nn*3)/2-Math.ceil((Wn*1.4-Nn*3)/2),marginInlineEnd:Rn},[`tr${Cn}-expanded-row`]:{"&, &:hover":{"> td":{background:Xn}},[`${_n}-descriptions-view`]:{display:"flex",table:{flex:"auto",width:"auto"}}},[`${Cn}-expanded-row-fixed`]:{position:"relative",margin:`-${Gn}px -${Go}px`,padding:`${Gn}px ${Go}px`}}}},genExpandStyle$1=genExpandStyle,genFilterStyle=$n=>{const{componentCls:Cn,antCls:_n,iconCls:Pn,tableFilterDropdownWidth:In,tableFilterDropdownSearchWidth:Nn,paddingXXS:Rn,paddingXS:Dn,colorText:Ln,lineWidth:Fn,lineType:Bn,tableBorderColor:Hn,tableHeaderIconColor:zn,fontSizeSM:Wn,tablePaddingHorizontal:Yn,borderRadius:Gn,motionDurationSlow:Go,colorTextDescription:Xn,colorPrimary:Yo,tableHeaderFilterActiveBg:qo,colorTextDisabled:Jo,tableFilterDropdownBg:Zo,tableFilterDropdownHeight:rr,controlItemBgHover:nr,controlItemBgActive:ta,boxShadowSecondary:oa}=$n,ra=`${_n}-dropdown`,ea=`${Cn}-filter-dropdown`,la=`${_n}-tree`,ua=`${Fn}px ${Bn} ${Hn}`;return[{[`${Cn}-wrapper`]:{[`${Cn}-filter-column`]:{display:"flex",justifyContent:"space-between"},[`${Cn}-filter-trigger`]:{position:"relative",display:"flex",alignItems:"center",marginBlock:-Rn,marginInline:`${Rn}px ${-Yn/2}px`,padding:`0 ${Rn}px`,color:zn,fontSize:Wn,borderRadius:Gn,cursor:"pointer",transition:`all ${Go}`,"&:hover":{color:Xn,background:qo},"&.active":{color:Yo}}}},{[`${_n}-dropdown`]:{[ea]:_extends$1(_extends$1({},resetComponent($n)),{minWidth:In,backgroundColor:Zo,borderRadius:Gn,boxShadow:oa,[`${ra}-menu`]:{maxHeight:rr,overflowX:"hidden",border:0,boxShadow:"none","&:empty::after":{display:"block",padding:`${Dn}px 0`,color:Jo,fontSize:Wn,textAlign:"center",content:'"Not Found"'}},[`${ea}-tree`]:{paddingBlock:`${Dn}px 0`,paddingInline:Dn,[la]:{padding:0},[`${la}-treenode ${la}-node-content-wrapper:hover`]:{backgroundColor:nr},[`${la}-treenode-checkbox-checked ${la}-node-content-wrapper`]:{"&, &:hover":{backgroundColor:ta}}},[`${ea}-search`]:{padding:Dn,borderBottom:ua,"&-input":{input:{minWidth:Nn},[Pn]:{color:Jo}}},[`${ea}-checkall`]:{width:"100%",marginBottom:Rn,marginInlineStart:Rn},[`${ea}-btns`]:{display:"flex",justifyContent:"space-between",padding:`${Dn-Fn}px ${Dn}px`,overflow:"hidden",backgroundColor:"inherit",borderTop:ua}})}},{[`${_n}-dropdown ${ea}, ${ea}-submenu`]:{[`${_n}-checkbox-wrapper + span`]:{paddingInlineStart:Dn,color:Ln},"> ul":{maxHeight:"calc(100vh - 130px)",overflowX:"hidden",overflowY:"auto"}}}]},genFilterStyle$1=genFilterStyle,genFixedStyle=$n=>{const{componentCls:Cn,lineWidth:_n,colorSplit:Pn,motionDurationSlow:In,zIndexTableFixed:Nn,tableBg:Rn,zIndexTableSticky:Dn}=$n,Ln=Pn;return{[`${Cn}-wrapper`]:{[` - ${Cn}-cell-fix-left, - ${Cn}-cell-fix-right - `]:{position:"sticky !important",zIndex:Nn,background:Rn},[` - ${Cn}-cell-fix-left-first::after, - ${Cn}-cell-fix-left-last::after - `]:{position:"absolute",top:0,right:{_skip_check_:!0,value:0},bottom:-_n,width:30,transform:"translateX(100%)",transition:`box-shadow ${In}`,content:'""',pointerEvents:"none"},[`${Cn}-cell-fix-left-all::after`]:{display:"none"},[` - ${Cn}-cell-fix-right-first::after, - ${Cn}-cell-fix-right-last::after - `]:{position:"absolute",top:0,bottom:-_n,left:{_skip_check_:!0,value:0},width:30,transform:"translateX(-100%)",transition:`box-shadow ${In}`,content:'""',pointerEvents:"none"},[`${Cn}-container`]:{"&::before, &::after":{position:"absolute",top:0,bottom:0,zIndex:Dn+1,width:30,transition:`box-shadow ${In}`,content:'""',pointerEvents:"none"},"&::before":{insetInlineStart:0},"&::after":{insetInlineEnd:0}},[`${Cn}-ping-left`]:{[`&:not(${Cn}-has-fix-left) ${Cn}-container`]:{position:"relative","&::before":{boxShadow:`inset 10px 0 8px -8px ${Ln}`}},[` - ${Cn}-cell-fix-left-first::after, - ${Cn}-cell-fix-left-last::after - `]:{boxShadow:`inset 10px 0 8px -8px ${Ln}`},[`${Cn}-cell-fix-left-last::before`]:{backgroundColor:"transparent !important"}},[`${Cn}-ping-right`]:{[`&:not(${Cn}-has-fix-right) ${Cn}-container`]:{position:"relative","&::after":{boxShadow:`inset -10px 0 8px -8px ${Ln}`}},[` - ${Cn}-cell-fix-right-first::after, - ${Cn}-cell-fix-right-last::after - `]:{boxShadow:`inset -10px 0 8px -8px ${Ln}`}}}}},genFixedStyle$1=genFixedStyle,genPaginationStyle=$n=>{const{componentCls:Cn,antCls:_n}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-pagination${_n}-pagination`]:{margin:`${$n.margin}px 0`},[`${Cn}-pagination`]:{display:"flex",flexWrap:"wrap",rowGap:$n.paddingXS,"> *":{flex:"none"},"&-left":{justifyContent:"flex-start"},"&-center":{justifyContent:"center"},"&-right":{justifyContent:"flex-end"}}}}},genPaginationStyle$1=genPaginationStyle,genRadiusStyle=$n=>{const{componentCls:Cn,tableRadius:_n}=$n;return{[`${Cn}-wrapper`]:{[Cn]:{[`${Cn}-title, ${Cn}-header`]:{borderRadius:`${_n}px ${_n}px 0 0`},[`${Cn}-title + ${Cn}-container`]:{borderStartStartRadius:0,borderStartEndRadius:0,table:{borderRadius:0,"> thead > tr:first-child":{"th:first-child":{borderRadius:0},"th:last-child":{borderRadius:0}}}},"&-container":{borderStartStartRadius:_n,borderStartEndRadius:_n,"table > thead > tr:first-child":{"> *:first-child":{borderStartStartRadius:_n},"> *:last-child":{borderStartEndRadius:_n}}},"&-footer":{borderRadius:`0 0 ${_n}px ${_n}px`}}}}},genRadiusStyle$1=genRadiusStyle,genStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-wrapper-rtl`]:{direction:"rtl",table:{direction:"rtl"},[`${Cn}-pagination-left`]:{justifyContent:"flex-end"},[`${Cn}-pagination-right`]:{justifyContent:"flex-start"},[`${Cn}-row-expand-icon`]:{"&::after":{transform:"rotate(-90deg)"},"&-collapsed::before":{transform:"rotate(180deg)"},"&-collapsed::after":{transform:"rotate(0deg)"}}}}},genRtlStyle$2=genStyle,genSelectionStyle=$n=>{const{componentCls:Cn,antCls:_n,iconCls:Pn,fontSizeIcon:In,paddingXS:Nn,tableHeaderIconColor:Rn,tableHeaderIconColorHover:Dn}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-selection-col`]:{width:$n.tableSelectionColumnWidth},[`${Cn}-bordered ${Cn}-selection-col`]:{width:$n.tableSelectionColumnWidth+Nn*2},[` - table tr th${Cn}-selection-column, - table tr td${Cn}-selection-column - `]:{paddingInlineEnd:$n.paddingXS,paddingInlineStart:$n.paddingXS,textAlign:"center",[`${_n}-radio-wrapper`]:{marginInlineEnd:0}},[`table tr th${Cn}-selection-column${Cn}-cell-fix-left`]:{zIndex:$n.zIndexTableFixed+1},[`table tr th${Cn}-selection-column::after`]:{backgroundColor:"transparent !important"},[`${Cn}-selection`]:{position:"relative",display:"inline-flex",flexDirection:"column"},[`${Cn}-selection-extra`]:{position:"absolute",top:0,zIndex:1,cursor:"pointer",transition:`all ${$n.motionDurationSlow}`,marginInlineStart:"100%",paddingInlineStart:`${$n.tablePaddingHorizontal/4}px`,[Pn]:{color:Rn,fontSize:In,verticalAlign:"baseline","&:hover":{color:Dn}}}}}},genSelectionStyle$1=genSelectionStyle,genSizeStyle=$n=>{const{componentCls:Cn}=$n,_n=(Pn,In,Nn,Rn)=>({[`${Cn}${Cn}-${Pn}`]:{fontSize:Rn,[` - ${Cn}-title, - ${Cn}-footer, - ${Cn}-thead > tr > th, - ${Cn}-tbody > tr > td, - tfoot > tr > th, - tfoot > tr > td - `]:{padding:`${In}px ${Nn}px`},[`${Cn}-filter-trigger`]:{marginInlineEnd:`-${Nn/2}px`},[`${Cn}-expanded-row-fixed`]:{margin:`-${In}px -${Nn}px`},[`${Cn}-tbody`]:{[`${Cn}-wrapper:only-child ${Cn}`]:{marginBlock:`-${In}px`,marginInline:`${$n.tableExpandColumnWidth-Nn}px -${Nn}px`}},[`${Cn}-selection-column`]:{paddingInlineStart:`${Nn/4}px`}}});return{[`${Cn}-wrapper`]:_extends$1(_extends$1({},_n("middle",$n.tablePaddingVerticalMiddle,$n.tablePaddingHorizontalMiddle,$n.tableFontSizeMiddle)),_n("small",$n.tablePaddingVerticalSmall,$n.tablePaddingHorizontalSmall,$n.tableFontSizeSmall))}},genSizeStyle$1=genSizeStyle,genResizeStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-wrapper ${Cn}-resize-handle`]:{position:"absolute",top:0,height:"100% !important",bottom:0,left:" auto !important",right:" -8px",cursor:"col-resize",touchAction:"none",userSelect:"auto",width:"16px",zIndex:1,"&-line":{display:"block",width:"1px",marginLeft:"7px",height:"100% !important",backgroundColor:$n.colorPrimary,opacity:0},"&:hover &-line":{opacity:1}},[`${Cn}-wrapper ${Cn}-resize-handle.dragging`]:{overflow:"hidden",[`${Cn}-resize-handle-line`]:{opacity:1},"&:before":{position:"absolute",top:0,bottom:0,content:'" "',width:"200vw",transform:"translateX(-50%)",opacity:0}}}},genResizeStyle$1=genResizeStyle,genSorterStyle=$n=>{const{componentCls:Cn,marginXXS:_n,fontSizeIcon:Pn,tableHeaderIconColor:In,tableHeaderIconColorHover:Nn}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-thead th${Cn}-column-has-sorters`]:{outline:"none",cursor:"pointer",transition:`all ${$n.motionDurationSlow}`,"&:hover":{background:$n.tableHeaderSortHoverBg,"&::before":{backgroundColor:"transparent !important"}},"&:focus-visible":{color:$n.colorPrimary},[` - &${Cn}-cell-fix-left:hover, - &${Cn}-cell-fix-right:hover - `]:{background:$n.tableFixedHeaderSortActiveBg}},[`${Cn}-thead th${Cn}-column-sort`]:{background:$n.tableHeaderSortBg,"&::before":{backgroundColor:"transparent !important"}},[`td${Cn}-column-sort`]:{background:$n.tableBodySortBg},[`${Cn}-column-title`]:{position:"relative",zIndex:1,flex:1},[`${Cn}-column-sorters`]:{display:"flex",flex:"auto",alignItems:"center",justifyContent:"space-between","&::after":{position:"absolute",inset:0,width:"100%",height:"100%",content:'""'}},[`${Cn}-column-sorter`]:{marginInlineStart:_n,color:In,fontSize:0,transition:`color ${$n.motionDurationSlow}`,"&-inner":{display:"inline-flex",flexDirection:"column",alignItems:"center"},"&-up, &-down":{fontSize:Pn,"&.active":{color:$n.colorPrimary}},[`${Cn}-column-sorter-up + ${Cn}-column-sorter-down`]:{marginTop:"-0.3em"}},[`${Cn}-column-sorters:hover ${Cn}-column-sorter`]:{color:Nn}}}},genSorterStyle$1=genSorterStyle,genStickyStyle=$n=>{const{componentCls:Cn,opacityLoading:_n,tableScrollThumbBg:Pn,tableScrollThumbBgHover:In,tableScrollThumbSize:Nn,tableScrollBg:Rn,zIndexTableSticky:Dn}=$n,Ln=`${$n.lineWidth}px ${$n.lineType} ${$n.tableBorderColor}`;return{[`${Cn}-wrapper`]:{[`${Cn}-sticky`]:{"&-holder":{position:"sticky",zIndex:Dn,background:$n.colorBgContainer},"&-scroll":{position:"sticky",bottom:0,height:`${Nn}px !important`,zIndex:Dn,display:"flex",alignItems:"center",background:Rn,borderTop:Ln,opacity:_n,"&:hover":{transformOrigin:"center bottom"},"&-bar":{height:Nn,backgroundColor:Pn,borderRadius:100,transition:`all ${$n.motionDurationSlow}, transform none`,position:"absolute",bottom:0,"&:hover, &-active":{backgroundColor:In}}}}}}},genStickyStyle$1=genStickyStyle,genSummaryStyle=$n=>{const{componentCls:Cn,lineWidth:_n,tableBorderColor:Pn}=$n,In=`${_n}px ${$n.lineType} ${Pn}`;return{[`${Cn}-wrapper`]:{[`${Cn}-summary`]:{position:"relative",zIndex:$n.zIndexTableFixed,background:$n.tableBg,"> tr":{"> th, > td":{borderBottom:In}}},[`div${Cn}-summary`]:{boxShadow:`0 -${_n}px 0 ${Pn}`}}}},genSummaryStyle$1=genSummaryStyle,genTableStyle=$n=>{const{componentCls:Cn,fontWeightStrong:_n,tablePaddingVertical:Pn,tablePaddingHorizontal:In,lineWidth:Nn,lineType:Rn,tableBorderColor:Dn,tableFontSize:Ln,tableBg:Fn,tableRadius:Bn,tableHeaderTextColor:Hn,motionDurationMid:zn,tableHeaderBg:Wn,tableHeaderCellSplitColor:Yn,tableRowHoverBg:Gn,tableSelectedRowBg:Go,tableSelectedRowHoverBg:Xn,tableFooterTextColor:Yo,tableFooterBg:qo,paddingContentVerticalLG:Jo}=$n,Zo=`${Nn}px ${Rn} ${Dn}`;return{[`${Cn}-wrapper`]:_extends$1(_extends$1({clear:"both",maxWidth:"100%"},clearFix()),{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{fontSize:Ln,background:Fn,borderRadius:`${Bn}px ${Bn}px 0 0`}),table:{width:"100%",textAlign:"start",borderRadius:`${Bn}px ${Bn}px 0 0`,borderCollapse:"separate",borderSpacing:0},[` - ${Cn}-thead > tr > th, - ${Cn}-tbody > tr > td, - tfoot > tr > th, - tfoot > tr > td - `]:{position:"relative",padding:`${Jo}px ${In}px`,overflowWrap:"break-word"},[`${Cn}-title`]:{padding:`${Pn}px ${In}px`},[`${Cn}-thead`]:{"\n > tr > th,\n > tr > td\n ":{position:"relative",color:Hn,fontWeight:_n,textAlign:"start",background:Wn,borderBottom:Zo,transition:`background ${zn} ease`,"&[colspan]:not([colspan='1'])":{textAlign:"center"},[`&:not(:last-child):not(${Cn}-selection-column):not(${Cn}-row-expand-icon-cell):not([colspan])::before`]:{position:"absolute",top:"50%",insetInlineEnd:0,width:1,height:"1.6em",backgroundColor:Yn,transform:"translateY(-50%)",transition:`background-color ${zn}`,content:'""'}},"> tr:not(:last-child) > th[colspan]":{borderBottom:0}},[`${Cn}:not(${Cn}-bordered)`]:{[`${Cn}-tbody`]:{"> tr":{"> td":{borderTop:Zo,borderBottom:"transparent"},"&:last-child > td":{borderBottom:Zo},[`&:first-child > td, - &${Cn}-measure-row + tr > td`]:{borderTop:"none",borderTopColor:"transparent"}}}},[`${Cn}${Cn}-bordered`]:{[`${Cn}-tbody`]:{"> tr":{"> td":{borderBottom:Zo}}}},[`${Cn}-tbody`]:{"> tr":{"> td":{transition:`background ${zn}, border-color ${zn}`,[` - > ${Cn}-wrapper:only-child, - > ${Cn}-expanded-row-fixed > ${Cn}-wrapper:only-child - `]:{[Cn]:{marginBlock:`-${Pn}px`,marginInline:`${$n.tableExpandColumnWidth-In}px -${In}px`,[`${Cn}-tbody > tr:last-child > td`]:{borderBottom:0,"&:first-child, &:last-child":{borderRadius:0}}}}},[` - &${Cn}-row:hover > td, - > td${Cn}-cell-row-hover - `]:{background:Gn},[`&${Cn}-row-selected`]:{"> td":{background:Go},"&:hover > td":{background:Xn}}}},[`${Cn}-footer`]:{padding:`${Pn}px ${In}px`,color:Yo,background:qo}})}},useStyle$9=genComponentStyleHook("Table",$n=>{const{controlItemBgActive:Cn,controlItemBgActiveHover:_n,colorTextPlaceholder:Pn,colorTextHeading:In,colorSplit:Nn,colorBorderSecondary:Rn,fontSize:Dn,padding:Ln,paddingXS:Fn,paddingSM:Bn,controlHeight:Hn,colorFillAlter:zn,colorIcon:Wn,colorIconHover:Yn,opacityLoading:Gn,colorBgContainer:Go,borderRadiusLG:Xn,colorFillContent:Yo,colorFillSecondary:qo,controlInteractiveSize:Jo}=$n,Zo=new TinyColor(Wn),rr=new TinyColor(Yn),nr=Cn,ta=2,oa=new TinyColor(qo).onBackground(Go).toHexString(),ra=new TinyColor(Yo).onBackground(Go).toHexString(),ea=new TinyColor(zn).onBackground(Go).toHexString(),la=merge$1($n,{tableFontSize:Dn,tableBg:Go,tableRadius:Xn,tablePaddingVertical:Ln,tablePaddingHorizontal:Ln,tablePaddingVerticalMiddle:Bn,tablePaddingHorizontalMiddle:Fn,tablePaddingVerticalSmall:Fn,tablePaddingHorizontalSmall:Fn,tableBorderColor:Rn,tableHeaderTextColor:In,tableHeaderBg:ea,tableFooterTextColor:In,tableFooterBg:ea,tableHeaderCellSplitColor:Rn,tableHeaderSortBg:oa,tableHeaderSortHoverBg:ra,tableHeaderIconColor:Zo.clone().setAlpha(Zo.getAlpha()*Gn).toRgbString(),tableHeaderIconColorHover:rr.clone().setAlpha(rr.getAlpha()*Gn).toRgbString(),tableBodySortBg:ea,tableFixedHeaderSortActiveBg:oa,tableHeaderFilterActiveBg:Yo,tableFilterDropdownBg:Go,tableRowHoverBg:ea,tableSelectedRowBg:nr,tableSelectedRowHoverBg:_n,zIndexTableFixed:ta,zIndexTableSticky:ta+1,tableFontSizeMiddle:Dn,tableFontSizeSmall:Dn,tableSelectionColumnWidth:Hn,tableExpandIconBg:Go,tableExpandColumnWidth:Jo+2*$n.padding,tableExpandedRowBg:zn,tableFilterDropdownWidth:120,tableFilterDropdownHeight:264,tableFilterDropdownSearchWidth:140,tableScrollThumbSize:8,tableScrollThumbBg:Pn,tableScrollThumbBgHover:In,tableScrollBg:Nn});return[genTableStyle(la),genPaginationStyle$1(la),genSummaryStyle$1(la),genSorterStyle$1(la),genFilterStyle$1(la),genBorderedStyle$1(la),genRadiusStyle$1(la),genExpandStyle$1(la),genSummaryStyle$1(la),genEmptyStyle$1(la),genSelectionStyle$1(la),genFixedStyle$1(la),genStickyStyle$1(la),genEllipsisStyle$1(la),genSizeStyle$1(la),genResizeStyle$1(la),genRtlStyle$2(la)]}),EMPTY_LIST=[],tableProps=()=>({prefixCls:stringType(),columns:arrayType(),rowKey:someType([String,Function]),tableLayout:stringType(),rowClassName:someType([String,Function]),title:functionType(),footer:functionType(),id:stringType(),showHeader:booleanType(),components:objectType(),customRow:functionType(),customHeaderRow:functionType(),direction:stringType(),expandFixed:someType([Boolean,String]),expandColumnWidth:Number,expandedRowKeys:arrayType(),defaultExpandedRowKeys:arrayType(),expandedRowRender:functionType(),expandRowByClick:booleanType(),expandIcon:functionType(),onExpand:functionType(),onExpandedRowsChange:functionType(),"onUpdate:expandedRowKeys":functionType(),defaultExpandAllRows:booleanType(),indentSize:Number,expandIconColumnIndex:Number,showExpandColumn:booleanType(),expandedRowClassName:functionType(),childrenColumnName:stringType(),rowExpandable:functionType(),sticky:someType([Boolean,Object]),dropdownPrefixCls:String,dataSource:arrayType(),pagination:someType([Boolean,Object]),loading:someType([Boolean,Object]),size:stringType(),bordered:booleanType(),locale:objectType(),onChange:functionType(),onResizeColumn:functionType(),rowSelection:objectType(),getPopupContainer:functionType(),scroll:objectType(),sortDirections:arrayType(),showSorterTooltip:someType([Boolean,Object],!0),transformCellText:functionType()}),InternalTable=defineComponent({name:"InternalTable",inheritAttrs:!1,props:initDefaultProps(_extends$1(_extends$1({},tableProps()),{contextSlots:objectType()}),{rowKey:"key"}),setup($n,Cn){let{attrs:_n,slots:Pn,expose:In,emit:Nn}=Cn;devWarning(!(typeof $n.rowKey=="function"&&$n.rowKey.length>1),"Table","`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected."),useProvideSlots(computed(()=>$n.contextSlots)),useProvideTableContext({onResizeColumn:(Aa,Ra)=>{Nn("resizeColumn",Aa,Ra)}});const Rn=useBreakpoint(),Dn=computed(()=>{const Aa=new Set(Object.keys(Rn.value).filter(Ra=>Rn.value[Ra]));return $n.columns.filter(Ra=>!Ra.responsive||Ra.responsive.some(Fa=>Aa.has(Fa)))}),{size:Ln,renderEmpty:Fn,direction:Bn,prefixCls:Hn,configProvider:zn}=useConfigInject("table",$n),[Wn,Yn]=useStyle$9(Hn),Gn=computed(()=>{var Aa;return $n.transformCellText||((Aa=zn.transformCellText)===null||Aa===void 0?void 0:Aa.value)}),[Go]=useLocaleReceiver("Table",localeValues$1.Table,toRef($n,"locale")),Xn=computed(()=>$n.dataSource||EMPTY_LIST),Yo=computed(()=>zn.getPrefixCls("dropdown",$n.dropdownPrefixCls)),qo=computed(()=>$n.childrenColumnName||"children"),Jo=computed(()=>Xn.value.some(Aa=>Aa==null?void 0:Aa[qo.value])?"nest":$n.expandedRowRender?"row":null),Zo=reactive({body:null}),rr=Aa=>{_extends$1(Zo,Aa)},nr=computed(()=>typeof $n.rowKey=="function"?$n.rowKey:Aa=>Aa==null?void 0:Aa[$n.rowKey]),[ta]=useLazyKVMap(Xn,qo,nr),oa={},ra=function(Aa,Ra){let Fa=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;const{pagination:za,scroll:Wa,onChange:Ya}=$n,ja=_extends$1(_extends$1({},oa),Aa);Fa&&(oa.resetPagination(),ja.pagination.current&&(ja.pagination.current=1),za&&za.onChange&&za.onChange(1,ja.pagination.pageSize)),Wa&&Wa.scrollToFirstRowOnChange!==!1&&Zo.body&&scrollTo$1(0,{getContainer:()=>Zo.body}),Ya==null||Ya(ja.pagination,ja.filters,ja.sorter,{currentDataSource:getFilterData(getSortData(Xn.value,ja.sorterStates,qo.value),ja.filterStates),action:Ra})},ea=(Aa,Ra)=>{ra({sorter:Aa,sorterStates:Ra},"sort",!1)},[la,ua,ga,aa]=useFilterSorter({prefixCls:Hn,mergedColumns:Dn,onSorterChange:ea,sortDirections:computed(()=>$n.sortDirections||["ascend","descend"]),tableLocale:Go,showSorterTooltip:toRef($n,"showSorterTooltip")}),ca=computed(()=>getSortData(Xn.value,ua.value,qo.value)),sa=(Aa,Ra)=>{ra({filters:Aa,filterStates:Ra},"filter",!0)},[ia,fa,ma]=useFilter({prefixCls:Hn,locale:Go,dropdownPrefixCls:Yo,mergedColumns:Dn,onFilterChange:sa,getPopupContainer:toRef($n,"getPopupContainer")}),ya=computed(()=>getFilterData(ca.value,fa.value)),[ba]=useColumns(toRef($n,"contextSlots")),Ia=computed(()=>{const Aa={},Ra=ma.value;return Object.keys(Ra).forEach(Fa=>{Ra[Fa]!==null&&(Aa[Fa]=Ra[Fa])}),_extends$1(_extends$1({},ga.value),{filters:Aa})}),[Ea]=useTitleColumns(Ia),xa=(Aa,Ra)=>{ra({pagination:_extends$1(_extends$1({},oa.pagination),{current:Aa,pageSize:Ra})},"paginate")},[Ta,wa]=usePagination(computed(()=>ya.value.length),toRef($n,"pagination"),xa);watchEffect(()=>{oa.sorter=aa.value,oa.sorterStates=ua.value,oa.filters=ma.value,oa.filterStates=fa.value,oa.pagination=$n.pagination===!1?{}:getPaginationParam(Ta.value,$n.pagination),oa.resetPagination=wa});const La=computed(()=>{if($n.pagination===!1||!Ta.value.pageSize)return ya.value;const{current:Aa=1,total:Ra,pageSize:Fa=DEFAULT_PAGE_SIZE}=Ta.value;return devWarning(Aa>0,"Table","`current` should be positive number."),ya.value.lengthFa?ya.value.slice((Aa-1)*Fa,Aa*Fa):ya.value:ya.value.slice((Aa-1)*Fa,Aa*Fa)});watchEffect(()=>{nextTick(()=>{const{total:Aa,pageSize:Ra=DEFAULT_PAGE_SIZE}=Ta.value;ya.value.lengthRa&&devWarning(!1,"Table","`dataSource` length is less than `pagination.total` but large than `pagination.pageSize`. Please make sure your config correct data with async mode.")})},{flush:"post"});const Na=computed(()=>$n.showExpandColumn===!1?-1:Jo.value==="nest"&&$n.expandIconColumnIndex===void 0?$n.rowSelection?1:0:$n.expandIconColumnIndex>0&&$n.rowSelection?$n.expandIconColumnIndex-1:$n.expandIconColumnIndex),$a=ref();watch(()=>$n.rowSelection,()=>{$a.value=$n.rowSelection?_extends$1({},$n.rowSelection):$n.rowSelection},{deep:!0,immediate:!0});const[ka,Ha]=useSelection($a,{prefixCls:Hn,data:ya,pageData:La,getRowKey:nr,getRecordByKey:ta,expandType:Jo,childrenColumnName:qo,locale:Go,getPopupContainer:computed(()=>$n.getPopupContainer)}),da=(Aa,Ra,Fa)=>{let za;const{rowClassName:Wa}=$n;return typeof Wa=="function"?za=classNames(Wa(Aa,Ra,Fa)):za=classNames(Wa),classNames({[`${Hn.value}-row-selected`]:Ha.value.has(nr.value(Aa,Ra))},za)};In({selectedKeySet:Ha});const pa=computed(()=>typeof $n.indentSize=="number"?$n.indentSize:15),Sa=Aa=>Ea(ka(ia(la(ba(Aa)))));return()=>{var Aa;const{expandIcon:Ra=Pn.expandIcon||renderExpandIcon(Go.value),pagination:Fa,loading:za,bordered:Wa}=$n;let Ya,ja;if(Fa!==!1&&(!((Aa=Ta.value)===null||Aa===void 0)&&Aa.total)){let Ma;Ta.value.size?Ma=Ta.value.size:Ma=Ln.value==="small"||Ln.value==="middle"?"small":void 0;const Ua=fi=>createVNode(Pagination,_objectSpread2$1(_objectSpread2$1({},Ta.value),{},{class:[`${Hn.value}-pagination ${Hn.value}-pagination-${fi}`,Ta.value.class],size:Ma}),null),Qa=Bn.value==="rtl"?"left":"right",{position:ri}=Ta.value;if(ri!==null&&Array.isArray(ri)){const fi=ri.find(ni=>ni.includes("top")),ei=ri.find(ni=>ni.includes("bottom")),ti=ri.every(ni=>`${ni}`=="none");!fi&&!ei&&!ti&&(ja=Ua(Qa)),fi&&(Ya=Ua(fi.toLowerCase().replace("top",""))),ei&&(ja=Ua(ei.toLowerCase().replace("bottom","")))}else ja=Ua(Qa)}let qa;typeof za=="boolean"?qa={spinning:za}:typeof za=="object"&&(qa=_extends$1({spinning:!0},za));const Xa=classNames(`${Hn.value}-wrapper`,{[`${Hn.value}-wrapper-rtl`]:Bn.value==="rtl"},_n.class,Yn.value),Oa=omit$1($n,["columns"]);return Wn(createVNode("div",{class:Xa,style:_n.style},[createVNode(Spin,_objectSpread2$1({spinning:!1},qa),{default:()=>[Ya,createVNode(Table$2,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),Oa),{},{expandedRowKeys:$n.expandedRowKeys,defaultExpandedRowKeys:$n.defaultExpandedRowKeys,expandIconColumnIndex:Na.value,indentSize:pa.value,expandIcon:Ra,columns:Dn.value,direction:Bn.value,prefixCls:Hn.value,class:classNames({[`${Hn.value}-middle`]:Ln.value==="middle",[`${Hn.value}-small`]:Ln.value==="small",[`${Hn.value}-bordered`]:Wa,[`${Hn.value}-empty`]:Xn.value.length===0}),data:La.value,rowKey:nr.value,rowClassName:da,internalHooks:INTERNAL_HOOKS,internalRefs:Zo,onUpdateInternalRefs:rr,transformColumns:Sa,transformCellText:Gn.value}),_extends$1(_extends$1({},Pn),{emptyText:()=>{var Ma,Ua;return((Ma=Pn.emptyText)===null||Ma===void 0?void 0:Ma.call(Pn))||((Ua=$n.locale)===null||Ua===void 0?void 0:Ua.emptyText)||Fn("Table")}})),ja]})]))}}}),Table=defineComponent({name:"ATable",inheritAttrs:!1,props:initDefaultProps(tableProps(),{rowKey:"key"}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,expose:In}=Cn;const Nn=ref();return In({table:Nn}),()=>{var Rn;const Dn=$n.columns||convertChildrenToColumns((Rn=Pn.default)===null||Rn===void 0?void 0:Rn.call(Pn));return createVNode(InternalTable,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Nn},_n),$n),{},{columns:Dn||[],expandedRowRender:Pn.expandedRowRender||$n.expandedRowRender,contextSlots:_extends$1({},Pn)}),Pn)}}}),Table$1=Table,Column=defineComponent({name:"ATableColumn",slots:Object,render(){return null}}),ColumnGroup=defineComponent({name:"ATableColumnGroup",slots:Object,__ANT_TABLE_COLUMN_GROUP:!0,render(){return null}}),TableSummaryRow=SummaryRow,TableSummaryCell=SummaryCell,TableSummary=_extends$1(FooterComponents,{Cell:TableSummaryCell,Row:TableSummaryRow,name:"ATableSummary"}),index$9=_extends$1(Table$1,{SELECTION_ALL,SELECTION_INVERT,SELECTION_NONE,SELECTION_COLUMN,EXPAND_COLUMN,Column,ColumnGroup,Summary:TableSummary,install:$n=>($n.component(TableSummary.name,TableSummary),$n.component(TableSummaryCell.name,TableSummaryCell),$n.component(TableSummaryRow.name,TableSummaryRow),$n.component(Table$1.name,Table$1),$n.component(Column.name,Column),$n.component(ColumnGroup.name,ColumnGroup),$n)}),transferSearchProps={prefixCls:String,placeholder:String,value:String,handleClear:Function,disabled:{type:Boolean,default:void 0},onChange:Function},Search=defineComponent({compatConfig:{MODE:3},name:"Search",inheritAttrs:!1,props:initDefaultProps(transferSearchProps,{placeholder:""}),emits:["change"],setup($n,Cn){let{emit:_n}=Cn;const Pn=In=>{var Nn;_n("change",In),In.target.value===""&&((Nn=$n.handleClear)===null||Nn===void 0||Nn.call($n))};return()=>{const{placeholder:In,value:Nn,prefixCls:Rn,disabled:Dn}=$n;return createVNode(Input,{placeholder:In,class:Rn,value:Nn,onChange:Pn,disabled:Dn,allowClear:!0},{prefix:()=>createVNode(SearchOutlined$1,null,null)})}}});var DeleteOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"}}]},name:"delete",theme:"outlined"};const DeleteOutlinedSvg=DeleteOutlined$2;function _objectSpread$8($n){for(var Cn=1;Cn{const{renderedText:Pn,renderedEl:In,item:Nn,checked:Rn,disabled:Dn,prefixCls:Ln,showRemove:Fn}=$n,Bn=classNames({[`${Ln}-content-item`]:!0,[`${Ln}-content-item-disabled`]:Dn||Nn.disabled});let Hn;return(typeof Pn=="string"||typeof Pn=="number")&&(Hn=String(Pn)),createVNode(LocaleReceiver,{componentName:"Transfer",defaultLocale:localeValues$1.Transfer},{default:zn=>{const Wn=createVNode("span",{class:`${Ln}-content-item-text`},[In]);return Fn?createVNode("li",{class:Bn,title:Hn},[Wn,createVNode(TransButton$1,{disabled:Dn||Nn.disabled,class:`${Ln}-content-item-remove`,"aria-label":zn.remove,onClick:()=>{_n("remove",Nn)}},{default:()=>[createVNode(DeleteOutlined$1,null,null)]})]):createVNode("li",{class:Bn,title:Hn,onClick:Dn||Nn.disabled?noop$3:()=>{_n("click",Nn)}},[createVNode(Checkbox,{class:`${Ln}-checkbox`,checked:Rn,disabled:Dn||Nn.disabled},null),Wn])}})}}}),transferListBodyProps={prefixCls:String,filteredRenderItems:PropTypes.array.def([]),selectedKeys:PropTypes.array,disabled:booleanType(),showRemove:booleanType(),pagination:PropTypes.any,onItemSelect:Function,onScroll:Function,onItemRemove:Function};function parsePagination($n){if(!$n)return null;const Cn={pageSize:10,simple:!0,showSizeChanger:!1,showLessItems:!1};return typeof $n=="object"?_extends$1(_extends$1({},Cn),$n):Cn}const ListBody=defineComponent({compatConfig:{MODE:3},name:"ListBody",inheritAttrs:!1,props:transferListBodyProps,emits:["itemSelect","itemRemove","scroll"],setup($n,Cn){let{emit:_n,expose:Pn}=Cn;const In=ref(1),Nn=Hn=>{const{selectedKeys:zn}=$n,Wn=zn.indexOf(Hn.key)>=0;_n("itemSelect",Hn.key,!Wn)},Rn=Hn=>{_n("itemRemove",[Hn.key])},Dn=Hn=>{_n("scroll",Hn)},Ln=computed(()=>parsePagination($n.pagination));watch([Ln,()=>$n.filteredRenderItems],()=>{if(Ln.value){const Hn=Math.ceil($n.filteredRenderItems.length/Ln.value.pageSize);In.value=Math.min(In.value,Hn)}},{immediate:!0});const Fn=computed(()=>{const{filteredRenderItems:Hn}=$n;let zn=Hn;return Ln.value&&(zn=Hn.slice((In.value-1)*Ln.value.pageSize,In.value*Ln.value.pageSize)),zn}),Bn=Hn=>{In.value=Hn};return Pn({items:Fn}),()=>{const{prefixCls:Hn,filteredRenderItems:zn,selectedKeys:Wn,disabled:Yn,showRemove:Gn}=$n;let Go=null;Ln.value&&(Go=createVNode(Pagination,{simple:Ln.value.simple,showSizeChanger:Ln.value.showSizeChanger,showLessItems:Ln.value.showLessItems,size:"small",disabled:Yn,class:`${Hn}-pagination`,total:zn.length,pageSize:Ln.value.pageSize,current:In.value,onChange:Bn},null));const Xn=Fn.value.map(Yo=>{let{renderedEl:qo,renderedText:Jo,item:Zo}=Yo;const{disabled:rr}=Zo,nr=Wn.indexOf(Zo.key)>=0;return createVNode(ListItem$1,{disabled:Yn||rr,key:Zo.key,item:Zo,renderedText:Jo,renderedEl:qo,checked:nr,prefixCls:Hn,onClick:Nn,onRemove:Rn,showRemove:Gn},null)});return createVNode(Fragment,null,[createVNode("ul",{class:classNames(`${Hn}-content`,{[`${Hn}-content-show-remove`]:Gn}),onScroll:Dn},[Xn]),Go])}}}),ListBody$1=ListBody,groupKeysMap=$n=>{const Cn=new Map;return $n.forEach((_n,Pn)=>{Cn.set(_n,Pn)}),Cn},groupDisabledKeysMap=$n=>{const Cn=new Map;return $n.forEach((_n,Pn)=>{let{disabled:In,key:Nn}=_n;In&&Cn.set(Nn,Pn)}),Cn},defaultRender=()=>null;function isRenderResultPlainObject($n){return!!($n&&!isValidElement($n)&&Object.prototype.toString.call($n)==="[object Object]")}function getEnabledItemKeys($n){return $n.filter(Cn=>!Cn.disabled).map(Cn=>Cn.key)}const transferListProps={prefixCls:String,dataSource:arrayType([]),filter:String,filterOption:Function,checkedKeys:PropTypes.arrayOf(PropTypes.string),handleFilter:Function,handleClear:Function,renderItem:Function,showSearch:booleanType(!1),searchPlaceholder:String,notFoundContent:PropTypes.any,itemUnit:String,itemsUnit:String,renderList:PropTypes.any,disabled:booleanType(),direction:stringType(),showSelectAll:booleanType(),remove:String,selectAll:String,selectCurrent:String,selectInvert:String,removeAll:String,removeCurrent:String,selectAllLabel:PropTypes.any,showRemove:booleanType(),pagination:PropTypes.any,onItemSelect:Function,onItemSelectAll:Function,onItemRemove:Function,onScroll:Function},List=defineComponent({compatConfig:{MODE:3},name:"TransferList",inheritAttrs:!1,props:transferListProps,slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const In=ref(""),Nn=ref(),Rn=ref(),Dn=(Zo,rr)=>{let nr=Zo?Zo(rr):null;const ta=!!nr&&filterEmpty(nr).length>0;return ta||(nr=createVNode(ListBody$1,_objectSpread2$1(_objectSpread2$1({},rr),{},{ref:Rn}),null)),{customize:ta,bodyContent:nr}},Ln=Zo=>{const{renderItem:rr=defaultRender}=$n,nr=rr(Zo),ta=isRenderResultPlainObject(nr);return{renderedText:ta?nr.value:nr,renderedEl:ta?nr.label:nr,item:Zo}},Fn=ref([]),Bn=ref([]);watchEffect(()=>{const Zo=[],rr=[];$n.dataSource.forEach(nr=>{const ta=Ln(nr),{renderedText:oa}=ta;if(In.value&&In.value.trim()&&!Xn(oa,nr))return null;Zo.push(nr),rr.push(ta)}),Fn.value=Zo,Bn.value=rr});const Hn=computed(()=>{const{checkedKeys:Zo}=$n;if(Zo.length===0)return"none";const rr=groupKeysMap(Zo);return Fn.value.every(nr=>rr.has(nr.key)||!!nr.disabled)?"all":"part"}),zn=computed(()=>getEnabledItemKeys(Fn.value)),Wn=(Zo,rr)=>Array.from(new Set([...Zo,...$n.checkedKeys])).filter(nr=>rr.indexOf(nr)===-1),Yn=Zo=>{let{disabled:rr,prefixCls:nr}=Zo;var ta;const oa=Hn.value==="all";return createVNode(Checkbox,{disabled:((ta=$n.dataSource)===null||ta===void 0?void 0:ta.length)===0||rr,checked:oa,indeterminate:Hn.value==="part",class:`${nr}-checkbox`,onChange:()=>{const ea=zn.value;$n.onItemSelectAll(Wn(oa?[]:ea,oa?$n.checkedKeys:[]))}},null)},Gn=Zo=>{var rr;const{target:{value:nr}}=Zo;In.value=nr,(rr=$n.handleFilter)===null||rr===void 0||rr.call($n,Zo)},Go=Zo=>{var rr;In.value="",(rr=$n.handleClear)===null||rr===void 0||rr.call($n,Zo)},Xn=(Zo,rr)=>{const{filterOption:nr}=$n;return nr?nr(In.value,rr):Zo.includes(In.value)},Yo=(Zo,rr)=>{const{itemsUnit:nr,itemUnit:ta,selectAllLabel:oa}=$n;if(oa)return typeof oa=="function"?oa({selectedCount:Zo,totalCount:rr}):oa;const ra=rr>1?nr:ta;return createVNode(Fragment,null,[(Zo>0?`${Zo}/`:"")+rr,createTextVNode(" "),ra])},qo=computed(()=>Array.isArray($n.notFoundContent)?$n.notFoundContent[$n.direction==="left"?0:1]:$n.notFoundContent),Jo=(Zo,rr,nr,ta,oa,ra)=>{const ea=oa?createVNode("div",{class:`${Zo}-body-search-wrapper`},[createVNode(Search,{prefixCls:`${Zo}-search`,onChange:Gn,handleClear:Go,placeholder:rr,value:In.value,disabled:ra},null)]):null;let la;const{onEvents:ua}=splitAttrs(_n),{bodyContent:ga,customize:aa}=Dn(ta,_extends$1(_extends$1(_extends$1({},$n),{filteredItems:Fn.value,filteredRenderItems:Bn.value,selectedKeys:nr}),ua));return aa?la=createVNode("div",{class:`${Zo}-body-customize-wrapper`},[ga]):la=Fn.value.length?ga:createVNode("div",{class:`${Zo}-body-not-found`},[qo.value]),createVNode("div",{class:oa?`${Zo}-body ${Zo}-body-with-search`:`${Zo}-body`,ref:Nn},[ea,la])};return()=>{var Zo,rr;const{prefixCls:nr,checkedKeys:ta,disabled:oa,showSearch:ra,searchPlaceholder:ea,selectAll:la,selectCurrent:ua,selectInvert:ga,removeAll:aa,removeCurrent:ca,renderList:sa,onItemSelectAll:ia,onItemRemove:fa,showSelectAll:ma=!0,showRemove:ya,pagination:ba}=$n,Ia=(Zo=Pn.footer)===null||Zo===void 0?void 0:Zo.call(Pn,_extends$1({},$n)),Ea=classNames(nr,{[`${nr}-with-pagination`]:!!ba,[`${nr}-with-footer`]:!!Ia}),xa=Jo(nr,ea,ta,sa,ra,oa),Ta=Ia?createVNode("div",{class:`${nr}-footer`},[Ia]):null,wa=!ya&&!ba&&Yn({disabled:oa,prefixCls:nr});let La=null;ya?La=createVNode(Menu,null,{default:()=>[ba&&createVNode(Menu.Item,{key:"removeCurrent",onClick:()=>{const $a=getEnabledItemKeys((Rn.value.items||[]).map(ka=>ka.item));fa==null||fa($a)}},{default:()=>[ca]}),createVNode(Menu.Item,{key:"removeAll",onClick:()=>{fa==null||fa(zn.value)}},{default:()=>[aa]})]}):La=createVNode(Menu,null,{default:()=>[createVNode(Menu.Item,{key:"selectAll",onClick:()=>{const $a=zn.value;ia(Wn($a,[]))}},{default:()=>[la]}),ba&&createVNode(Menu.Item,{onClick:()=>{const $a=getEnabledItemKeys((Rn.value.items||[]).map(ka=>ka.item));ia(Wn($a,[]))}},{default:()=>[ua]}),createVNode(Menu.Item,{key:"selectInvert",onClick:()=>{let $a;ba?$a=getEnabledItemKeys((Rn.value.items||[]).map(pa=>pa.item)):$a=zn.value;const ka=new Set(ta),Ha=[],da=[];$a.forEach(pa=>{ka.has(pa)?da.push(pa):Ha.push(pa)}),ia(Wn(Ha,da))}},{default:()=>[ga]})]});const Na=createVNode(Dropdown$1,{class:`${nr}-header-dropdown`,overlay:La,disabled:oa},{default:()=>[createVNode(DownOutlined$1,null,null)]});return createVNode("div",{class:Ea,style:_n.style},[createVNode("div",{class:`${nr}-header`},[ma?createVNode(Fragment,null,[wa,Na]):null,createVNode("span",{class:`${nr}-header-selected`},[createVNode("span",null,[Yo(ta.length,Fn.value.length)]),createVNode("span",{class:`${nr}-header-title`},[(rr=Pn.titleText)===null||rr===void 0?void 0:rr.call(Pn)])])]),xa,Ta])}}});function noop$2(){}const Operation=$n=>{const{disabled:Cn,moveToLeft:_n=noop$2,moveToRight:Pn=noop$2,leftArrowText:In="",rightArrowText:Nn="",leftActive:Rn,rightActive:Dn,class:Ln,style:Fn,direction:Bn,oneWay:Hn}=$n;return createVNode("div",{class:Ln,style:Fn},[createVNode(Button$1,{type:"primary",size:"small",disabled:Cn||!Dn,onClick:Pn,icon:createVNode(Bn!=="rtl"?RightOutlined$1:LeftOutlined$1,null,null)},{default:()=>[Nn]}),!Hn&&createVNode(Button$1,{type:"primary",size:"small",disabled:Cn||!Rn,onClick:_n,icon:createVNode(Bn!=="rtl"?LeftOutlined$1:RightOutlined$1,null,null)},{default:()=>[In]})])};Operation.displayName="Operation";Operation.inheritAttrs=!1;const Operation$1=Operation,genTransferCustomizeStyle=$n=>{const{antCls:Cn,componentCls:_n,listHeight:Pn,controlHeightLG:In,marginXXS:Nn,margin:Rn}=$n,Dn=`${Cn}-table`,Ln=`${Cn}-input`;return{[`${_n}-customize-list`]:{[`${_n}-list`]:{flex:"1 1 50%",width:"auto",height:"auto",minHeight:Pn},[`${Dn}-wrapper`]:{[`${Dn}-small`]:{border:0,borderRadius:0,[`${Dn}-selection-column`]:{width:In,minWidth:In}},[`${Dn}-pagination${Dn}-pagination`]:{margin:`${Rn}px 0 ${Nn}px`}},[`${Ln}[disabled]`]:{backgroundColor:"transparent"}}}},genTransferStatusColor=($n,Cn)=>{const{componentCls:_n,colorBorder:Pn}=$n;return{[`${_n}-list`]:{borderColor:Cn,"&-search:not([disabled])":{borderColor:Pn}}}},genTransferStatusStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-status-error`]:_extends$1({},genTransferStatusColor($n,$n.colorError)),[`${Cn}-status-warning`]:_extends$1({},genTransferStatusColor($n,$n.colorWarning))}},genTransferListStyle=$n=>{const{componentCls:Cn,colorBorder:_n,colorSplit:Pn,lineWidth:In,transferItemHeight:Nn,transferHeaderHeight:Rn,transferHeaderVerticalPadding:Dn,transferItemPaddingVertical:Ln,controlItemBgActive:Fn,controlItemBgActiveHover:Bn,colorTextDisabled:Hn,listHeight:zn,listWidth:Wn,listWidthLG:Yn,fontSizeIcon:Gn,marginXS:Go,paddingSM:Xn,lineType:Yo,iconCls:qo,motionDurationSlow:Jo}=$n;return{display:"flex",flexDirection:"column",width:Wn,height:zn,border:`${In}px ${Yo} ${_n}`,borderRadius:$n.borderRadiusLG,"&-with-pagination":{width:Yn,height:"auto"},"&-search":{[`${qo}-search`]:{color:Hn}},"&-header":{display:"flex",flex:"none",alignItems:"center",height:Rn,padding:`${Dn-In}px ${Xn}px ${Dn}px`,color:$n.colorText,background:$n.colorBgContainer,borderBottom:`${In}px ${Yo} ${Pn}`,borderRadius:`${$n.borderRadiusLG}px ${$n.borderRadiusLG}px 0 0`,"> *:not(:last-child)":{marginInlineEnd:4},"> *":{flex:"none"},"&-title":_extends$1(_extends$1({},textEllipsis),{flex:"auto",textAlign:"end"}),"&-dropdown":_extends$1(_extends$1({},resetIcon()),{fontSize:Gn,transform:"translateY(10%)",cursor:"pointer","&[disabled]":{cursor:"not-allowed"}})},"&-body":{display:"flex",flex:"auto",flexDirection:"column",overflow:"hidden",fontSize:$n.fontSize,"&-search-wrapper":{position:"relative",flex:"none",padding:Xn}},"&-content":{flex:"auto",margin:0,padding:0,overflow:"auto",listStyle:"none","&-item":{display:"flex",alignItems:"center",minHeight:Nn,padding:`${Ln}px ${Xn}px`,transition:`all ${Jo}`,"> *:not(:last-child)":{marginInlineEnd:Go},"> *":{flex:"none"},"&-text":_extends$1(_extends$1({},textEllipsis),{flex:"auto"}),"&-remove":{position:"relative",color:_n,cursor:"pointer",transition:`all ${Jo}`,"&:hover":{color:$n.colorLinkHover},"&::after":{position:"absolute",insert:`-${Ln}px -50%`,content:'""'}},[`&:not(${Cn}-list-content-item-disabled)`]:{"&:hover":{backgroundColor:$n.controlItemBgHover,cursor:"pointer"},[`&${Cn}-list-content-item-checked:hover`]:{backgroundColor:Bn}},"&-checked":{backgroundColor:Fn},"&-disabled":{color:Hn,cursor:"not-allowed"}},[`&-show-remove ${Cn}-list-content-item:not(${Cn}-list-content-item-disabled):hover`]:{background:"transparent",cursor:"default"}},"&-pagination":{padding:`${$n.paddingXS}px 0`,textAlign:"end",borderTop:`${In}px ${Yo} ${Pn}`},"&-body-not-found":{flex:"none",width:"100%",margin:"auto 0",color:Hn,textAlign:"center"},"&-footer":{borderTop:`${In}px ${Yo} ${Pn}`},"&-checkbox":{lineHeight:1}}},genTransferStyle=$n=>{const{antCls:Cn,iconCls:_n,componentCls:Pn,transferHeaderHeight:In,marginXS:Nn,marginXXS:Rn,fontSizeIcon:Dn,fontSize:Ln,lineHeight:Fn}=$n;return{[Pn]:_extends$1(_extends$1({},resetComponent($n)),{position:"relative",display:"flex",alignItems:"stretch",[`${Pn}-disabled`]:{[`${Pn}-list`]:{background:$n.colorBgContainerDisabled}},[`${Pn}-list`]:genTransferListStyle($n),[`${Pn}-operation`]:{display:"flex",flex:"none",flexDirection:"column",alignSelf:"center",margin:`0 ${Nn}px`,verticalAlign:"middle",[`${Cn}-btn`]:{display:"block","&:first-child":{marginBottom:Rn},[_n]:{fontSize:Dn}}},[`${Cn}-empty-image`]:{maxHeight:In/2-Math.round(Ln*Fn)}})}},genTransferRTLStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-rtl`]:{direction:"rtl"}}},useStyle$8=genComponentStyleHook("Transfer",$n=>{const{fontSize:Cn,lineHeight:_n,lineWidth:Pn,controlHeightLG:In,controlHeight:Nn}=$n,Rn=Math.round(Cn*_n),Dn=In,Ln=Nn,Fn=merge$1($n,{transferItemHeight:Ln,transferHeaderHeight:Dn,transferHeaderVerticalPadding:Math.ceil((Dn-Pn-Rn)/2),transferItemPaddingVertical:(Ln-Rn)/2});return[genTransferStyle(Fn),genTransferCustomizeStyle(Fn),genTransferStatusStyle(Fn),genTransferRTLStyle(Fn)]},{listWidth:180,listHeight:200,listWidthLG:250}),transferProps=()=>({id:String,prefixCls:String,dataSource:arrayType([]),disabled:booleanType(),targetKeys:arrayType(),selectedKeys:arrayType(),render:functionType(),listStyle:someType([Function,Object],()=>({})),operationStyle:objectType(void 0),titles:arrayType(),operations:arrayType(),showSearch:booleanType(!1),filterOption:functionType(),searchPlaceholder:String,notFoundContent:PropTypes.any,locale:objectType(),rowKey:functionType(),showSelectAll:booleanType(),selectAllLabels:arrayType(),children:functionType(),oneWay:booleanType(),pagination:someType([Object,Boolean]),status:stringType(),onChange:functionType(),onSelectChange:functionType(),onSearch:functionType(),onScroll:functionType(),"onUpdate:targetKeys":functionType(),"onUpdate:selectedKeys":functionType()}),Transfer=defineComponent({compatConfig:{MODE:3},name:"ATransfer",inheritAttrs:!1,props:transferProps(),slots:Object,setup($n,Cn){let{emit:_n,attrs:Pn,slots:In,expose:Nn}=Cn;const{configProvider:Rn,prefixCls:Dn,direction:Ln}=useConfigInject("transfer",$n),[Fn,Bn]=useStyle$8(Dn),Hn=ref([]),zn=ref([]),Wn=useInjectFormItemContext(),Yn=FormItemInputContext.useInject(),Gn=computed(()=>getMergedStatus(Yn.status,$n.status));watch(()=>$n.selectedKeys,()=>{var xa,Ta;Hn.value=((xa=$n.selectedKeys)===null||xa===void 0?void 0:xa.filter(wa=>$n.targetKeys.indexOf(wa)===-1))||[],zn.value=((Ta=$n.selectedKeys)===null||Ta===void 0?void 0:Ta.filter(wa=>$n.targetKeys.indexOf(wa)>-1))||[]},{immediate:!0});const Go=(xa,Ta)=>{const wa={notFoundContent:Ta("Transfer")},La=getPropsSlot(In,$n,"notFoundContent");return La&&(wa.notFoundContent=La),$n.searchPlaceholder!==void 0&&(wa.searchPlaceholder=$n.searchPlaceholder),_extends$1(_extends$1(_extends$1({},xa),wa),$n.locale)},Xn=xa=>{const{targetKeys:Ta=[],dataSource:wa=[]}=$n,La=xa==="right"?Hn.value:zn.value,Na=groupDisabledKeysMap(wa),$a=La.filter(pa=>!Na.has(pa)),ka=groupKeysMap($a),Ha=xa==="right"?$a.concat(Ta):Ta.filter(pa=>!ka.has(pa)),da=xa==="right"?"left":"right";xa==="right"?Hn.value=[]:zn.value=[],_n("update:targetKeys",Ha),nr(da,[]),_n("change",Ha,xa,$a),Wn.onFieldChange()},Yo=()=>{Xn("left")},qo=()=>{Xn("right")},Jo=(xa,Ta)=>{nr(xa,Ta)},Zo=xa=>Jo("left",xa),rr=xa=>Jo("right",xa),nr=(xa,Ta)=>{xa==="left"?($n.selectedKeys||(Hn.value=Ta),_n("update:selectedKeys",[...Ta,...zn.value]),_n("selectChange",Ta,toRaw(zn.value))):($n.selectedKeys||(zn.value=Ta),_n("update:selectedKeys",[...Ta,...Hn.value]),_n("selectChange",toRaw(Hn.value),Ta))},ta=(xa,Ta)=>{const wa=Ta.target.value;_n("search",xa,wa)},oa=xa=>{ta("left",xa)},ra=xa=>{ta("right",xa)},ea=xa=>{_n("search",xa,"")},la=()=>{ea("left")},ua=()=>{ea("right")},ga=(xa,Ta,wa)=>{const La=xa==="left"?[...Hn.value]:[...zn.value],Na=La.indexOf(Ta);Na>-1&&La.splice(Na,1),wa&&La.push(Ta),nr(xa,La)},aa=(xa,Ta)=>ga("left",xa,Ta),ca=(xa,Ta)=>ga("right",xa,Ta),sa=xa=>{const{targetKeys:Ta=[]}=$n,wa=Ta.filter(La=>!xa.includes(La));_n("update:targetKeys",wa),_n("change",wa,"left",[...xa])},ia=(xa,Ta)=>{_n("scroll",xa,Ta)},fa=xa=>{ia("left",xa)},ma=xa=>{ia("right",xa)},ya=(xa,Ta)=>typeof xa=="function"?xa({direction:Ta}):xa,ba=ref([]),Ia=ref([]);watchEffect(()=>{const{dataSource:xa,rowKey:Ta,targetKeys:wa=[]}=$n,La=[],Na=new Array(wa.length),$a=groupKeysMap(wa);xa.forEach(ka=>{Ta&&(ka.key=Ta(ka)),$a.has(ka.key)?Na[$a.get(ka.key)]=ka:La.push(ka)}),ba.value=La,Ia.value=Na}),Nn({handleSelectChange:nr});const Ea=xa=>{var Ta,wa,La,Na,$a,ka;const{disabled:Ha,operations:da=[],showSearch:pa,listStyle:Sa,operationStyle:Aa,filterOption:Ra,showSelectAll:Fa,selectAllLabels:za=[],oneWay:Wa,pagination:Ya,id:ja=Wn.id.value}=$n,{class:qa,style:Xa}=Pn,Oa=In.children,Ma=!Oa&&Ya,Ua=Rn.renderEmpty,Qa=Go(xa,Ua),{footer:ri}=In,fi=$n.render||In.render,ei=zn.value.length>0,ti=Hn.value.length>0,ni=classNames(Dn.value,qa,{[`${Dn.value}-disabled`]:Ha,[`${Dn.value}-customize-list`]:!!Oa,[`${Dn.value}-rtl`]:Ln.value==="rtl"},getStatusClassNames(Dn.value,Gn.value,Yn.hasFeedback),Bn.value),ui=$n.titles,mi=(La=(Ta=ui&&ui[0])!==null&&Ta!==void 0?Ta:(wa=In.leftTitle)===null||wa===void 0?void 0:wa.call(In))!==null&&La!==void 0?La:(Qa.titles||["",""])[0],di=(ka=(Na=ui&&ui[1])!==null&&Na!==void 0?Na:($a=In.rightTitle)===null||$a===void 0?void 0:$a.call(In))!==null&&ka!==void 0?ka:(Qa.titles||["",""])[1];return createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:ni,style:Xa,id:ja}),[createVNode(List,_objectSpread2$1({key:"leftList",prefixCls:`${Dn.value}-list`,dataSource:ba.value,filterOption:Ra,style:ya(Sa,"left"),checkedKeys:Hn.value,handleFilter:oa,handleClear:la,onItemSelect:aa,onItemSelectAll:Zo,renderItem:fi,showSearch:pa,renderList:Oa,onScroll:fa,disabled:Ha,direction:Ln.value==="rtl"?"right":"left",showSelectAll:Fa,selectAllLabel:za[0]||In.leftSelectAllLabel,pagination:Ma},Qa),{titleText:()=>mi,footer:ri}),createVNode(Operation$1,{key:"operation",class:`${Dn.value}-operation`,rightActive:ti,rightArrowText:da[0],moveToRight:qo,leftActive:ei,leftArrowText:da[1],moveToLeft:Yo,style:Aa,disabled:Ha,direction:Ln.value,oneWay:Wa},null),createVNode(List,_objectSpread2$1({key:"rightList",prefixCls:`${Dn.value}-list`,dataSource:Ia.value,filterOption:Ra,style:ya(Sa,"right"),checkedKeys:zn.value,handleFilter:ra,handleClear:ua,onItemSelect:ca,onItemSelectAll:rr,onItemRemove:sa,renderItem:fi,showSearch:pa,renderList:Oa,onScroll:ma,disabled:Ha,direction:Ln.value==="rtl"?"left":"right",showSelectAll:Fa,selectAllLabel:za[1]||In.rightSelectAllLabel,showRemove:Wa,pagination:Ma},Qa),{titleText:()=>di,footer:ri})])};return()=>Fn(createVNode(LocaleReceiver,{componentName:"Transfer",defaultLocale:localeValues$1.Transfer,children:Ea},null))}}),index$8=withInstall(Transfer);function toArray($n){return Array.isArray($n)?$n:$n!==void 0?[$n]:[]}function fillFieldNames($n){const{label:Cn,value:_n,children:Pn}=$n||{},In=_n||"value";return{_title:Cn?[Cn]:["title","label"],value:In,key:In,children:Pn||"children"}}function isCheckDisabled($n){return $n.disabled||$n.disableCheckbox||$n.checkable===!1}function getAllKeys($n,Cn){const _n=[];function Pn(In){In.forEach(Nn=>{_n.push(Nn[Cn.value]);const Rn=Nn[Cn.children];Rn&&Pn(Rn)})}return Pn($n),_n}function isNil($n){return $n==null}const TreeSelectContextPropsKey=Symbol("TreeSelectContextPropsKey");function useProvideSelectContext($n){return provide(TreeSelectContextPropsKey,$n)}function useInjectSelectContext(){return inject(TreeSelectContextPropsKey,{})}const HIDDEN_STYLE={width:0,height:0,display:"flex",overflow:"hidden",opacity:0,border:0,padding:0,margin:0},OptionList=defineComponent({compatConfig:{MODE:3},name:"OptionList",inheritAttrs:!1,setup($n,Cn){let{slots:_n,expose:Pn}=Cn;const In=useBaseProps(),Nn=useInjectLegacySelectContext(),Rn=useInjectSelectContext(),Dn=ref(),Ln=useMemo(()=>Rn.treeData,[()=>In.open,()=>Rn.treeData],Zo=>Zo[0]),Fn=computed(()=>{const{checkable:Zo,halfCheckedKeys:rr,checkedKeys:nr}=Nn;return Zo?{checked:nr,halfChecked:rr}:null});watch(()=>In.open,()=>{nextTick(()=>{var Zo;In.open&&!In.multiple&&Nn.checkedKeys.length&&((Zo=Dn.value)===null||Zo===void 0||Zo.scrollTo({key:Nn.checkedKeys[0]}))})},{immediate:!0,flush:"post"});const Bn=computed(()=>String(In.searchValue).toLowerCase()),Hn=Zo=>Bn.value?String(Zo[Nn.treeNodeFilterProp]).toLowerCase().includes(Bn.value):!1,zn=shallowRef(Nn.treeDefaultExpandedKeys),Wn=shallowRef(null);watch(()=>In.searchValue,()=>{In.searchValue&&(Wn.value=getAllKeys(toRaw(Rn.treeData),toRaw(Rn.fieldNames)))},{immediate:!0});const Yn=computed(()=>Nn.treeExpandedKeys?Nn.treeExpandedKeys.slice():In.searchValue?Wn.value:zn.value),Gn=Zo=>{var rr;zn.value=Zo,Wn.value=Zo,(rr=Nn.onTreeExpand)===null||rr===void 0||rr.call(Nn,Zo)},Go=Zo=>{Zo.preventDefault()},Xn=(Zo,rr)=>{let{node:nr}=rr;var ta,oa;const{checkable:ra,checkedKeys:ea}=Nn;ra&&isCheckDisabled(nr)||((ta=Rn.onSelect)===null||ta===void 0||ta.call(Rn,nr.key,{selected:!ea.includes(nr.key)}),In.multiple||(oa=In.toggleOpen)===null||oa===void 0||oa.call(In,!1))},Yo=ref(null),qo=computed(()=>Nn.keyEntities[Yo.value]),Jo=Zo=>{Yo.value=Zo};return Pn({scrollTo:function(){for(var Zo,rr,nr=arguments.length,ta=new Array(nr),oa=0;oa{var rr;const{which:nr}=Zo;switch(nr){case KeyCode$1.UP:case KeyCode$1.DOWN:case KeyCode$1.LEFT:case KeyCode$1.RIGHT:(rr=Dn.value)===null||rr===void 0||rr.onKeydown(Zo);break;case KeyCode$1.ENTER:{if(qo.value){const{selectable:ta,value:oa}=qo.value.node||{};ta!==!1&&Xn(null,{node:{key:Yo.value},selected:!Nn.checkedKeys.includes(oa)})}break}case KeyCode$1.ESC:In.toggleOpen(!1)}},onKeyup:()=>{}}),()=>{var Zo;const{prefixCls:rr,multiple:nr,searchValue:ta,open:oa,notFoundContent:ra=(Zo=_n.notFoundContent)===null||Zo===void 0?void 0:Zo.call(_n)}=In,{listHeight:ea,listItemHeight:la,virtual:ua,dropdownMatchSelectWidth:ga,treeExpandAction:aa}=Rn,{checkable:ca,treeDefaultExpandAll:sa,treeIcon:ia,showTreeIcon:fa,switcherIcon:ma,treeLine:ya,loadData:ba,treeLoadedKeys:Ia,treeMotion:Ea,onTreeLoad:xa,checkedKeys:Ta}=Nn;if(Ln.value.length===0)return createVNode("div",{role:"listbox",class:`${rr}-empty`,onMousedown:Go},[ra]);const wa={fieldNames:Rn.fieldNames};return Ia&&(wa.loadedKeys=Ia),Yn.value&&(wa.expandedKeys=Yn.value),createVNode("div",{onMousedown:Go},[qo.value&&oa&&createVNode("span",{style:HIDDEN_STYLE,"aria-live":"assertive"},[qo.value.node.value]),createVNode(Tree$2,_objectSpread2$1(_objectSpread2$1({ref:Dn,focusable:!1,prefixCls:`${rr}-tree`,treeData:Ln.value,height:ea,itemHeight:la,virtual:ua!==!1&&ga!==!1,multiple:nr,icon:ia,showIcon:fa,switcherIcon:ma,showLine:ya,loadData:ta?null:ba,motion:Ea,activeKey:Yo.value,checkable:ca,checkStrictly:!0,checkedKeys:Fn.value,selectedKeys:ca?[]:Ta,defaultExpandAll:sa},wa),{},{onActiveChange:Jo,onSelect:Xn,onCheck:Xn,onExpand:Gn,onLoad:xa,filterTreeNode:Hn,expandAction:aa}),_extends$1(_extends$1({},_n),{checkable:Nn.customSlots.treeCheckable}))])}}}),SHOW_ALL="SHOW_ALL",SHOW_PARENT="SHOW_PARENT",SHOW_CHILD="SHOW_CHILD";function formatStrategyValues($n,Cn,_n,Pn){const In=new Set($n);return Cn===SHOW_CHILD?$n.filter(Nn=>{const Rn=_n[Nn];return!(Rn&&Rn.children&&Rn.children.some(Dn=>{let{node:Ln}=Dn;return In.has(Ln[Pn.value])})&&Rn.children.every(Dn=>{let{node:Ln}=Dn;return isCheckDisabled(Ln)||In.has(Ln[Pn.value])}))}):Cn===SHOW_PARENT?$n.filter(Nn=>{const Rn=_n[Nn],Dn=Rn?Rn.parent:null;return!(Dn&&!isCheckDisabled(Dn.node)&&In.has(Dn.key))}):$n}const TreeNode=()=>null;TreeNode.inheritAttrs=!1;TreeNode.displayName="ATreeSelectNode";TreeNode.isTreeSelectNode=!0;const TreeNode$1=TreeNode;var __rest$b=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In0&&arguments[0]!==void 0?arguments[0]:[];return filterEmpty(_n).map(Pn=>{var In,Nn,Rn;if(!isTreeSelectNode(Pn))return null;const Dn=Pn.children||{},Ln=Pn.key,Fn={};for(const[nr,ta]of Object.entries(Pn.props))Fn[camelize(nr)]=ta;const{isLeaf:Bn,checkable:Hn,selectable:zn,disabled:Wn,disableCheckbox:Yn}=Fn,Gn={isLeaf:Bn||Bn===""||void 0,checkable:Hn||Hn===""||void 0,selectable:zn||zn===""||void 0,disabled:Wn||Wn===""||void 0,disableCheckbox:Yn||Yn===""||void 0},Go=_extends$1(_extends$1({},Fn),Gn),{title:Xn=(In=Dn.title)===null||In===void 0?void 0:In.call(Dn,Go),switcherIcon:Yo=(Nn=Dn.switcherIcon)===null||Nn===void 0?void 0:Nn.call(Dn,Go)}=Fn,qo=__rest$b(Fn,["title","switcherIcon"]),Jo=(Rn=Dn.default)===null||Rn===void 0?void 0:Rn.call(Dn),Zo=_extends$1(_extends$1(_extends$1({},qo),{title:Xn,switcherIcon:Yo,key:Ln,isLeaf:Bn}),Gn),rr=Cn(Jo);return rr.length&&(Zo.children=rr),Zo})}return Cn($n)}function fillLegacyProps($n){if(!$n)return $n;const Cn=_extends$1({},$n);return"props"in Cn||Object.defineProperty(Cn,"props",{get(){return Cn}}),Cn}function fillAdditionalInfo($n,Cn,_n,Pn,In,Nn){let Rn=null,Dn=null;function Ln(){function Fn(Bn){let Hn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"0",zn=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;return Bn.map((Wn,Yn)=>{const Gn=`${Hn}-${Yn}`,Go=Wn[Nn.value],Xn=_n.includes(Go),Yo=Fn(Wn[Nn.children]||[],Gn,Xn),qo=createVNode(TreeNode$1,Wn,{default:()=>[Yo.map(Jo=>Jo.node)]});if(Cn===Go&&(Rn=qo),Xn){const Jo={pos:Gn,node:qo,children:Yo};return zn||Dn.push(Jo),Jo}return null}).filter(Wn=>Wn)}Dn||(Dn=[],Fn(Pn),Dn.sort((Bn,Hn)=>{let{node:{props:{value:zn}}}=Bn,{node:{props:{value:Wn}}}=Hn;const Yn=_n.indexOf(zn),Gn=_n.indexOf(Wn);return Yn-Gn}))}Object.defineProperty($n,"triggerNode",{get(){return Ln(),Rn}}),Object.defineProperty($n,"allCheckedNodes",{get(){return Ln(),In?Dn:Dn.map(Fn=>{let{node:Bn}=Fn;return Bn})}})}function parseSimpleTreeData($n,Cn){let{id:_n,pId:Pn,rootPId:In}=Cn;const Nn={},Rn=[];return $n.map(Ln=>{const Fn=_extends$1({},Ln),Bn=Fn[_n];return Nn[Bn]=Fn,Fn.key=Fn.key||Bn,Fn}).forEach(Ln=>{const Fn=Ln[Pn],Bn=Nn[Fn];Bn&&(Bn.children=Bn.children||[],Bn.children.push(Ln)),(Fn===In||!Bn&&In===null)&&Rn.push(Ln)}),Rn}function useTreeData($n,Cn,_n){const Pn=shallowRef();return watch([_n,$n,Cn],()=>{const In=_n.value;$n.value?Pn.value=_n.value?parseSimpleTreeData(toRaw($n.value),_extends$1({id:"id",pId:"pId",rootPId:null},In!==!0?In:{})):toRaw($n.value).slice():Pn.value=convertChildrenToData(toRaw(Cn.value))},{immediate:!0,deep:!0}),Pn}const useCache=$n=>{const Cn=shallowRef({valueLabels:new Map}),_n=shallowRef();return watch($n,()=>{_n.value=toRaw($n.value)},{immediate:!0}),[computed(()=>{const{valueLabels:In}=Cn.value,Nn=new Map,Rn=_n.value.map(Dn=>{var Ln;const{value:Fn}=Dn,Bn=(Ln=Dn.label)!==null&&Ln!==void 0?Ln:In.get(Fn);return Nn.set(Fn,Bn),_extends$1(_extends$1({},Dn),{label:Bn})});return Cn.value.valueLabels=Nn,Rn})]},useDataEntities=($n,Cn)=>{const _n=shallowRef(new Map),Pn=shallowRef({});return watchEffect(()=>{const In=Cn.value,Nn=convertDataToEntities($n.value,{fieldNames:In,initWrapper:Rn=>_extends$1(_extends$1({},Rn),{valueEntities:new Map}),processEntity:(Rn,Dn)=>{const Ln=Rn.node[In.value];Dn.valueEntities.set(Ln,Rn)}});_n.value=Nn.valueEntities,Pn.value=Nn.keyEntities}),{valueEntities:_n,keyEntities:Pn}},useCheckedKeys=($n,Cn,_n,Pn,In,Nn)=>{const Rn=shallowRef([]),Dn=shallowRef([]);return watchEffect(()=>{let Ln=$n.value.map(Hn=>{let{value:zn}=Hn;return zn}),Fn=Cn.value.map(Hn=>{let{value:zn}=Hn;return zn});const Bn=Ln.filter(Hn=>!Pn.value[Hn]);_n.value&&({checkedKeys:Ln,halfCheckedKeys:Fn}=conductCheck(Ln,!0,Pn.value,In.value,Nn.value)),Rn.value=Array.from(new Set([...Bn,...Ln])),Dn.value=Fn}),[Rn,Dn]},useFilterTreeData=($n,Cn,_n)=>{let{treeNodeFilterProp:Pn,filterTreeNode:In,fieldNames:Nn}=_n;return computed(()=>{const{children:Rn}=Nn.value,Dn=Cn.value,Ln=Pn==null?void 0:Pn.value;if(!Dn||In.value===!1)return $n.value;let Fn;if(typeof In.value=="function")Fn=In.value;else{const Hn=Dn.toUpperCase();Fn=(zn,Wn)=>{const Yn=Wn[Ln];return String(Yn).toUpperCase().includes(Hn)}}function Bn(Hn){let zn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const Wn=[];for(let Yn=0,Gn=Hn.length;Yn$n.treeCheckable&&!$n.treeCheckStrictly),Dn=computed(()=>$n.treeCheckable||$n.treeCheckStrictly),Ln=computed(()=>$n.treeCheckStrictly||$n.labelInValue),Fn=computed(()=>Dn.value||$n.multiple),Bn=computed(()=>fillFieldNames($n.fieldNames)),[Hn,zn]=useMergedState("",{value:computed(()=>$n.searchValue!==void 0?$n.searchValue:$n.inputValue),postState:ja=>ja||""}),Wn=ja=>{var qa;zn(ja),(qa=$n.onSearch)===null||qa===void 0||qa.call($n,ja)},Yn=useTreeData(toRef($n,"treeData"),toRef($n,"children"),toRef($n,"treeDataSimpleMode")),{keyEntities:Gn,valueEntities:Go}=useDataEntities(Yn,Bn),Xn=ja=>{const qa=[],Xa=[];return ja.forEach(Oa=>{Go.value.has(Oa)?Xa.push(Oa):qa.push(Oa)}),{missingRawValues:qa,existRawValues:Xa}},Yo=useFilterTreeData(Yn,Hn,{fieldNames:Bn,treeNodeFilterProp:toRef($n,"treeNodeFilterProp"),filterTreeNode:toRef($n,"filterTreeNode")}),qo=ja=>{if(ja){if($n.treeNodeLabelProp)return ja[$n.treeNodeLabelProp];const{_title:qa}=Bn.value;for(let Xa=0;XatoArray(ja).map(Xa=>isRawValue(Xa)?{value:Xa}:Xa),Zo=ja=>Jo(ja).map(Xa=>{let{label:Oa}=Xa;const{value:Ma,halfChecked:Ua}=Xa;let Qa;const ri=Go.value.get(Ma);return ri&&(Oa=Oa??qo(ri.node),Qa=ri.node.disabled),{label:Oa,value:Ma,halfChecked:Ua,disabled:Qa}}),[rr,nr]=useMergedState($n.defaultValue,{value:toRef($n,"value")}),ta=computed(()=>Jo(rr.value)),oa=shallowRef([]),ra=shallowRef([]);watchEffect(()=>{const ja=[],qa=[];ta.value.forEach(Xa=>{Xa.halfChecked?qa.push(Xa):ja.push(Xa)}),oa.value=ja,ra.value=qa});const ea=computed(()=>oa.value.map(ja=>ja.value)),{maxLevel:la,levelEntities:ua}=useMaxLevel(Gn),[ga,aa]=useCheckedKeys(oa,ra,Rn,Gn,la,ua),ca=computed(()=>{const Xa=formatStrategyValues(ga.value,$n.showCheckedStrategy,Gn.value,Bn.value).map(Ua=>{var Qa,ri,fi;return(fi=(ri=(Qa=Gn.value[Ua])===null||Qa===void 0?void 0:Qa.node)===null||ri===void 0?void 0:ri[Bn.value.value])!==null&&fi!==void 0?fi:Ua}).map(Ua=>{const Qa=oa.value.find(ri=>ri.value===Ua);return{value:Ua,label:Qa==null?void 0:Qa.label}}),Oa=Zo(Xa),Ma=Oa[0];return!Fn.value&&Ma&&isNil(Ma.value)&&isNil(Ma.label)?[]:Oa.map(Ua=>{var Qa;return _extends$1(_extends$1({},Ua),{label:(Qa=Ua.label)!==null&&Qa!==void 0?Qa:Ua.value})})}),[sa]=useCache(ca),ia=(ja,qa,Xa)=>{const Oa=Zo(ja);if(nr(Oa),$n.autoClearSearchValue&&zn(""),$n.onChange){let Ma=ja;Rn.value&&(Ma=formatStrategyValues(ja,$n.showCheckedStrategy,Gn.value,Bn.value).map(mi=>{const di=Go.value.get(mi);return di?di.node[Bn.value.value]:mi}));const{triggerValue:Ua,selected:Qa}=qa||{triggerValue:void 0,selected:void 0};let ri=Ma;if($n.treeCheckStrictly){const ui=ra.value.filter(mi=>!Ma.includes(mi.value));ri=[...ri,...ui]}const fi=Zo(ri),ei={preValue:oa.value,triggerValue:Ua};let ti=!0;($n.treeCheckStrictly||Xa==="selection"&&!Qa)&&(ti=!1),fillAdditionalInfo(ei,Ua,ja,Yn.value,ti,Bn.value),Dn.value?ei.checked=Qa:ei.selected=Qa;const ni=Ln.value?fi:fi.map(ui=>ui.value);$n.onChange(Fn.value?ni:ni[0],Ln.value?null:fi.map(ui=>ui.label),ei)}},fa=(ja,qa)=>{let{selected:Xa,source:Oa}=qa;var Ma,Ua,Qa;const ri=toRaw(Gn.value),fi=toRaw(Go.value),ei=ri[ja],ti=ei==null?void 0:ei.node,ni=(Ma=ti==null?void 0:ti[Bn.value.value])!==null&&Ma!==void 0?Ma:ja;if(!Fn.value)ia([ni],{selected:!0,triggerValue:ni},"option");else{let ui=Xa?[...ea.value,ni]:ga.value.filter(mi=>mi!==ni);if(Rn.value){const{missingRawValues:mi,existRawValues:di}=Xn(ui),gi=di.map(Ti=>fi.get(Ti).key);let wi;Xa?{checkedKeys:wi}=conductCheck(gi,!0,ri,la.value,ua.value):{checkedKeys:wi}=conductCheck(gi,{checked:!1,halfCheckedKeys:aa.value},ri,la.value,ua.value),ui=[...mi,...wi.map(Ti=>ri[Ti].node[Bn.value.value])]}ia(ui,{selected:Xa,triggerValue:ni},Oa||"option")}Xa||!Fn.value?(Ua=$n.onSelect)===null||Ua===void 0||Ua.call($n,ni,fillLegacyProps(ti)):(Qa=$n.onDeselect)===null||Qa===void 0||Qa.call($n,ni,fillLegacyProps(ti))},ma=ja=>{if($n.onDropdownVisibleChange){const qa={};Object.defineProperty(qa,"documentClickClose",{get(){return!1}}),$n.onDropdownVisibleChange(ja,qa)}},ya=(ja,qa)=>{const Xa=ja.map(Oa=>Oa.value);if(qa.type==="clear"){ia(Xa,{},"selection");return}qa.values.length&&fa(qa.values[0].value,{selected:!1,source:"selection"})},{treeNodeFilterProp:ba,loadData:Ia,treeLoadedKeys:Ea,onTreeLoad:xa,treeDefaultExpandAll:Ta,treeExpandedKeys:wa,treeDefaultExpandedKeys:La,onTreeExpand:Na,virtual:$a,listHeight:ka,listItemHeight:Ha,treeLine:da,treeIcon:pa,showTreeIcon:Sa,switcherIcon:Aa,treeMotion:Ra,customSlots:Fa,dropdownMatchSelectWidth:za,treeExpandAction:Wa}=toRefs($n);useProvideLegacySelectContext(toReactive({checkable:Dn,loadData:Ia,treeLoadedKeys:Ea,onTreeLoad:xa,checkedKeys:ga,halfCheckedKeys:aa,treeDefaultExpandAll:Ta,treeExpandedKeys:wa,treeDefaultExpandedKeys:La,onTreeExpand:Na,treeIcon:pa,treeMotion:Ra,showTreeIcon:Sa,switcherIcon:Aa,treeLine:da,treeNodeFilterProp:ba,keyEntities:Gn,customSlots:Fa})),useProvideSelectContext(toReactive({virtual:$a,listHeight:ka,listItemHeight:Ha,treeData:Yo,fieldNames:Bn,onSelect:fa,dropdownMatchSelectWidth:za,treeExpandAction:Wa}));const Ya=ref();return Pn({focus(){var ja;(ja=Ya.value)===null||ja===void 0||ja.focus()},blur(){var ja;(ja=Ya.value)===null||ja===void 0||ja.blur()},scrollTo(ja){var qa;(qa=Ya.value)===null||qa===void 0||qa.scrollTo(ja)}}),()=>{var ja;const qa=omit$1($n,["id","prefixCls","customSlots","value","defaultValue","onChange","onSelect","onDeselect","searchValue","inputValue","onSearch","autoClearSearchValue","filterTreeNode","treeNodeFilterProp","showCheckedStrategy","treeNodeLabelProp","multiple","treeCheckable","treeCheckStrictly","labelInValue","fieldNames","treeDataSimpleMode","treeData","children","loadData","treeLoadedKeys","onTreeLoad","treeDefaultExpandAll","treeExpandedKeys","treeDefaultExpandedKeys","onTreeExpand","virtual","listHeight","listItemHeight","onDropdownVisibleChange","treeLine","treeIcon","showTreeIcon","switcherIcon","treeMotion"]);return createVNode(BaseSelect,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({ref:Ya},_n),qa),{},{id:Nn,prefixCls:$n.prefixCls,mode:Fn.value?"multiple":void 0,displayValues:sa.value,onDisplayValuesChange:ya,searchValue:Hn.value,onSearch:Wn,OptionList,emptyOptions:!Yn.value.length,onDropdownVisibleChange:ma,tagRender:$n.tagRender||In.tagRender,dropdownMatchSelectWidth:(ja=$n.dropdownMatchSelectWidth)!==null&&ja!==void 0?ja:!0}),In)}}}),genBaseStyle$3=$n=>{const{componentCls:Cn,treePrefixCls:_n,colorBgElevated:Pn}=$n,In=`.${_n}`;return[{[`${Cn}-dropdown`]:[{padding:`${$n.paddingXS}px ${$n.paddingXS/2}px`},genTreeStyle(_n,merge$1($n,{colorBgContainer:Pn})),{[In]:{borderRadius:0,"&-list-holder-inner":{alignItems:"stretch",[`${In}-treenode`]:{[`${In}-node-content-wrapper`]:{flex:"auto"}}}}},getStyle$2(`${_n}-checkbox`,$n),{"&-rtl":{direction:"rtl",[`${In}-switcher${In}-switcher_close`]:{[`${In}-switcher-icon svg`]:{transform:"rotate(90deg)"}}}}]}]};function useTreeSelectStyle($n,Cn){return genComponentStyleHook("TreeSelect",_n=>{const Pn=merge$1(_n,{treePrefixCls:Cn.value});return[genBaseStyle$3(Pn)]})($n)}const getTransitionName=($n,Cn,_n)=>_n!==void 0?_n:`${$n}-${Cn}`;function treeSelectProps(){return _extends$1(_extends$1({},omit$1(treeSelectProps$1(),["showTreeIcon","treeMotion","inputIcon","getInputElement","treeLine","customSlots"])),{suffixIcon:PropTypes.any,size:stringType(),bordered:booleanType(),treeLine:someType([Boolean,Object]),replaceFields:objectType(),placement:stringType(),status:stringType(),popupClassName:String,dropdownClassName:String,"onUpdate:value":functionType(),"onUpdate:treeExpandedKeys":functionType(),"onUpdate:searchValue":functionType()})}const TreeSelect=defineComponent({compatConfig:{MODE:3},name:"ATreeSelect",inheritAttrs:!1,props:initDefaultProps(treeSelectProps(),{choiceTransitionName:"",listHeight:256,treeIcon:!1,listItemHeight:26,bordered:!0}),slots:Object,setup($n,Cn){let{attrs:_n,slots:Pn,expose:In,emit:Nn}=Cn;$n.treeData===void 0&&Pn.default,devWarning($n.multiple!==!1||!$n.treeCheckable,"TreeSelect","`multiple` will always be `true` when `treeCheckable` is true"),devWarning($n.replaceFields===void 0,"TreeSelect","`replaceFields` is deprecated, please use fieldNames instead"),devWarning(!$n.dropdownClassName,"TreeSelect","`dropdownClassName` is deprecated. Please use `popupClassName` instead.");const Rn=useInjectFormItemContext(),Dn=FormItemInputContext.useInject(),Ln=computed(()=>getMergedStatus(Dn.status,$n.status)),{prefixCls:Fn,renderEmpty:Bn,direction:Hn,virtual:zn,dropdownMatchSelectWidth:Wn,size:Yn,getPopupContainer:Gn,getPrefixCls:Go,disabled:Xn}=useConfigInject("select",$n),{compactSize:Yo,compactItemClassnames:qo}=useCompactItemContext(Fn,Hn),Jo=computed(()=>Yo.value||Yn.value),Zo=useInjectDisabled(),rr=computed(()=>{var Ea;return(Ea=Xn.value)!==null&&Ea!==void 0?Ea:Zo.value}),nr=computed(()=>Go()),ta=computed(()=>$n.placement!==void 0?$n.placement:Hn.value==="rtl"?"bottomRight":"bottomLeft"),oa=computed(()=>getTransitionName(nr.value,getTransitionDirection(ta.value),$n.transitionName)),ra=computed(()=>getTransitionName(nr.value,"",$n.choiceTransitionName)),ea=computed(()=>Go("select-tree",$n.prefixCls)),la=computed(()=>Go("tree-select",$n.prefixCls)),[ua,ga]=useSelectStyle(Fn),[aa]=useTreeSelectStyle(la,ea),ca=computed(()=>classNames($n.popupClassName||$n.dropdownClassName,`${la.value}-dropdown`,{[`${la.value}-dropdown-rtl`]:Hn.value==="rtl"},ga.value)),sa=computed(()=>!!($n.treeCheckable||$n.multiple)),ia=computed(()=>$n.showArrow!==void 0?$n.showArrow:$n.loading||!sa.value),fa=ref();In({focus(){var Ea,xa;(xa=(Ea=fa.value).focus)===null||xa===void 0||xa.call(Ea)},blur(){var Ea,xa;(xa=(Ea=fa.value).blur)===null||xa===void 0||xa.call(Ea)}});const ma=function(){for(var Ea=arguments.length,xa=new Array(Ea),Ta=0;Ta{Nn("update:treeExpandedKeys",Ea),Nn("treeExpand",Ea)},ba=Ea=>{Nn("update:searchValue",Ea),Nn("search",Ea)},Ia=Ea=>{Nn("blur",Ea),Rn.onFieldBlur()};return()=>{var Ea,xa;const{notFoundContent:Ta=(Ea=Pn.notFoundContent)===null||Ea===void 0?void 0:Ea.call(Pn),prefixCls:wa,bordered:La,listHeight:Na,listItemHeight:$a,multiple:ka,treeIcon:Ha,treeLine:da,showArrow:pa,switcherIcon:Sa=(xa=Pn.switcherIcon)===null||xa===void 0?void 0:xa.call(Pn),fieldNames:Aa=$n.replaceFields,id:Ra=Rn.id.value}=$n,{isFormItemInput:Fa,hasFeedback:za,feedbackIcon:Wa}=Dn,{suffixIcon:Ya,removeIcon:ja,clearIcon:qa}=getIcons(_extends$1(_extends$1({},$n),{multiple:sa.value,showArrow:ia.value,hasFeedback:za,feedbackIcon:Wa,prefixCls:Fn.value}),Pn);let Xa;Ta!==void 0?Xa=Ta:Xa=Bn("Select");const Oa=omit$1($n,["suffixIcon","itemIcon","removeIcon","clearIcon","switcherIcon","bordered","status","onUpdate:value","onUpdate:treeExpandedKeys","onUpdate:searchValue"]),Ma=classNames(!wa&&la.value,{[`${Fn.value}-lg`]:Jo.value==="large",[`${Fn.value}-sm`]:Jo.value==="small",[`${Fn.value}-rtl`]:Hn.value==="rtl",[`${Fn.value}-borderless`]:!La,[`${Fn.value}-in-form-item`]:Fa},getStatusClassNames(Fn.value,Ln.value,za),qo.value,_n.class,ga.value),Ua={};return $n.treeData===void 0&&Pn.default&&(Ua.children=flattenChildren(Pn.default())),ua(aa(createVNode(TreeSelect$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),Oa),{},{disabled:rr.value,virtual:zn.value,dropdownMatchSelectWidth:Wn.value,id:Ra,fieldNames:Aa,ref:fa,prefixCls:Fn.value,class:Ma,listHeight:Na,listItemHeight:$a,treeLine:!!da,inputIcon:Ya,multiple:ka,removeIcon:ja,clearIcon:qa,switcherIcon:Qa=>renderSwitcherIcon(ea.value,Sa,Qa,Pn.leafIcon,da),showTreeIcon:Ha,notFoundContent:Xa,getPopupContainer:Gn==null?void 0:Gn.value,treeMotion:null,dropdownClassName:ca.value,choiceTransitionName:ra.value,onChange:ma,onBlur:Ia,onSearch:ba,onTreeExpand:ya},Ua),{},{transitionName:oa.value,customSlots:_extends$1(_extends$1({},Pn),{treeCheckable:()=>createVNode("span",{class:`${Fn.value}-tree-checkbox-inner`},null)}),maxTagPlaceholder:$n.maxTagPlaceholder||Pn.maxTagPlaceholder,placement:ta.value,showArrow:za||pa}),_extends$1(_extends$1({},Pn),{treeCheckable:()=>createVNode("span",{class:`${Fn.value}-tree-checkbox-inner`},null)}))))}}}),TreeSelectNode=TreeNode$1,index$7=_extends$1(TreeSelect,{TreeNode:TreeNode$1,SHOW_ALL,SHOW_PARENT,SHOW_CHILD,install:$n=>($n.component(TreeSelect.name,TreeSelect),$n.component(TreeSelectNode.displayName,TreeSelectNode),$n)}),timePickerProps=()=>({format:String,showNow:booleanType(),showHour:booleanType(),showMinute:booleanType(),showSecond:booleanType(),use12Hours:booleanType(),hourStep:Number,minuteStep:Number,secondStep:Number,hideDisabledOptions:booleanType(),popupClassName:String,status:stringType()});function createTimePicker($n){const Cn=generatePicker($n,_extends$1(_extends$1({},timePickerProps()),{order:{type:Boolean,default:!0}})),{TimePicker:_n,RangePicker:Pn}=Cn,In=defineComponent({name:"ATimePicker",inheritAttrs:!1,props:_extends$1(_extends$1(_extends$1(_extends$1({},commonProps$1()),datePickerProps()),timePickerProps()),{addon:{type:Function}}),slots:Object,setup(Rn,Dn){let{slots:Ln,expose:Fn,emit:Bn,attrs:Hn}=Dn;const zn=Rn,Wn=useInjectFormItemContext();devWarning(!(Ln.addon||zn.addon),"TimePicker","`addon` is deprecated. Please use `v-slot:renderExtraFooter` instead.");const Yn=ref();Fn({focus:()=>{var Jo;(Jo=Yn.value)===null||Jo===void 0||Jo.focus()},blur:()=>{var Jo;(Jo=Yn.value)===null||Jo===void 0||Jo.blur()}});const Gn=(Jo,Zo)=>{Bn("update:value",Jo),Bn("change",Jo,Zo),Wn.onFieldChange()},Go=Jo=>{Bn("update:open",Jo),Bn("openChange",Jo)},Xn=Jo=>{Bn("focus",Jo)},Yo=Jo=>{Bn("blur",Jo),Wn.onFieldBlur()},qo=Jo=>{Bn("ok",Jo)};return()=>{const{id:Jo=Wn.id.value}=zn;return createVNode(_n,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Hn),omit$1(zn,["onUpdate:value","onUpdate:open"])),{},{id:Jo,dropdownClassName:zn.popupClassName,mode:void 0,ref:Yn,renderExtraFooter:zn.addon||Ln.addon||zn.renderExtraFooter||Ln.renderExtraFooter,onChange:Gn,onOpenChange:Go,onFocus:Xn,onBlur:Yo,onOk:qo}),Ln)}}}),Nn=defineComponent({name:"ATimeRangePicker",inheritAttrs:!1,props:_extends$1(_extends$1(_extends$1(_extends$1({},commonProps$1()),rangePickerProps()),timePickerProps()),{order:{type:Boolean,default:!0}}),slots:Object,setup(Rn,Dn){let{slots:Ln,expose:Fn,emit:Bn,attrs:Hn}=Dn;const zn=Rn,Wn=ref(),Yn=useInjectFormItemContext();Fn({focus:()=>{var rr;(rr=Wn.value)===null||rr===void 0||rr.focus()},blur:()=>{var rr;(rr=Wn.value)===null||rr===void 0||rr.blur()}});const Gn=(rr,nr)=>{Bn("update:value",rr),Bn("change",rr,nr),Yn.onFieldChange()},Go=rr=>{Bn("update:open",rr),Bn("openChange",rr)},Xn=rr=>{Bn("focus",rr)},Yo=rr=>{Bn("blur",rr),Yn.onFieldBlur()},qo=(rr,nr)=>{Bn("panelChange",rr,nr)},Jo=rr=>{Bn("ok",rr)},Zo=(rr,nr,ta)=>{Bn("calendarChange",rr,nr,ta)};return()=>{const{id:rr=Yn.id.value}=zn;return createVNode(Pn,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},Hn),omit$1(zn,["onUpdate:open","onUpdate:value"])),{},{id:rr,dropdownClassName:zn.popupClassName,picker:"time",mode:void 0,ref:Wn,onChange:Gn,onOpenChange:Go,onFocus:Xn,onBlur:Yo,onPanelChange:qo,onOk:Jo,onCalendarChange:Zo}),Ln)}}});return{TimePicker:In,TimeRangePicker:Nn}}const{TimePicker:TimePicker$1,TimeRangePicker}=createTimePicker(dayjsGenerateConfig),TimePicker$2=_extends$1(TimePicker$1,{TimePicker:TimePicker$1,TimeRangePicker,install:$n=>($n.component(TimePicker$1.name,TimePicker$1),$n.component(TimeRangePicker.name,TimeRangePicker),$n)}),timelineItemProps=()=>({prefixCls:String,color:String,dot:PropTypes.any,pending:booleanType(),position:PropTypes.oneOf(tuple$1("left","right","")).def(""),label:PropTypes.any}),TimelineItem=defineComponent({compatConfig:{MODE:3},name:"ATimelineItem",props:initDefaultProps(timelineItemProps(),{color:"blue",pending:!1}),slots:Object,setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn}=useConfigInject("timeline",$n),In=computed(()=>({[`${Pn.value}-item`]:!0,[`${Pn.value}-item-pending`]:$n.pending})),Nn=computed(()=>/blue|red|green|gray/.test($n.color||"")?void 0:$n.color||"blue"),Rn=computed(()=>({[`${Pn.value}-item-head`]:!0,[`${Pn.value}-item-head-${$n.color||"blue"}`]:!Nn.value}));return()=>{var Dn,Ln,Fn;const{label:Bn=(Dn=_n.label)===null||Dn===void 0?void 0:Dn.call(_n),dot:Hn=(Ln=_n.dot)===null||Ln===void 0?void 0:Ln.call(_n)}=$n;return createVNode("li",{class:In.value},[Bn&&createVNode("div",{class:`${Pn.value}-item-label`},[Bn]),createVNode("div",{class:`${Pn.value}-item-tail`},null),createVNode("div",{class:[Rn.value,!!Hn&&`${Pn.value}-item-head-custom`],style:{borderColor:Nn.value,color:Nn.value}},[Hn]),createVNode("div",{class:`${Pn.value}-item-content`},[(Fn=_n.default)===null||Fn===void 0?void 0:Fn.call(_n)])])}}}),genTimelineStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{margin:0,padding:0,listStyle:"none",[`${Cn}-item`]:{position:"relative",margin:0,paddingBottom:$n.timeLineItemPaddingBottom,fontSize:$n.fontSize,listStyle:"none","&-tail":{position:"absolute",insetBlockStart:$n.timeLineItemHeadSize,insetInlineStart:($n.timeLineItemHeadSize-$n.timeLineItemTailWidth)/2,height:`calc(100% - ${$n.timeLineItemHeadSize}px)`,borderInlineStart:`${$n.timeLineItemTailWidth}px ${$n.lineType} ${$n.colorSplit}`},"&-pending":{[`${Cn}-item-head`]:{fontSize:$n.fontSizeSM,backgroundColor:"transparent"},[`${Cn}-item-tail`]:{display:"none"}},"&-head":{position:"absolute",width:$n.timeLineItemHeadSize,height:$n.timeLineItemHeadSize,backgroundColor:$n.colorBgContainer,border:`${$n.timeLineHeadBorderWidth}px ${$n.lineType} transparent`,borderRadius:"50%","&-blue":{color:$n.colorPrimary,borderColor:$n.colorPrimary},"&-red":{color:$n.colorError,borderColor:$n.colorError},"&-green":{color:$n.colorSuccess,borderColor:$n.colorSuccess},"&-gray":{color:$n.colorTextDisabled,borderColor:$n.colorTextDisabled}},"&-head-custom":{position:"absolute",insetBlockStart:$n.timeLineItemHeadSize/2,insetInlineStart:$n.timeLineItemHeadSize/2,width:"auto",height:"auto",marginBlockStart:0,paddingBlock:$n.timeLineItemCustomHeadPaddingVertical,lineHeight:1,textAlign:"center",border:0,borderRadius:0,transform:"translate(-50%, -50%)"},"&-content":{position:"relative",insetBlockStart:-($n.fontSize*$n.lineHeight-$n.fontSize)+$n.lineWidth,marginInlineStart:$n.margin+$n.timeLineItemHeadSize,marginInlineEnd:0,marginBlockStart:0,marginBlockEnd:0,wordBreak:"break-word"},"&-last":{[`> ${Cn}-item-tail`]:{display:"none"},[`> ${Cn}-item-content`]:{minHeight:$n.controlHeightLG*1.2}}},[`&${Cn}-alternate, - &${Cn}-right, - &${Cn}-label`]:{[`${Cn}-item`]:{"&-tail, &-head, &-head-custom":{insetInlineStart:"50%"},"&-head":{marginInlineStart:`-${$n.marginXXS}px`,"&-custom":{marginInlineStart:$n.timeLineItemTailWidth/2}},"&-left":{[`${Cn}-item-content`]:{insetInlineStart:`calc(50% - ${$n.marginXXS}px)`,width:`calc(50% - ${$n.marginSM}px)`,textAlign:"start"}},"&-right":{[`${Cn}-item-content`]:{width:`calc(50% - ${$n.marginSM}px)`,margin:0,textAlign:"end"}}}},[`&${Cn}-right`]:{[`${Cn}-item-right`]:{[`${Cn}-item-tail, - ${Cn}-item-head, - ${Cn}-item-head-custom`]:{insetInlineStart:`calc(100% - ${($n.timeLineItemHeadSize+$n.timeLineItemTailWidth)/2}px)`},[`${Cn}-item-content`]:{width:`calc(100% - ${$n.timeLineItemHeadSize+$n.marginXS}px)`}}},[`&${Cn}-pending - ${Cn}-item-last - ${Cn}-item-tail`]:{display:"block",height:`calc(100% - ${$n.margin}px)`,borderInlineStart:`${$n.timeLineItemTailWidth}px dotted ${$n.colorSplit}`},[`&${Cn}-reverse - ${Cn}-item-last - ${Cn}-item-tail`]:{display:"none"},[`&${Cn}-reverse ${Cn}-item-pending`]:{[`${Cn}-item-tail`]:{insetBlockStart:$n.margin,display:"block",height:`calc(100% - ${$n.margin}px)`,borderInlineStart:`${$n.timeLineItemTailWidth}px dotted ${$n.colorSplit}`},[`${Cn}-item-content`]:{minHeight:$n.controlHeightLG*1.2}},[`&${Cn}-label`]:{[`${Cn}-item-label`]:{position:"absolute",insetBlockStart:-($n.fontSize*$n.lineHeight-$n.fontSize)+$n.timeLineItemTailWidth,width:`calc(50% - ${$n.marginSM}px)`,textAlign:"end"},[`${Cn}-item-right`]:{[`${Cn}-item-label`]:{insetInlineStart:`calc(50% + ${$n.marginSM}px)`,width:`calc(50% - ${$n.marginSM}px)`,textAlign:"start"}}},"&-rtl":{direction:"rtl",[`${Cn}-item-head-custom`]:{transform:"translate(50%, -50%)"}}})}},useStyle$7=genComponentStyleHook("Timeline",$n=>{const Cn=merge$1($n,{timeLineItemPaddingBottom:$n.padding*1.25,timeLineItemHeadSize:10,timeLineItemCustomHeadPaddingVertical:$n.paddingXXS,timeLinePaddingInlineEnd:2,timeLineItemTailWidth:$n.lineWidthBold,timeLineHeadBorderWidth:$n.wireframe?$n.lineWidthBold:$n.lineWidth*3});return[genTimelineStyle(Cn)]}),timelineProps=()=>({prefixCls:String,pending:PropTypes.any,pendingDot:PropTypes.any,reverse:booleanType(),mode:PropTypes.oneOf(tuple$1("left","alternate","right",""))}),Timeline=defineComponent({compatConfig:{MODE:3},name:"ATimeline",inheritAttrs:!1,props:initDefaultProps(timelineProps(),{reverse:!1,mode:""}),slots:Object,setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("timeline",$n),[Rn,Dn]=useStyle$7(In),Ln=(Fn,Bn)=>{const Hn=Fn.props||{};return $n.mode==="alternate"?Hn.position==="right"?`${In.value}-item-right`:Hn.position==="left"?`${In.value}-item-left`:Bn%2===0?`${In.value}-item-left`:`${In.value}-item-right`:$n.mode==="left"?`${In.value}-item-left`:$n.mode==="right"?`${In.value}-item-right`:Hn.position==="right"?`${In.value}-item-right`:""};return()=>{var Fn,Bn,Hn;const{pending:zn=(Fn=_n.pending)===null||Fn===void 0?void 0:Fn.call(_n),pendingDot:Wn=(Bn=_n.pendingDot)===null||Bn===void 0?void 0:Bn.call(_n),reverse:Yn,mode:Gn}=$n,Go=typeof zn=="boolean"?null:zn,Xn=filterEmpty((Hn=_n.default)===null||Hn===void 0?void 0:Hn.call(_n)),Yo=zn?createVNode(TimelineItem,{pending:!!zn,dot:Wn||createVNode(LoadingOutlined$1,null,null)},{default:()=>[Go]}):null;Yo&&Xn.push(Yo);const qo=Yn?Xn.reverse():Xn,Jo=qo.length,Zo=`${In.value}-item-last`,rr=qo.map((oa,ra)=>{const ea=ra===Jo-2?Zo:"",la=ra===Jo-1?Zo:"";return cloneVNode(oa,{class:classNames([!Yn&&zn?ea:la,Ln(oa,ra)])})}),nr=qo.some(oa=>{var ra,ea;return!!(!((ra=oa.props)===null||ra===void 0)&&ra.label||!((ea=oa.children)===null||ea===void 0)&&ea.label)}),ta=classNames(In.value,{[`${In.value}-pending`]:!!zn,[`${In.value}-reverse`]:!!Yn,[`${In.value}-${Gn}`]:!!Gn&&!nr,[`${In.value}-label`]:nr,[`${In.value}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value);return Rn(createVNode("ul",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:ta}),[rr]))}}});Timeline.Item=TimelineItem;Timeline.install=function($n){return $n.component(Timeline.name,Timeline),$n.component(TimelineItem.name,TimelineItem),$n};var EnterOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M864 170h-60c-4.4 0-8 3.6-8 8v518H310v-73c0-6.7-7.8-10.5-13-6.3l-141.9 112a8 8 0 000 12.6l141.9 112c5.3 4.2 13 .4 13-6.3v-75h498c35.3 0 64-28.7 64-64V178c0-4.4-3.6-8-8-8z"}}]},name:"enter",theme:"outlined"};const EnterOutlinedSvg=EnterOutlined$2;function _objectSpread$7($n){for(var Cn=1;Cn{const{sizeMarginHeadingVerticalEnd:In,fontWeightStrong:Nn}=Pn;return{marginBottom:In,color:_n,fontWeight:Nn,fontSize:$n,lineHeight:Cn}},getTitleStyles=$n=>{const Cn=[1,2,3,4,5],_n={};return Cn.forEach(Pn=>{_n[` - h${Pn}&, - div&-h${Pn}, - div&-h${Pn} > textarea, - h${Pn} - `]=getTitleStyle($n[`fontSizeHeading${Pn}`],$n[`lineHeightHeading${Pn}`],$n.colorTextHeading,$n)}),_n},getLinkStyles=$n=>{const{componentCls:Cn}=$n;return{"a&, a":_extends$1(_extends$1({},operationUnit($n)),{textDecoration:$n.linkDecoration,"&:active, &:hover":{textDecoration:$n.linkHoverDecoration},[`&[disabled], &${Cn}-disabled`]:{color:$n.colorTextDisabled,cursor:"not-allowed","&:active, &:hover":{color:$n.colorTextDisabled},"&:active":{pointerEvents:"none"}}})}},getResetStyles=()=>({code:{margin:"0 0.2em",paddingInline:"0.4em",paddingBlock:"0.2em 0.1em",fontSize:"85%",background:"rgba(150, 150, 150, 0.1)",border:"1px solid rgba(100, 100, 100, 0.2)",borderRadius:3},kbd:{margin:"0 0.2em",paddingInline:"0.4em",paddingBlock:"0.15em 0.1em",fontSize:"90%",background:"rgba(150, 150, 150, 0.06)",border:"1px solid rgba(100, 100, 100, 0.2)",borderBottomWidth:2,borderRadius:3},mark:{padding:0,backgroundColor:gold[2]},"u, ins":{textDecoration:"underline",textDecorationSkipInk:"auto"},"s, del":{textDecoration:"line-through"},strong:{fontWeight:600},"ul, ol":{marginInline:0,marginBlock:"0 1em",padding:0,li:{marginInline:"20px 0",marginBlock:0,paddingInline:"4px 0",paddingBlock:0}},ul:{listStyleType:"circle",ul:{listStyleType:"disc"}},ol:{listStyleType:"decimal"},"pre, blockquote":{margin:"1em 0"},pre:{padding:"0.4em 0.6em",whiteSpace:"pre-wrap",wordWrap:"break-word",background:"rgba(150, 150, 150, 0.1)",border:"1px solid rgba(100, 100, 100, 0.2)",borderRadius:3,code:{display:"inline",margin:0,padding:0,fontSize:"inherit",fontFamily:"inherit",background:"transparent",border:0}},blockquote:{paddingInline:"0.6em 0",paddingBlock:0,borderInlineStart:"4px solid rgba(100, 100, 100, 0.2)",opacity:.85}}),getEditableStyles=$n=>{const{componentCls:Cn}=$n,Pn=initInputToken($n).inputPaddingVertical+1;return{"&-edit-content":{position:"relative","div&":{insetInlineStart:-$n.paddingSM,marginTop:-Pn,marginBottom:`calc(1em - ${Pn}px)`},[`${Cn}-edit-content-confirm`]:{position:"absolute",insetInlineEnd:$n.marginXS+2,insetBlockEnd:$n.marginXS,color:$n.colorTextDescription,fontWeight:"normal",fontSize:$n.fontSize,fontStyle:"normal",pointerEvents:"none"},textarea:{margin:"0!important",MozTransition:"none",height:"1em"}}}},getCopiableStyles=$n=>({"&-copy-success":{"\n &,\n &:hover,\n &:focus":{color:$n.colorSuccess}}}),getEllipsisStyles=()=>({"\n a&-ellipsis,\n span&-ellipsis\n ":{display:"inline-block",maxWidth:"100%"},"&-single-line":{whiteSpace:"nowrap"},"&-ellipsis-single-line":{overflow:"hidden",textOverflow:"ellipsis","a&, span&":{verticalAlign:"bottom"}},"&-ellipsis-multiple-line":{display:"-webkit-box",overflow:"hidden",WebkitLineClamp:3,WebkitBoxOrient:"vertical"}}),genTypographyStyle=$n=>{const{componentCls:Cn,sizeMarginHeadingVerticalStart:_n}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({color:$n.colorText,wordBreak:"break-word",lineHeight:$n.lineHeight,[`&${Cn}-secondary`]:{color:$n.colorTextDescription},[`&${Cn}-success`]:{color:$n.colorSuccess},[`&${Cn}-warning`]:{color:$n.colorWarning},[`&${Cn}-danger`]:{color:$n.colorError,"a&:active, a&:focus":{color:$n.colorErrorActive},"a&:hover":{color:$n.colorErrorHover}},[`&${Cn}-disabled`]:{color:$n.colorTextDisabled,cursor:"not-allowed",userSelect:"none"},"\n div&,\n p\n ":{marginBottom:"1em"}},getTitleStyles($n)),{[` - & + h1${Cn}, - & + h2${Cn}, - & + h3${Cn}, - & + h4${Cn}, - & + h5${Cn} - `]:{marginTop:_n},"\n div,\n ul,\n li,\n p,\n h1,\n h2,\n h3,\n h4,\n h5":{"\n + h1,\n + h2,\n + h3,\n + h4,\n + h5\n ":{marginTop:_n}}}),getResetStyles()),getLinkStyles($n)),{[` - ${Cn}-expand, - ${Cn}-edit, - ${Cn}-copy - `]:_extends$1(_extends$1({},operationUnit($n)),{marginInlineStart:$n.marginXXS})}),getEditableStyles($n)),getCopiableStyles($n)),getEllipsisStyles()),{"&-rtl":{direction:"rtl"}})}},useStyle$6=genComponentStyleHook("Typography",$n=>[genTypographyStyle($n)],{sizeMarginHeadingVerticalStart:"1.2em",sizeMarginHeadingVerticalEnd:"0.5em"}),editableProps=()=>({prefixCls:String,value:String,maxlength:Number,autoSize:{type:[Boolean,Object]},onSave:Function,onCancel:Function,onEnd:Function,onChange:Function,originContent:String,direction:String,component:String}),Editable=defineComponent({compatConfig:{MODE:3},name:"Editable",inheritAttrs:!1,props:editableProps(),setup($n,Cn){let{emit:_n,slots:Pn,attrs:In}=Cn;const{prefixCls:Nn}=toRefs($n),Rn=reactive({current:$n.value||"",lastKeyCode:void 0,inComposition:!1,cancelFlag:!1});watch(()=>$n.value,Yo=>{Rn.current=Yo});const Dn=ref();onMounted(()=>{var Yo;if(Dn.value){const qo=(Yo=Dn.value)===null||Yo===void 0?void 0:Yo.resizableTextArea,Jo=qo==null?void 0:qo.textArea;Jo.focus();const{length:Zo}=Jo.value;Jo.setSelectionRange(Zo,Zo)}});function Ln(Yo){Dn.value=Yo}function Fn(Yo){let{target:{value:qo}}=Yo;Rn.current=qo.replace(/[\r\n]/g,""),_n("change",Rn.current)}function Bn(){Rn.inComposition=!0}function Hn(){Rn.inComposition=!1}function zn(Yo){const{keyCode:qo}=Yo;qo===KeyCode$1.ENTER&&Yo.preventDefault(),!Rn.inComposition&&(Rn.lastKeyCode=qo)}function Wn(Yo){const{keyCode:qo,ctrlKey:Jo,altKey:Zo,metaKey:rr,shiftKey:nr}=Yo;Rn.lastKeyCode===qo&&!Rn.inComposition&&!Jo&&!Zo&&!rr&&!nr&&(qo===KeyCode$1.ENTER?(Gn(),_n("end")):qo===KeyCode$1.ESC&&(Rn.current=$n.originContent,_n("cancel")))}function Yn(){Gn()}function Gn(){_n("save",Rn.current.trim())}const[Go,Xn]=useStyle$6(Nn);return()=>{const Yo=classNames({[`${Nn.value}`]:!0,[`${Nn.value}-edit-content`]:!0,[`${Nn.value}-rtl`]:$n.direction==="rtl",[$n.component?`${Nn.value}-${$n.component}`:""]:!0},In.class,Xn.value);return Go(createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{class:Yo}),[createVNode(TextArea,{ref:Ln,maxlength:$n.maxlength,value:Rn.current,onChange:Fn,onKeydown:zn,onKeyup:Wn,onCompositionstart:Bn,onCompositionend:Hn,onBlur:Yn,rows:1,autoSize:$n.autoSize===void 0||$n.autoSize},null),Pn.enterIcon?Pn.enterIcon({className:`${$n.prefixCls}-edit-content-confirm`}):createVNode(EnterOutlined$1,{class:`${$n.prefixCls}-edit-content-confirm`},null)]))}}}),Editable$1=Editable,TEXT_NODE=3,COMMENT_NODE=8;let ellipsisContainer;const wrapperStyle={padding:0,margin:0,display:"inline",lineHeight:"inherit"};function styleToString($n){return Array.prototype.slice.apply($n).map(_n=>`${_n}: ${$n.getPropertyValue(_n)};`).join("")}function resetDomStyles($n,Cn){$n.setAttribute("aria-hidden","true");const _n=window.getComputedStyle(Cn),Pn=styleToString(_n);$n.setAttribute("style",Pn),$n.style.position="fixed",$n.style.left="0",$n.style.height="auto",$n.style.minHeight="auto",$n.style.maxHeight="auto",$n.style.paddingTop="0",$n.style.paddingBottom="0",$n.style.borderTopWidth="0",$n.style.borderBottomWidth="0",$n.style.top="-999999px",$n.style.zIndex="-1000",$n.style.textOverflow="clip",$n.style.whiteSpace="normal",$n.style.webkitLineClamp="none"}function getRealLineHeight($n){const Cn=document.createElement("div");resetDomStyles(Cn,$n),Cn.appendChild(document.createTextNode("text")),document.body.appendChild(Cn);const _n=Cn.getBoundingClientRect().height;return document.body.removeChild(Cn),_n}const measure=($n,Cn,_n,Pn,In)=>{ellipsisContainer||(ellipsisContainer=document.createElement("div"),ellipsisContainer.setAttribute("aria-hidden","true"),document.body.appendChild(ellipsisContainer));const{rows:Nn,suffix:Rn=""}=Cn,Dn=getRealLineHeight($n),Ln=Math.round(Dn*Nn*100)/100;resetDomStyles(ellipsisContainer,$n);const Fn=createApp({render(){return createVNode("div",{style:wrapperStyle},[createVNode("span",{style:wrapperStyle},[_n,Rn]),createVNode("span",{style:wrapperStyle},[Pn])])}});Fn.mount(ellipsisContainer);function Bn(){return Math.round(ellipsisContainer.getBoundingClientRect().height*100)/100-.1<=Ln}if(Bn())return Fn.unmount(),{content:_n,text:ellipsisContainer.innerHTML,ellipsis:!1};const Hn=Array.prototype.slice.apply(ellipsisContainer.childNodes[0].childNodes[0].cloneNode(!0).childNodes).filter(qo=>{let{nodeType:Jo,data:Zo}=qo;return Jo!==COMMENT_NODE&&Zo!==""}),zn=Array.prototype.slice.apply(ellipsisContainer.childNodes[0].childNodes[1].cloneNode(!0).childNodes);Fn.unmount();const Wn=[];ellipsisContainer.innerHTML="";const Yn=document.createElement("span");ellipsisContainer.appendChild(Yn);const Gn=document.createTextNode(In+Rn);Yn.appendChild(Gn),zn.forEach(qo=>{ellipsisContainer.appendChild(qo)});function Go(qo){Yn.insertBefore(qo,Gn)}function Xn(qo,Jo){let Zo=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,rr=arguments.length>3&&arguments[3]!==void 0?arguments[3]:Jo.length,nr=arguments.length>4&&arguments[4]!==void 0?arguments[4]:0;const ta=Math.floor((Zo+rr)/2),oa=Jo.slice(0,ta);if(qo.textContent=oa,Zo>=rr-1)for(let ra=rr;ra>=Zo;ra-=1){const ea=Jo.slice(0,ra);if(qo.textContent=ea,Bn()||!ea)return ra===Jo.length?{finished:!1,vNode:Jo}:{finished:!0,vNode:ea}}return Bn()?Xn(qo,Jo,ta,rr,ta):Xn(qo,Jo,Zo,ta,nr)}function Yo(qo){if(qo.nodeType===TEXT_NODE){const Zo=qo.textContent||"",rr=document.createTextNode(Zo);return Go(rr),Xn(rr,Zo)}return{finished:!1,vNode:null}}return Hn.some(qo=>{const{finished:Jo,vNode:Zo}=Yo(qo);return Zo&&Wn.push(Zo),Jo}),{content:Wn,text:ellipsisContainer.innerHTML,ellipsis:!0}};var __rest$a=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In({prefixCls:String,direction:String,component:String}),Typography=defineComponent({name:"ATypography",inheritAttrs:!1,props:typographyProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const{prefixCls:In,direction:Nn}=useConfigInject("typography",$n),[Rn,Dn]=useStyle$6(In);return()=>{var Ln;const Fn=_extends$1(_extends$1({},$n),Pn),{prefixCls:Bn,direction:Hn,component:zn="article"}=Fn,Wn=__rest$a(Fn,["prefixCls","direction","component"]);return Rn(createVNode(zn,_objectSpread2$1(_objectSpread2$1({},Wn),{},{class:classNames(In.value,{[`${In.value}-rtl`]:Nn.value==="rtl"},Pn.class,Dn.value)}),{default:()=>[(Ln=_n.default)===null||Ln===void 0?void 0:Ln.call(_n)]}))}}}),Typography$1=Typography,deselectCurrent=()=>{const $n=document.getSelection();if(!$n.rangeCount)return function(){};let Cn=document.activeElement;const _n=[];for(let Pn=0;Pn<$n.rangeCount;Pn++)_n.push($n.getRangeAt(Pn));switch(Cn.tagName.toUpperCase()){case"INPUT":case"TEXTAREA":Cn.blur();break;default:Cn=null;break}return $n.removeAllRanges(),function(){$n.type==="Caret"&&$n.removeAllRanges(),$n.rangeCount||_n.forEach(function(Pn){$n.addRange(Pn)}),Cn&&Cn.focus()}},clipboardToIE11Formatting={"text/plain":"Text","text/html":"Url",default:"Text"},defaultMessage="Copy to clipboard: #{key}, Enter";function format$2($n){const Cn=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C";return $n.replace(/#{\s*key\s*}/g,Cn)}function copy($n,Cn){let _n,Pn,In,Nn,Rn,Dn=!1;Cn||(Cn={});const Ln=Cn.debug||!1;try{if(Pn=deselectCurrent(),In=document.createRange(),Nn=document.getSelection(),Rn=document.createElement("span"),Rn.textContent=$n,Rn.style.all="unset",Rn.style.position="fixed",Rn.style.top=0,Rn.style.clip="rect(0, 0, 0, 0)",Rn.style.whiteSpace="pre",Rn.style.webkitUserSelect="text",Rn.style.MozUserSelect="text",Rn.style.msUserSelect="text",Rn.style.userSelect="text",Rn.addEventListener("copy",function(Bn){if(Bn.stopPropagation(),Cn.format)if(Bn.preventDefault(),typeof Bn.clipboardData>"u"){Ln&&console.warn("unable to use e.clipboardData"),Ln&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();const Hn=clipboardToIE11Formatting[Cn.format]||clipboardToIE11Formatting.default;window.clipboardData.setData(Hn,$n)}else Bn.clipboardData.clearData(),Bn.clipboardData.setData(Cn.format,$n);Cn.onCopy&&(Bn.preventDefault(),Cn.onCopy(Bn.clipboardData))}),document.body.appendChild(Rn),In.selectNodeContents(Rn),Nn.addRange(In),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");Dn=!0}catch(Fn){Ln&&console.error("unable to copy using execCommand: ",Fn),Ln&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(Cn.format||"text",$n),Cn.onCopy&&Cn.onCopy(window.clipboardData),Dn=!0}catch(Bn){Ln&&console.error("unable to copy using clipboardData: ",Bn),Ln&&console.error("falling back to prompt"),_n=format$2("message"in Cn?Cn.message:defaultMessage),window.prompt(_n,$n)}}finally{Nn&&(typeof Nn.removeRange=="function"?Nn.removeRange(In):Nn.removeAllRanges()),Rn&&document.body.removeChild(Rn),Pn()}return Dn}var CopyOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"}}]},name:"copy",theme:"outlined"};const CopyOutlinedSvg=CopyOutlined$2;function _objectSpread$6($n){for(var Cn=1;Cn({editable:{type:[Boolean,Object],default:void 0},copyable:{type:[Boolean,Object],default:void 0},prefixCls:String,component:String,type:String,disabled:{type:Boolean,default:void 0},ellipsis:{type:[Boolean,Object],default:void 0},code:{type:Boolean,default:void 0},mark:{type:Boolean,default:void 0},underline:{type:Boolean,default:void 0},delete:{type:Boolean,default:void 0},strong:{type:Boolean,default:void 0},keyboard:{type:Boolean,default:void 0},content:String,"onUpdate:content":Function}),Base=defineComponent({compatConfig:{MODE:3},name:"TypographyBase",inheritAttrs:!1,props:baseProps(),setup($n,Cn){let{slots:_n,attrs:Pn,emit:In}=Cn;const{prefixCls:Nn,direction:Rn}=useConfigInject("typography",$n),Dn=reactive({copied:!1,ellipsisText:"",ellipsisContent:null,isEllipsis:!1,expanded:!1,clientRendered:!1,expandStr:"",copyStr:"",copiedStr:"",editStr:"",copyId:void 0,rafId:void 0,prevProps:void 0,originContent:""}),Ln=ref(),Fn=ref(),Bn=computed(()=>{const aa=$n.ellipsis;return aa?_extends$1({rows:1,expandable:!1},typeof aa=="object"?aa:null):{}});onMounted(()=>{Dn.clientRendered=!0,ta()}),onBeforeUnmount(()=>{clearTimeout(Dn.copyId),wrapperRaf.cancel(Dn.rafId)}),watch([()=>Bn.value.rows,()=>$n.content],()=>{nextTick(()=>{rr()})},{flush:"post",deep:!0}),watchEffect(()=>{$n.content===void 0&&(warning$3(!$n.editable),warning$3(!$n.ellipsis))});function Hn(){var aa;return $n.ellipsis||$n.editable?$n.content:(aa=findDOMNode(Ln.value))===null||aa===void 0?void 0:aa.innerText}function zn(aa){const{onExpand:ca}=Bn.value;Dn.expanded=!0,ca==null||ca(aa)}function Wn(aa){aa.preventDefault(),Dn.originContent=$n.content,Zo(!0)}function Yn(aa){Gn(aa),Zo(!1)}function Gn(aa){const{onChange:ca}=Yo.value;aa!==$n.content&&(In("update:content",aa),ca==null||ca(aa))}function Go(){var aa,ca;(ca=(aa=Yo.value).onCancel)===null||ca===void 0||ca.call(aa),Zo(!1)}function Xn(aa){aa.preventDefault(),aa.stopPropagation();const{copyable:ca}=$n,sa=_extends$1({},typeof ca=="object"?ca:null);sa.text===void 0&&(sa.text=Hn()),copy(sa.text||""),Dn.copied=!0,nextTick(()=>{sa.onCopy&&sa.onCopy(aa),Dn.copyId=setTimeout(()=>{Dn.copied=!1},3e3)})}const Yo=computed(()=>{const aa=$n.editable;return aa?_extends$1({},typeof aa=="object"?aa:null):{editing:!1}}),[qo,Jo]=useMergedState(!1,{value:computed(()=>Yo.value.editing)});function Zo(aa){const{onStart:ca}=Yo.value;aa&&ca&&ca(),Jo(aa)}watch(qo,aa=>{var ca;aa||(ca=Fn.value)===null||ca===void 0||ca.focus()},{flush:"post"});function rr(aa){if(aa){const{width:ca,height:sa}=aa;if(!ca||!sa)return}wrapperRaf.cancel(Dn.rafId),Dn.rafId=wrapperRaf(()=>{ta()})}const nr=computed(()=>{const{rows:aa,expandable:ca,suffix:sa,onEllipsis:ia,tooltip:fa}=Bn.value;return sa||fa||$n.editable||$n.copyable||ca||ia?!1:aa===1?isTextOverflowSupport:isLineClampSupport}),ta=()=>{const{ellipsisText:aa,isEllipsis:ca}=Dn,{rows:sa,suffix:ia,onEllipsis:fa}=Bn.value;if(!sa||sa<0||!findDOMNode(Ln.value)||Dn.expanded||$n.content===void 0||nr.value)return;const{content:ma,text:ya,ellipsis:ba}=measure(findDOMNode(Ln.value),{rows:sa,suffix:ia},$n.content,ga(!0),ELLIPSIS_STR);(aa!==ya||Dn.isEllipsis!==ba)&&(Dn.ellipsisText=ya,Dn.ellipsisContent=ma,Dn.isEllipsis=ba,ca!==ba&&fa&&fa(ba))};function oa(aa,ca){let{mark:sa,code:ia,underline:fa,delete:ma,strong:ya,keyboard:ba}=aa,Ia=ca;function Ea(xa,Ta){if(!xa)return;const wa=function(){return Ia}();Ia=createVNode(Ta,null,{default:()=>[wa]})}return Ea(ya,"strong"),Ea(fa,"u"),Ea(ma,"del"),Ea(ia,"code"),Ea(sa,"mark"),Ea(ba,"kbd"),Ia}function ra(aa){const{expandable:ca,symbol:sa}=Bn.value;if(!ca||!aa&&(Dn.expanded||!Dn.isEllipsis))return null;const ia=(_n.ellipsisSymbol?_n.ellipsisSymbol():sa)||Dn.expandStr;return createVNode("a",{key:"expand",class:`${Nn.value}-expand`,onClick:zn,"aria-label":Dn.expandStr},[ia])}function ea(){if(!$n.editable)return;const{tooltip:aa,triggerType:ca=["icon"]}=$n.editable,sa=_n.editableIcon?_n.editableIcon():createVNode(EditOutlined$1,{role:"button"},null),ia=_n.editableTooltip?_n.editableTooltip():Dn.editStr,fa=typeof ia=="string"?ia:"";return ca.indexOf("icon")!==-1?createVNode(Tooltip,{key:"edit",title:aa===!1?"":ia},{default:()=>[createVNode(TransButton$1,{ref:Fn,class:`${Nn.value}-edit`,onClick:Wn,"aria-label":fa},{default:()=>[sa]})]}):null}function la(){if(!$n.copyable)return;const{tooltip:aa}=$n.copyable,ca=Dn.copied?Dn.copiedStr:Dn.copyStr,sa=_n.copyableTooltip?_n.copyableTooltip({copied:Dn.copied}):ca,ia=typeof sa=="string"?sa:"",fa=Dn.copied?createVNode(CheckOutlined$1,null,null):createVNode(CopyOutlined$1,null,null),ma=_n.copyableIcon?_n.copyableIcon({copied:!!Dn.copied}):fa;return createVNode(Tooltip,{key:"copy",title:aa===!1?"":sa},{default:()=>[createVNode(TransButton$1,{class:[`${Nn.value}-copy`,{[`${Nn.value}-copy-success`]:Dn.copied}],onClick:Xn,"aria-label":ia},{default:()=>[ma]})]})}function ua(){const{class:aa,style:ca}=Pn,{maxlength:sa,autoSize:ia,onEnd:fa}=Yo.value;return createVNode(Editable$1,{class:aa,style:ca,prefixCls:Nn.value,value:$n.content,originContent:Dn.originContent,maxlength:sa,autoSize:ia,onSave:Yn,onChange:Gn,onCancel:Go,onEnd:fa,direction:Rn.value,component:$n.component},{enterIcon:_n.editableEnterIcon})}function ga(aa){return[ra(aa),ea(),la()].filter(ca=>ca)}return()=>{var aa;const{triggerType:ca=["icon"]}=Yo.value,sa=$n.ellipsis||$n.editable?$n.content!==void 0?$n.content:(aa=_n.default)===null||aa===void 0?void 0:aa.call(_n):_n.default?_n.default():$n.content;return qo.value?ua():createVNode(LocaleReceiver,{componentName:"Text",children:ia=>{const fa=_extends$1(_extends$1({},$n),Pn),{type:ma,disabled:ya,content:ba,class:Ia,style:Ea}=fa,xa=__rest$9(fa,["type","disabled","content","class","style"]),{rows:Ta,suffix:wa,tooltip:La}=Bn.value,{edit:Na,copy:$a,copied:ka,expand:Ha}=ia;Dn.editStr=Na,Dn.copyStr=$a,Dn.copiedStr=ka,Dn.expandStr=Ha;const da=omit$1(xa,["prefixCls","editable","copyable","ellipsis","mark","code","delete","underline","strong","keyboard","onUpdate:content"]),pa=nr.value,Sa=Ta===1&&pa,Aa=Ta&&Ta>1&&pa;let Ra=sa,Fa;if(Ta&&Dn.isEllipsis&&!Dn.expanded&&!pa){const{title:Ya}=xa;let ja=Ya||"";!Ya&&(typeof sa=="string"||typeof sa=="number")&&(ja=String(sa)),ja=ja==null?void 0:ja.slice(String(Dn.ellipsisContent||"").length),Ra=createVNode(Fragment,null,[toRaw(Dn.ellipsisContent),createVNode("span",{title:ja,"aria-hidden":"true"},[ELLIPSIS_STR]),wa])}else Ra=createVNode(Fragment,null,[sa,wa]);Ra=oa($n,Ra);const za=La&&Ta&&Dn.isEllipsis&&!Dn.expanded&&!pa,Wa=_n.ellipsisTooltip?_n.ellipsisTooltip():La;return createVNode(ResizeObserver$1,{onResize:rr,disabled:!Ta},{default:()=>[createVNode(Typography$1,_objectSpread2$1({ref:Ln,class:[{[`${Nn.value}-${ma}`]:ma,[`${Nn.value}-disabled`]:ya,[`${Nn.value}-ellipsis`]:Ta,[`${Nn.value}-single-line`]:Ta===1&&!Dn.isEllipsis,[`${Nn.value}-ellipsis-single-line`]:Sa,[`${Nn.value}-ellipsis-multiple-line`]:Aa},Ia],style:_extends$1(_extends$1({},Ea),{WebkitLineClamp:Aa?Ta:void 0}),"aria-label":Fa,direction:Rn.value,onClick:ca.indexOf("text")!==-1?Wn:()=>{}},da),{default:()=>[za?createVNode(Tooltip,{title:La===!0?sa:Wa},{default:()=>[createVNode("span",null,[Ra])]}):Ra,ga()]})]})}},null)}}}),Base$1=Base;var __rest$8=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);Inomit$1(_extends$1(_extends$1({},baseProps()),{ellipsis:{type:Boolean,default:void 0}}),["component"]),Link=($n,Cn)=>{let{slots:_n,attrs:Pn}=Cn;const In=_extends$1(_extends$1({},$n),Pn),{ellipsis:Nn,rel:Rn}=In,Dn=__rest$8(In,["ellipsis","rel"]);warning$3();const Ln=_extends$1(_extends$1({},Dn),{rel:Rn===void 0&&Dn.target==="_blank"?"noopener noreferrer":Rn,ellipsis:!!Nn,component:"a"});return delete Ln.navigate,createVNode(Base$1,Ln,_n)};Link.displayName="ATypographyLink";Link.inheritAttrs=!1;Link.props=linkProps();const Link$1=Link,paragraphProps=()=>omit$1(baseProps(),["component"]),Paragraph=($n,Cn)=>{let{slots:_n,attrs:Pn}=Cn;const In=_extends$1(_extends$1(_extends$1({},$n),{component:"div"}),Pn);return createVNode(Base$1,In,_n)};Paragraph.displayName="ATypographyParagraph";Paragraph.inheritAttrs=!1;Paragraph.props=paragraphProps();const Paragraph$1=Paragraph,textProps=()=>_extends$1(_extends$1({},omit$1(baseProps(),["component"])),{ellipsis:{type:[Boolean,Object],default:void 0}}),Text=($n,Cn)=>{let{slots:_n,attrs:Pn}=Cn;const{ellipsis:In}=$n;warning$3();const Nn=_extends$1(_extends$1(_extends$1({},$n),{ellipsis:In&&typeof In=="object"?omit$1(In,["expandable","rows"]):In,component:"span"}),Pn);return createVNode(Base$1,Nn,_n)};Text.displayName="ATypographyText";Text.inheritAttrs=!1;Text.props=textProps();const Text$1=Text;var __rest$7=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In_extends$1(_extends$1({},omit$1(baseProps(),["component","strong"])),{level:Number}),Title=($n,Cn)=>{let{slots:_n,attrs:Pn}=Cn;const{level:In=1}=$n,Nn=__rest$7($n,["level"]);let Rn;TITLE_ELE_LIST.includes(In)?Rn=`h${In}`:(warning$3(),Rn="h1");const Dn=_extends$1(_extends$1(_extends$1({},Nn),{component:Rn}),Pn);return createVNode(Base$1,Dn,_n)};Title.displayName="ATypographyTitle";Title.inheritAttrs=!1;Title.props=titleProps();const Title$1=Title;Typography$1.Text=Text$1;Typography$1.Title=Title$1;Typography$1.Paragraph=Paragraph$1;Typography$1.Link=Link$1;Typography$1.Base=Base$1;Typography$1.install=function($n){return $n.component(Typography$1.name,Typography$1),$n.component(Typography$1.Text.displayName,Text$1),$n.component(Typography$1.Title.displayName,Title$1),$n.component(Typography$1.Paragraph.displayName,Paragraph$1),$n.component(Typography$1.Link.displayName,Link$1),$n};function getError($n,Cn){const _n=`cannot ${$n.method} ${$n.action} ${Cn.status}'`,Pn=new Error(_n);return Pn.status=Cn.status,Pn.method=$n.method,Pn.url=$n.action,Pn}function getBody($n){const Cn=$n.responseText||$n.response;if(!Cn)return Cn;try{return JSON.parse(Cn)}catch{return Cn}}function upload($n){const Cn=new XMLHttpRequest;$n.onProgress&&Cn.upload&&(Cn.upload.onprogress=function(Nn){Nn.total>0&&(Nn.percent=Nn.loaded/Nn.total*100),$n.onProgress(Nn)});const _n=new FormData;$n.data&&Object.keys($n.data).forEach(In=>{const Nn=$n.data[In];if(Array.isArray(Nn)){Nn.forEach(Rn=>{_n.append(`${In}[]`,Rn)});return}_n.append(In,Nn)}),$n.file instanceof Blob?_n.append($n.filename,$n.file,$n.file.name):_n.append($n.filename,$n.file),Cn.onerror=function(Nn){$n.onError(Nn)},Cn.onload=function(){return Cn.status<200||Cn.status>=300?$n.onError(getError($n,Cn),getBody(Cn)):$n.onSuccess(getBody(Cn),Cn)},Cn.open($n.method,$n.action,!0),$n.withCredentials&&"withCredentials"in Cn&&(Cn.withCredentials=!0);const Pn=$n.headers||{};return Pn["X-Requested-With"]!==null&&Cn.setRequestHeader("X-Requested-With","XMLHttpRequest"),Object.keys(Pn).forEach(In=>{Pn[In]!==null&&Cn.setRequestHeader(In,Pn[In])}),Cn.send(_n),{abort(){Cn.abort()}}}const now=+new Date;let index$6=0;function uid(){return`vc-upload-${now}-${++index$6}`}const attrAccept=($n,Cn)=>{if($n&&Cn){const _n=Array.isArray(Cn)?Cn:Cn.split(","),Pn=$n.name||"",In=$n.type||"",Nn=In.replace(/\/.*$/,"");return _n.some(Rn=>{const Dn=Rn.trim();if(/^\*(\/\*)?$/.test(Rn))return!0;if(Dn.charAt(0)==="."){const Ln=Pn.toLowerCase(),Fn=Dn.toLowerCase();let Bn=[Fn];return(Fn===".jpg"||Fn===".jpeg")&&(Bn=[".jpg",".jpeg"]),Bn.some(Hn=>Ln.endsWith(Hn))}return/\/\*$/.test(Dn)?Nn===Dn.replace(/\/.*$/,""):!!(In===Dn||/^\w+$/.test(Dn))})}return!0};function loopFiles($n,Cn){const _n=$n.createReader();let Pn=[];function In(){_n.readEntries(Nn=>{const Rn=Array.prototype.slice.apply(Nn);Pn=Pn.concat(Rn),!Rn.length?Cn(Pn):In()})}In()}const traverseFileTree=($n,Cn,_n)=>{const Pn=(In,Nn)=>{In.path=Nn||"",In.isFile?In.file(Rn=>{_n(Rn)&&(In.fullPath&&!Rn.webkitRelativePath&&(Object.defineProperties(Rn,{webkitRelativePath:{writable:!0}}),Rn.webkitRelativePath=In.fullPath.replace(/^\//,""),Object.defineProperties(Rn,{webkitRelativePath:{writable:!1}})),Cn([Rn]))}):In.isDirectory&&loopFiles(In,Rn=>{Rn.forEach(Dn=>{Pn(Dn,`${Nn}${In.name}/`)})})};$n.forEach(In=>{Pn(In.webkitGetAsEntry())})},traverseFileTree$1=traverseFileTree,uploadProps$1=()=>({capture:[Boolean,String],multipart:{type:Boolean,default:void 0},name:String,disabled:{type:Boolean,default:void 0},componentTag:String,action:[String,Function],method:String,directory:{type:Boolean,default:void 0},data:[Object,Function],headers:Object,accept:String,multiple:{type:Boolean,default:void 0},onBatchStart:Function,onReject:Function,onStart:Function,onError:Function,onSuccess:Function,onProgress:Function,beforeUpload:Function,customRequest:Function,withCredentials:{type:Boolean,default:void 0},openFileDialogOnClick:{type:Boolean,default:void 0},prefixCls:String,id:String,onMouseenter:Function,onMouseleave:Function,onClick:Function});var __awaiter$1=function($n,Cn,_n,Pn){function In(Nn){return Nn instanceof _n?Nn:new _n(function(Rn){Rn(Nn)})}return new(_n||(_n=Promise))(function(Nn,Rn){function Dn(Bn){try{Fn(Pn.next(Bn))}catch(Hn){Rn(Hn)}}function Ln(Bn){try{Fn(Pn.throw(Bn))}catch(Hn){Rn(Hn)}}function Fn(Bn){Bn.done?Nn(Bn.value):In(Bn.value).then(Dn,Ln)}Fn((Pn=Pn.apply($n,Cn||[])).next())})},__rest$6=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In__awaiter$1(this,void 0,void 0,function*(){const{beforeUpload:Jo}=$n;let Zo=Yo;if(Jo){try{Zo=yield Jo(Yo,qo)}catch{Zo=!1}if(Zo===!1)return{origin:Yo,parsedFile:null,action:null,data:null}}const{action:rr}=$n;let nr;typeof rr=="function"?nr=yield rr(Yo):nr=rr;const{data:ta}=$n;let oa;typeof ta=="function"?oa=yield ta(Yo):oa=ta;const ra=(typeof Zo=="object"||typeof Zo=="string")&&Zo?Zo:Yo;let ea;ra instanceof File?ea=ra:ea=new File([ra],Yo.name,{type:Yo.type});const la=ea;return la.uid=Yo.uid,{origin:Yo,data:oa,parsedFile:la,action:nr}}),Bn=Yo=>{let{data:qo,origin:Jo,action:Zo,parsedFile:rr}=Yo;if(!Ln)return;const{onStart:nr,customRequest:ta,name:oa,headers:ra,withCredentials:ea,method:la}=$n,{uid:ua}=Jo,ga=ta||upload,aa={action:Zo,filename:oa,data:qo,file:rr,headers:ra,withCredentials:ea,method:la||"post",onProgress:ca=>{const{onProgress:sa}=$n;sa==null||sa(ca,rr)},onSuccess:(ca,sa)=>{const{onSuccess:ia}=$n;ia==null||ia(ca,rr,sa),delete Rn[ua]},onError:(ca,sa)=>{const{onError:ia}=$n;ia==null||ia(ca,sa,rr),delete Rn[ua]}};nr(Jo),Rn[ua]=ga(aa)},Hn=()=>{Nn.value=uid()},zn=Yo=>{if(Yo){const qo=Yo.uid?Yo.uid:Yo;Rn[qo]&&Rn[qo].abort&&Rn[qo].abort(),delete Rn[qo]}else Object.keys(Rn).forEach(qo=>{Rn[qo]&&Rn[qo].abort&&Rn[qo].abort(),delete Rn[qo]})};onMounted(()=>{Ln=!0}),onBeforeUnmount(()=>{Ln=!1,zn()});const Wn=Yo=>{const qo=[...Yo],Jo=qo.map(Zo=>(Zo.uid=uid(),Fn(Zo,qo)));Promise.all(Jo).then(Zo=>{const{onBatchStart:rr}=$n;rr==null||rr(Zo.map(nr=>{let{origin:ta,parsedFile:oa}=nr;return{file:ta,parsedFile:oa}})),Zo.filter(nr=>nr.parsedFile!==null).forEach(nr=>{Bn(nr)})})},Yn=Yo=>{const{accept:qo,directory:Jo}=$n,{files:Zo}=Yo.target,rr=[...Zo].filter(nr=>!Jo||attrAccept(nr,qo));Wn(rr),Hn()},Gn=Yo=>{const qo=Dn.value;if(!qo)return;const{onClick:Jo}=$n;qo.click(),Jo&&Jo(Yo)},Go=Yo=>{Yo.key==="Enter"&&Gn(Yo)},Xn=Yo=>{const{multiple:qo}=$n;if(Yo.preventDefault(),Yo.type!=="dragover")if($n.directory)traverseFileTree$1(Array.prototype.slice.call(Yo.dataTransfer.items),Wn,Jo=>attrAccept(Jo,$n.accept));else{const Jo=partition$1(Array.prototype.slice.call(Yo.dataTransfer.files),nr=>attrAccept(nr,$n.accept));let Zo=Jo[0];const rr=Jo[1];qo===!1&&(Zo=Zo.slice(0,1)),Wn(Zo),rr.length&&$n.onReject&&$n.onReject(rr)}};return In({abort:zn}),()=>{var Yo;const{componentTag:qo,prefixCls:Jo,disabled:Zo,id:rr,multiple:nr,accept:ta,capture:oa,directory:ra,openFileDialogOnClick:ea,onMouseenter:la,onMouseleave:ua}=$n,ga=__rest$6($n,["componentTag","prefixCls","disabled","id","multiple","accept","capture","directory","openFileDialogOnClick","onMouseenter","onMouseleave"]),aa={[Jo]:!0,[`${Jo}-disabled`]:Zo,[Pn.class]:!!Pn.class},ca=ra?{directory:"directory",webkitdirectory:"webkitdirectory"}:{};return createVNode(qo,_objectSpread2$1(_objectSpread2$1({},Zo?{}:{onClick:ea?Gn:()=>{},onKeydown:ea?Go:()=>{},onMouseenter:la,onMouseleave:ua,onDrop:Xn,onDragover:Xn,tabindex:"0"}),{},{class:aa,role:"button",style:Pn.style}),{default:()=>[createVNode("input",_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},pickAttrs(ga,{aria:!0,data:!0})),{},{id:rr,type:"file",ref:Dn,onClick:ia=>ia.stopPropagation(),onCancel:ia=>ia.stopPropagation(),key:Nn.value,style:{display:"none"},accept:ta},ca),{},{multiple:nr,onChange:Yn},oa!=null?{capture:oa}:{}),null),(Yo=_n.default)===null||Yo===void 0?void 0:Yo.call(_n)]})}}});function empty(){}const Upload$1=defineComponent({compatConfig:{MODE:3},name:"Upload",inheritAttrs:!1,props:initDefaultProps(uploadProps$1(),{componentTag:"span",prefixCls:"rc-upload",data:{},headers:{},name:"file",multipart:!1,onStart:empty,onError:empty,onSuccess:empty,multiple:!1,beforeUpload:null,customRequest:null,withCredentials:!1,openFileDialogOnClick:!0}),setup($n,Cn){let{slots:_n,attrs:Pn,expose:In}=Cn;const Nn=ref();return In({abort:Dn=>{var Ln;(Ln=Nn.value)===null||Ln===void 0||Ln.abort(Dn)}}),()=>createVNode(AjaxUpload,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},$n),Pn),{},{ref:Nn}),_n)}});var PaperClipOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 00174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"}}]},name:"paper-clip",theme:"outlined"};const PaperClipOutlinedSvg=PaperClipOutlined$2;function _objectSpread$4($n){for(var Cn=1;Cn{let{uid:Nn}=In;return Nn===$n.uid});return Pn===-1?_n.push($n):_n[Pn]=$n,_n}function getFileItem($n,Cn){const _n=$n.uid!==void 0?"uid":"name";return Cn.filter(Pn=>Pn[_n]===$n[_n])[0]}function removeFileItem($n,Cn){const _n=$n.uid!==void 0?"uid":"name",Pn=Cn.filter(In=>In[_n]!==$n[_n]);return Pn.length===Cn.length?null:Pn}const extname=function(){const Cn=(arguments.length>0&&arguments[0]!==void 0?arguments[0]:"").split("/"),Pn=Cn[Cn.length-1].split(/#|\?/)[0];return(/\.[^./\\]*$/.exec(Pn)||[""])[0]},isImageFileType=$n=>$n.indexOf("image/")===0,isImageUrl=$n=>{if($n.type&&!$n.thumbUrl)return isImageFileType($n.type);const Cn=$n.thumbUrl||$n.url||"",_n=extname(Cn);return/^data:image\//.test(Cn)||/(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico)$/i.test(_n)?!0:!(/^data:/.test(Cn)||_n)},MEASURE_SIZE=200;function previewImage($n){return new Promise(Cn=>{if(!$n.type||!isImageFileType($n.type)){Cn("");return}const _n=document.createElement("canvas");_n.width=MEASURE_SIZE,_n.height=MEASURE_SIZE,_n.style.cssText=`position: fixed; left: 0; top: 0; width: ${MEASURE_SIZE}px; height: ${MEASURE_SIZE}px; z-index: 9999; display: none;`,document.body.appendChild(_n);const Pn=_n.getContext("2d"),In=new Image;if(In.onload=()=>{const{width:Nn,height:Rn}=In;let Dn=MEASURE_SIZE,Ln=MEASURE_SIZE,Fn=0,Bn=0;Nn>Rn?(Ln=Rn*(MEASURE_SIZE/Nn),Bn=-(Ln-Dn)/2):(Dn=Nn*(MEASURE_SIZE/Rn),Fn=-(Dn-Ln)/2),Pn.drawImage(In,Fn,Bn,Dn,Ln);const Hn=_n.toDataURL();document.body.removeChild(_n),Cn(Hn)},In.crossOrigin="anonymous",$n.type.startsWith("image/svg+xml")){const Nn=new FileReader;Nn.addEventListener("load",()=>{Nn.result&&(In.src=Nn.result)}),Nn.readAsDataURL($n)}else In.src=window.URL.createObjectURL($n)})}var DownloadOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"download",theme:"outlined"};const DownloadOutlinedSvg=DownloadOutlined$2;function _objectSpread$1($n){for(var Cn=1;Cn({prefixCls:String,locale:objectType(void 0),file:objectType(),items:arrayType(),listType:stringType(),isImgUrl:functionType(),showRemoveIcon:booleanType(),showDownloadIcon:booleanType(),showPreviewIcon:booleanType(),removeIcon:functionType(),downloadIcon:functionType(),previewIcon:functionType(),iconRender:functionType(),actionIconRender:functionType(),itemRender:functionType(),onPreview:functionType(),onClose:functionType(),onDownload:functionType(),progress:objectType()}),ListItem=defineComponent({compatConfig:{MODE:3},name:"ListItem",inheritAttrs:!1,props:listItemProps(),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;var In;const Nn=shallowRef(!1),Rn=shallowRef();onMounted(()=>{Rn.value=setTimeout(()=>{Nn.value=!0},300)}),onBeforeUnmount(()=>{clearTimeout(Rn.value)});const Dn=shallowRef((In=$n.file)===null||In===void 0?void 0:In.status);watch(()=>{var Bn;return(Bn=$n.file)===null||Bn===void 0?void 0:Bn.status},Bn=>{Bn!=="removed"&&(Dn.value=Bn)});const{rootPrefixCls:Ln}=useConfigInject("upload",$n),Fn=computed(()=>getTransitionProps(`${Ln.value}-fade`));return()=>{var Bn,Hn;const{prefixCls:zn,locale:Wn,listType:Yn,file:Gn,items:Go,progress:Xn,iconRender:Yo=_n.iconRender,actionIconRender:qo=_n.actionIconRender,itemRender:Jo=_n.itemRender,isImgUrl:Zo,showPreviewIcon:rr,showRemoveIcon:nr,showDownloadIcon:ta,previewIcon:oa=_n.previewIcon,removeIcon:ra=_n.removeIcon,downloadIcon:ea=_n.downloadIcon,onPreview:la,onDownload:ua,onClose:ga}=$n,{class:aa,style:ca}=Pn,sa=Yo({file:Gn});let ia=createVNode("div",{class:`${zn}-text-icon`},[sa]);if(Yn==="picture"||Yn==="picture-card")if(Dn.value==="uploading"||!Gn.thumbUrl&&!Gn.url){const da={[`${zn}-list-item-thumbnail`]:!0,[`${zn}-list-item-file`]:Dn.value!=="uploading"};ia=createVNode("div",{class:da},[sa])}else{const da=Zo!=null&&Zo(Gn)?createVNode("img",{src:Gn.thumbUrl||Gn.url,alt:Gn.name,class:`${zn}-list-item-image`,crossorigin:Gn.crossOrigin},null):sa,pa={[`${zn}-list-item-thumbnail`]:!0,[`${zn}-list-item-file`]:Zo&&!Zo(Gn)};ia=createVNode("a",{class:pa,onClick:Sa=>la(Gn,Sa),href:Gn.url||Gn.thumbUrl,target:"_blank",rel:"noopener noreferrer"},[da])}const fa={[`${zn}-list-item`]:!0,[`${zn}-list-item-${Dn.value}`]:!0},ma=typeof Gn.linkProps=="string"?JSON.parse(Gn.linkProps):Gn.linkProps,ya=nr?qo({customIcon:ra?ra({file:Gn}):createVNode(DeleteOutlined$1,null,null),callback:()=>ga(Gn),prefixCls:zn,title:Wn.removeFile}):null,ba=ta&&Dn.value==="done"?qo({customIcon:ea?ea({file:Gn}):createVNode(DownloadOutlined$1,null,null),callback:()=>ua(Gn),prefixCls:zn,title:Wn.downloadFile}):null,Ia=Yn!=="picture-card"&&createVNode("span",{key:"download-delete",class:[`${zn}-list-item-actions`,{picture:Yn==="picture"}]},[ba,ya]),Ea=`${zn}-list-item-name`,xa=Gn.url?[createVNode("a",_objectSpread2$1(_objectSpread2$1({key:"view",target:"_blank",rel:"noopener noreferrer",class:Ea,title:Gn.name},ma),{},{href:Gn.url,onClick:da=>la(Gn,da)}),[Gn.name]),Ia]:[createVNode("span",{key:"view",class:Ea,onClick:da=>la(Gn,da),title:Gn.name},[Gn.name]),Ia],Ta={pointerEvents:"none",opacity:.5},wa=rr?createVNode("a",{href:Gn.url||Gn.thumbUrl,target:"_blank",rel:"noopener noreferrer",style:Gn.url||Gn.thumbUrl?void 0:Ta,onClick:da=>la(Gn,da),title:Wn.previewFile},[oa?oa({file:Gn}):createVNode(EyeOutlined$1,null,null)]):null,La=Yn==="picture-card"&&Dn.value!=="uploading"&&createVNode("span",{class:`${zn}-list-item-actions`},[wa,Dn.value==="done"&&ba,ya]),Na=createVNode("div",{class:fa},[ia,xa,La,Nn.value&&createVNode(Transition,Fn.value,{default:()=>[withDirectives(createVNode("div",{class:`${zn}-list-item-progress`},["percent"in Gn?createVNode(Progress,_objectSpread2$1(_objectSpread2$1({},Xn),{},{type:"line",percent:Gn.percent}),null):null]),[[vShow,Dn.value==="uploading"]])]})]),$a={[`${zn}-list-item-container`]:!0,[`${aa}`]:!!aa},ka=Gn.response&&typeof Gn.response=="string"?Gn.response:((Bn=Gn.error)===null||Bn===void 0?void 0:Bn.statusText)||((Hn=Gn.error)===null||Hn===void 0?void 0:Hn.message)||Wn.uploadError,Ha=Dn.value==="error"?createVNode(Tooltip,{title:ka,getPopupContainer:da=>da.parentNode},{default:()=>[Na]}):Na;return createVNode("div",{class:$a,style:ca},[Jo?Jo({originNode:Ha,file:Gn,fileList:Go,actions:{download:ua.bind(null,Gn),preview:la.bind(null,Gn),remove:ga.bind(null,Gn)}}):Ha])}}}),HackSlot=($n,Cn)=>{let{slots:_n}=Cn;var Pn;return filterEmpty((Pn=_n.default)===null||Pn===void 0?void 0:Pn.call(_n))[0]},UploadList=defineComponent({compatConfig:{MODE:3},name:"AUploadList",props:initDefaultProps(uploadListProps(),{listType:"text",progress:{strokeWidth:2,showInfo:!1},showRemoveIcon:!0,showDownloadIcon:!1,showPreviewIcon:!0,previewFile:previewImage,isImageUrl,items:[],appendActionVisible:!0}),setup($n,Cn){let{slots:_n,expose:Pn}=Cn;const In=shallowRef(!1);onMounted(()=>{In.value==!0});const Nn=shallowRef([]);watch(()=>$n.items,function(){let Gn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];Nn.value=Gn.slice()},{immediate:!0,deep:!0}),watchEffect(()=>{if($n.listType!=="picture"&&$n.listType!=="picture-card")return;let Gn=!1;($n.items||[]).forEach((Go,Xn)=>{typeof document>"u"||typeof window>"u"||!window.FileReader||!window.File||!(Go.originFileObj instanceof File||Go.originFileObj instanceof Blob)||Go.thumbUrl!==void 0||(Go.thumbUrl="",$n.previewFile&&$n.previewFile(Go.originFileObj).then(Yo=>{const qo=Yo||"";qo!==Go.thumbUrl&&(Nn.value[Xn].thumbUrl=qo,Gn=!0)}))}),Gn&&triggerRef(Nn)});const Rn=(Gn,Go)=>{if($n.onPreview)return Go==null||Go.preventDefault(),$n.onPreview(Gn)},Dn=Gn=>{typeof $n.onDownload=="function"?$n.onDownload(Gn):Gn.url&&window.open(Gn.url)},Ln=Gn=>{var Go;(Go=$n.onRemove)===null||Go===void 0||Go.call($n,Gn)},Fn=Gn=>{let{file:Go}=Gn;const Xn=$n.iconRender||_n.iconRender;if(Xn)return Xn({file:Go,listType:$n.listType});const Yo=Go.status==="uploading",qo=$n.isImageUrl&&$n.isImageUrl(Go)?createVNode(PictureTwoTone$1,null,null):createVNode(FileTwoTone$1,null,null);let Jo=createVNode(Yo?LoadingOutlined$1:PaperClipOutlined$1,null,null);return $n.listType==="picture"?Jo=Yo?createVNode(LoadingOutlined$1,null,null):qo:$n.listType==="picture-card"&&(Jo=Yo?$n.locale.uploading:qo),Jo},Bn=Gn=>{const{customIcon:Go,callback:Xn,prefixCls:Yo,title:qo}=Gn,Jo={type:"text",size:"small",title:qo,onClick:()=>{Xn()},class:`${Yo}-list-item-action`};return isValidElement(Go)?createVNode(Button$1,Jo,{icon:()=>Go}):createVNode(Button$1,Jo,{default:()=>[createVNode("span",null,[Go])]})};Pn({handlePreview:Rn,handleDownload:Dn});const{prefixCls:Hn,rootPrefixCls:zn}=useConfigInject("upload",$n),Wn=computed(()=>({[`${Hn.value}-list`]:!0,[`${Hn.value}-list-${$n.listType}`]:!0})),Yn=computed(()=>{const Gn=_extends$1({},collapseMotion$1(`${zn.value}-motion-collapse`));delete Gn.onAfterAppear,delete Gn.onAfterEnter,delete Gn.onAfterLeave;const Go=_extends$1(_extends$1({},getTransitionGroupProps(`${Hn.value}-${$n.listType==="picture-card"?"animate-inline":"animate"}`)),{class:Wn.value,appear:In.value});return $n.listType!=="picture-card"?_extends$1(_extends$1({},Gn),Go):Go});return()=>{const{listType:Gn,locale:Go,isImageUrl:Xn,showPreviewIcon:Yo,showRemoveIcon:qo,showDownloadIcon:Jo,removeIcon:Zo,previewIcon:rr,downloadIcon:nr,progress:ta,appendAction:oa,itemRender:ra,appendActionVisible:ea}=$n,la=oa==null?void 0:oa(),ua=Nn.value;return createVNode(TransitionGroup,_objectSpread2$1(_objectSpread2$1({},Yn.value),{},{tag:"div"}),{default:()=>[ua.map(ga=>{const{uid:aa}=ga;return createVNode(ListItem,{key:aa,locale:Go,prefixCls:Hn.value,file:ga,items:ua,progress:ta,listType:Gn,isImgUrl:Xn,showPreviewIcon:Yo,showRemoveIcon:qo,showDownloadIcon:Jo,onPreview:Rn,onDownload:Dn,onClose:Ln,removeIcon:Zo,previewIcon:rr,downloadIcon:nr,itemRender:ra},_extends$1(_extends$1({},_n),{iconRender:Fn,actionIconRender:Bn}))}),oa?withDirectives(createVNode(HackSlot,{key:"__ant_upload_appendAction"},{default:()=>la}),[[vShow,!!ea]]):null]})}}}),genDraggerStyle=$n=>{const{componentCls:Cn,iconCls:_n}=$n;return{[`${Cn}-wrapper`]:{[`${Cn}-drag`]:{position:"relative",width:"100%",height:"100%",textAlign:"center",background:$n.colorFillAlter,border:`${$n.lineWidth}px dashed ${$n.colorBorder}`,borderRadius:$n.borderRadiusLG,cursor:"pointer",transition:`border-color ${$n.motionDurationSlow}`,[Cn]:{padding:`${$n.padding}px 0`},[`${Cn}-btn`]:{display:"table",width:"100%",height:"100%",outline:"none"},[`${Cn}-drag-container`]:{display:"table-cell",verticalAlign:"middle"},[`&:not(${Cn}-disabled):hover`]:{borderColor:$n.colorPrimaryHover},[`p${Cn}-drag-icon`]:{marginBottom:$n.margin,[_n]:{color:$n.colorPrimary,fontSize:$n.uploadThumbnailSize}},[`p${Cn}-text`]:{margin:`0 0 ${$n.marginXXS}px`,color:$n.colorTextHeading,fontSize:$n.fontSizeLG},[`p${Cn}-hint`]:{color:$n.colorTextDescription,fontSize:$n.fontSize},[`&${Cn}-disabled`]:{cursor:"not-allowed",[`p${Cn}-drag-icon ${_n}, - p${Cn}-text, - p${Cn}-hint - `]:{color:$n.colorTextDisabled}}}}}},genDraggerStyle$1=genDraggerStyle,genListStyle=$n=>{const{componentCls:Cn,antCls:_n,iconCls:Pn,fontSize:In,lineHeight:Nn}=$n,Rn=`${Cn}-list-item`,Dn=`${Rn}-actions`,Ln=`${Rn}-action`,Fn=Math.round(In*Nn);return{[`${Cn}-wrapper`]:{[`${Cn}-list`]:_extends$1(_extends$1({},clearFix()),{lineHeight:$n.lineHeight,[Rn]:{position:"relative",height:$n.lineHeight*In,marginTop:$n.marginXS,fontSize:In,display:"flex",alignItems:"center",transition:`background-color ${$n.motionDurationSlow}`,"&:hover":{backgroundColor:$n.controlItemBgHover},[`${Rn}-name`]:_extends$1(_extends$1({},textEllipsis),{padding:`0 ${$n.paddingXS}px`,lineHeight:Nn,flex:"auto",transition:`all ${$n.motionDurationSlow}`}),[Dn]:{[Ln]:{opacity:0},[`${Ln}${_n}-btn-sm`]:{height:Fn,border:0,lineHeight:1,"> span":{transform:"scale(1)"}},[` - ${Ln}:focus, - &.picture ${Ln} - `]:{opacity:1},[Pn]:{color:$n.colorTextDescription,transition:`all ${$n.motionDurationSlow}`},[`&:hover ${Pn}`]:{color:$n.colorText}},[`${Cn}-icon ${Pn}`]:{color:$n.colorTextDescription,fontSize:In},[`${Rn}-progress`]:{position:"absolute",bottom:-$n.uploadProgressOffset,width:"100%",paddingInlineStart:In+$n.paddingXS,fontSize:In,lineHeight:0,pointerEvents:"none","> div":{margin:0}}},[`${Rn}:hover ${Ln}`]:{opacity:1,color:$n.colorText},[`${Rn}-error`]:{color:$n.colorError,[`${Rn}-name, ${Cn}-icon ${Pn}`]:{color:$n.colorError},[Dn]:{[`${Pn}, ${Pn}:hover`]:{color:$n.colorError},[Ln]:{opacity:1}}},[`${Cn}-list-item-container`]:{transition:`opacity ${$n.motionDurationSlow}, height ${$n.motionDurationSlow}`,"&::before":{display:"table",width:0,height:0,content:'""'}}})}}},genListStyle$1=genListStyle,uploadAnimateInlineIn=new Keyframes("uploadAnimateInlineIn",{from:{width:0,height:0,margin:0,padding:0,opacity:0}}),uploadAnimateInlineOut=new Keyframes("uploadAnimateInlineOut",{to:{width:0,height:0,margin:0,padding:0,opacity:0}}),genMotionStyle=$n=>{const{componentCls:Cn}=$n,_n=`${Cn}-animate-inline`;return[{[`${Cn}-wrapper`]:{[`${_n}-appear, ${_n}-enter, ${_n}-leave`]:{animationDuration:$n.motionDurationSlow,animationTimingFunction:$n.motionEaseInOutCirc,animationFillMode:"forwards"},[`${_n}-appear, ${_n}-enter`]:{animationName:uploadAnimateInlineIn},[`${_n}-leave`]:{animationName:uploadAnimateInlineOut}}},uploadAnimateInlineIn,uploadAnimateInlineOut]},genMotionStyle$1=genMotionStyle,genPictureStyle=$n=>{const{componentCls:Cn,iconCls:_n,uploadThumbnailSize:Pn,uploadProgressOffset:In}=$n,Nn=`${Cn}-list`,Rn=`${Nn}-item`;return{[`${Cn}-wrapper`]:{[`${Nn}${Nn}-picture, ${Nn}${Nn}-picture-card`]:{[Rn]:{position:"relative",height:Pn+$n.lineWidth*2+$n.paddingXS*2,padding:$n.paddingXS,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorBorder}`,borderRadius:$n.borderRadiusLG,"&:hover":{background:"transparent"},[`${Rn}-thumbnail`]:_extends$1(_extends$1({},textEllipsis),{width:Pn,height:Pn,lineHeight:`${Pn+$n.paddingSM}px`,textAlign:"center",flex:"none",[_n]:{fontSize:$n.fontSizeHeading2,color:$n.colorPrimary},img:{display:"block",width:"100%",height:"100%",overflow:"hidden"}}),[`${Rn}-progress`]:{bottom:In,width:`calc(100% - ${$n.paddingSM*2}px)`,marginTop:0,paddingInlineStart:Pn+$n.paddingXS}},[`${Rn}-error`]:{borderColor:$n.colorError,[`${Rn}-thumbnail ${_n}`]:{"svg path[fill='#e6f7ff']":{fill:$n.colorErrorBg},"svg path[fill='#1890ff']":{fill:$n.colorError}}},[`${Rn}-uploading`]:{borderStyle:"dashed",[`${Rn}-name`]:{marginBottom:In}}}}}},genPictureCardStyle=$n=>{const{componentCls:Cn,iconCls:_n,fontSizeLG:Pn,colorTextLightSolid:In}=$n,Nn=`${Cn}-list`,Rn=`${Nn}-item`,Dn=$n.uploadPicCardSize;return{[`${Cn}-wrapper${Cn}-picture-card-wrapper`]:_extends$1(_extends$1({},clearFix()),{display:"inline-block",width:"100%",[`${Cn}${Cn}-select`]:{width:Dn,height:Dn,marginInlineEnd:$n.marginXS,marginBottom:$n.marginXS,textAlign:"center",verticalAlign:"top",backgroundColor:$n.colorFillAlter,border:`${$n.lineWidth}px dashed ${$n.colorBorder}`,borderRadius:$n.borderRadiusLG,cursor:"pointer",transition:`border-color ${$n.motionDurationSlow}`,[`> ${Cn}`]:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",textAlign:"center"},[`&:not(${Cn}-disabled):hover`]:{borderColor:$n.colorPrimary}},[`${Nn}${Nn}-picture-card`]:{[`${Nn}-item-container`]:{display:"inline-block",width:Dn,height:Dn,marginBlock:`0 ${$n.marginXS}px`,marginInline:`0 ${$n.marginXS}px`,verticalAlign:"top"},"&::after":{display:"none"},[Rn]:{height:"100%",margin:0,"&::before":{position:"absolute",zIndex:1,width:`calc(100% - ${$n.paddingXS*2}px)`,height:`calc(100% - ${$n.paddingXS*2}px)`,backgroundColor:$n.colorBgMask,opacity:0,transition:`all ${$n.motionDurationSlow}`,content:'" "'}},[`${Rn}:hover`]:{[`&::before, ${Rn}-actions`]:{opacity:1}},[`${Rn}-actions`]:{position:"absolute",insetInlineStart:0,zIndex:10,width:"100%",whiteSpace:"nowrap",textAlign:"center",opacity:0,transition:`all ${$n.motionDurationSlow}`,[`${_n}-eye, ${_n}-download, ${_n}-delete`]:{zIndex:10,width:Pn,margin:`0 ${$n.marginXXS}px`,fontSize:Pn,cursor:"pointer",transition:`all ${$n.motionDurationSlow}`}},[`${Rn}-actions, ${Rn}-actions:hover`]:{[`${_n}-eye, ${_n}-download, ${_n}-delete`]:{color:new TinyColor(In).setAlpha(.65).toRgbString(),"&:hover":{color:In}}},[`${Rn}-thumbnail, ${Rn}-thumbnail img`]:{position:"static",display:"block",width:"100%",height:"100%",objectFit:"contain"},[`${Rn}-name`]:{display:"none",textAlign:"center"},[`${Rn}-file + ${Rn}-name`]:{position:"absolute",bottom:$n.margin,display:"block",width:`calc(100% - ${$n.paddingXS*2}px)`},[`${Rn}-uploading`]:{[`&${Rn}`]:{backgroundColor:$n.colorFillAlter},[`&::before, ${_n}-eye, ${_n}-download, ${_n}-delete`]:{display:"none"}},[`${Rn}-progress`]:{bottom:$n.marginXL,width:`calc(100% - ${$n.paddingXS*2}px)`,paddingInlineStart:0}}})}},genRtlStyle=$n=>{const{componentCls:Cn}=$n;return{[`${Cn}-rtl`]:{direction:"rtl"}}},genRtlStyle$1=genRtlStyle,genBaseStyle$2=$n=>{const{componentCls:Cn,colorTextDisabled:_n}=$n;return{[`${Cn}-wrapper`]:_extends$1(_extends$1({},resetComponent($n)),{[Cn]:{outline:0,"input[type='file']":{cursor:"pointer"}},[`${Cn}-select`]:{display:"inline-block"},[`${Cn}-disabled`]:{color:_n,cursor:"not-allowed"}})}},useStyle$5=genComponentStyleHook("Upload",$n=>{const{fontSizeHeading3:Cn,fontSize:_n,lineHeight:Pn,lineWidth:In,controlHeightLG:Nn}=$n,Rn=Math.round(_n*Pn),Dn=merge$1($n,{uploadThumbnailSize:Cn*2,uploadProgressOffset:Rn/2+In,uploadPicCardSize:Nn*2.55});return[genBaseStyle$2(Dn),genDraggerStyle$1(Dn),genPictureStyle(Dn),genPictureCardStyle(Dn),genListStyle$1(Dn),genMotionStyle$1(Dn),genRtlStyle$1(Dn),genCollapseMotion$1(Dn)]});var __awaiter=function($n,Cn,_n,Pn){function In(Nn){return Nn instanceof _n?Nn:new _n(function(Rn){Rn(Nn)})}return new(_n||(_n=Promise))(function(Nn,Rn){function Dn(Bn){try{Fn(Pn.next(Bn))}catch(Hn){Rn(Hn)}}function Ln(Bn){try{Fn(Pn.throw(Bn))}catch(Hn){Rn(Hn)}}function Fn(Bn){Bn.done?Nn(Bn.value):In(Bn.value).then(Dn,Ln)}Fn((Pn=Pn.apply($n,Cn||[])).next())})},__rest$5=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{var ea;return(ea=Ln.value)!==null&&ea!==void 0?ea:Hn.value}),[Wn,Yn]=useMergedState($n.defaultFileList||[],{value:toRef($n,"fileList"),postState:ea=>{const la=Date.now();return(ea??[]).map((ua,ga)=>(!ua.uid&&!Object.isFrozen(ua)&&(ua.uid=`__AUTO__${la}_${ga}__`),ua))}}),Gn=ref("drop"),Go=ref(null);onMounted(()=>{devWarning($n.fileList!==void 0||Pn.value===void 0,"Upload","`value` is not a valid prop, do you mean `fileList`?"),devWarning($n.transformFile===void 0,"Upload","`transformFile` is deprecated. Please use `beforeUpload` directly."),devWarning($n.remove===void 0,"Upload","`remove` props is deprecated. Please use `remove` event.")});const Xn=(ea,la,ua)=>{var ga,aa;let ca=[...la];$n.maxCount===1?ca=ca.slice(-1):$n.maxCount&&(ca=ca.slice(0,$n.maxCount)),Yn(ca);const sa={file:ea,fileList:ca};ua&&(sa.event=ua),(ga=$n["onUpdate:fileList"])===null||ga===void 0||ga.call($n,sa.fileList),(aa=$n.onChange)===null||aa===void 0||aa.call($n,sa),Nn.onFieldChange()},Yo=(ea,la)=>__awaiter(this,void 0,void 0,function*(){const{beforeUpload:ua,transformFile:ga}=$n;let aa=ea;if(ua){const ca=yield ua(ea,la);if(ca===!1)return!1;if(delete ea[LIST_IGNORE],ca===LIST_IGNORE)return Object.defineProperty(ea,LIST_IGNORE,{value:!0,configurable:!0}),!1;typeof ca=="object"&&ca&&(aa=ca)}return ga&&(aa=yield ga(aa)),aa}),qo=ea=>{const la=ea.filter(aa=>!aa.file[LIST_IGNORE]);if(!la.length)return;const ua=la.map(aa=>file2Obj(aa.file));let ga=[...Wn.value];ua.forEach(aa=>{ga=updateFileList(aa,ga)}),ua.forEach((aa,ca)=>{let sa=aa;if(la[ca].parsedFile)aa.status="uploading";else{const{originFileObj:ia}=aa;let fa;try{fa=new File([ia],ia.name,{type:ia.type})}catch{fa=new Blob([ia],{type:ia.type}),fa.name=ia.name,fa.lastModifiedDate=new Date,fa.lastModified=new Date().getTime()}fa.uid=aa.uid,sa=fa}Xn(sa,ga)})},Jo=(ea,la,ua)=>{try{typeof ea=="string"&&(ea=JSON.parse(ea))}catch{}if(!getFileItem(la,Wn.value))return;const ga=file2Obj(la);ga.status="done",ga.percent=100,ga.response=ea,ga.xhr=ua;const aa=updateFileList(ga,Wn.value);Xn(ga,aa)},Zo=(ea,la)=>{if(!getFileItem(la,Wn.value))return;const ua=file2Obj(la);ua.status="uploading",ua.percent=ea.percent;const ga=updateFileList(ua,Wn.value);Xn(ua,ga,ea)},rr=(ea,la,ua)=>{if(!getFileItem(ua,Wn.value))return;const ga=file2Obj(ua);ga.error=ea,ga.response=la,ga.status="error";const aa=updateFileList(ga,Wn.value);Xn(ga,aa)},nr=ea=>{let la;const ua=$n.onRemove||$n.remove;Promise.resolve(typeof ua=="function"?ua(ea):ua).then(ga=>{var aa,ca;if(ga===!1)return;const sa=removeFileItem(ea,Wn.value);sa&&(la=_extends$1(_extends$1({},ea),{status:"removed"}),(aa=Wn.value)===null||aa===void 0||aa.forEach(ia=>{const fa=la.uid!==void 0?"uid":"name";ia[fa]===la[fa]&&!Object.isFrozen(ia)&&(ia.status="removed")}),(ca=Go.value)===null||ca===void 0||ca.abort(la),Xn(la,sa))})},ta=ea=>{var la;Gn.value=ea.type,ea.type==="drop"&&((la=$n.onDrop)===null||la===void 0||la.call($n,ea))};In({onBatchStart:qo,onSuccess:Jo,onProgress:Zo,onError:rr,fileList:Wn,upload:Go});const[oa]=useLocaleReceiver("Upload",localeValues$1.Upload,computed(()=>$n.locale)),ra=(ea,la)=>{const{removeIcon:ua,previewIcon:ga,downloadIcon:aa,previewFile:ca,onPreview:sa,onDownload:ia,isImageUrl:fa,progress:ma,itemRender:ya,iconRender:ba,showUploadList:Ia}=$n,{showDownloadIcon:Ea,showPreviewIcon:xa,showRemoveIcon:Ta}=typeof Ia=="boolean"?{}:Ia;return Ia?createVNode(UploadList,{prefixCls:Rn.value,listType:$n.listType,items:Wn.value,previewFile:ca,onPreview:sa,onDownload:ia,onRemove:nr,showRemoveIcon:!zn.value&&Ta,showPreviewIcon:xa,showDownloadIcon:Ea,removeIcon:ua,previewIcon:ga,downloadIcon:aa,iconRender:ba,locale:oa.value,isImageUrl:fa,progress:ma,itemRender:ya,appendActionVisible:la,appendAction:ea},_extends$1({},_n)):ea==null?void 0:ea()};return()=>{var ea,la,ua;const{listType:ga,type:aa}=$n,{class:ca,style:sa}=Pn,ia=__rest$5(Pn,["class","style"]),fa=_extends$1(_extends$1(_extends$1({onBatchStart:qo,onError:rr,onProgress:Zo,onSuccess:Jo},ia),$n),{id:(ea=$n.id)!==null&&ea!==void 0?ea:Nn.id.value,prefixCls:Rn.value,beforeUpload:Yo,onChange:void 0,disabled:zn.value});delete fa.remove,(!_n.default||zn.value)&&delete fa.id;const ma={[`${Rn.value}-rtl`]:Dn.value==="rtl"};if(aa==="drag"){const Ea=classNames(Rn.value,{[`${Rn.value}-drag`]:!0,[`${Rn.value}-drag-uploading`]:Wn.value.some(xa=>xa.status==="uploading"),[`${Rn.value}-drag-hover`]:Gn.value==="dragover",[`${Rn.value}-disabled`]:zn.value,[`${Rn.value}-rtl`]:Dn.value==="rtl"},Pn.class,Bn.value);return Fn(createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:classNames(`${Rn.value}-wrapper`,ma,ca,Bn.value)}),[createVNode("div",{class:Ea,onDrop:ta,onDragover:ta,onDragleave:ta,style:Pn.style},[createVNode(Upload$1,_objectSpread2$1(_objectSpread2$1({},fa),{},{ref:Go,class:`${Rn.value}-btn`}),_objectSpread2$1({default:()=>[createVNode("div",{class:`${Rn.value}-drag-container`},[(la=_n.default)===null||la===void 0?void 0:la.call(_n)])]},_n))]),ra()]))}const ya=classNames(Rn.value,{[`${Rn.value}-select`]:!0,[`${Rn.value}-select-${ga}`]:!0,[`${Rn.value}-disabled`]:zn.value,[`${Rn.value}-rtl`]:Dn.value==="rtl"}),ba=flattenChildren((ua=_n.default)===null||ua===void 0?void 0:ua.call(_n)),Ia=Ea=>createVNode("div",{class:ya,style:Ea},[createVNode(Upload$1,_objectSpread2$1(_objectSpread2$1({},fa),{},{ref:Go}),_n)]);return Fn(ga==="picture-card"?createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:classNames(`${Rn.value}-wrapper`,`${Rn.value}-picture-card-wrapper`,ma,Pn.class,Bn.value)}),[ra(Ia,!!(ba&&ba.length))]):createVNode("span",_objectSpread2$1(_objectSpread2$1({},Pn),{},{class:classNames(`${Rn.value}-wrapper`,ma,Pn.class,Bn.value)}),[Ia(ba&&ba.length?void 0:{display:"none"}),ra()]))}}});var __rest$4=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const{height:In}=$n,Nn=__rest$4($n,["height"]),{style:Rn}=Pn,Dn=__rest$4(Pn,["style"]),Ln=_extends$1(_extends$1(_extends$1({},Nn),Dn),{type:"drag",style:_extends$1(_extends$1({},Rn),{height:typeof In=="number"?`${In}px`:In})});return createVNode(Upload,Ln,_n)}}}),UploadDragger=Dragger,index$5=_extends$1(Upload,{Dragger,LIST_IGNORE,install($n){return $n.component(Upload.name,Upload),$n.component(Dragger.name,Dragger),$n}});function toLowercaseSeparator($n){return $n.replace(/([A-Z])/g,"-$1").toLowerCase()}function getStyleStr($n){return Object.keys($n).map(Cn=>`${toLowercaseSeparator(Cn)}: ${$n[Cn]};`).join(" ")}function getPixelRatio(){return window.devicePixelRatio||1}function rotateWatermark($n,Cn,_n,Pn){$n.translate(Cn,_n),$n.rotate(Math.PI/180*Number(Pn)),$n.translate(-Cn,-_n)}const reRendering=($n,Cn)=>{let _n=!1;return $n.removedNodes.length&&(_n=Array.from($n.removedNodes).some(Pn=>Pn===Cn)),$n.type==="attributes"&&$n.target===Cn&&(_n=!0),_n};var __rest$3=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In2&&arguments[2]!==void 0?arguments[2]:{};const{window:Pn=defaultWindow$1}=_n,In=__rest$3(_n,["window"]);let Nn;const Rn=useSupported(()=>Pn&&"MutationObserver"in Pn),Dn=()=>{Nn&&(Nn.disconnect(),Nn=void 0)},Ln=watch(()=>unrefElement$1($n),Bn=>{Dn(),Rn.value&&Pn&&Bn&&(Nn=new MutationObserver(Cn),Nn.observe(Bn,In))},{immediate:!0}),Fn=()=>{Dn(),Ln()};return tryOnScopeDispose$1(Fn),{isSupported:Rn,stop:Fn}}const BaseSize=2,FontGap=3,watermarkProps=()=>({zIndex:Number,rotate:Number,width:Number,height:Number,image:String,content:someType([String,Array]),font:objectType(),rootClassName:String,gap:arrayType(),offset:arrayType()}),Watermark=defineComponent({name:"AWatermark",inheritAttrs:!1,props:initDefaultProps(watermarkProps(),{zIndex:9,rotate:-22,font:{},gap:[100,100]}),setup($n,Cn){let{slots:_n,attrs:Pn}=Cn;const[,In]=useToken(),Nn=shallowRef(),Rn=shallowRef(),Dn=shallowRef(!1),Ln=computed(()=>{var ra,ea;return(ea=(ra=$n.gap)===null||ra===void 0?void 0:ra[0])!==null&&ea!==void 0?ea:100}),Fn=computed(()=>{var ra,ea;return(ea=(ra=$n.gap)===null||ra===void 0?void 0:ra[1])!==null&&ea!==void 0?ea:100}),Bn=computed(()=>Ln.value/2),Hn=computed(()=>Fn.value/2),zn=computed(()=>{var ra,ea;return(ea=(ra=$n.offset)===null||ra===void 0?void 0:ra[0])!==null&&ea!==void 0?ea:Bn.value}),Wn=computed(()=>{var ra,ea;return(ea=(ra=$n.offset)===null||ra===void 0?void 0:ra[1])!==null&&ea!==void 0?ea:Hn.value}),Yn=computed(()=>{var ra,ea;return(ea=(ra=$n.font)===null||ra===void 0?void 0:ra.fontSize)!==null&&ea!==void 0?ea:In.value.fontSizeLG}),Gn=computed(()=>{var ra,ea;return(ea=(ra=$n.font)===null||ra===void 0?void 0:ra.fontWeight)!==null&&ea!==void 0?ea:"normal"}),Go=computed(()=>{var ra,ea;return(ea=(ra=$n.font)===null||ra===void 0?void 0:ra.fontStyle)!==null&&ea!==void 0?ea:"normal"}),Xn=computed(()=>{var ra,ea;return(ea=(ra=$n.font)===null||ra===void 0?void 0:ra.fontFamily)!==null&&ea!==void 0?ea:"sans-serif"}),Yo=computed(()=>{var ra,ea;return(ea=(ra=$n.font)===null||ra===void 0?void 0:ra.color)!==null&&ea!==void 0?ea:In.value.colorFill}),qo=computed(()=>{var ra;const ea={zIndex:(ra=$n.zIndex)!==null&&ra!==void 0?ra:9,position:"absolute",left:0,top:0,width:"100%",height:"100%",pointerEvents:"none",backgroundRepeat:"repeat"};let la=zn.value-Bn.value,ua=Wn.value-Hn.value;return la>0&&(ea.left=`${la}px`,ea.width=`calc(100% - ${la}px)`,la=0),ua>0&&(ea.top=`${ua}px`,ea.height=`calc(100% - ${ua}px)`,ua=0),ea.backgroundPosition=`${la}px ${ua}px`,ea}),Jo=()=>{Rn.value&&(Rn.value.remove(),Rn.value=void 0)},Zo=(ra,ea)=>{var la;Nn.value&&Rn.value&&(Dn.value=!0,Rn.value.setAttribute("style",getStyleStr(_extends$1(_extends$1({},qo.value),{backgroundImage:`url('${ra}')`,backgroundSize:`${(Ln.value+ea)*BaseSize}px`}))),(la=Nn.value)===null||la===void 0||la.append(Rn.value),setTimeout(()=>{Dn.value=!1}))},rr=ra=>{let ea=120,la=64;const ua=$n.content,ga=$n.image,aa=$n.width,ca=$n.height;if(!ga&&ra.measureText){ra.font=`${Number(Yn.value)}px ${Xn.value}`;const sa=Array.isArray(ua)?ua:[ua],ia=sa.map(fa=>ra.measureText(fa).width);ea=Math.ceil(Math.max(...ia)),la=Number(Yn.value)*sa.length+(sa.length-1)*FontGap}return[aa??ea,ca??la]},nr=(ra,ea,la,ua,ga)=>{const aa=getPixelRatio(),ca=$n.content,sa=Number(Yn.value)*aa;ra.font=`${Go.value} normal ${Gn.value} ${sa}px/${ga}px ${Xn.value}`,ra.fillStyle=Yo.value,ra.textAlign="center",ra.textBaseline="top",ra.translate(ua/2,0);const ia=Array.isArray(ca)?ca:[ca];ia==null||ia.forEach((fa,ma)=>{ra.fillText(fa??"",ea,la+ma*(sa+FontGap*aa))})},ta=()=>{var ra;const ea=document.createElement("canvas"),la=ea.getContext("2d"),ua=$n.image,ga=(ra=$n.rotate)!==null&&ra!==void 0?ra:-22;if(la){Rn.value||(Rn.value=document.createElement("div"));const aa=getPixelRatio(),[ca,sa]=rr(la),ia=(Ln.value+ca)*aa,fa=(Fn.value+sa)*aa;ea.setAttribute("width",`${ia*BaseSize}px`),ea.setAttribute("height",`${fa*BaseSize}px`);const ma=Ln.value*aa/2,ya=Fn.value*aa/2,ba=ca*aa,Ia=sa*aa,Ea=(ba+Ln.value*aa)/2,xa=(Ia+Fn.value*aa)/2,Ta=ma+ia,wa=ya+fa,La=Ea+ia,Na=xa+fa;if(la.save(),rotateWatermark(la,Ea,xa,ga),ua){const $a=new Image;$a.onload=()=>{la.drawImage($a,ma,ya,ba,Ia),la.restore(),rotateWatermark(la,La,Na,ga),la.drawImage($a,Ta,wa,ba,Ia),Zo(ea.toDataURL(),ca)},$a.crossOrigin="anonymous",$a.referrerPolicy="no-referrer",$a.src=ua}else nr(la,ma,ya,ba,Ia),la.restore(),rotateWatermark(la,La,Na,ga),nr(la,Ta,wa,ba,Ia),Zo(ea.toDataURL(),ca)}};return onMounted(()=>{ta()}),watch(()=>[$n,In.value.colorFill,In.value.fontSizeLG],()=>{ta()},{deep:!0,flush:"post"}),onBeforeUnmount(()=>{Jo()}),useMutationObserver(Nn,ra=>{Dn.value||ra.forEach(ea=>{reRendering(ea,Rn.value)&&(Jo(),ta())})},{attributes:!0,subtree:!0,childList:!0,attributeFilter:["style","class"]}),()=>{var ra;return createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{ref:Nn,class:[Pn.class,$n.rootClassName],style:[{position:"relative"},Pn.style]}),[(ra=_n.default)===null||ra===void 0?void 0:ra.call(_n)])}}}),index$4=withInstall(Watermark);function getItemDisabledStyle($n,Cn){return{[`${$n}, ${$n}:hover, ${$n}:focus`]:{color:Cn.colorTextDisabled,cursor:"not-allowed"}}}function getItemSelectedStyle($n){return{backgroundColor:$n.bgColorSelected,boxShadow:$n.boxShadow}}const segmentedTextEllipsisCss=_extends$1({overflow:"hidden"},textEllipsis),genSegmentedStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1(_extends$1(_extends$1(_extends$1({},resetComponent($n)),{display:"inline-block",padding:$n.segmentedContainerPadding,color:$n.labelColor,backgroundColor:$n.bgColor,borderRadius:$n.borderRadius,transition:`all ${$n.motionDurationMid} ${$n.motionEaseInOut}`,[`${Cn}-group`]:{position:"relative",display:"flex",alignItems:"stretch",justifyItems:"flex-start",width:"100%"},[`&${Cn}-rtl`]:{direction:"rtl"},[`&${Cn}-block`]:{display:"flex"},[`&${Cn}-block ${Cn}-item`]:{flex:1,minWidth:0},[`${Cn}-item`]:{position:"relative",textAlign:"center",cursor:"pointer",transition:`color ${$n.motionDurationMid} ${$n.motionEaseInOut}`,borderRadius:$n.borderRadiusSM,"&-selected":_extends$1(_extends$1({},getItemSelectedStyle($n)),{color:$n.labelColorHover}),"&::after":{content:'""',position:"absolute",width:"100%",height:"100%",top:0,insetInlineStart:0,borderRadius:"inherit",transition:`background-color ${$n.motionDurationMid}`,pointerEvents:"none"},[`&:hover:not(${Cn}-item-selected):not(${Cn}-item-disabled)`]:{color:$n.labelColorHover,"&::after":{backgroundColor:$n.bgColorHover}},"&-label":_extends$1({minHeight:$n.controlHeight-$n.segmentedContainerPadding*2,lineHeight:`${$n.controlHeight-$n.segmentedContainerPadding*2}px`,padding:`0 ${$n.segmentedPaddingHorizontal}px`},segmentedTextEllipsisCss),"&-icon + *":{marginInlineStart:$n.marginSM/2},"&-input":{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:0,opacity:0,pointerEvents:"none"}},[`${Cn}-thumb`]:_extends$1(_extends$1({},getItemSelectedStyle($n)),{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:"100%",padding:`${$n.paddingXXS}px 0`,borderRadius:$n.borderRadiusSM,[`& ~ ${Cn}-item:not(${Cn}-item-selected):not(${Cn}-item-disabled)::after`]:{backgroundColor:"transparent"}}),[`&${Cn}-lg`]:{borderRadius:$n.borderRadiusLG,[`${Cn}-item-label`]:{minHeight:$n.controlHeightLG-$n.segmentedContainerPadding*2,lineHeight:`${$n.controlHeightLG-$n.segmentedContainerPadding*2}px`,padding:`0 ${$n.segmentedPaddingHorizontal}px`,fontSize:$n.fontSizeLG},[`${Cn}-item, ${Cn}-thumb`]:{borderRadius:$n.borderRadius}},[`&${Cn}-sm`]:{borderRadius:$n.borderRadiusSM,[`${Cn}-item-label`]:{minHeight:$n.controlHeightSM-$n.segmentedContainerPadding*2,lineHeight:`${$n.controlHeightSM-$n.segmentedContainerPadding*2}px`,padding:`0 ${$n.segmentedPaddingHorizontalSM}px`},[`${Cn}-item, ${Cn}-thumb`]:{borderRadius:$n.borderRadiusXS}}}),getItemDisabledStyle(`&-disabled ${Cn}-item`,$n)),getItemDisabledStyle(`${Cn}-item-disabled`,$n)),{[`${Cn}-thumb-motion-appear-active`]:{transition:`transform ${$n.motionDurationSlow} ${$n.motionEaseInOut}, width ${$n.motionDurationSlow} ${$n.motionEaseInOut}`,willChange:"transform, width"}})}},useStyle$4=genComponentStyleHook("Segmented",$n=>{const{lineWidthBold:Cn,lineWidth:_n,colorTextLabel:Pn,colorText:In,colorFillSecondary:Nn,colorBgLayout:Rn,colorBgElevated:Dn}=$n,Ln=merge$1($n,{segmentedPaddingHorizontal:$n.controlPaddingHorizontal-_n,segmentedPaddingHorizontalSM:$n.controlPaddingHorizontalSM-_n,segmentedContainerPadding:Cn,labelColor:Pn,labelColorHover:In,bgColor:Rn,bgColorHover:Nn,bgColorSelected:Dn});return[genSegmentedStyle(Ln)]}),calcThumbStyle=$n=>$n?{left:$n.offsetLeft,right:$n.parentElement.clientWidth-$n.clientWidth-$n.offsetLeft,width:$n.clientWidth}:null,toPX=$n=>$n!==void 0?`${$n}px`:void 0,MotionThumb=defineComponent({props:{value:anyType(),getValueIndex:anyType(),prefixCls:anyType(),motionName:anyType(),onMotionStart:anyType(),onMotionEnd:anyType(),direction:anyType(),containerRef:anyType()},emits:["motionStart","motionEnd"],setup($n,Cn){let{emit:_n}=Cn;const Pn=ref(),In=Yn=>{var Gn;const Go=$n.getValueIndex(Yn),Xn=(Gn=$n.containerRef.value)===null||Gn===void 0?void 0:Gn.querySelectorAll(`.${$n.prefixCls}-item`)[Go];return(Xn==null?void 0:Xn.offsetParent)&&Xn},Nn=ref(null),Rn=ref(null);watch(()=>$n.value,(Yn,Gn)=>{const Go=In(Gn),Xn=In(Yn),Yo=calcThumbStyle(Go),qo=calcThumbStyle(Xn);Nn.value=Yo,Rn.value=qo,_n(Go&&Xn?"motionStart":"motionEnd")},{flush:"post"});const Dn=computed(()=>{var Yn,Gn;return $n.direction==="rtl"?toPX(-((Yn=Nn.value)===null||Yn===void 0?void 0:Yn.right)):toPX((Gn=Nn.value)===null||Gn===void 0?void 0:Gn.left)}),Ln=computed(()=>{var Yn,Gn;return $n.direction==="rtl"?toPX(-((Yn=Rn.value)===null||Yn===void 0?void 0:Yn.right)):toPX((Gn=Rn.value)===null||Gn===void 0?void 0:Gn.left)});let Fn;const Bn=Yn=>{clearTimeout(Fn),nextTick(()=>{Yn&&(Yn.style.transform="translateX(var(--thumb-start-left))",Yn.style.width="var(--thumb-start-width)")})},Hn=Yn=>{Fn=setTimeout(()=>{Yn&&(addClass(Yn,`${$n.motionName}-appear-active`),Yn.style.transform="translateX(var(--thumb-active-left))",Yn.style.width="var(--thumb-active-width)")})},zn=Yn=>{Nn.value=null,Rn.value=null,Yn&&(Yn.style.transform=null,Yn.style.width=null,removeClass(Yn,`${$n.motionName}-appear-active`)),_n("motionEnd")},Wn=computed(()=>{var Yn,Gn;return{"--thumb-start-left":Dn.value,"--thumb-start-width":toPX((Yn=Nn.value)===null||Yn===void 0?void 0:Yn.width),"--thumb-active-left":Ln.value,"--thumb-active-width":toPX((Gn=Rn.value)===null||Gn===void 0?void 0:Gn.width)}});return onBeforeUnmount(()=>{clearTimeout(Fn)}),()=>{const Yn={ref:Pn,style:Wn.value,class:[`${$n.prefixCls}-thumb`]};return createVNode(Transition,{appear:!0,onBeforeEnter:Bn,onEnter:Hn,onAfterEnter:zn},{default:()=>[!Nn.value||!Rn.value?null:createVNode("div",Yn,null)]})}}}),MotionThumb$1=MotionThumb;function normalizeOptions($n){return $n.map(Cn=>typeof Cn=="object"&&Cn!==null?Cn:{label:Cn==null?void 0:Cn.toString(),title:Cn==null?void 0:Cn.toString(),value:Cn})}const segmentedProps=()=>({prefixCls:String,options:arrayType(),block:booleanType(),disabled:booleanType(),size:stringType(),value:_extends$1(_extends$1({},someType([String,Number])),{required:!0}),motionName:String,onChange:functionType(),"onUpdate:value":functionType()}),SegmentedOption=($n,Cn)=>{let{slots:_n,emit:Pn}=Cn;const{value:In,disabled:Nn,payload:Rn,title:Dn,prefixCls:Ln,label:Fn=_n.label,checked:Bn,className:Hn}=$n,zn=Wn=>{Nn||Pn("change",Wn,In)};return createVNode("label",{class:classNames({[`${Ln}-item-disabled`]:Nn},Hn)},[createVNode("input",{class:`${Ln}-item-input`,type:"radio",disabled:Nn,checked:Bn,onChange:zn},null),createVNode("div",{class:`${Ln}-item-label`,title:typeof Dn=="string"?Dn:""},[typeof Fn=="function"?Fn({value:In,disabled:Nn,payload:Rn,title:Dn}):Fn??In])])};SegmentedOption.inheritAttrs=!1;const Segmented=defineComponent({name:"ASegmented",inheritAttrs:!1,props:initDefaultProps(segmentedProps(),{options:[],motionName:"thumb-motion"}),slots:Object,setup($n,Cn){let{emit:_n,slots:Pn,attrs:In}=Cn;const{prefixCls:Nn,direction:Rn,size:Dn}=useConfigInject("segmented",$n),[Ln,Fn]=useStyle$4(Nn),Bn=shallowRef(),Hn=shallowRef(!1),zn=computed(()=>normalizeOptions($n.options)),Wn=(Yn,Gn)=>{$n.disabled||(_n("update:value",Gn),_n("change",Gn))};return()=>{const Yn=Nn.value;return Ln(createVNode("div",_objectSpread2$1(_objectSpread2$1({},In),{},{class:classNames(Yn,{[Fn.value]:!0,[`${Yn}-block`]:$n.block,[`${Yn}-disabled`]:$n.disabled,[`${Yn}-lg`]:Dn.value=="large",[`${Yn}-sm`]:Dn.value=="small",[`${Yn}-rtl`]:Rn.value==="rtl"},In.class),ref:Bn}),[createVNode("div",{class:`${Yn}-group`},[createVNode(MotionThumb$1,{containerRef:Bn,prefixCls:Yn,value:$n.value,motionName:`${Yn}-${$n.motionName}`,direction:Rn.value,getValueIndex:Gn=>zn.value.findIndex(Go=>Go.value===Gn),onMotionStart:()=>{Hn.value=!0},onMotionEnd:()=>{Hn.value=!1}},null),zn.value.map(Gn=>createVNode(SegmentedOption,_objectSpread2$1(_objectSpread2$1({key:Gn.value,prefixCls:Yn,checked:Gn.value===$n.value,onChange:Wn},Gn),{},{className:classNames(Gn.className,`${Yn}-item`,{[`${Yn}-item-selected`]:Gn.value===$n.value&&!Hn.value}),disabled:!!$n.disabled||!!Gn.disabled}),Pn))])]))}}}),index$3=withInstall(Segmented),genQRCodeStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{display:"flex",justifyContent:"center",alignItems:"center",padding:$n.paddingSM,backgroundColor:$n.colorWhite,borderRadius:$n.borderRadiusLG,border:`${$n.lineWidth}px ${$n.lineType} ${$n.colorSplit}`,position:"relative",width:"100%",height:"100%",overflow:"hidden",[`& > ${Cn}-mask`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,zIndex:10,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",width:"100%",height:"100%",color:$n.colorText,lineHeight:$n.lineHeight,background:$n.QRCodeMaskBackgroundColor,textAlign:"center",[`& > ${Cn}-expired , & > ${Cn}-scanned`]:{color:$n.QRCodeTextColor}},"&-icon":{marginBlockEnd:$n.marginXS,fontSize:$n.controlHeight}}),[`${Cn}-borderless`]:{borderColor:"transparent"}}},useStyle$3=genComponentStyleHook("QRCode",$n=>genQRCodeStyle(merge$1($n,{QRCodeTextColor:"rgba(0, 0, 0, 0.88)",QRCodeMaskBackgroundColor:"rgba(255, 255, 255, 0.96)"})));var ReloadOutlined$2={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};const ReloadOutlinedSvg=ReloadOutlined$2;function _objectSpread($n){for(var Cn=1;Cn({size:{type:Number,default:160},value:{type:String,required:!0},type:stringType("canvas"),color:String,bgColor:String,includeMargin:Boolean,imageSettings:objectType()}),qrcodeProps=()=>_extends$1(_extends$1({},qrProps()),{errorLevel:stringType("M"),icon:String,iconSize:{type:Number,default:40},status:stringType("active"),bordered:{type:Boolean,default:!0}});/** - * @license QR Code generator library (TypeScript) - * Copyright (c) Project Nayuki. - * SPDX-License-Identifier: MIT - */var qrcodegen;(function($n){class Cn{static encodeText(Dn,Ln){const Fn=$n.QrSegment.makeSegments(Dn);return Cn.encodeSegments(Fn,Ln)}static encodeBinary(Dn,Ln){const Fn=$n.QrSegment.makeBytes(Dn);return Cn.encodeSegments([Fn],Ln)}static encodeSegments(Dn,Ln){let Fn=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,Bn=arguments.length>3&&arguments[3]!==void 0?arguments[3]:40,Hn=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1,zn=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;if(!(Cn.MIN_VERSION<=Fn&&Fn<=Bn&&Bn<=Cn.MAX_VERSION)||Hn<-1||Hn>7)throw new RangeError("Invalid value");let Wn,Yn;for(Wn=Fn;;Wn++){const Yo=Cn.getNumDataCodewords(Wn,Ln)*8,qo=Nn.getTotalBits(Dn,Wn);if(qo<=Yo){Yn=qo;break}if(Wn>=Bn)throw new RangeError("Data too long")}for(const Yo of[Cn.Ecc.MEDIUM,Cn.Ecc.QUARTILE,Cn.Ecc.HIGH])zn&&Yn<=Cn.getNumDataCodewords(Wn,Yo)*8&&(Ln=Yo);const Gn=[];for(const Yo of Dn){_n(Yo.mode.modeBits,4,Gn),_n(Yo.numChars,Yo.mode.numCharCountBits(Wn),Gn);for(const qo of Yo.getData())Gn.push(qo)}In(Gn.length==Yn);const Go=Cn.getNumDataCodewords(Wn,Ln)*8;In(Gn.length<=Go),_n(0,Math.min(4,Go-Gn.length),Gn),_n(0,(8-Gn.length%8)%8,Gn),In(Gn.length%8==0);for(let Yo=236;Gn.lengthXn[qo>>>3]|=Yo<<7-(qo&7)),new Cn(Wn,Ln,Xn,Hn)}constructor(Dn,Ln,Fn,Bn){if(this.version=Dn,this.errorCorrectionLevel=Ln,this.modules=[],this.isFunction=[],DnCn.MAX_VERSION)throw new RangeError("Version value out of range");if(Bn<-1||Bn>7)throw new RangeError("Mask value out of range");this.size=Dn*4+17;const Hn=[];for(let Wn=0;Wn>>9)*1335;const Bn=(Ln<<10|Fn)^21522;In(Bn>>>15==0);for(let Hn=0;Hn<=5;Hn++)this.setFunctionModule(8,Hn,Pn(Bn,Hn));this.setFunctionModule(8,7,Pn(Bn,6)),this.setFunctionModule(8,8,Pn(Bn,7)),this.setFunctionModule(7,8,Pn(Bn,8));for(let Hn=9;Hn<15;Hn++)this.setFunctionModule(14-Hn,8,Pn(Bn,Hn));for(let Hn=0;Hn<8;Hn++)this.setFunctionModule(this.size-1-Hn,8,Pn(Bn,Hn));for(let Hn=8;Hn<15;Hn++)this.setFunctionModule(8,this.size-15+Hn,Pn(Bn,Hn));this.setFunctionModule(8,this.size-8,!0)}drawVersion(){if(this.version<7)return;let Dn=this.version;for(let Fn=0;Fn<12;Fn++)Dn=Dn<<1^(Dn>>>11)*7973;const Ln=this.version<<12|Dn;In(Ln>>>18==0);for(let Fn=0;Fn<18;Fn++){const Bn=Pn(Ln,Fn),Hn=this.size-11+Fn%3,zn=Math.floor(Fn/3);this.setFunctionModule(Hn,zn,Bn),this.setFunctionModule(zn,Hn,Bn)}}drawFinderPattern(Dn,Ln){for(let Fn=-4;Fn<=4;Fn++)for(let Bn=-4;Bn<=4;Bn++){const Hn=Math.max(Math.abs(Bn),Math.abs(Fn)),zn=Dn+Bn,Wn=Ln+Fn;0<=zn&&zn{(Yo!=Yn-Hn||Jo>=Wn)&&Xn.push(qo[Yo])});return In(Xn.length==zn),Xn}drawCodewords(Dn){if(Dn.length!=Math.floor(Cn.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");let Ln=0;for(let Fn=this.size-1;Fn>=1;Fn-=2){Fn==6&&(Fn=5);for(let Bn=0;Bn>>3],7-(Ln&7)),Ln++)}}In(Ln==Dn.length*8)}applyMask(Dn){if(Dn<0||Dn>7)throw new RangeError("Mask value out of range");for(let Ln=0;Ln5&&Dn++):(this.finderPenaltyAddHistory(Wn,Yn),zn||(Dn+=this.finderPenaltyCountPatterns(Yn)*Cn.PENALTY_N3),zn=this.modules[Hn][Gn],Wn=1);Dn+=this.finderPenaltyTerminateAndCount(zn,Wn,Yn)*Cn.PENALTY_N3}for(let Hn=0;Hn5&&Dn++):(this.finderPenaltyAddHistory(Wn,Yn),zn||(Dn+=this.finderPenaltyCountPatterns(Yn)*Cn.PENALTY_N3),zn=this.modules[Gn][Hn],Wn=1);Dn+=this.finderPenaltyTerminateAndCount(zn,Wn,Yn)*Cn.PENALTY_N3}for(let Hn=0;Hnzn+(Wn?1:0),Ln);const Fn=this.size*this.size,Bn=Math.ceil(Math.abs(Ln*20-Fn*10)/Fn)-1;return In(0<=Bn&&Bn<=9),Dn+=Bn*Cn.PENALTY_N4,In(0<=Dn&&Dn<=2568888),Dn}getAlignmentPatternPositions(){if(this.version==1)return[];{const Dn=Math.floor(this.version/7)+2,Ln=this.version==32?26:Math.ceil((this.version*4+4)/(Dn*2-2))*2,Fn=[6];for(let Bn=this.size-7;Fn.lengthCn.MAX_VERSION)throw new RangeError("Version number out of range");let Ln=(16*Dn+128)*Dn+64;if(Dn>=2){const Fn=Math.floor(Dn/7)+2;Ln-=(25*Fn-10)*Fn-55,Dn>=7&&(Ln-=36)}return In(208<=Ln&&Ln<=29648),Ln}static getNumDataCodewords(Dn,Ln){return Math.floor(Cn.getNumRawDataModules(Dn)/8)-Cn.ECC_CODEWORDS_PER_BLOCK[Ln.ordinal][Dn]*Cn.NUM_ERROR_CORRECTION_BLOCKS[Ln.ordinal][Dn]}static reedSolomonComputeDivisor(Dn){if(Dn<1||Dn>255)throw new RangeError("Degree out of range");const Ln=[];for(let Bn=0;Bn0);for(const Bn of Dn){const Hn=Bn^Fn.shift();Fn.push(0),Ln.forEach((zn,Wn)=>Fn[Wn]^=Cn.reedSolomonMultiply(zn,Hn))}return Fn}static reedSolomonMultiply(Dn,Ln){if(Dn>>>8||Ln>>>8)throw new RangeError("Byte out of range");let Fn=0;for(let Bn=7;Bn>=0;Bn--)Fn=Fn<<1^(Fn>>>7)*285,Fn^=(Ln>>>Bn&1)*Dn;return In(Fn>>>8==0),Fn}finderPenaltyCountPatterns(Dn){const Ln=Dn[1];In(Ln<=this.size*3);const Fn=Ln>0&&Dn[2]==Ln&&Dn[3]==Ln*3&&Dn[4]==Ln&&Dn[5]==Ln;return(Fn&&Dn[0]>=Ln*4&&Dn[6]>=Ln?1:0)+(Fn&&Dn[6]>=Ln*4&&Dn[0]>=Ln?1:0)}finderPenaltyTerminateAndCount(Dn,Ln,Fn){return Dn&&(this.finderPenaltyAddHistory(Ln,Fn),Ln=0),Ln+=this.size,this.finderPenaltyAddHistory(Ln,Fn),this.finderPenaltyCountPatterns(Fn)}finderPenaltyAddHistory(Dn,Ln){Ln[0]==0&&(Dn+=this.size),Ln.pop(),Ln.unshift(Dn)}}Cn.MIN_VERSION=1,Cn.MAX_VERSION=40,Cn.PENALTY_N1=3,Cn.PENALTY_N2=3,Cn.PENALTY_N3=40,Cn.PENALTY_N4=10,Cn.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],Cn.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],$n.QrCode=Cn;function _n(Rn,Dn,Ln){if(Dn<0||Dn>31||Rn>>>Dn)throw new RangeError("Value out of range");for(let Fn=Dn-1;Fn>=0;Fn--)Ln.push(Rn>>>Fn&1)}function Pn(Rn,Dn){return(Rn>>>Dn&1)!=0}function In(Rn){if(!Rn)throw new Error("Assertion error")}class Nn{static makeBytes(Dn){const Ln=[];for(const Fn of Dn)_n(Fn,8,Ln);return new Nn(Nn.Mode.BYTE,Dn.length,Ln)}static makeNumeric(Dn){if(!Nn.isNumeric(Dn))throw new RangeError("String contains non-numeric characters");const Ln=[];for(let Fn=0;Fn=1<1&&arguments[1]!==void 0?arguments[1]:0;const _n=[];return $n.forEach(function(Pn,In){let Nn=null;Pn.forEach(function(Rn,Dn){if(!Rn&&Nn!==null){_n.push(`M${Nn+Cn} ${In+Cn}h${Dn-Nn}v1H${Nn+Cn}z`),Nn=null;return}if(Dn===Pn.length-1){if(!Rn)return;Nn===null?_n.push(`M${Dn+Cn},${In+Cn} h1v1H${Dn+Cn}z`):_n.push(`M${Nn+Cn},${In+Cn} h${Dn+1-Nn}v1H${Nn+Cn}z`);return}Rn&&Nn===null&&(Nn=Dn)})}),_n.join("")}function excavateModules($n,Cn){return $n.slice().map((_n,Pn)=>Pn=Cn.y+Cn.h?_n:_n.map((In,Nn)=>Nn=Cn.x+Cn.w?In:!1))}function getImageSettings($n,Cn,_n,Pn){if(Pn==null)return null;const In=$n.length+_n*2,Nn=Math.floor(Cn*DEFAULT_IMG_SCALE),Rn=In/Cn,Dn=(Pn.width||Nn)*Rn,Ln=(Pn.height||Nn)*Rn,Fn=Pn.x==null?$n.length/2-Dn/2:Pn.x*Rn,Bn=Pn.y==null?$n.length/2-Ln/2:Pn.y*Rn;let Hn=null;if(Pn.excavate){const zn=Math.floor(Fn),Wn=Math.floor(Bn),Yn=Math.ceil(Dn+Fn-zn),Gn=Math.ceil(Ln+Bn-Wn);Hn={x:zn,y:Wn,w:Yn,h:Gn}}return{x:Fn,y:Bn,h:Ln,w:Dn,excavation:Hn}}function getMarginSize($n,Cn){return Cn!=null?Math.floor(Cn):$n?SPEC_MARGIN_SIZE:DEFAULT_MARGIN_SIZE}const SUPPORTS_PATH2D=function(){try{new Path2D().addPath(new Path2D)}catch{return!1}return!0}(),QRCodeCanvas=defineComponent({name:"QRCodeCanvas",inheritAttrs:!1,props:_extends$1(_extends$1({},qrProps()),{level:String,bgColor:String,fgColor:String,marginSize:Number}),setup($n,Cn){let{attrs:_n,expose:Pn}=Cn;const In=computed(()=>{var Ln;return(Ln=$n.imageSettings)===null||Ln===void 0?void 0:Ln.src}),Nn=shallowRef(null),Rn=shallowRef(null),Dn=shallowRef(!1);return Pn({toDataURL:(Ln,Fn)=>{var Bn;return(Bn=Nn.value)===null||Bn===void 0?void 0:Bn.toDataURL(Ln,Fn)}}),watchEffect(()=>{const{value:Ln,size:Fn=DEFAULT_SIZE,level:Bn=DEFAULT_LEVEL,bgColor:Hn=DEFAULT_BGCOLOR,fgColor:zn=DEFAULT_FGCOLOR,includeMargin:Wn=DEFAULT_INCLUDEMARGIN,marginSize:Yn,imageSettings:Gn}=$n;if(Nn.value!=null){const Go=Nn.value,Xn=Go.getContext("2d");if(!Xn)return;let Yo=qrcodegen$1.QrCode.encodeText(Ln,ERROR_LEVEL_MAP[Bn]).getModules();const qo=getMarginSize(Wn,Yn),Jo=Yo.length+qo*2,Zo=getImageSettings(Yo,Fn,qo,Gn),rr=Rn.value,nr=Dn.value&&Zo!=null&&rr!==null&&rr.complete&&rr.naturalHeight!==0&&rr.naturalWidth!==0;nr&&Zo.excavation!=null&&(Yo=excavateModules(Yo,Zo.excavation));const ta=window.devicePixelRatio||1;Go.height=Go.width=Fn*ta;const oa=Fn/Jo*ta;Xn.scale(oa,oa),Xn.fillStyle=Hn,Xn.fillRect(0,0,Jo,Jo),Xn.fillStyle=zn,SUPPORTS_PATH2D?Xn.fill(new Path2D(generatePath(Yo,qo))):Yo.forEach(function(ra,ea){ra.forEach(function(la,ua){la&&Xn.fillRect(ua+qo,ea+qo,1,1)})}),nr&&Xn.drawImage(rr,Zo.x+qo,Zo.y+qo,Zo.w,Zo.h)}},{flush:"post"}),watch(In,()=>{Dn.value=!1}),()=>{var Ln;const Fn=(Ln=$n.size)!==null&&Ln!==void 0?Ln:DEFAULT_SIZE,Bn={height:`${Fn}px`,width:`${Fn}px`};let Hn=null;return In.value!=null&&(Hn=createVNode("img",{src:In.value,key:In.value,style:{display:"none"},onLoad:()=>{Dn.value=!0},ref:Rn},null)),createVNode(Fragment,null,[createVNode("canvas",_objectSpread2$1(_objectSpread2$1({},_n),{},{style:[Bn,_n.style],ref:Nn}),null),Hn])}}}),QRCodeSVG=defineComponent({name:"QRCodeSVG",inheritAttrs:!1,props:_extends$1(_extends$1({},qrProps()),{color:String,level:String,bgColor:String,fgColor:String,marginSize:Number,title:String}),setup($n){let Cn=null,_n=null,Pn=null,In=null,Nn=null,Rn=null;return watchEffect(()=>{const{value:Dn,size:Ln=DEFAULT_SIZE,level:Fn=DEFAULT_LEVEL,includeMargin:Bn=DEFAULT_INCLUDEMARGIN,marginSize:Hn,imageSettings:zn}=$n;Cn=qrcodegen$1.QrCode.encodeText(Dn,ERROR_LEVEL_MAP[Fn]).getModules(),_n=getMarginSize(Bn,Hn),Pn=Cn.length+_n*2,In=getImageSettings(Cn,Ln,_n,zn),zn!=null&&In!=null&&(In.excavation!=null&&(Cn=excavateModules(Cn,In.excavation)),Rn=createVNode("image",{"xlink:href":zn.src,height:In.h,width:In.w,x:In.x+_n,y:In.y+_n,preserveAspectRatio:"none"},null)),Nn=generatePath(Cn,_n)}),()=>{const Dn=$n.bgColor&&DEFAULT_BGCOLOR,Ln=$n.fgColor&&DEFAULT_FGCOLOR;return createVNode("svg",{height:$n.size,width:$n.size,viewBox:`0 0 ${Pn} ${Pn}`},[!!$n.title&&createVNode("title",null,[$n.title]),createVNode("path",{fill:Dn,d:`M0,0 h${Pn}v${Pn}H0z`,"shape-rendering":"crispEdges"},null),createVNode("path",{fill:Ln,d:Nn,"shape-rendering":"crispEdges"},null),Rn])}}}),QRCode=defineComponent({name:"AQrcode",inheritAttrs:!1,props:qrcodeProps(),emits:["refresh"],setup($n,Cn){let{emit:_n,attrs:Pn,expose:In}=Cn;const[Nn]=useLocaleReceiver("QRCode"),{prefixCls:Rn}=useConfigInject("qrcode",$n),[Dn,Ln]=useStyle$3(Rn),[,Fn]=useToken(),Bn=ref();In({toDataURL:(zn,Wn)=>{var Yn;return(Yn=Bn.value)===null||Yn===void 0?void 0:Yn.toDataURL(zn,Wn)}});const Hn=computed(()=>{const{value:zn,icon:Wn="",size:Yn=160,iconSize:Gn=40,color:Go=Fn.value.colorText,bgColor:Xn="transparent",errorLevel:Yo="M"}=$n,qo={src:Wn,x:void 0,y:void 0,height:Gn,width:Gn,excavate:!0};return{value:zn,size:Yn-(Fn.value.paddingSM+Fn.value.lineWidth)*2,level:Yo,bgColor:Xn,fgColor:Go,imageSettings:Wn?qo:void 0}});return()=>{const zn=Rn.value;return Dn(createVNode("div",_objectSpread2$1(_objectSpread2$1({},Pn),{},{style:[Pn.style,{width:`${$n.size}px`,height:`${$n.size}px`,backgroundColor:Hn.value.bgColor}],class:[Ln.value,zn,{[`${zn}-borderless`]:!$n.bordered}]}),[$n.status!=="active"&&createVNode("div",{class:`${zn}-mask`},[$n.status==="loading"&&createVNode(Spin,null,null),$n.status==="expired"&&createVNode(Fragment,null,[createVNode("p",{class:`${zn}-expired`},[Nn.value.expired]),createVNode(Button$1,{type:"link",onClick:Wn=>_n("refresh",Wn)},{default:()=>[Nn.value.refresh],icon:()=>createVNode(ReloadOutlined$1,null,null)})]),$n.status==="scanned"&&createVNode("p",{class:`${zn}-scanned`},[Nn.value.scanned])]),$n.type==="canvas"?createVNode(QRCodeCanvas,_objectSpread2$1({ref:Bn},Hn.value),null):createVNode(QRCodeSVG,Hn.value,null)]))}}}),index$2=withInstall(QRCode);function isInViewPort($n){const Cn=window.innerWidth||document.documentElement.clientWidth,_n=window.innerHeight||document.documentElement.clientHeight,{top:Pn,right:In,bottom:Nn,left:Rn}=$n.getBoundingClientRect();return Pn>=0&&Rn>=0&&In<=Cn&&Nn<=_n}function useTarget($n,Cn,_n,Pn){const[In,Nn]=useState(void 0);watchEffect(()=>{const Bn=typeof $n.value=="function"?$n.value():$n.value;Nn(Bn||null)},{flush:"post"});const[Rn,Dn]=useState(null),Ln=()=>{if(!Cn.value){Dn(null);return}if(In.value){!isInViewPort(In.value)&&Cn.value&&In.value.scrollIntoView(Pn.value);const{left:Bn,top:Hn,width:zn,height:Wn}=In.value.getBoundingClientRect(),Yn={left:Bn,top:Hn,width:zn,height:Wn,radius:0};JSON.stringify(Rn.value)!==JSON.stringify(Yn)&&Dn(Yn)}else Dn(null)};return onMounted(()=>{watch([Cn,In],()=>{Ln()},{flush:"post",immediate:!0}),window.addEventListener("resize",Ln)}),onBeforeUnmount(()=>{window.removeEventListener("resize",Ln)}),[computed(()=>{var Bn,Hn;if(!Rn.value)return Rn.value;const zn=((Bn=_n.value)===null||Bn===void 0?void 0:Bn.offset)||6,Wn=((Hn=_n.value)===null||Hn===void 0?void 0:Hn.radius)||2;return{left:Rn.value.left-zn,top:Rn.value.top-zn,width:Rn.value.width+zn*2,height:Rn.value.height+zn*2,radius:Wn}}),In]}const tourStepInfo=()=>({arrow:someType([Boolean,Object]),target:someType([String,Function,Object]),title:someType([String,Object]),description:someType([String,Object]),placement:stringType(),mask:someType([Object,Boolean],!0),className:{type:String},style:objectType(),scrollIntoViewOptions:someType([Boolean,Object])}),tourStepProps$1=()=>_extends$1(_extends$1({},tourStepInfo()),{prefixCls:{type:String},total:{type:Number},current:{type:Number},onClose:functionType(),onFinish:functionType(),renderPanel:functionType(),onPrev:functionType(),onNext:functionType()}),DefaultPanel=defineComponent({name:"DefaultPanel",inheritAttrs:!1,props:tourStepProps$1(),setup($n,Cn){let{attrs:_n}=Cn;return()=>{const{prefixCls:Pn,current:In,total:Nn,title:Rn,description:Dn,onClose:Ln,onPrev:Fn,onNext:Bn,onFinish:Hn}=$n;return createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{class:classNames(`${Pn}-content`,_n.class)}),[createVNode("div",{class:`${Pn}-inner`},[createVNode("button",{type:"button",onClick:Ln,"aria-label":"Close",class:`${Pn}-close`},[createVNode("span",{class:`${Pn}-close-x`},[createTextVNode("×")])]),createVNode("div",{class:`${Pn}-header`},[createVNode("div",{class:`${Pn}-title`},[Rn])]),createVNode("div",{class:`${Pn}-description`},[Dn]),createVNode("div",{class:`${Pn}-footer`},[createVNode("div",{class:`${Pn}-sliders`},[Nn>1?[...Array.from({length:Nn}).keys()].map((zn,Wn)=>createVNode("span",{key:zn,class:Wn===In?"active":""},null)):null]),createVNode("div",{class:`${Pn}-buttons`},[In!==0?createVNode("button",{class:`${Pn}-prev-btn`,onClick:Fn},[createTextVNode("Prev")]):null,In===Nn-1?createVNode("button",{class:`${Pn}-finish-btn`,onClick:Hn},[createTextVNode("Finish")]):createVNode("button",{class:`${Pn}-next-btn`,onClick:Bn},[createTextVNode("Next")])])])])])}}}),DefaultPanel$1=DefaultPanel,TourStep=defineComponent({name:"TourStep",inheritAttrs:!1,props:tourStepProps$1(),setup($n,Cn){let{attrs:_n}=Cn;return()=>{const{current:Pn,renderPanel:In}=$n;return createVNode(Fragment,null,[typeof In=="function"?In(_extends$1(_extends$1({},_n),$n),Pn):createVNode(DefaultPanel$1,_objectSpread2$1(_objectSpread2$1({},_n),$n),null)])}}}),TourStep$1=TourStep;let uuid=0;const isBrowserClient=canUseDom$1();function getUUID(){let $n;return isBrowserClient?($n=uuid,uuid+=1):$n="TEST_OR_SSR",$n}function useId(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ref("");const Cn=`vc_unique_${getUUID()}`;return $n.value||Cn}const COVER_PROPS={fill:"transparent","pointer-events":"auto"},Mask=defineComponent({name:"TourMask",props:{prefixCls:{type:String},pos:objectType(),rootClassName:{type:String},showMask:booleanType(),fill:{type:String,default:"rgba(0,0,0,0.5)"},open:booleanType(),animated:someType([Boolean,Object]),zIndex:{type:Number}},setup($n,Cn){let{attrs:_n}=Cn;const Pn=useId();return()=>{const{prefixCls:In,open:Nn,rootClassName:Rn,pos:Dn,showMask:Ln,fill:Fn,animated:Bn,zIndex:Hn}=$n,zn=`${In}-mask-${Pn}`,Wn=typeof Bn=="object"?Bn==null?void 0:Bn.placeholder:Bn;return createVNode(Portal,{visible:Nn,autoLock:!0},{default:()=>Nn&&createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{class:classNames(`${In}-mask`,Rn,_n.class),style:[{position:"fixed",left:0,right:0,top:0,bottom:0,zIndex:Hn,pointerEvents:"none"},_n.style]}),[Ln?createVNode("svg",{style:{width:"100%",height:"100%"}},[createVNode("defs",null,[createVNode("mask",{id:zn},[createVNode("rect",{x:"0",y:"0",width:"100vw",height:"100vh",fill:"white"},null),Dn&&createVNode("rect",{x:Dn.left,y:Dn.top,rx:Dn.radius,width:Dn.width,height:Dn.height,fill:"black",class:Wn?`${In}-placeholder-animated`:""},null)])]),createVNode("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:Fn,mask:`url(#${zn})`},null),Dn&&createVNode(Fragment,null,[createVNode("rect",_objectSpread2$1(_objectSpread2$1({},COVER_PROPS),{},{x:"0",y:"0",width:"100%",height:Dn.top}),null),createVNode("rect",_objectSpread2$1(_objectSpread2$1({},COVER_PROPS),{},{x:"0",y:"0",width:Dn.left,height:"100%"}),null),createVNode("rect",_objectSpread2$1(_objectSpread2$1({},COVER_PROPS),{},{x:"0",y:Dn.top+Dn.height,width:"100%",height:`calc(100vh - ${Dn.top+Dn.height}px)`}),null),createVNode("rect",_objectSpread2$1(_objectSpread2$1({},COVER_PROPS),{},{x:Dn.left+Dn.width,y:"0",width:`calc(100vw - ${Dn.left+Dn.width}px)`,height:"100%"}),null)])]):null])})}}}),Mask$1=Mask,targetOffset=[0,0],basePlacements$1={left:{points:["cr","cl"],offset:[-8,0]},right:{points:["cl","cr"],offset:[8,0]},top:{points:["bc","tc"],offset:[0,-8]},bottom:{points:["tc","bc"],offset:[0,8]},topLeft:{points:["bl","tl"],offset:[0,-8]},leftTop:{points:["tr","tl"],offset:[-8,0]},topRight:{points:["br","tr"],offset:[0,-8]},rightTop:{points:["tl","tr"],offset:[8,0]},bottomRight:{points:["tr","br"],offset:[0,8]},rightBottom:{points:["bl","br"],offset:[8,0]},bottomLeft:{points:["tl","bl"],offset:[0,8]},leftBottom:{points:["br","bl"],offset:[-8,0]}};function getPlacements(){let $n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1;const Cn={};return Object.keys(basePlacements$1).forEach(_n=>{Cn[_n]=_extends$1(_extends$1({},basePlacements$1[_n]),{autoArrow:$n,targetOffset})}),Cn}getPlacements();var __rest$2=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const{builtinPlacements:$n,popupAlign:Cn}=triggerProps();return{builtinPlacements:$n,popupAlign:Cn,steps:arrayType(),open:booleanType(),defaultCurrent:{type:Number},current:{type:Number},onChange:functionType(),onClose:functionType(),onFinish:functionType(),mask:someType([Boolean,Object],!0),arrow:someType([Boolean,Object],!0),rootClassName:{type:String},placement:stringType("bottom"),prefixCls:{type:String,default:"rc-tour"},renderPanel:functionType(),gap:objectType(),animated:someType([Boolean,Object]),scrollIntoViewOptions:someType([Boolean,Object],!0),zIndex:{type:Number,default:1001}}},Tour$1=defineComponent({name:"Tour",inheritAttrs:!1,props:initDefaultProps(tourProps$1(),{}),setup($n){const{defaultCurrent:Cn,placement:_n,mask:Pn,scrollIntoViewOptions:In,open:Nn,gap:Rn,arrow:Dn}=toRefs($n),Ln=ref(),[Fn,Bn]=useMergedState(0,{value:computed(()=>$n.current),defaultValue:Cn.value}),[Hn,zn]=useMergedState(void 0,{value:computed(()=>$n.open),postState:nr=>Fn.value<0||Fn.value>=$n.steps.length?!1:nr??!0}),Wn=shallowRef(Hn.value);watchEffect(()=>{Hn.value&&!Wn.value&&Bn(0),Wn.value=Hn.value});const Yn=computed(()=>$n.steps[Fn.value]||{}),Gn=computed(()=>{var nr;return(nr=Yn.value.placement)!==null&&nr!==void 0?nr:_n.value}),Go=computed(()=>{var nr;return Hn.value&&((nr=Yn.value.mask)!==null&&nr!==void 0?nr:Pn.value)}),Xn=computed(()=>{var nr;return(nr=Yn.value.scrollIntoViewOptions)!==null&&nr!==void 0?nr:In.value}),[Yo,qo]=useTarget(computed(()=>Yn.value.target),Nn,Rn,Xn),Jo=computed(()=>qo.value?typeof Yn.value.arrow>"u"?Dn.value:Yn.value.arrow:!1),Zo=computed(()=>typeof Jo.value=="object"?Jo.value.pointAtCenter:!1);watch(Zo,()=>{var nr;(nr=Ln.value)===null||nr===void 0||nr.forcePopupAlign()}),watch(Fn,()=>{var nr;(nr=Ln.value)===null||nr===void 0||nr.forcePopupAlign()});const rr=nr=>{var ta;Bn(nr),(ta=$n.onChange)===null||ta===void 0||ta.call($n,nr)};return()=>{var nr;const{prefixCls:ta,steps:oa,onClose:ra,onFinish:ea,rootClassName:la,renderPanel:ua,animated:ga,zIndex:aa}=$n,ca=__rest$2($n,["prefixCls","steps","onClose","onFinish","rootClassName","renderPanel","animated","zIndex"]);if(qo.value===void 0)return null;const sa=()=>{zn(!1),ra==null||ra(Fn.value)},ia=typeof Go.value=="boolean"?Go.value:!!Go.value,fa=typeof Go.value=="boolean"?void 0:Go.value,ma=()=>qo.value||document.body,ya=()=>createVNode(TourStep$1,_objectSpread2$1({arrow:Jo.value,key:"content",prefixCls:ta,total:oa.length,renderPanel:ua,onPrev:()=>{rr(Fn.value-1)},onNext:()=>{rr(Fn.value+1)},onClose:sa,current:Fn.value,onFinish:()=>{sa(),ea==null||ea()}},Yn.value),null),ba=computed(()=>{const Ia=Yo.value||CENTER_PLACEHOLDER,Ea={};return Object.keys(Ia).forEach(xa=>{typeof Ia[xa]=="number"?Ea[xa]=`${Ia[xa]}px`:Ea[xa]=Ia[xa]}),Ea});return Hn.value?createVNode(Fragment,null,[createVNode(Mask$1,{zIndex:aa,prefixCls:ta,pos:Yo.value,showMask:ia,style:fa==null?void 0:fa.style,fill:fa==null?void 0:fa.color,open:Hn.value,animated:ga,rootClassName:la},null),createVNode(Trigger,_objectSpread2$1(_objectSpread2$1({},ca),{},{builtinPlacements:Yn.value.target?(nr=ca.builtinPlacements)!==null&&nr!==void 0?nr:getPlacements(Zo.value):void 0,ref:Ln,popupStyle:Yn.value.target?Yn.value.style:_extends$1(_extends$1({},Yn.value.style),{position:"fixed",left:CENTER_PLACEHOLDER.left,top:CENTER_PLACEHOLDER.top,transform:"translate(-50%, -50%)"}),popupPlacement:Gn.value,popupVisible:Hn.value,popupClassName:classNames(la,Yn.value.className),prefixCls:ta,popup:ya,forceRender:!1,destroyPopupOnHide:!0,zIndex:aa,mask:!1,getTriggerDOMNode:ma}),{default:()=>[createVNode(Portal,{visible:Hn.value,autoLock:!0},{default:()=>[createVNode("div",{class:classNames(la,`${ta}-target-placeholder`),style:_extends$1(_extends$1({},ba.value),{position:"fixed",pointerEvents:"none"})},null)]})]})]):null}}}),Tour$2=Tour$1,tourProps=()=>_extends$1(_extends$1({},tourProps$1()),{steps:{type:Array},prefixCls:{type:String},current:{type:Number},type:{type:String},"onUpdate:current":Function}),tourStepProps=()=>_extends$1(_extends$1({},tourStepProps$1()),{cover:{type:Object},nextButtonProps:{type:Object},prevButtonProps:{type:Object},current:{type:Number},type:{type:String}}),panelRender=defineComponent({name:"ATourPanel",inheritAttrs:!1,props:tourStepProps(),setup($n,Cn){let{attrs:_n,slots:Pn}=Cn;const{current:In,total:Nn}=toRefs($n),Rn=computed(()=>In.value===Nn.value-1),Dn=Fn=>{var Bn;const Hn=$n.prevButtonProps;(Bn=$n.onPrev)===null||Bn===void 0||Bn.call($n,Fn),typeof(Hn==null?void 0:Hn.onClick)=="function"&&(Hn==null||Hn.onClick())},Ln=Fn=>{var Bn,Hn;const zn=$n.nextButtonProps;Rn.value?(Bn=$n.onFinish)===null||Bn===void 0||Bn.call($n,Fn):(Hn=$n.onNext)===null||Hn===void 0||Hn.call($n,Fn),typeof(zn==null?void 0:zn.onClick)=="function"&&(zn==null||zn.onClick())};return()=>{const{prefixCls:Fn,title:Bn,onClose:Hn,cover:zn,description:Wn,type:Yn,arrow:Gn}=$n,Go=$n.prevButtonProps,Xn=$n.nextButtonProps;let Yo;Bn&&(Yo=createVNode("div",{class:`${Fn}-header`},[createVNode("div",{class:`${Fn}-title`},[Bn])]));let qo;Wn&&(qo=createVNode("div",{class:`${Fn}-description`},[Wn]));let Jo;zn&&(Jo=createVNode("div",{class:`${Fn}-cover`},[zn]));let Zo;Pn.indicatorsRender?Zo=Pn.indicatorsRender({current:In.value,total:Nn}):Zo=[...Array.from({length:Nn.value}).keys()].map((ta,oa)=>createVNode("span",{key:ta,class:classNames(oa===In.value&&`${Fn}-indicator-active`,`${Fn}-indicator`)},null));const rr=Yn==="primary"?"default":"primary",nr={type:"default",ghost:Yn==="primary"};return createVNode(LocaleReceiver,{componentName:"Tour",defaultLocale:localeValues$1.Tour},{default:ta=>{var oa,ra;return createVNode("div",_objectSpread2$1(_objectSpread2$1({},_n),{},{class:classNames(Yn==="primary"?`${Fn}-primary`:"",_n.class,`${Fn}-content`)}),[Gn&&createVNode("div",{class:`${Fn}-arrow`,key:"arrow"},null),createVNode("div",{class:`${Fn}-inner`},[createVNode(CloseOutlined$1,{class:`${Fn}-close`,onClick:Hn},null),Jo,Yo,qo,createVNode("div",{class:`${Fn}-footer`},[Nn.value>1&&createVNode("div",{class:`${Fn}-indicators`},[Zo]),createVNode("div",{class:`${Fn}-buttons`},[In.value!==0?createVNode(Button$1,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},nr),Go),{},{onClick:Dn,size:"small",class:classNames(`${Fn}-prev-btn`,Go==null?void 0:Go.className)}),{default:()=>[(oa=Go==null?void 0:Go.children)!==null&&oa!==void 0?oa:ta.Previous]}):null,createVNode(Button$1,_objectSpread2$1(_objectSpread2$1({type:rr},Xn),{},{onClick:Ln,size:"small",class:classNames(`${Fn}-next-btn`,Xn==null?void 0:Xn.className)}),{default:()=>[(ra=Xn==null?void 0:Xn.children)!==null&&ra!==void 0?ra:Rn.value?ta.Finish:ta.Next]})])])])])}})}}}),TourPanel=panelRender,useMergedType=$n=>{let{defaultType:Cn,steps:_n,current:Pn,defaultCurrent:In}=$n;const Nn=ref(In==null?void 0:In.value),Rn=computed(()=>Pn==null?void 0:Pn.value);watch(Rn,Bn=>{Nn.value=Bn??(In==null?void 0:In.value)},{immediate:!0});const Dn=Bn=>{Nn.value=Bn},Ln=computed(()=>{var Bn,Hn;return typeof Nn.value=="number"?_n&&((Hn=(Bn=_n.value)===null||Bn===void 0?void 0:Bn[Nn.value])===null||Hn===void 0?void 0:Hn.type):Cn==null?void 0:Cn.value});return{currentMergedType:computed(()=>{var Bn;return(Bn=Ln.value)!==null&&Bn!==void 0?Bn:Cn==null?void 0:Cn.value}),updateInnerCurrent:Dn}},genBaseStyle$1=$n=>{const{componentCls:Cn,lineHeight:_n,padding:Pn,paddingXS:In,borderRadius:Nn,borderRadiusXS:Rn,colorPrimary:Dn,colorText:Ln,colorFill:Fn,indicatorHeight:Bn,indicatorWidth:Hn,boxShadowTertiary:zn,tourZIndexPopup:Wn,fontSize:Yn,colorBgContainer:Gn,fontWeightStrong:Go,marginXS:Xn,colorTextLightSolid:Yo,tourBorderRadius:qo,colorWhite:Jo,colorBgTextHover:Zo,tourCloseSize:rr,motionDurationSlow:nr,antCls:ta}=$n;return[{[Cn]:_extends$1(_extends$1({},resetComponent($n)),{color:Ln,position:"absolute",zIndex:Wn,display:"block",visibility:"visible",fontSize:Yn,lineHeight:_n,width:520,"--antd-arrow-background-color":Gn,"&-pure":{maxWidth:"100%",position:"relative"},[`&${Cn}-hidden`]:{display:"none"},[`${Cn}-content`]:{position:"relative"},[`${Cn}-inner`]:{textAlign:"start",textDecoration:"none",borderRadius:qo,boxShadow:zn,position:"relative",backgroundColor:Gn,border:"none",backgroundClip:"padding-box",[`${Cn}-close`]:{position:"absolute",top:Pn,insetInlineEnd:Pn,color:$n.colorIcon,outline:"none",width:rr,height:rr,borderRadius:$n.borderRadiusSM,transition:`background-color ${$n.motionDurationMid}, color ${$n.motionDurationMid}`,display:"flex",alignItems:"center",justifyContent:"center","&:hover":{color:$n.colorIconHover,backgroundColor:$n.wireframe?"transparent":$n.colorFillContent}},[`${Cn}-cover`]:{textAlign:"center",padding:`${Pn+rr+In}px ${Pn}px 0`,img:{width:"100%"}},[`${Cn}-header`]:{padding:`${Pn}px ${Pn}px ${In}px`,[`${Cn}-title`]:{lineHeight:_n,fontSize:Yn,fontWeight:Go}},[`${Cn}-description`]:{padding:`0 ${Pn}px`,lineHeight:_n,wordWrap:"break-word"},[`${Cn}-footer`]:{padding:`${In}px ${Pn}px ${Pn}px`,textAlign:"end",borderRadius:`0 0 ${Rn}px ${Rn}px`,display:"flex",[`${Cn}-indicators`]:{display:"inline-block",[`${Cn}-indicator`]:{width:Hn,height:Bn,display:"inline-block",borderRadius:"50%",background:Fn,"&:not(:last-child)":{marginInlineEnd:Bn},"&-active":{background:Dn}}},[`${Cn}-buttons`]:{marginInlineStart:"auto",[`${ta}-btn`]:{marginInlineStart:Xn}}}},[`${Cn}-primary, &${Cn}-primary`]:{"--antd-arrow-background-color":Dn,[`${Cn}-inner`]:{color:Yo,textAlign:"start",textDecoration:"none",backgroundColor:Dn,borderRadius:Nn,boxShadow:zn,[`${Cn}-close`]:{color:Yo},[`${Cn}-indicators`]:{[`${Cn}-indicator`]:{background:new TinyColor(Yo).setAlpha(.15).toRgbString(),"&-active":{background:Yo}}},[`${Cn}-prev-btn`]:{color:Yo,borderColor:new TinyColor(Yo).setAlpha(.15).toRgbString(),backgroundColor:Dn,"&:hover":{backgroundColor:new TinyColor(Yo).setAlpha(.15).toRgbString(),borderColor:"transparent"}},[`${Cn}-next-btn`]:{color:Dn,borderColor:"transparent",background:Jo,"&:hover":{background:new TinyColor(Zo).onBackground(Jo).toRgbString()}}}}}),[`${Cn}-mask`]:{[`${Cn}-placeholder-animated`]:{transition:`all ${nr}`}},[["&-placement-left","&-placement-leftTop","&-placement-leftBottom","&-placement-right","&-placement-rightTop","&-placement-rightBottom"].join(",")]:{[`${Cn}-inner`]:{borderRadius:Math.min(qo,MAX_VERTICAL_CONTENT_RADIUS)}}},getArrowStyle($n,{colorBg:"var(--antd-arrow-background-color)",contentRadius:qo,limitVerticalRadius:!0})]},useStyle$2=genComponentStyleHook("Tour",$n=>{const{borderRadiusLG:Cn,fontSize:_n,lineHeight:Pn}=$n,In=merge$1($n,{tourZIndexPopup:$n.zIndexPopupBase+70,indicatorWidth:6,indicatorHeight:6,tourBorderRadius:Cn,tourCloseSize:_n*Pn});return[genBaseStyle$1(In)]});var __rest$1=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{const{steps:Gn,current:Go,type:Xn,rootClassName:Yo}=$n,qo=__rest$1($n,["steps","current","type","rootClassName"]),Jo=classNames({[`${Fn.value}-primary`]:Wn.value==="primary",[`${Fn.value}-rtl`]:Bn.value==="rtl"},zn.value,Yo),Zo=(ta,oa)=>createVNode(TourPanel,_objectSpread2$1(_objectSpread2$1({},ta),{},{type:Xn,current:oa}),{indicatorsRender:In.indicatorsRender}),rr=ta=>{Yn(ta),Pn("update:current",ta),Pn("change",ta)},nr=computed(()=>getPlacements$1({arrowPointAtCenter:!0,autoAdjustOverflow:!0}));return Hn(createVNode(Tour$2,_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({},_n),qo),{},{rootClassName:Jo,prefixCls:Fn.value,current:Go,defaultCurrent:$n.defaultCurrent,animated:!0,renderPanel:Zo,onChange:rr,steps:Gn,builtinPlacements:nr.value}),null))}}}),index$1=withInstall(Tour),AppConfigContextKey=Symbol("appConfigContext"),useProvideAppConfigContext=$n=>provide(AppConfigContextKey,$n),useInjectAppConfigContext=()=>inject(AppConfigContextKey,{}),AppContextKey=Symbol("appContext"),useProvideAppContext=$n=>provide(AppContextKey,$n),defaultAppContext=reactive({message:{},notification:{},modal:{}}),useInjectAppContext=()=>inject(AppContextKey,defaultAppContext),genBaseStyle=$n=>{const{componentCls:Cn,colorText:_n,fontSize:Pn,lineHeight:In,fontFamily:Nn}=$n;return{[Cn]:{color:_n,fontSize:Pn,lineHeight:In,fontFamily:Nn}}},useStyle$1=genComponentStyleHook("App",$n=>[genBaseStyle($n)]),AppProps=()=>({rootClassName:String,message:objectType(),notification:objectType()}),useApp=()=>useInjectAppContext(),App=defineComponent({name:"AApp",props:initDefaultProps(AppProps(),{}),setup($n,Cn){let{slots:_n}=Cn;const{prefixCls:Pn}=useConfigInject("app",$n),[In,Nn]=useStyle$1(Pn),Rn=computed(()=>classNames(Nn.value,Pn.value,$n.rootClassName)),Dn=useInjectAppConfigContext(),Ln=computed(()=>({message:_extends$1(_extends$1({},Dn.message),$n.message),notification:_extends$1(_extends$1({},Dn.notification),$n.notification)}));useProvideAppConfigContext(Ln.value);const[Fn,Bn]=useMessage(Ln.value.message),[Hn,zn]=useNotification(Ln.value.notification),[Wn,Yn]=useModal(),Gn=computed(()=>({message:Fn,notification:Hn,modal:Wn}));return useProvideAppContext(Gn.value),()=>{var Go;return In(createVNode("div",{class:Rn.value},[Yn(),Bn(),zn(),(Go=_n.default)===null||Go===void 0?void 0:Go.call(_n)]))}}});App.useApp=useApp;App.install=function($n){$n.component(App.name,App)};const App$1=App,flexWrapValues=["wrap","nowrap","wrap-reverse"],justifyContentValues=["flex-start","flex-end","start","end","center","space-between","space-around","space-evenly","stretch","normal","left","right"],alignItemsValues=["center","start","end","flex-start","flex-end","self-start","self-end","baseline","normal","stretch"],genClsWrap=($n,Cn)=>{const _n={};return flexWrapValues.forEach(Pn=>{_n[`${$n}-wrap-${Pn}`]=Cn.wrap===Pn}),_n},genClsAlign=($n,Cn)=>{const _n={};return alignItemsValues.forEach(Pn=>{_n[`${$n}-align-${Pn}`]=Cn.align===Pn}),_n[`${$n}-align-stretch`]=!Cn.align&&!!Cn.vertical,_n},genClsJustify=($n,Cn)=>{const _n={};return justifyContentValues.forEach(Pn=>{_n[`${$n}-justify-${Pn}`]=Cn.justify===Pn}),_n};function createFlexClassNames($n,Cn){return classNames(_extends$1(_extends$1(_extends$1({},genClsWrap($n,Cn)),genClsAlign($n,Cn)),genClsJustify($n,Cn)))}const genFlexStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{display:"flex","&-vertical":{flexDirection:"column"},"&-rtl":{direction:"rtl"},"&:empty":{display:"none"}}}},genFlexGapStyle=$n=>{const{componentCls:Cn}=$n;return{[Cn]:{"&-gap-small":{gap:$n.flexGapSM},"&-gap-middle":{gap:$n.flexGap},"&-gap-large":{gap:$n.flexGapLG}}}},genFlexWrapStyle=$n=>{const{componentCls:Cn}=$n,_n={};return flexWrapValues.forEach(Pn=>{_n[`${Cn}-wrap-${Pn}`]={flexWrap:Pn}}),_n},genAlignItemsStyle=$n=>{const{componentCls:Cn}=$n,_n={};return alignItemsValues.forEach(Pn=>{_n[`${Cn}-align-${Pn}`]={alignItems:Pn}}),_n},genJustifyContentStyle=$n=>{const{componentCls:Cn}=$n,_n={};return justifyContentValues.forEach(Pn=>{_n[`${Cn}-justify-${Pn}`]={justifyContent:Pn}}),_n},useStyle=genComponentStyleHook("Flex",$n=>{const Cn=merge$1($n,{flexGapSM:$n.paddingXS,flexGap:$n.padding,flexGapLG:$n.paddingLG});return[genFlexStyle(Cn),genFlexGapStyle(Cn),genFlexWrapStyle(Cn),genAlignItemsStyle(Cn),genJustifyContentStyle(Cn)]});function isPresetSize($n){return["small","middle","large"].includes($n)}const flexProps=()=>({prefixCls:stringType(),vertical:booleanType(),wrap:stringType(),justify:stringType(),align:stringType(),flex:someType([Number,String]),gap:someType([Number,String]),component:anyType()});var __rest=function($n,Cn){var _n={};for(var Pn in $n)Object.prototype.hasOwnProperty.call($n,Pn)&&Cn.indexOf(Pn)<0&&(_n[Pn]=$n[Pn]);if($n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var In=0,Pn=Object.getOwnPropertySymbols($n);In{var Bn;return[Rn.value,Ln.value,createFlexClassNames(Rn.value,$n),{[`${Rn.value}-rtl`]:Nn.value==="rtl",[`${Rn.value}-gap-${$n.gap}`]:isPresetSize($n.gap),[`${Rn.value}-vertical`]:(Bn=$n.vertical)!==null&&Bn!==void 0?Bn:In==null?void 0:In.value.vertical}]});return()=>{var Bn;const{flex:Hn,gap:zn,component:Wn="div"}=$n,Yn=__rest($n,["flex","gap","component"]),Gn={};return Hn&&(Gn.flex=Hn),zn&&!isPresetSize(zn)&&(Gn.gap=`${zn}px`),Dn(createVNode(Wn,_objectSpread2$1({class:[Pn.class,Fn.value],style:[Pn.style,Gn]},omit$1(Yn,["justify","wrap","align","vertical"])),{default:()=>[(Bn=_n.default)===null||Bn===void 0?void 0:Bn.call(_n)]}))}}}),index=withInstall(AFlex),components=Object.freeze(Object.defineProperty({__proto__:null,Affix:Affix$1,Alert:index$r,Anchor,AnchorLink,App:App$1,AutoComplete:index$s,AutoCompleteOptGroup,AutoCompleteOption,Avatar:Avatar$1,AvatarGroup:Group$4,BackTop:BackTop$1,Badge,BadgeRibbon:Ribbon,Breadcrumb,BreadcrumbItem,BreadcrumbSeparator,Button:Button$1,ButtonGroup:ButtonGroup$1,Calendar:Calendar$1,Card:Card$1,CardGrid:Grid,CardMeta:Meta,Carousel:index$q,Cascader:index$p,CheckableTag:CheckableTag$1,Checkbox,CheckboxGroup,Col:index$n,Collapse,CollapsePanel,Comment:index$m,Compact:Compact$1,ConfigProvider:ConfigProvider$1,DatePicker:DatePicker$2,Descriptions:Descriptions$1,DescriptionsItem,DirectoryTree,Divider:index$l,Drawer:index$k,Dropdown:Dropdown$1,DropdownButton,Empty:Empty$1,Flex:index,FloatButton:FloatButton$1,FloatButtonGroup:FloatButtonGroup$1,Form:Form$1,FormItem,FormItemRest,Grid:index$o,Image:Image$2,ImagePreviewGroup:PreviewGroup,Input,InputGroup:Group$1,InputNumber:index$j,InputPassword:Password,InputSearch:Search$1,Layout:index$i,LayoutContent,LayoutFooter,LayoutHeader,LayoutSider,List:List$2,ListItem:Item,ListItemMeta:ItemMeta,LocaleProvider:locale$3,Mentions:index$h,MentionsOption,Menu,MenuDivider:Divider$1,MenuItem:MenuItem$1,MenuItemGroup:ItemGroup,Modal,MonthPicker,PageHeader:index$g,Pagination,Popconfirm:index$f,Popover:Popover$1,Progress,QRCode:index$2,QuarterPicker,Radio,RadioButton:Button,RadioGroup:Group$2,RangePicker,Rate:index$e,Result:Result$1,Row:index$d,Segmented:index$3,Select:VcSelect,SelectOptGroup,SelectOption,Skeleton:Skeleton$1,SkeletonAvatar:SkeletonAvatar$1,SkeletonButton:SkeletonButton$1,SkeletonImage:SkeletonImage$1,SkeletonInput:SkeletonInput$1,SkeletonTitle:SkeletonTitle$1,Slider:index$c,Space:Space$1,Spin,Statistic,StatisticCountdown,Step,Steps:index$b,SubMenu:SubMenu$1,Switch:index$a,TabPane:TabPane$1,Table:index$9,TableColumn:Column,TableColumnGroup:ColumnGroup,TableSummary,TableSummaryCell,TableSummaryRow,Tabs,Tag:Tag$1,Textarea:TextArea,TimePicker:TimePicker$2,TimeRangePicker,Timeline,TimelineItem,Tooltip,Tour:index$1,Transfer:index$8,Tree,TreeNode:TreeNode$2,TreeSelect:index$7,TreeSelectNode,Typography:Typography$1,TypographyLink:Link$1,TypographyParagraph:Paragraph$1,TypographyText:Text$1,TypographyTitle:Title$1,Upload:index$5,UploadDragger,Watermark:index$4,WeekPicker,message,notification},Symbol.toStringTag,{value:"Module"})),install=function($n){return Object.keys(components).forEach(Cn=>{const _n=components[Cn];_n.install&&$n.use(_n)}),$n.use(cssinjs$1.StyleProvider),$n.config.globalProperties.$message=message,$n.config.globalProperties.$notification=notification,$n.config.globalProperties.$info=Modal.info,$n.config.globalProperties.$success=Modal.success,$n.config.globalProperties.$error=Modal.error,$n.config.globalProperties.$warning=Modal.warning,$n.config.globalProperties.$confirm=Modal.confirm,$n.config.globalProperties.$destroyAll=Modal.destroyAll,$n},Antd={version,install};/*! - * vue-router v4.2.5 - * (c) 2023 Eduardo San Martin Morote - * @license MIT - */const isBrowser=typeof window<"u";function isESModule($n){return $n.__esModule||$n[Symbol.toStringTag]==="Module"}const assign$3=Object.assign;function applyToParams($n,Cn){const _n={};for(const Pn in Cn){const In=Cn[Pn];_n[Pn]=isArray$1(In)?In.map($n):$n(In)}return _n}const noop$1=()=>{},isArray$1=Array.isArray,TRAILING_SLASH_RE=/\/$/,removeTrailingSlash=$n=>$n.replace(TRAILING_SLASH_RE,"");function parseURL($n,Cn,_n="/"){let Pn,In={},Nn="",Rn="";const Dn=Cn.indexOf("#");let Ln=Cn.indexOf("?");return Dn=0&&(Ln=-1),Ln>-1&&(Pn=Cn.slice(0,Ln),Nn=Cn.slice(Ln+1,Dn>-1?Dn:Cn.length),In=$n(Nn)),Dn>-1&&(Pn=Pn||Cn.slice(0,Dn),Rn=Cn.slice(Dn,Cn.length)),Pn=resolveRelativePath(Pn??Cn,_n),{fullPath:Pn+(Nn&&"?")+Nn+Rn,path:Pn,query:In,hash:Rn}}function stringifyURL($n,Cn){const _n=Cn.query?$n(Cn.query):"";return Cn.path+(_n&&"?")+_n+(Cn.hash||"")}function stripBase($n,Cn){return!Cn||!$n.toLowerCase().startsWith(Cn.toLowerCase())?$n:$n.slice(Cn.length)||"/"}function isSameRouteLocation($n,Cn,_n){const Pn=Cn.matched.length-1,In=_n.matched.length-1;return Pn>-1&&Pn===In&&isSameRouteRecord(Cn.matched[Pn],_n.matched[In])&&isSameRouteLocationParams(Cn.params,_n.params)&&$n(Cn.query)===$n(_n.query)&&Cn.hash===_n.hash}function isSameRouteRecord($n,Cn){return($n.aliasOf||$n)===(Cn.aliasOf||Cn)}function isSameRouteLocationParams($n,Cn){if(Object.keys($n).length!==Object.keys(Cn).length)return!1;for(const _n in $n)if(!isSameRouteLocationParamsValue($n[_n],Cn[_n]))return!1;return!0}function isSameRouteLocationParamsValue($n,Cn){return isArray$1($n)?isEquivalentArray($n,Cn):isArray$1(Cn)?isEquivalentArray(Cn,$n):$n===Cn}function isEquivalentArray($n,Cn){return isArray$1(Cn)?$n.length===Cn.length&&$n.every((_n,Pn)=>_n===Cn[Pn]):$n.length===1&&$n[0]===Cn}function resolveRelativePath($n,Cn){if($n.startsWith("/"))return $n;if(!$n)return Cn;const _n=Cn.split("/"),Pn=$n.split("/"),In=Pn[Pn.length-1];(In===".."||In===".")&&Pn.push("");let Nn=_n.length-1,Rn,Dn;for(Rn=0;Rn1&&Nn--;else break;return _n.slice(0,Nn).join("/")+"/"+Pn.slice(Rn-(Rn===Pn.length?1:0)).join("/")}var NavigationType;(function($n){$n.pop="pop",$n.push="push"})(NavigationType||(NavigationType={}));var NavigationDirection;(function($n){$n.back="back",$n.forward="forward",$n.unknown=""})(NavigationDirection||(NavigationDirection={}));function normalizeBase($n){if(!$n)if(isBrowser){const Cn=document.querySelector("base");$n=Cn&&Cn.getAttribute("href")||"/",$n=$n.replace(/^\w+:\/\/[^\/]+/,"")}else $n="/";return $n[0]!=="/"&&$n[0]!=="#"&&($n="/"+$n),removeTrailingSlash($n)}const BEFORE_HASH_RE=/^[^#]+#/;function createHref($n,Cn){return $n.replace(BEFORE_HASH_RE,"#")+Cn}function getElementPosition($n,Cn){const _n=document.documentElement.getBoundingClientRect(),Pn=$n.getBoundingClientRect();return{behavior:Cn.behavior,left:Pn.left-_n.left-(Cn.left||0),top:Pn.top-_n.top-(Cn.top||0)}}const computeScrollPosition=()=>({left:window.pageXOffset,top:window.pageYOffset});function scrollToPosition($n){let Cn;if("el"in $n){const _n=$n.el,Pn=typeof _n=="string"&&_n.startsWith("#"),In=typeof _n=="string"?Pn?document.getElementById(_n.slice(1)):document.querySelector(_n):_n;if(!In)return;Cn=getElementPosition(In,$n)}else Cn=$n;"scrollBehavior"in document.documentElement.style?window.scrollTo(Cn):window.scrollTo(Cn.left!=null?Cn.left:window.pageXOffset,Cn.top!=null?Cn.top:window.pageYOffset)}function getScrollKey($n,Cn){return(history.state?history.state.position-Cn:-1)+$n}const scrollPositions=new Map;function saveScrollPosition($n,Cn){scrollPositions.set($n,Cn)}function getSavedScrollPosition($n){const Cn=scrollPositions.get($n);return scrollPositions.delete($n),Cn}let createBaseLocation=()=>location.protocol+"//"+location.host;function createCurrentLocation($n,Cn){const{pathname:_n,search:Pn,hash:In}=Cn,Nn=$n.indexOf("#");if(Nn>-1){let Dn=In.includes($n.slice(Nn))?$n.slice(Nn).length:1,Ln=In.slice(Dn);return Ln[0]!=="/"&&(Ln="/"+Ln),stripBase(Ln,"")}return stripBase(_n,$n)+Pn+In}function useHistoryListeners($n,Cn,_n,Pn){let In=[],Nn=[],Rn=null;const Dn=({state:zn})=>{const Wn=createCurrentLocation($n,location),Yn=_n.value,Gn=Cn.value;let Go=0;if(zn){if(_n.value=Wn,Cn.value=zn,Rn&&Rn===Yn){Rn=null;return}Go=Gn?zn.position-Gn.position:0}else Pn(Wn);In.forEach(Xn=>{Xn(_n.value,Yn,{delta:Go,type:NavigationType.pop,direction:Go?Go>0?NavigationDirection.forward:NavigationDirection.back:NavigationDirection.unknown})})};function Ln(){Rn=_n.value}function Fn(zn){In.push(zn);const Wn=()=>{const Yn=In.indexOf(zn);Yn>-1&&In.splice(Yn,1)};return Nn.push(Wn),Wn}function Bn(){const{history:zn}=window;zn.state&&zn.replaceState(assign$3({},zn.state,{scroll:computeScrollPosition()}),"")}function Hn(){for(const zn of Nn)zn();Nn=[],window.removeEventListener("popstate",Dn),window.removeEventListener("beforeunload",Bn)}return window.addEventListener("popstate",Dn),window.addEventListener("beforeunload",Bn,{passive:!0}),{pauseListeners:Ln,listen:Fn,destroy:Hn}}function buildState($n,Cn,_n,Pn=!1,In=!1){return{back:$n,current:Cn,forward:_n,replaced:Pn,position:window.history.length,scroll:In?computeScrollPosition():null}}function useHistoryStateNavigation($n){const{history:Cn,location:_n}=window,Pn={value:createCurrentLocation($n,_n)},In={value:Cn.state};In.value||Nn(Pn.value,{back:null,current:Pn.value,forward:null,position:Cn.length-1,replaced:!0,scroll:null},!0);function Nn(Ln,Fn,Bn){const Hn=$n.indexOf("#"),zn=Hn>-1?(_n.host&&document.querySelector("base")?$n:$n.slice(Hn))+Ln:createBaseLocation()+$n+Ln;try{Cn[Bn?"replaceState":"pushState"](Fn,"",zn),In.value=Fn}catch(Wn){console.error(Wn),_n[Bn?"replace":"assign"](zn)}}function Rn(Ln,Fn){const Bn=assign$3({},Cn.state,buildState(In.value.back,Ln,In.value.forward,!0),Fn,{position:In.value.position});Nn(Ln,Bn,!0),Pn.value=Ln}function Dn(Ln,Fn){const Bn=assign$3({},In.value,Cn.state,{forward:Ln,scroll:computeScrollPosition()});Nn(Bn.current,Bn,!0);const Hn=assign$3({},buildState(Pn.value,Ln,null),{position:Bn.position+1},Fn);Nn(Ln,Hn,!1),Pn.value=Ln}return{location:Pn,state:In,push:Dn,replace:Rn}}function createWebHistory($n){$n=normalizeBase($n);const Cn=useHistoryStateNavigation($n),_n=useHistoryListeners($n,Cn.state,Cn.location,Cn.replace);function Pn(Nn,Rn=!0){Rn||_n.pauseListeners(),history.go(Nn)}const In=assign$3({location:"",base:$n,go:Pn,createHref:createHref.bind(null,$n)},Cn,_n);return Object.defineProperty(In,"location",{enumerable:!0,get:()=>Cn.location.value}),Object.defineProperty(In,"state",{enumerable:!0,get:()=>Cn.state.value}),In}function isRouteLocation($n){return typeof $n=="string"||$n&&typeof $n=="object"}function isRouteName($n){return typeof $n=="string"||typeof $n=="symbol"}const START_LOCATION_NORMALIZED={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},NavigationFailureSymbol=Symbol("");var NavigationFailureType;(function($n){$n[$n.aborted=4]="aborted",$n[$n.cancelled=8]="cancelled",$n[$n.duplicated=16]="duplicated"})(NavigationFailureType||(NavigationFailureType={}));function createRouterError($n,Cn){return assign$3(new Error,{type:$n,[NavigationFailureSymbol]:!0},Cn)}function isNavigationFailure($n,Cn){return $n instanceof Error&&NavigationFailureSymbol in $n&&(Cn==null||!!($n.type&Cn))}const BASE_PARAM_PATTERN="[^/]+?",BASE_PATH_PARSER_OPTIONS={sensitive:!1,strict:!1,start:!0,end:!0},REGEX_CHARS_RE=/[.+*?^${}()[\]/\\]/g;function tokensToParser($n,Cn){const _n=assign$3({},BASE_PATH_PARSER_OPTIONS,Cn),Pn=[];let In=_n.start?"^":"";const Nn=[];for(const Fn of $n){const Bn=Fn.length?[]:[90];_n.strict&&!Fn.length&&(In+="/");for(let Hn=0;HnCn.length?Cn.length===1&&Cn[0]===80?1:-1:0}function comparePathParserScore($n,Cn){let _n=0;const Pn=$n.score,In=Cn.score;for(;_n0&&Cn[Cn.length-1]<0}const ROOT_TOKEN={type:0,value:""},VALID_PARAM_RE=/[a-zA-Z0-9_]/;function tokenizePath($n){if(!$n)return[[]];if($n==="/")return[[ROOT_TOKEN]];if(!$n.startsWith("/"))throw new Error(`Invalid path "${$n}"`);function Cn(Wn){throw new Error(`ERR (${_n})/"${Fn}": ${Wn}`)}let _n=0,Pn=_n;const In=[];let Nn;function Rn(){Nn&&In.push(Nn),Nn=[]}let Dn=0,Ln,Fn="",Bn="";function Hn(){Fn&&(_n===0?Nn.push({type:0,value:Fn}):_n===1||_n===2||_n===3?(Nn.length>1&&(Ln==="*"||Ln==="+")&&Cn(`A repeatable param (${Fn}) must be alone in its segment. eg: '/:ids+.`),Nn.push({type:1,value:Fn,regexp:Bn,repeatable:Ln==="*"||Ln==="+",optional:Ln==="*"||Ln==="?"})):Cn("Invalid state to consume buffer"),Fn="")}function zn(){Fn+=Ln}for(;Dn<$n.length;){if(Ln=$n[Dn++],Ln==="\\"&&_n!==2){Pn=_n,_n=4;continue}switch(_n){case 0:Ln==="/"?(Fn&&Hn(),Rn()):Ln===":"?(Hn(),_n=1):zn();break;case 4:zn(),_n=Pn;break;case 1:Ln==="("?_n=2:VALID_PARAM_RE.test(Ln)?zn():(Hn(),_n=0,Ln!=="*"&&Ln!=="?"&&Ln!=="+"&&Dn--);break;case 2:Ln===")"?Bn[Bn.length-1]=="\\"?Bn=Bn.slice(0,-1)+Ln:_n=3:Bn+=Ln;break;case 3:Hn(),_n=0,Ln!=="*"&&Ln!=="?"&&Ln!=="+"&&Dn--,Bn="";break;default:Cn("Unknown state");break}}return _n===2&&Cn(`Unfinished custom RegExp for param "${Fn}"`),Hn(),Rn(),In}function createRouteRecordMatcher($n,Cn,_n){const Pn=tokensToParser(tokenizePath($n.path),_n),In=assign$3(Pn,{record:$n,parent:Cn,children:[],alias:[]});return Cn&&!In.record.aliasOf==!Cn.record.aliasOf&&Cn.children.push(In),In}function createRouterMatcher($n,Cn){const _n=[],Pn=new Map;Cn=mergeOptions({strict:!1,end:!0,sensitive:!1},Cn);function In(Bn){return Pn.get(Bn)}function Nn(Bn,Hn,zn){const Wn=!zn,Yn=normalizeRouteRecord(Bn);Yn.aliasOf=zn&&zn.record;const Gn=mergeOptions(Cn,Bn),Go=[Yn];if("alias"in Bn){const qo=typeof Bn.alias=="string"?[Bn.alias]:Bn.alias;for(const Jo of qo)Go.push(assign$3({},Yn,{components:zn?zn.record.components:Yn.components,path:Jo,aliasOf:zn?zn.record:Yn}))}let Xn,Yo;for(const qo of Go){const{path:Jo}=qo;if(Hn&&Jo[0]!=="/"){const Zo=Hn.record.path,rr=Zo[Zo.length-1]==="/"?"":"/";qo.path=Hn.record.path+(Jo&&rr+Jo)}if(Xn=createRouteRecordMatcher(qo,Hn,Gn),zn?zn.alias.push(Xn):(Yo=Yo||Xn,Yo!==Xn&&Yo.alias.push(Xn),Wn&&Bn.name&&!isAliasRecord(Xn)&&Rn(Bn.name)),Yn.children){const Zo=Yn.children;for(let rr=0;rr{Rn(Yo)}:noop$1}function Rn(Bn){if(isRouteName(Bn)){const Hn=Pn.get(Bn);Hn&&(Pn.delete(Bn),_n.splice(_n.indexOf(Hn),1),Hn.children.forEach(Rn),Hn.alias.forEach(Rn))}else{const Hn=_n.indexOf(Bn);Hn>-1&&(_n.splice(Hn,1),Bn.record.name&&Pn.delete(Bn.record.name),Bn.children.forEach(Rn),Bn.alias.forEach(Rn))}}function Dn(){return _n}function Ln(Bn){let Hn=0;for(;Hn<_n.length&&comparePathParserScore(Bn,_n[Hn])>=0&&(Bn.record.path!==_n[Hn].record.path||!isRecordChildOf(Bn,_n[Hn]));)Hn++;_n.splice(Hn,0,Bn),Bn.record.name&&!isAliasRecord(Bn)&&Pn.set(Bn.record.name,Bn)}function Fn(Bn,Hn){let zn,Wn={},Yn,Gn;if("name"in Bn&&Bn.name){if(zn=Pn.get(Bn.name),!zn)throw createRouterError(1,{location:Bn});Gn=zn.record.name,Wn=assign$3(paramsFromLocation(Hn.params,zn.keys.filter(Yo=>!Yo.optional).map(Yo=>Yo.name)),Bn.params&¶msFromLocation(Bn.params,zn.keys.map(Yo=>Yo.name))),Yn=zn.stringify(Wn)}else if("path"in Bn)Yn=Bn.path,zn=_n.find(Yo=>Yo.re.test(Yn)),zn&&(Wn=zn.parse(Yn),Gn=zn.record.name);else{if(zn=Hn.name?Pn.get(Hn.name):_n.find(Yo=>Yo.re.test(Hn.path)),!zn)throw createRouterError(1,{location:Bn,currentLocation:Hn});Gn=zn.record.name,Wn=assign$3({},Hn.params,Bn.params),Yn=zn.stringify(Wn)}const Go=[];let Xn=zn;for(;Xn;)Go.unshift(Xn.record),Xn=Xn.parent;return{name:Gn,path:Yn,params:Wn,matched:Go,meta:mergeMetaFields(Go)}}return $n.forEach(Bn=>Nn(Bn)),{addRoute:Nn,resolve:Fn,removeRoute:Rn,getRoutes:Dn,getRecordMatcher:In}}function paramsFromLocation($n,Cn){const _n={};for(const Pn of Cn)Pn in $n&&(_n[Pn]=$n[Pn]);return _n}function normalizeRouteRecord($n){return{path:$n.path,redirect:$n.redirect,name:$n.name,meta:$n.meta||{},aliasOf:void 0,beforeEnter:$n.beforeEnter,props:normalizeRecordProps($n),children:$n.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in $n?$n.components||null:$n.component&&{default:$n.component}}}function normalizeRecordProps($n){const Cn={},_n=$n.props||!1;if("component"in $n)Cn.default=_n;else for(const Pn in $n.components)Cn[Pn]=typeof _n=="object"?_n[Pn]:_n;return Cn}function isAliasRecord($n){for(;$n;){if($n.record.aliasOf)return!0;$n=$n.parent}return!1}function mergeMetaFields($n){return $n.reduce((Cn,_n)=>assign$3(Cn,_n.meta),{})}function mergeOptions($n,Cn){const _n={};for(const Pn in $n)_n[Pn]=Pn in Cn?Cn[Pn]:$n[Pn];return _n}function isRecordChildOf($n,Cn){return Cn.children.some(_n=>_n===$n||isRecordChildOf($n,_n))}const HASH_RE=/#/g,AMPERSAND_RE=/&/g,SLASH_RE=/\//g,EQUAL_RE=/=/g,IM_RE=/\?/g,PLUS_RE=/\+/g,ENC_BRACKET_OPEN_RE=/%5B/g,ENC_BRACKET_CLOSE_RE=/%5D/g,ENC_CARET_RE=/%5E/g,ENC_BACKTICK_RE=/%60/g,ENC_CURLY_OPEN_RE=/%7B/g,ENC_PIPE_RE=/%7C/g,ENC_CURLY_CLOSE_RE=/%7D/g,ENC_SPACE_RE=/%20/g;function commonEncode($n){return encodeURI(""+$n).replace(ENC_PIPE_RE,"|").replace(ENC_BRACKET_OPEN_RE,"[").replace(ENC_BRACKET_CLOSE_RE,"]")}function encodeHash($n){return commonEncode($n).replace(ENC_CURLY_OPEN_RE,"{").replace(ENC_CURLY_CLOSE_RE,"}").replace(ENC_CARET_RE,"^")}function encodeQueryValue($n){return commonEncode($n).replace(PLUS_RE,"%2B").replace(ENC_SPACE_RE,"+").replace(HASH_RE,"%23").replace(AMPERSAND_RE,"%26").replace(ENC_BACKTICK_RE,"`").replace(ENC_CURLY_OPEN_RE,"{").replace(ENC_CURLY_CLOSE_RE,"}").replace(ENC_CARET_RE,"^")}function encodeQueryKey($n){return encodeQueryValue($n).replace(EQUAL_RE,"%3D")}function encodePath($n){return commonEncode($n).replace(HASH_RE,"%23").replace(IM_RE,"%3F")}function encodeParam($n){return $n==null?"":encodePath($n).replace(SLASH_RE,"%2F")}function decode($n){try{return decodeURIComponent(""+$n)}catch{}return""+$n}function parseQuery($n){const Cn={};if($n===""||$n==="?")return Cn;const Pn=($n[0]==="?"?$n.slice(1):$n).split("&");for(let In=0;InNn&&encodeQueryValue(Nn)):[Pn&&encodeQueryValue(Pn)]).forEach(Nn=>{Nn!==void 0&&(Cn+=(Cn.length?"&":"")+_n,Nn!=null&&(Cn+="="+Nn))})}return Cn}function normalizeQuery($n){const Cn={};for(const _n in $n){const Pn=$n[_n];Pn!==void 0&&(Cn[_n]=isArray$1(Pn)?Pn.map(In=>In==null?null:""+In):Pn==null?Pn:""+Pn)}return Cn}const matchedRouteKey=Symbol(""),viewDepthKey=Symbol(""),routerKey=Symbol(""),routeLocationKey=Symbol(""),routerViewLocationKey=Symbol("");function useCallbacks(){let $n=[];function Cn(Pn){return $n.push(Pn),()=>{const In=$n.indexOf(Pn);In>-1&&$n.splice(In,1)}}function _n(){$n=[]}return{add:Cn,list:()=>$n.slice(),reset:_n}}function guardToPromiseFn($n,Cn,_n,Pn,In){const Nn=Pn&&(Pn.enterCallbacks[In]=Pn.enterCallbacks[In]||[]);return()=>new Promise((Rn,Dn)=>{const Ln=Hn=>{Hn===!1?Dn(createRouterError(4,{from:_n,to:Cn})):Hn instanceof Error?Dn(Hn):isRouteLocation(Hn)?Dn(createRouterError(2,{from:Cn,to:Hn})):(Nn&&Pn.enterCallbacks[In]===Nn&&typeof Hn=="function"&&Nn.push(Hn),Rn())},Fn=$n.call(Pn&&Pn.instances[In],Cn,_n,Ln);let Bn=Promise.resolve(Fn);$n.length<3&&(Bn=Bn.then(Ln)),Bn.catch(Hn=>Dn(Hn))})}function extractComponentsGuards($n,Cn,_n,Pn){const In=[];for(const Nn of $n)for(const Rn in Nn.components){let Dn=Nn.components[Rn];if(!(Cn!=="beforeRouteEnter"&&!Nn.instances[Rn]))if(isRouteComponent(Dn)){const Fn=(Dn.__vccOpts||Dn)[Cn];Fn&&In.push(guardToPromiseFn(Fn,_n,Pn,Nn,Rn))}else{let Ln=Dn();In.push(()=>Ln.then(Fn=>{if(!Fn)return Promise.reject(new Error(`Couldn't resolve component "${Rn}" at "${Nn.path}"`));const Bn=isESModule(Fn)?Fn.default:Fn;Nn.components[Rn]=Bn;const zn=(Bn.__vccOpts||Bn)[Cn];return zn&&guardToPromiseFn(zn,_n,Pn,Nn,Rn)()}))}}return In}function isRouteComponent($n){return typeof $n=="object"||"displayName"in $n||"props"in $n||"__vccOpts"in $n}function useLink($n){const Cn=inject(routerKey),_n=inject(routeLocationKey),Pn=computed(()=>Cn.resolve(unref($n.to))),In=computed(()=>{const{matched:Ln}=Pn.value,{length:Fn}=Ln,Bn=Ln[Fn-1],Hn=_n.matched;if(!Bn||!Hn.length)return-1;const zn=Hn.findIndex(isSameRouteRecord.bind(null,Bn));if(zn>-1)return zn;const Wn=getOriginalPath(Ln[Fn-2]);return Fn>1&&getOriginalPath(Bn)===Wn&&Hn[Hn.length-1].path!==Wn?Hn.findIndex(isSameRouteRecord.bind(null,Ln[Fn-2])):zn}),Nn=computed(()=>In.value>-1&&includesParams(_n.params,Pn.value.params)),Rn=computed(()=>In.value>-1&&In.value===_n.matched.length-1&&isSameRouteLocationParams(_n.params,Pn.value.params));function Dn(Ln={}){return guardEvent(Ln)?Cn[unref($n.replace)?"replace":"push"](unref($n.to)).catch(noop$1):Promise.resolve()}return{route:Pn,href:computed(()=>Pn.value.href),isActive:Nn,isExactActive:Rn,navigate:Dn}}const RouterLinkImpl=defineComponent({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink,setup($n,{slots:Cn}){const _n=reactive(useLink($n)),{options:Pn}=inject(routerKey),In=computed(()=>({[getLinkClass($n.activeClass,Pn.linkActiveClass,"router-link-active")]:_n.isActive,[getLinkClass($n.exactActiveClass,Pn.linkExactActiveClass,"router-link-exact-active")]:_n.isExactActive}));return()=>{const Nn=Cn.default&&Cn.default(_n);return $n.custom?Nn:h$3("a",{"aria-current":_n.isExactActive?$n.ariaCurrentValue:null,href:_n.href,onClick:_n.navigate,class:In.value},Nn)}}}),RouterLink=RouterLinkImpl;function guardEvent($n){if(!($n.metaKey||$n.altKey||$n.ctrlKey||$n.shiftKey)&&!$n.defaultPrevented&&!($n.button!==void 0&&$n.button!==0)){if($n.currentTarget&&$n.currentTarget.getAttribute){const Cn=$n.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(Cn))return}return $n.preventDefault&&$n.preventDefault(),!0}}function includesParams($n,Cn){for(const _n in Cn){const Pn=Cn[_n],In=$n[_n];if(typeof Pn=="string"){if(Pn!==In)return!1}else if(!isArray$1(In)||In.length!==Pn.length||Pn.some((Nn,Rn)=>Nn!==In[Rn]))return!1}return!0}function getOriginalPath($n){return $n?$n.aliasOf?$n.aliasOf.path:$n.path:""}const getLinkClass=($n,Cn,_n)=>$n??Cn??_n,RouterViewImpl=defineComponent({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup($n,{attrs:Cn,slots:_n}){const Pn=inject(routerViewLocationKey),In=computed(()=>$n.route||Pn.value),Nn=inject(viewDepthKey,0),Rn=computed(()=>{let Fn=unref(Nn);const{matched:Bn}=In.value;let Hn;for(;(Hn=Bn[Fn])&&!Hn.components;)Fn++;return Fn}),Dn=computed(()=>In.value.matched[Rn.value]);provide(viewDepthKey,computed(()=>Rn.value+1)),provide(matchedRouteKey,Dn),provide(routerViewLocationKey,In);const Ln=ref();return watch(()=>[Ln.value,Dn.value,$n.name],([Fn,Bn,Hn],[zn,Wn,Yn])=>{Bn&&(Bn.instances[Hn]=Fn,Wn&&Wn!==Bn&&Fn&&Fn===zn&&(Bn.leaveGuards.size||(Bn.leaveGuards=Wn.leaveGuards),Bn.updateGuards.size||(Bn.updateGuards=Wn.updateGuards))),Fn&&Bn&&(!Wn||!isSameRouteRecord(Bn,Wn)||!zn)&&(Bn.enterCallbacks[Hn]||[]).forEach(Gn=>Gn(Fn))},{flush:"post"}),()=>{const Fn=In.value,Bn=$n.name,Hn=Dn.value,zn=Hn&&Hn.components[Bn];if(!zn)return normalizeSlot(_n.default,{Component:zn,route:Fn});const Wn=Hn.props[Bn],Yn=Wn?Wn===!0?Fn.params:typeof Wn=="function"?Wn(Fn):Wn:null,Go=h$3(zn,assign$3({},Yn,Cn,{onVnodeUnmounted:Xn=>{Xn.component.isUnmounted&&(Hn.instances[Bn]=null)},ref:Ln}));return normalizeSlot(_n.default,{Component:Go,route:Fn})||Go}}});function normalizeSlot($n,Cn){if(!$n)return null;const _n=$n(Cn);return _n.length===1?_n[0]:_n}const RouterView=RouterViewImpl;function createRouter($n){const Cn=createRouterMatcher($n.routes,$n),_n=$n.parseQuery||parseQuery,Pn=$n.stringifyQuery||stringifyQuery,In=$n.history,Nn=useCallbacks(),Rn=useCallbacks(),Dn=useCallbacks(),Ln=shallowRef(START_LOCATION_NORMALIZED);let Fn=START_LOCATION_NORMALIZED;isBrowser&&$n.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const Bn=applyToParams.bind(null,wa=>""+wa),Hn=applyToParams.bind(null,encodeParam),zn=applyToParams.bind(null,decode);function Wn(wa,La){let Na,$a;return isRouteName(wa)?(Na=Cn.getRecordMatcher(wa),$a=La):$a=wa,Cn.addRoute($a,Na)}function Yn(wa){const La=Cn.getRecordMatcher(wa);La&&Cn.removeRoute(La)}function Gn(){return Cn.getRoutes().map(wa=>wa.record)}function Go(wa){return!!Cn.getRecordMatcher(wa)}function Xn(wa,La){if(La=assign$3({},La||Ln.value),typeof wa=="string"){const pa=parseURL(_n,wa,La.path),Sa=Cn.resolve({path:pa.path},La),Aa=In.createHref(pa.fullPath);return assign$3(pa,Sa,{params:zn(Sa.params),hash:decode(pa.hash),redirectedFrom:void 0,href:Aa})}let Na;if("path"in wa)Na=assign$3({},wa,{path:parseURL(_n,wa.path,La.path).path});else{const pa=assign$3({},wa.params);for(const Sa in pa)pa[Sa]==null&&delete pa[Sa];Na=assign$3({},wa,{params:Hn(pa)}),La.params=Hn(La.params)}const $a=Cn.resolve(Na,La),ka=wa.hash||"";$a.params=Bn(zn($a.params));const Ha=stringifyURL(Pn,assign$3({},wa,{hash:encodeHash(ka),path:$a.path})),da=In.createHref(Ha);return assign$3({fullPath:Ha,hash:ka,query:Pn===stringifyQuery?normalizeQuery(wa.query):wa.query||{}},$a,{redirectedFrom:void 0,href:da})}function Yo(wa){return typeof wa=="string"?parseURL(_n,wa,Ln.value.path):assign$3({},wa)}function qo(wa,La){if(Fn!==wa)return createRouterError(8,{from:La,to:wa})}function Jo(wa){return nr(wa)}function Zo(wa){return Jo(assign$3(Yo(wa),{replace:!0}))}function rr(wa){const La=wa.matched[wa.matched.length-1];if(La&&La.redirect){const{redirect:Na}=La;let $a=typeof Na=="function"?Na(wa):Na;return typeof $a=="string"&&($a=$a.includes("?")||$a.includes("#")?$a=Yo($a):{path:$a},$a.params={}),assign$3({query:wa.query,hash:wa.hash,params:"path"in $a?{}:wa.params},$a)}}function nr(wa,La){const Na=Fn=Xn(wa),$a=Ln.value,ka=wa.state,Ha=wa.force,da=wa.replace===!0,pa=rr(Na);if(pa)return nr(assign$3(Yo(pa),{state:typeof pa=="object"?assign$3({},ka,pa.state):ka,force:Ha,replace:da}),La||Na);const Sa=Na;Sa.redirectedFrom=La;let Aa;return!Ha&&isSameRouteLocation(Pn,$a,Na)&&(Aa=createRouterError(16,{to:Sa,from:$a}),ya($a,$a,!0,!1)),(Aa?Promise.resolve(Aa):ra(Sa,$a)).catch(Ra=>isNavigationFailure(Ra)?isNavigationFailure(Ra,2)?Ra:ma(Ra):ia(Ra,Sa,$a)).then(Ra=>{if(Ra){if(isNavigationFailure(Ra,2))return nr(assign$3({replace:da},Yo(Ra.to),{state:typeof Ra.to=="object"?assign$3({},ka,Ra.to.state):ka,force:Ha}),La||Sa)}else Ra=la(Sa,$a,!0,da,ka);return ea(Sa,$a,Ra),Ra})}function ta(wa,La){const Na=qo(wa,La);return Na?Promise.reject(Na):Promise.resolve()}function oa(wa){const La=Ea.values().next().value;return La&&typeof La.runWithContext=="function"?La.runWithContext(wa):wa()}function ra(wa,La){let Na;const[$a,ka,Ha]=extractChangingRecords(wa,La);Na=extractComponentsGuards($a.reverse(),"beforeRouteLeave",wa,La);for(const pa of $a)pa.leaveGuards.forEach(Sa=>{Na.push(guardToPromiseFn(Sa,wa,La))});const da=ta.bind(null,wa,La);return Na.push(da),Ta(Na).then(()=>{Na=[];for(const pa of Nn.list())Na.push(guardToPromiseFn(pa,wa,La));return Na.push(da),Ta(Na)}).then(()=>{Na=extractComponentsGuards(ka,"beforeRouteUpdate",wa,La);for(const pa of ka)pa.updateGuards.forEach(Sa=>{Na.push(guardToPromiseFn(Sa,wa,La))});return Na.push(da),Ta(Na)}).then(()=>{Na=[];for(const pa of Ha)if(pa.beforeEnter)if(isArray$1(pa.beforeEnter))for(const Sa of pa.beforeEnter)Na.push(guardToPromiseFn(Sa,wa,La));else Na.push(guardToPromiseFn(pa.beforeEnter,wa,La));return Na.push(da),Ta(Na)}).then(()=>(wa.matched.forEach(pa=>pa.enterCallbacks={}),Na=extractComponentsGuards(Ha,"beforeRouteEnter",wa,La),Na.push(da),Ta(Na))).then(()=>{Na=[];for(const pa of Rn.list())Na.push(guardToPromiseFn(pa,wa,La));return Na.push(da),Ta(Na)}).catch(pa=>isNavigationFailure(pa,8)?pa:Promise.reject(pa))}function ea(wa,La,Na){Dn.list().forEach($a=>oa(()=>$a(wa,La,Na)))}function la(wa,La,Na,$a,ka){const Ha=qo(wa,La);if(Ha)return Ha;const da=La===START_LOCATION_NORMALIZED,pa=isBrowser?history.state:{};Na&&($a||da?In.replace(wa.fullPath,assign$3({scroll:da&&pa&&pa.scroll},ka)):In.push(wa.fullPath,ka)),Ln.value=wa,ya(wa,La,Na,da),ma()}let ua;function ga(){ua||(ua=In.listen((wa,La,Na)=>{if(!xa.listening)return;const $a=Xn(wa),ka=rr($a);if(ka){nr(assign$3(ka,{replace:!0}),$a).catch(noop$1);return}Fn=$a;const Ha=Ln.value;isBrowser&&saveScrollPosition(getScrollKey(Ha.fullPath,Na.delta),computeScrollPosition()),ra($a,Ha).catch(da=>isNavigationFailure(da,12)?da:isNavigationFailure(da,2)?(nr(da.to,$a).then(pa=>{isNavigationFailure(pa,20)&&!Na.delta&&Na.type===NavigationType.pop&&In.go(-1,!1)}).catch(noop$1),Promise.reject()):(Na.delta&&In.go(-Na.delta,!1),ia(da,$a,Ha))).then(da=>{da=da||la($a,Ha,!1),da&&(Na.delta&&!isNavigationFailure(da,8)?In.go(-Na.delta,!1):Na.type===NavigationType.pop&&isNavigationFailure(da,20)&&In.go(-1,!1)),ea($a,Ha,da)}).catch(noop$1)}))}let aa=useCallbacks(),ca=useCallbacks(),sa;function ia(wa,La,Na){ma(wa);const $a=ca.list();return $a.length?$a.forEach(ka=>ka(wa,La,Na)):console.error(wa),Promise.reject(wa)}function fa(){return sa&&Ln.value!==START_LOCATION_NORMALIZED?Promise.resolve():new Promise((wa,La)=>{aa.add([wa,La])})}function ma(wa){return sa||(sa=!wa,ga(),aa.list().forEach(([La,Na])=>wa?Na(wa):La()),aa.reset()),wa}function ya(wa,La,Na,$a){const{scrollBehavior:ka}=$n;if(!isBrowser||!ka)return Promise.resolve();const Ha=!Na&&getSavedScrollPosition(getScrollKey(wa.fullPath,0))||($a||!Na)&&history.state&&history.state.scroll||null;return nextTick().then(()=>ka(wa,La,Ha)).then(da=>da&&scrollToPosition(da)).catch(da=>ia(da,wa,La))}const ba=wa=>In.go(wa);let Ia;const Ea=new Set,xa={currentRoute:Ln,listening:!0,addRoute:Wn,removeRoute:Yn,hasRoute:Go,getRoutes:Gn,resolve:Xn,options:$n,push:Jo,replace:Zo,go:ba,back:()=>ba(-1),forward:()=>ba(1),beforeEach:Nn.add,beforeResolve:Rn.add,afterEach:Dn.add,onError:ca.add,isReady:fa,install(wa){const La=this;wa.component("RouterLink",RouterLink),wa.component("RouterView",RouterView),wa.config.globalProperties.$router=La,Object.defineProperty(wa.config.globalProperties,"$route",{enumerable:!0,get:()=>unref(Ln)}),isBrowser&&!Ia&&Ln.value===START_LOCATION_NORMALIZED&&(Ia=!0,Jo(In.location).catch(ka=>{}));const Na={};for(const ka in START_LOCATION_NORMALIZED)Object.defineProperty(Na,ka,{get:()=>Ln.value[ka],enumerable:!0});wa.provide(routerKey,La),wa.provide(routeLocationKey,shallowReactive(Na)),wa.provide(routerViewLocationKey,Ln);const $a=wa.unmount;Ea.add(wa),wa.unmount=function(){Ea.delete(wa),Ea.size<1&&(Fn=START_LOCATION_NORMALIZED,ua&&ua(),ua=null,Ln.value=START_LOCATION_NORMALIZED,Ia=!1,sa=!1),$a()}}};function Ta(wa){return wa.reduce((La,Na)=>La.then(()=>oa(Na)),Promise.resolve())}return xa}function extractChangingRecords($n,Cn){const _n=[],Pn=[],In=[],Nn=Math.max(Cn.matched.length,$n.matched.length);for(let Rn=0;RnisSameRouteRecord(Fn,Dn))?Pn.push(Dn):_n.push(Dn));const Ln=$n.matched[Rn];Ln&&(Cn.matched.find(Fn=>isSameRouteRecord(Fn,Ln))||In.push(Ln))}return[_n,Pn,In]}function useRouter(){return inject(routerKey)}function useRoute(){return inject(routeLocationKey)}const scriptRel="modulepreload",assetsURL=function($n){return"/admin/"+$n},seen={},__vitePreload=function(Cn,_n,Pn){let In=Promise.resolve();if(_n&&_n.length>0){const Nn=document.getElementsByTagName("link");In=Promise.all(_n.map(Rn=>{if(Rn=assetsURL(Rn),Rn in seen)return;seen[Rn]=!0;const Dn=Rn.endsWith(".css"),Ln=Dn?'[rel="stylesheet"]':"";if(!!Pn)for(let Hn=Nn.length-1;Hn>=0;Hn--){const zn=Nn[Hn];if(zn.href===Rn&&(!Dn||zn.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${Rn}"]${Ln}`))return;const Bn=document.createElement("link");if(Bn.rel=Dn?"stylesheet":scriptRel,Dn||(Bn.as="script",Bn.crossOrigin=""),Bn.href=Rn,document.head.appendChild(Bn),Dn)return new Promise((Hn,zn)=>{Bn.addEventListener("load",Hn),Bn.addEventListener("error",()=>zn(new Error(`Unable to preload CSS for ${Rn}`)))})}))}return In.then(()=>Cn()).catch(Nn=>{const Rn=new Event("vite:preloadError",{cancelable:!0});if(Rn.payload=Nn,window.dispatchEvent(Rn),!Rn.defaultPrevented)throw Nn})},matchIconName=/^[a-z0-9]+(-[a-z0-9]+)*$/,stringToIcon=($n,Cn,_n,Pn="")=>{const In=$n.split(":");if($n.slice(0,1)==="@"){if(In.length<2||In.length>3)return null;Pn=In.shift().slice(1)}if(In.length>3||!In.length)return null;if(In.length>1){const Dn=In.pop(),Ln=In.pop(),Fn={provider:In.length>0?In[0]:Pn,prefix:Ln,name:Dn};return Cn&&!validateIconName(Fn)?null:Fn}const Nn=In[0],Rn=Nn.split("-");if(Rn.length>1){const Dn={provider:Pn,prefix:Rn.shift(),name:Rn.join("-")};return Cn&&!validateIconName(Dn)?null:Dn}if(_n&&Pn===""){const Dn={provider:Pn,prefix:"",name:Nn};return Cn&&!validateIconName(Dn,_n)?null:Dn}return null},validateIconName=($n,Cn)=>$n?!!(($n.provider===""||$n.provider.match(matchIconName))&&(Cn&&$n.prefix===""||$n.prefix.match(matchIconName))&&$n.name.match(matchIconName)):!1,defaultIconDimensions=Object.freeze({left:0,top:0,width:16,height:16}),defaultIconTransformations=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),defaultIconProps=Object.freeze({...defaultIconDimensions,...defaultIconTransformations}),defaultExtendedIconProps=Object.freeze({...defaultIconProps,body:"",hidden:!1});function mergeIconTransformations($n,Cn){const _n={};!$n.hFlip!=!Cn.hFlip&&(_n.hFlip=!0),!$n.vFlip!=!Cn.vFlip&&(_n.vFlip=!0);const Pn=(($n.rotate||0)+(Cn.rotate||0))%4;return Pn&&(_n.rotate=Pn),_n}function mergeIconData($n,Cn){const _n=mergeIconTransformations($n,Cn);for(const Pn in defaultExtendedIconProps)Pn in defaultIconTransformations?Pn in $n&&!(Pn in _n)&&(_n[Pn]=defaultIconTransformations[Pn]):Pn in Cn?_n[Pn]=Cn[Pn]:Pn in $n&&(_n[Pn]=$n[Pn]);return _n}function getIconsTree($n,Cn){const _n=$n.icons,Pn=$n.aliases||Object.create(null),In=Object.create(null);function Nn(Rn){if(_n[Rn])return In[Rn]=[];if(!(Rn in In)){In[Rn]=null;const Dn=Pn[Rn]&&Pn[Rn].parent,Ln=Dn&&Nn(Dn);Ln&&(In[Rn]=[Dn].concat(Ln))}return In[Rn]}return(Cn||Object.keys(_n).concat(Object.keys(Pn))).forEach(Nn),In}function internalGetIconData($n,Cn,_n){const Pn=$n.icons,In=$n.aliases||Object.create(null);let Nn={};function Rn(Dn){Nn=mergeIconData(Pn[Dn]||In[Dn],Nn)}return Rn(Cn),_n.forEach(Rn),mergeIconData($n,Nn)}function parseIconSet($n,Cn){const _n=[];if(typeof $n!="object"||typeof $n.icons!="object")return _n;$n.not_found instanceof Array&&$n.not_found.forEach(In=>{Cn(In,null),_n.push(In)});const Pn=getIconsTree($n);for(const In in Pn){const Nn=Pn[In];Nn&&(Cn(In,internalGetIconData($n,In,Nn)),_n.push(In))}return _n}const optionalPropertyDefaults={provider:"",aliases:{},not_found:{},...defaultIconDimensions};function checkOptionalProps($n,Cn){for(const _n in Cn)if(_n in $n&&typeof $n[_n]!=typeof Cn[_n])return!1;return!0}function quicklyValidateIconSet($n){if(typeof $n!="object"||$n===null)return null;const Cn=$n;if(typeof Cn.prefix!="string"||!$n.icons||typeof $n.icons!="object"||!checkOptionalProps($n,optionalPropertyDefaults))return null;const _n=Cn.icons;for(const In in _n){const Nn=_n[In];if(!In.match(matchIconName)||typeof Nn.body!="string"||!checkOptionalProps(Nn,defaultExtendedIconProps))return null}const Pn=Cn.aliases||Object.create(null);for(const In in Pn){const Nn=Pn[In],Rn=Nn.parent;if(!In.match(matchIconName)||typeof Rn!="string"||!_n[Rn]&&!Pn[Rn]||!checkOptionalProps(Nn,defaultExtendedIconProps))return null}return Cn}const dataStorage=Object.create(null);function newStorage($n,Cn){return{provider:$n,prefix:Cn,icons:Object.create(null),missing:new Set}}function getStorage($n,Cn){const _n=dataStorage[$n]||(dataStorage[$n]=Object.create(null));return _n[Cn]||(_n[Cn]=newStorage($n,Cn))}function addIconSet($n,Cn){return quicklyValidateIconSet(Cn)?parseIconSet(Cn,(_n,Pn)=>{Pn?$n.icons[_n]=Pn:$n.missing.add(_n)}):[]}function addIconToStorage($n,Cn,_n){try{if(typeof _n.body=="string")return $n.icons[Cn]={..._n},!0}catch{}return!1}let simpleNames=!1;function allowSimpleNames($n){return typeof $n=="boolean"&&(simpleNames=$n),simpleNames}function getIconData($n){const Cn=typeof $n=="string"?stringToIcon($n,!0,simpleNames):$n;if(Cn){const _n=getStorage(Cn.provider,Cn.prefix),Pn=Cn.name;return _n.icons[Pn]||(_n.missing.has(Pn)?null:void 0)}}function addIcon($n,Cn){const _n=stringToIcon($n,!0,simpleNames);if(!_n)return!1;const Pn=getStorage(_n.provider,_n.prefix);return addIconToStorage(Pn,_n.name,Cn)}function addCollection($n,Cn){if(typeof $n!="object")return!1;if(typeof Cn!="string"&&(Cn=$n.provider||""),simpleNames&&!Cn&&!$n.prefix){let In=!1;return quicklyValidateIconSet($n)&&($n.prefix="",parseIconSet($n,(Nn,Rn)=>{Rn&&addIcon(Nn,Rn)&&(In=!0)})),In}const _n=$n.prefix;if(!validateIconName({provider:Cn,prefix:_n,name:"a"}))return!1;const Pn=getStorage(Cn,_n);return!!addIconSet(Pn,$n)}const defaultIconSizeCustomisations=Object.freeze({width:null,height:null}),defaultIconCustomisations=Object.freeze({...defaultIconSizeCustomisations,...defaultIconTransformations}),unitsSplit=/(-?[0-9.]*[0-9]+[0-9.]*)/g,unitsTest=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function calculateSize($n,Cn,_n){if(Cn===1)return $n;if(_n=_n||100,typeof $n=="number")return Math.ceil($n*Cn*_n)/_n;if(typeof $n!="string")return $n;const Pn=$n.split(unitsSplit);if(Pn===null||!Pn.length)return $n;const In=[];let Nn=Pn.shift(),Rn=unitsTest.test(Nn);for(;;){if(Rn){const Dn=parseFloat(Nn);isNaN(Dn)?In.push(Nn):In.push(Math.ceil(Dn*Cn*_n)/_n)}else In.push(Nn);if(Nn=Pn.shift(),Nn===void 0)return In.join("");Rn=!Rn}}const isUnsetKeyword=$n=>$n==="unset"||$n==="undefined"||$n==="none";function iconToSVG($n,Cn){const _n={...defaultIconProps,...$n},Pn={...defaultIconCustomisations,...Cn},In={left:_n.left,top:_n.top,width:_n.width,height:_n.height};let Nn=_n.body;[_n,Pn].forEach(Yn=>{const Gn=[],Go=Yn.hFlip,Xn=Yn.vFlip;let Yo=Yn.rotate;Go?Xn?Yo+=2:(Gn.push("translate("+(In.width+In.left).toString()+" "+(0-In.top).toString()+")"),Gn.push("scale(-1 1)"),In.top=In.left=0):Xn&&(Gn.push("translate("+(0-In.left).toString()+" "+(In.height+In.top).toString()+")"),Gn.push("scale(1 -1)"),In.top=In.left=0);let qo;switch(Yo<0&&(Yo-=Math.floor(Yo/4)*4),Yo=Yo%4,Yo){case 1:qo=In.height/2+In.top,Gn.unshift("rotate(90 "+qo.toString()+" "+qo.toString()+")");break;case 2:Gn.unshift("rotate(180 "+(In.width/2+In.left).toString()+" "+(In.height/2+In.top).toString()+")");break;case 3:qo=In.width/2+In.left,Gn.unshift("rotate(-90 "+qo.toString()+" "+qo.toString()+")");break}Yo%2===1&&(In.left!==In.top&&(qo=In.left,In.left=In.top,In.top=qo),In.width!==In.height&&(qo=In.width,In.width=In.height,In.height=qo)),Gn.length&&(Nn=''+Nn+"")});const Rn=Pn.width,Dn=Pn.height,Ln=In.width,Fn=In.height;let Bn,Hn;Rn===null?(Hn=Dn===null?"1em":Dn==="auto"?Fn:Dn,Bn=calculateSize(Hn,Ln/Fn)):(Bn=Rn==="auto"?Ln:Rn,Hn=Dn===null?calculateSize(Bn,Fn/Ln):Dn==="auto"?Fn:Dn);const zn={},Wn=(Yn,Gn)=>{isUnsetKeyword(Gn)||(zn[Yn]=Gn.toString())};return Wn("width",Bn),Wn("height",Hn),zn.viewBox=In.left.toString()+" "+In.top.toString()+" "+Ln.toString()+" "+Fn.toString(),{attributes:zn,body:Nn}}const regex=/\sid="(\S+)"/g,randomPrefix="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16);let counter=0;function replaceIDs($n,Cn=randomPrefix){const _n=[];let Pn;for(;Pn=regex.exec($n);)_n.push(Pn[1]);if(!_n.length)return $n;const In="suffix"+(Math.random()*16777216|Date.now()).toString(16);return _n.forEach(Nn=>{const Rn=typeof Cn=="function"?Cn(Nn):Cn+(counter++).toString(),Dn=Nn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");$n=$n.replace(new RegExp('([#;"])('+Dn+')([")]|\\.[a-z])',"g"),"$1"+Rn+In+"$3")}),$n=$n.replace(new RegExp(In,"g"),""),$n}const storage=Object.create(null);function setAPIModule($n,Cn){storage[$n]=Cn}function getAPIModule($n){return storage[$n]||storage[""]}function createAPIConfig($n){let Cn;if(typeof $n.resources=="string")Cn=[$n.resources];else if(Cn=$n.resources,!(Cn instanceof Array)||!Cn.length)return null;return{resources:Cn,path:$n.path||"/",maxURL:$n.maxURL||500,rotate:$n.rotate||750,timeout:$n.timeout||5e3,random:$n.random===!0,index:$n.index||0,dataAfterTimeout:$n.dataAfterTimeout!==!1}}const configStorage=Object.create(null),fallBackAPISources=["https://api.simplesvg.com","https://api.unisvg.com"],fallBackAPI=[];for(;fallBackAPISources.length>0;)fallBackAPISources.length===1||Math.random()>.5?fallBackAPI.push(fallBackAPISources.shift()):fallBackAPI.push(fallBackAPISources.pop());configStorage[""]=createAPIConfig({resources:["https://api.iconify.design"].concat(fallBackAPI)});function addAPIProvider($n,Cn){const _n=createAPIConfig(Cn);return _n===null?!1:(configStorage[$n]=_n,!0)}function getAPIConfig($n){return configStorage[$n]}const detectFetch=()=>{let $n;try{if($n=fetch,typeof $n=="function")return $n}catch{}};let fetchModule=detectFetch();function calculateMaxLength($n,Cn){const _n=getAPIConfig($n);if(!_n)return 0;let Pn;if(!_n.maxURL)Pn=0;else{let In=0;_n.resources.forEach(Rn=>{In=Math.max(In,Rn.length)});const Nn=Cn+".json?icons=";Pn=_n.maxURL-In-_n.path.length-Nn.length}return Pn}function shouldAbort($n){return $n===404}const prepare=($n,Cn,_n)=>{const Pn=[],In=calculateMaxLength($n,Cn),Nn="icons";let Rn={type:Nn,provider:$n,prefix:Cn,icons:[]},Dn=0;return _n.forEach((Ln,Fn)=>{Dn+=Ln.length+1,Dn>=In&&Fn>0&&(Pn.push(Rn),Rn={type:Nn,provider:$n,prefix:Cn,icons:[]},Dn=Ln.length),Rn.icons.push(Ln)}),Pn.push(Rn),Pn};function getPath($n){if(typeof $n=="string"){const Cn=getAPIConfig($n);if(Cn)return Cn.path}return"/"}const send=($n,Cn,_n)=>{if(!fetchModule){_n("abort",424);return}let Pn=getPath(Cn.provider);switch(Cn.type){case"icons":{const Nn=Cn.prefix,Dn=Cn.icons.join(","),Ln=new URLSearchParams({icons:Dn});Pn+=Nn+".json?"+Ln.toString();break}case"custom":{const Nn=Cn.uri;Pn+=Nn.slice(0,1)==="/"?Nn.slice(1):Nn;break}default:_n("abort",400);return}let In=503;fetchModule($n+Pn).then(Nn=>{const Rn=Nn.status;if(Rn!==200){setTimeout(()=>{_n(shouldAbort(Rn)?"abort":"next",Rn)});return}return In=501,Nn.json()}).then(Nn=>{if(typeof Nn!="object"||Nn===null){setTimeout(()=>{Nn===404?_n("abort",Nn):_n("next",In)});return}setTimeout(()=>{_n("success",Nn)})}).catch(()=>{_n("next",In)})},fetchAPIModule={prepare,send};function sortIcons($n){const Cn={loaded:[],missing:[],pending:[]},_n=Object.create(null);$n.sort((In,Nn)=>In.provider!==Nn.provider?In.provider.localeCompare(Nn.provider):In.prefix!==Nn.prefix?In.prefix.localeCompare(Nn.prefix):In.name.localeCompare(Nn.name));let Pn={provider:"",prefix:"",name:""};return $n.forEach(In=>{if(Pn.name===In.name&&Pn.prefix===In.prefix&&Pn.provider===In.provider)return;Pn=In;const Nn=In.provider,Rn=In.prefix,Dn=In.name,Ln=_n[Nn]||(_n[Nn]=Object.create(null)),Fn=Ln[Rn]||(Ln[Rn]=getStorage(Nn,Rn));let Bn;Dn in Fn.icons?Bn=Cn.loaded:Rn===""||Fn.missing.has(Dn)?Bn=Cn.missing:Bn=Cn.pending;const Hn={provider:Nn,prefix:Rn,name:Dn};Bn.push(Hn)}),Cn}function removeCallback($n,Cn){$n.forEach(_n=>{const Pn=_n.loaderCallbacks;Pn&&(_n.loaderCallbacks=Pn.filter(In=>In.id!==Cn))})}function updateCallbacks($n){$n.pendingCallbacksFlag||($n.pendingCallbacksFlag=!0,setTimeout(()=>{$n.pendingCallbacksFlag=!1;const Cn=$n.loaderCallbacks?$n.loaderCallbacks.slice(0):[];if(!Cn.length)return;let _n=!1;const Pn=$n.provider,In=$n.prefix;Cn.forEach(Nn=>{const Rn=Nn.icons,Dn=Rn.pending.length;Rn.pending=Rn.pending.filter(Ln=>{if(Ln.prefix!==In)return!0;const Fn=Ln.name;if($n.icons[Fn])Rn.loaded.push({provider:Pn,prefix:In,name:Fn});else if($n.missing.has(Fn))Rn.missing.push({provider:Pn,prefix:In,name:Fn});else return _n=!0,!0;return!1}),Rn.pending.length!==Dn&&(_n||removeCallback([$n],Nn.id),Nn.callback(Rn.loaded.slice(0),Rn.missing.slice(0),Rn.pending.slice(0),Nn.abort))})}))}let idCounter=0;function storeCallback($n,Cn,_n){const Pn=idCounter++,In=removeCallback.bind(null,_n,Pn);if(!Cn.pending.length)return In;const Nn={id:Pn,icons:Cn,callback:$n,abort:In};return _n.forEach(Rn=>{(Rn.loaderCallbacks||(Rn.loaderCallbacks=[])).push(Nn)}),In}function listToIcons($n,Cn=!0,_n=!1){const Pn=[];return $n.forEach(In=>{const Nn=typeof In=="string"?stringToIcon(In,Cn,_n):In;Nn&&Pn.push(Nn)}),Pn}var defaultConfig={resources:[],index:0,timeout:2e3,rotate:750,random:!1,dataAfterTimeout:!1};function sendQuery($n,Cn,_n,Pn){const In=$n.resources.length,Nn=$n.random?Math.floor(Math.random()*In):$n.index;let Rn;if($n.random){let rr=$n.resources.slice(0);for(Rn=[];rr.length>1;){const nr=Math.floor(Math.random()*rr.length);Rn.push(rr[nr]),rr=rr.slice(0,nr).concat(rr.slice(nr+1))}Rn=Rn.concat(rr)}else Rn=$n.resources.slice(Nn).concat($n.resources.slice(0,Nn));const Dn=Date.now();let Ln="pending",Fn=0,Bn,Hn=null,zn=[],Wn=[];typeof Pn=="function"&&Wn.push(Pn);function Yn(){Hn&&(clearTimeout(Hn),Hn=null)}function Gn(){Ln==="pending"&&(Ln="aborted"),Yn(),zn.forEach(rr=>{rr.status==="pending"&&(rr.status="aborted")}),zn=[]}function Go(rr,nr){nr&&(Wn=[]),typeof rr=="function"&&Wn.push(rr)}function Xn(){return{startTime:Dn,payload:Cn,status:Ln,queriesSent:Fn,queriesPending:zn.length,subscribe:Go,abort:Gn}}function Yo(){Ln="failed",Wn.forEach(rr=>{rr(void 0,Bn)})}function qo(){zn.forEach(rr=>{rr.status==="pending"&&(rr.status="aborted")}),zn=[]}function Jo(rr,nr,ta){const oa=nr!=="success";switch(zn=zn.filter(ra=>ra!==rr),Ln){case"pending":break;case"failed":if(oa||!$n.dataAfterTimeout)return;break;default:return}if(nr==="abort"){Bn=ta,Yo();return}if(oa){Bn=ta,zn.length||(Rn.length?Zo():Yo());return}if(Yn(),qo(),!$n.random){const ra=$n.resources.indexOf(rr.resource);ra!==-1&&ra!==$n.index&&($n.index=ra)}Ln="completed",Wn.forEach(ra=>{ra(ta)})}function Zo(){if(Ln!=="pending")return;Yn();const rr=Rn.shift();if(rr===void 0){if(zn.length){Hn=setTimeout(()=>{Yn(),Ln==="pending"&&(qo(),Yo())},$n.timeout);return}Yo();return}const nr={status:"pending",resource:rr,callback:(ta,oa)=>{Jo(nr,ta,oa)}};zn.push(nr),Fn++,Hn=setTimeout(Zo,$n.rotate),_n(rr,Cn,nr.callback)}return setTimeout(Zo),Xn}function initRedundancy($n){const Cn={...defaultConfig,...$n};let _n=[];function Pn(){_n=_n.filter(Dn=>Dn().status==="pending")}function In(Dn,Ln,Fn){const Bn=sendQuery(Cn,Dn,Ln,(Hn,zn)=>{Pn(),Fn&&Fn(Hn,zn)});return _n.push(Bn),Bn}function Nn(Dn){return _n.find(Ln=>Dn(Ln))||null}return{query:In,find:Nn,setIndex:Dn=>{Cn.index=Dn},getIndex:()=>Cn.index,cleanup:Pn}}function emptyCallback$1(){}const redundancyCache=Object.create(null);function getRedundancyCache($n){if(!redundancyCache[$n]){const Cn=getAPIConfig($n);if(!Cn)return;const _n=initRedundancy(Cn),Pn={config:Cn,redundancy:_n};redundancyCache[$n]=Pn}return redundancyCache[$n]}function sendAPIQuery($n,Cn,_n){let Pn,In;if(typeof $n=="string"){const Nn=getAPIModule($n);if(!Nn)return _n(void 0,424),emptyCallback$1;In=Nn.send;const Rn=getRedundancyCache($n);Rn&&(Pn=Rn.redundancy)}else{const Nn=createAPIConfig($n);if(Nn){Pn=initRedundancy(Nn);const Rn=$n.resources?$n.resources[0]:"",Dn=getAPIModule(Rn);Dn&&(In=Dn.send)}}return!Pn||!In?(_n(void 0,424),emptyCallback$1):Pn.query(Cn,In,_n)().abort}const browserCacheVersion="iconify2",browserCachePrefix="iconify",browserCacheCountKey=browserCachePrefix+"-count",browserCacheVersionKey=browserCachePrefix+"-version",browserStorageHour=36e5,browserStorageCacheExpiration=168;function getStoredItem($n,Cn){try{return $n.getItem(Cn)}catch{}}function setStoredItem($n,Cn,_n){try{return $n.setItem(Cn,_n),!0}catch{}}function removeStoredItem($n,Cn){try{$n.removeItem(Cn)}catch{}}function setBrowserStorageItemsCount($n,Cn){return setStoredItem($n,browserCacheCountKey,Cn.toString())}function getBrowserStorageItemsCount($n){return parseInt(getStoredItem($n,browserCacheCountKey))||0}const browserStorageConfig={local:!0,session:!0},browserStorageEmptyItems={local:new Set,session:new Set};let browserStorageStatus=!1;function setBrowserStorageStatus($n){browserStorageStatus=$n}let _window=typeof window>"u"?{}:window;function getBrowserStorage($n){const Cn=$n+"Storage";try{if(_window&&_window[Cn]&&typeof _window[Cn].length=="number")return _window[Cn]}catch{}browserStorageConfig[$n]=!1}function iterateBrowserStorage($n,Cn){const _n=getBrowserStorage($n);if(!_n)return;const Pn=getStoredItem(_n,browserCacheVersionKey);if(Pn!==browserCacheVersion){if(Pn){const Dn=getBrowserStorageItemsCount(_n);for(let Ln=0;Ln{const Ln=browserCachePrefix+Dn.toString(),Fn=getStoredItem(_n,Ln);if(typeof Fn=="string"){try{const Bn=JSON.parse(Fn);if(typeof Bn=="object"&&typeof Bn.cached=="number"&&Bn.cached>In&&typeof Bn.provider=="string"&&typeof Bn.data=="object"&&typeof Bn.data.prefix=="string"&&Cn(Bn,Dn))return!0}catch{}removeStoredItem(_n,Ln)}};let Rn=getBrowserStorageItemsCount(_n);for(let Dn=Rn-1;Dn>=0;Dn--)Nn(Dn)||(Dn===Rn-1?(Rn--,setBrowserStorageItemsCount(_n,Rn)):browserStorageEmptyItems[$n].add(Dn))}function initBrowserStorage(){if(!browserStorageStatus){setBrowserStorageStatus(!0);for(const $n in browserStorageConfig)iterateBrowserStorage($n,Cn=>{const _n=Cn.data,Pn=Cn.provider,In=_n.prefix,Nn=getStorage(Pn,In);if(!addIconSet(Nn,_n).length)return!1;const Rn=_n.lastModified||-1;return Nn.lastModifiedCached=Nn.lastModifiedCached?Math.min(Nn.lastModifiedCached,Rn):Rn,!0})}}function updateLastModified($n,Cn){const _n=$n.lastModifiedCached;if(_n&&_n>=Cn)return _n===Cn;if($n.lastModifiedCached=Cn,_n)for(const Pn in browserStorageConfig)iterateBrowserStorage(Pn,In=>{const Nn=In.data;return In.provider!==$n.provider||Nn.prefix!==$n.prefix||Nn.lastModified===Cn});return!0}function storeInBrowserStorage($n,Cn){browserStorageStatus||initBrowserStorage();function _n(Pn){let In;if(!browserStorageConfig[Pn]||!(In=getBrowserStorage(Pn)))return;const Nn=browserStorageEmptyItems[Pn];let Rn;if(Nn.size)Nn.delete(Rn=Array.from(Nn).shift());else if(Rn=getBrowserStorageItemsCount(In),!setBrowserStorageItemsCount(In,Rn+1))return;const Dn={cached:Math.floor(Date.now()/browserStorageHour),provider:$n.provider,data:Cn};return setStoredItem(In,browserCachePrefix+Rn.toString(),JSON.stringify(Dn))}Cn.lastModified&&!updateLastModified($n,Cn.lastModified)||Object.keys(Cn.icons).length&&(Cn.not_found&&(Cn=Object.assign({},Cn),delete Cn.not_found),_n("local")||_n("session"))}function emptyCallback(){}function loadedNewIcons($n){$n.iconsLoaderFlag||($n.iconsLoaderFlag=!0,setTimeout(()=>{$n.iconsLoaderFlag=!1,updateCallbacks($n)}))}function loadNewIcons($n,Cn){$n.iconsToLoad?$n.iconsToLoad=$n.iconsToLoad.concat(Cn).sort():$n.iconsToLoad=Cn,$n.iconsQueueFlag||($n.iconsQueueFlag=!0,setTimeout(()=>{$n.iconsQueueFlag=!1;const{provider:_n,prefix:Pn}=$n,In=$n.iconsToLoad;delete $n.iconsToLoad;let Nn;if(!In||!(Nn=getAPIModule(_n)))return;Nn.prepare(_n,Pn,In).forEach(Dn=>{sendAPIQuery(_n,Dn,Ln=>{if(typeof Ln!="object")Dn.icons.forEach(Fn=>{$n.missing.add(Fn)});else try{const Fn=addIconSet($n,Ln);if(!Fn.length)return;const Bn=$n.pendingIcons;Bn&&Fn.forEach(Hn=>{Bn.delete(Hn)}),storeInBrowserStorage($n,Ln)}catch(Fn){console.error(Fn)}loadedNewIcons($n)})})}))}const loadIcons=($n,Cn)=>{const _n=listToIcons($n,!0,allowSimpleNames()),Pn=sortIcons(_n);if(!Pn.pending.length){let Ln=!0;return Cn&&setTimeout(()=>{Ln&&Cn(Pn.loaded,Pn.missing,Pn.pending,emptyCallback)}),()=>{Ln=!1}}const In=Object.create(null),Nn=[];let Rn,Dn;return Pn.pending.forEach(Ln=>{const{provider:Fn,prefix:Bn}=Ln;if(Bn===Dn&&Fn===Rn)return;Rn=Fn,Dn=Bn,Nn.push(getStorage(Fn,Bn));const Hn=In[Fn]||(In[Fn]=Object.create(null));Hn[Bn]||(Hn[Bn]=[])}),Pn.pending.forEach(Ln=>{const{provider:Fn,prefix:Bn,name:Hn}=Ln,zn=getStorage(Fn,Bn),Wn=zn.pendingIcons||(zn.pendingIcons=new Set);Wn.has(Hn)||(Wn.add(Hn),In[Fn][Bn].push(Hn))}),Nn.forEach(Ln=>{const{provider:Fn,prefix:Bn}=Ln;In[Fn][Bn].length&&loadNewIcons(Ln,In[Fn][Bn])}),Cn?storeCallback(Cn,Pn,Nn):emptyCallback};function mergeCustomisations($n,Cn){const _n={...$n};for(const Pn in Cn){const In=Cn[Pn],Nn=typeof In;Pn in defaultIconSizeCustomisations?(In===null||In&&(Nn==="string"||Nn==="number"))&&(_n[Pn]=In):Nn===typeof _n[Pn]&&(_n[Pn]=Pn==="rotate"?In%4:In)}return _n}const separator=/[\s,]+/;function flipFromString($n,Cn){Cn.split(separator).forEach(_n=>{switch(_n.trim()){case"horizontal":$n.hFlip=!0;break;case"vertical":$n.vFlip=!0;break}})}function rotateFromString($n,Cn=0){const _n=$n.replace(/^-?[0-9.]*/,"");function Pn(In){for(;In<0;)In+=4;return In%4}if(_n===""){const In=parseInt($n);return isNaN(In)?0:Pn(In)}else if(_n!==$n){let In=0;switch(_n){case"%":In=25;break;case"deg":In=90}if(In){let Nn=parseFloat($n.slice(0,$n.length-_n.length));return isNaN(Nn)?0:(Nn=Nn/In,Nn%1===0?Pn(Nn):0)}}return Cn}function iconToHTML($n,Cn){let _n=$n.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const Pn in Cn)_n+=" "+Pn+'="'+Cn[Pn]+'"';return'"+$n+""}function encodeSVGforURL($n){return $n.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(//g,"%3E").replace(/\s+/g," ")}function svgToData($n){return"data:image/svg+xml,"+encodeSVGforURL($n)}function svgToURL($n){return'url("'+svgToData($n)+'")'}const defaultExtendedIconCustomisations={...defaultIconCustomisations,inline:!1},svgDefaults={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":!0,role:"img"},commonProps={display:"inline-block"},monotoneProps={backgroundColor:"currentColor"},coloredProps={backgroundColor:"transparent"},propsToAdd={Image:"var(--svg)",Repeat:"no-repeat",Size:"100% 100%"},propsToAddTo={webkitMask:monotoneProps,mask:monotoneProps,background:coloredProps};for(const $n in propsToAddTo){const Cn=propsToAddTo[$n];for(const _n in propsToAdd)Cn[$n+_n]=propsToAdd[_n]}const customisationAliases={};["horizontal","vertical"].forEach($n=>{const Cn=$n.slice(0,1)+"Flip";customisationAliases[$n+"-flip"]=Cn,customisationAliases[$n.slice(0,1)+"-flip"]=Cn,customisationAliases[$n+"Flip"]=Cn});function fixSize($n){return $n+($n.match(/^[-0-9.]+$/)?"px":"")}const render=($n,Cn)=>{const _n=mergeCustomisations(defaultExtendedIconCustomisations,Cn),Pn={...svgDefaults},In=Cn.mode||"svg",Nn={},Rn=Cn.style,Dn=typeof Rn=="object"&&!(Rn instanceof Array)?Rn:{};for(let Gn in Cn){const Go=Cn[Gn];if(Go!==void 0)switch(Gn){case"icon":case"style":case"onLoad":case"mode":break;case"inline":case"hFlip":case"vFlip":_n[Gn]=Go===!0||Go==="true"||Go===1;break;case"flip":typeof Go=="string"&&flipFromString(_n,Go);break;case"color":Nn.color=Go;break;case"rotate":typeof Go=="string"?_n[Gn]=rotateFromString(Go):typeof Go=="number"&&(_n[Gn]=Go);break;case"ariaHidden":case"aria-hidden":Go!==!0&&Go!=="true"&&delete Pn["aria-hidden"];break;default:{const Xn=customisationAliases[Gn];Xn?(Go===!0||Go==="true"||Go===1)&&(_n[Xn]=!0):defaultExtendedIconCustomisations[Gn]===void 0&&(Pn[Gn]=Go)}}}const Ln=iconToSVG($n,_n),Fn=Ln.attributes;if(_n.inline&&(Nn.verticalAlign="-0.125em"),In==="svg"){Pn.style={...Nn,...Dn},Object.assign(Pn,Fn);let Gn=0,Go=Cn.id;return typeof Go=="string"&&(Go=Go.replace(/-/g,"_")),Pn.innerHTML=replaceIDs(Ln.body,Go?()=>Go+"ID"+Gn++:"iconifyVue"),h$3("svg",Pn)}const{body:Bn,width:Hn,height:zn}=$n,Wn=In==="mask"||(In==="bg"?!1:Bn.indexOf("currentColor")!==-1),Yn=iconToHTML(Bn,{...Fn,width:Hn+"",height:zn+""});return Pn.style={...Nn,"--svg":svgToURL(Yn),width:fixSize(Fn.width),height:fixSize(Fn.height),...commonProps,...Wn?monotoneProps:coloredProps,...Dn},h$3("span",Pn)};allowSimpleNames(!0);setAPIModule("",fetchAPIModule);if(typeof document<"u"&&typeof window<"u"){initBrowserStorage();const $n=window;if($n.IconifyPreload!==void 0){const Cn=$n.IconifyPreload,_n="Invalid IconifyPreload syntax.";typeof Cn=="object"&&Cn!==null&&(Cn instanceof Array?Cn:[Cn]).forEach(Pn=>{try{(typeof Pn!="object"||Pn===null||Pn instanceof Array||typeof Pn.icons!="object"||typeof Pn.prefix!="string"||!addCollection(Pn))&&console.error(_n)}catch{console.error(_n)}})}if($n.IconifyProviders!==void 0){const Cn=$n.IconifyProviders;if(typeof Cn=="object"&&Cn!==null)for(let _n in Cn){const Pn="IconifyProviders["+_n+"] is invalid.";try{const In=Cn[_n];if(typeof In!="object"||!In||In.resources===void 0)continue;addAPIProvider(_n,In)||console.error(Pn)}catch{console.error(Pn)}}}}const emptyIcon={...defaultIconProps,body:""},Icon=defineComponent({inheritAttrs:!1,data(){return{iconMounted:!1,counter:0}},mounted(){this._name="",this._loadingIcon=null,this.iconMounted=!0},unmounted(){this.abortLoading()},methods:{abortLoading(){this._loadingIcon&&(this._loadingIcon.abort(),this._loadingIcon=null)},getIcon($n,Cn){if(typeof $n=="object"&&$n!==null&&typeof $n.body=="string")return this._name="",this.abortLoading(),{data:$n};let _n;if(typeof $n!="string"||(_n=stringToIcon($n,!1,!0))===null)return this.abortLoading(),null;const Pn=getIconData(_n);if(!Pn)return(!this._loadingIcon||this._loadingIcon.name!==$n)&&(this.abortLoading(),this._name="",Pn!==null&&(this._loadingIcon={name:$n,abort:loadIcons([_n],()=>{this.counter++})})),null;this.abortLoading(),this._name!==$n&&(this._name=$n,Cn&&Cn($n));const In=["iconify"];return _n.prefix!==""&&In.push("iconify--"+_n.prefix),_n.provider!==""&&In.push("iconify--"+_n.provider),{data:Pn,classes:In}}},render(){this.counter;const $n=this.$attrs,Cn=this.iconMounted?this.getIcon($n.icon,$n.onLoad):null;if(!Cn)return render(emptyIcon,$n);let _n=$n;return Cn.classes&&(_n={...$n,class:(typeof $n.class=="string"?$n.class+" ":"")+Cn.classes.join(" ")}),render({...defaultIconProps,...Cn.data},_n)}});var lodash={exports:{}};/** - * @license - * Lodash - * Copyright OpenJS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */lodash.exports;(function($n,Cn){(function(){var _n,Pn="4.17.21",In=200,Nn="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",Rn="Expected a function",Dn="Invalid `variable` option passed into `_.template`",Ln="__lodash_hash_undefined__",Fn=500,Bn="__lodash_placeholder__",Hn=1,zn=2,Wn=4,Yn=1,Gn=2,Go=1,Xn=2,Yo=4,qo=8,Jo=16,Zo=32,rr=64,nr=128,ta=256,oa=512,ra=30,ea="...",la=800,ua=16,ga=1,aa=2,ca=3,sa=1/0,ia=9007199254740991,fa=17976931348623157e292,ma=NaN,ya=4294967295,ba=ya-1,Ia=ya>>>1,Ea=[["ary",nr],["bind",Go],["bindKey",Xn],["curry",qo],["curryRight",Jo],["flip",oa],["partial",Zo],["partialRight",rr],["rearg",ta]],xa="[object Arguments]",Ta="[object Array]",wa="[object AsyncFunction]",La="[object Boolean]",Na="[object Date]",$a="[object DOMException]",ka="[object Error]",Ha="[object Function]",da="[object GeneratorFunction]",pa="[object Map]",Sa="[object Number]",Aa="[object Null]",Ra="[object Object]",Fa="[object Promise]",za="[object Proxy]",Wa="[object RegExp]",Ya="[object Set]",ja="[object String]",qa="[object Symbol]",Xa="[object Undefined]",Oa="[object WeakMap]",Ma="[object WeakSet]",Ua="[object ArrayBuffer]",Qa="[object DataView]",ri="[object Float32Array]",fi="[object Float64Array]",ei="[object Int8Array]",ti="[object Int16Array]",ni="[object Int32Array]",ui="[object Uint8Array]",mi="[object Uint8ClampedArray]",di="[object Uint16Array]",gi="[object Uint32Array]",wi=/\b__p \+= '';/g,Ti=/\b(__p \+=) '' \+/g,Ei=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Ni=/&(?:amp|lt|gt|quot|#39);/g,Ri=/[&<>"']/g,Zi=RegExp(Ni.source),Qi=RegExp(Ri.source),Ji=/<%-([\s\S]+?)%>/g,Yi=/<%([\s\S]+?)%>/g,rl=/<%=([\s\S]+?)%>/g,yi=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,il=/^\w*$/,Tl=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,ul=/[\\^$.*+?()[\]{}|]/g,ts=RegExp(ul.source),ci=/^\s+/,Ci=/\s/,bi=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Bi=/\{\n\/\* \[wrapped with (.+)\] \*/,nl=/,? & /,el=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,gl=/[()=,{}\[\]\/\s]/,ll=/\\(\\)?/g,Rl=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,ml=/\w*$/,hl=/^[-+]0x[0-9a-f]+$/i,zi=/^0b[01]+$/i,Pl=/^\[object .+?Constructor\]$/,Cl=/^0o[0-7]+$/i,Fl=/^(?:0|[1-9]\d*)$/,Bl=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,vl=/($^)/,ns=/['\n\r\u2028\u2029\\]/g,yl="\\ud800-\\udfff",js="\\u0300-\\u036f",Ac="\\ufe20-\\ufe2f",Mc="\\u20d0-\\u20ff",rc=js+Ac+Mc,ac="\\u2700-\\u27bf",Hs="a-z\\xdf-\\xf6\\xf8-\\xff",Dc="\\xac\\xb1\\xd7\\xf7",ps="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",zs="\\u2000-\\u206f",ic=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",lc="A-Z\\xc0-\\xd6\\xd8-\\xde",Ws="\\ufe0e\\ufe0f",Ps=Dc+ps+zs+ic,Is="['’]",sc="["+yl+"]",Os="["+Ps+"]",is="["+rc+"]",cc="\\d+",bl="["+ac+"]",jl="["+Hs+"]",Es="[^"+yl+Ps+cc+ac+Hs+lc+"]",gs="\\ud83c[\\udffb-\\udfff]",Ul="(?:"+is+"|"+gs+")",Ks="[^"+yl+"]",uc="(?:\\ud83c[\\udde6-\\uddff]){2}",ms="[\\ud800-\\udbff][\\udc00-\\udfff]",Gl="["+lc+"]",Us="\\u200d",Ns="(?:"+jl+"|"+Es+")",cd="(?:"+Gl+"|"+Es+")",cu="(?:"+Is+"(?:d|ll|m|re|s|t|ve))?",uu="(?:"+Is+"(?:D|LL|M|RE|S|T|VE))?",du=Ul+"?",fu="["+Ws+"]?",ud="(?:"+Us+"(?:"+[Ks,uc,ms].join("|")+")"+fu+du+")*",dd="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",fd="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",pu=fu+du+ud,pd="(?:"+[bl,uc,ms].join("|")+")"+pu,gd="(?:"+[Ks+is+"?",is,uc,ms,sc].join("|")+")",md=RegExp(Is,"g"),hd=RegExp(is,"g"),Gs=RegExp(gs+"(?="+gs+")|"+gd+pu,"g"),vd=RegExp([Gl+"?"+jl+"+"+cu+"(?="+[Os,Gl,"$"].join("|")+")",cd+"+"+uu+"(?="+[Os,Gl+Ns,"$"].join("|")+")",Gl+"?"+Ns+"+"+cu,Gl+"+"+uu,fd,dd,cc,pd].join("|"),"g"),yd=RegExp("["+Us+yl+rc+Ws+"]"),bd=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,$d=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Sd=-1,Xi={};Xi[ri]=Xi[fi]=Xi[ei]=Xi[ti]=Xi[ni]=Xi[ui]=Xi[mi]=Xi[di]=Xi[gi]=!0,Xi[xa]=Xi[Ta]=Xi[Ua]=Xi[La]=Xi[Qa]=Xi[Na]=Xi[ka]=Xi[Ha]=Xi[pa]=Xi[Sa]=Xi[Ra]=Xi[Wa]=Xi[Ya]=Xi[ja]=Xi[Oa]=!1;var Wi={};Wi[xa]=Wi[Ta]=Wi[Ua]=Wi[Qa]=Wi[La]=Wi[Na]=Wi[ri]=Wi[fi]=Wi[ei]=Wi[ti]=Wi[ni]=Wi[pa]=Wi[Sa]=Wi[Ra]=Wi[Wa]=Wi[Ya]=Wi[ja]=Wi[qa]=Wi[ui]=Wi[mi]=Wi[di]=Wi[gi]=!0,Wi[ka]=Wi[Ha]=Wi[Oa]=!1;var gu={À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"},Cd={"&":"&","<":"<",">":">",'"':""","'":"'"},xd={"&":"&","<":"<",">":">",""":'"',"'":"'"},mu={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},wd=parseFloat,_d=parseInt,kc=typeof commonjsGlobal=="object"&&commonjsGlobal&&commonjsGlobal.Object===Object&&commonjsGlobal,Td=typeof self=="object"&&self&&self.Object===Object&&self,dl=kc||Td||Function("return this")(),dc=Cn&&!Cn.nodeType&&Cn,hs=dc&&!0&&$n&&!$n.nodeType&&$n,hu=hs&&hs.exports===dc,fc=hu&&kc.process,Al=function(){try{var Za=hs&&hs.require&&hs.require("util").types;return Za||fc&&fc.binding&&fc.binding("util")}catch{}}(),vu=Al&&Al.isArrayBuffer,Lc=Al&&Al.isDate,yu=Al&&Al.isMap,bu=Al&&Al.isRegExp,Vc=Al&&Al.isSet,$u=Al&&Al.isTypedArray;function Il(Za,ii,oi){switch(oi.length){case 0:return Za.call(ii);case 1:return Za.call(ii,oi[0]);case 2:return Za.call(ii,oi[0],oi[1]);case 3:return Za.call(ii,oi[0],oi[1],oi[2])}return Za.apply(ii,oi)}function Su(Za,ii,oi,Si){for(var Ai=-1,Ki=Za==null?0:Za.length;++Ai-1}function gc(Za,ii,oi){for(var Si=-1,Ai=Za==null?0:Za.length;++Si-1;);return oi}function _u(Za,ii){for(var oi=Za.length;oi--&&Rs(ii,Za[oi],0)>-1;);return oi}function $c(Za,ii){for(var oi=Za.length,Si=0;oi--;)Za[oi]===ii&&++Si;return Si}var Sc=vc(gu),Rd=vc(Cd);function Tu(Za){return"\\"+mu[Za]}function Ad(Za,ii){return Za==null?_n:Za[ii]}function As(Za){return yd.test(Za)}function Md(Za){return bd.test(Za)}function Ba(Za){for(var ii,oi=[];!(ii=Za.next()).done;)oi.push(ii.value);return oi}function _i(Za){var ii=-1,oi=Array(Za.size);return Za.forEach(function(Si,Ai){oi[++ii]=[Ai,Si]}),oi}function Ms(Za,ii){return function(oi){return Za(ii(oi))}}function Yl(Za,ii){for(var oi=-1,Si=Za.length,Ai=0,Ki=[];++oi-1}function Jg(Un,Xo){var na=this.__data__,ha=ju(na,Un);return ha<0?(++this.size,na.push([Un,Xo])):na[ha][1]=Xo,this}ys.prototype.clear=Xg,ys.prototype.delete=qg,ys.prototype.get=Zg,ys.prototype.has=Qg,ys.prototype.set=Jg;function bs(Un){var Xo=-1,na=Un==null?0:Un.length;for(this.clear();++Xo=Xo?Un:Xo)),Un}function Zl(Un,Xo,na,ha,Ca,Va){var Ka,Ga=Xo&Hn,Ja=Xo&zn,li=Xo&Wn;if(na&&(Ka=Ca?na(Un,ha,Ca,Va):na(Un)),Ka!==_n)return Ka;if(!ol(Un))return Un;var si=Mi(Un);if(si){if(Ka=oh(Un),!Ga)return Dl(Un,Ka)}else{var pi=_l(Un),vi=pi==Ha||pi==da;if(Bs(Un))return up(Un,Ga);if(pi==Ra||pi==xa||vi&&!Ca){if(Ka=Ja||vi?{}:Op(Un),!Ga)return Ja?Um(Un,mm(Ka,Un)):Km(Un,Bf(Ka,Un))}else{if(!Wi[pi])return Ca?Un:{};Ka=rh(Un,pi,Ga)}}Va||(Va=new os);var xi=Va.get(Un);if(xi)return xi;Va.set(Un,Ka),rg(Un)?Un.forEach(function(Oi){Ka.add(Zl(Oi,Xo,na,Oi,Un,Va))}):ng(Un)&&Un.forEach(function(Oi,Fi){Ka.set(Fi,Zl(Oi,Xo,na,Fi,Un,Va))});var Ii=li?Ja?lf:af:Ja?Ll:$l,ki=si?_n:Ii(Un);return Ml(ki||Un,function(Oi,Fi){ki&&(Fi=Oi,Oi=Un[Fi]),eu(Ka,Fi,Zl(Oi,Xo,na,Fi,Un,Va))}),Ka}function hm(Un){var Xo=$l(Un);return function(na){return jf(na,Un,Xo)}}function jf(Un,Xo,na){var ha=na.length;if(Un==null)return!ha;for(Un=qi(Un);ha--;){var Ca=na[ha],Va=Xo[Ca],Ka=Un[Ca];if(Ka===_n&&!(Ca in Un)||!Va(Ka))return!1}return!0}function Hf(Un,Xo,na){if(typeof Un!="function")throw new Xl(Rn);return lu(function(){Un.apply(_n,na)},Xo)}function tu(Un,Xo,na,ha){var Ca=-1,Va=pc,Ka=!0,Ga=Un.length,Ja=[],li=Xo.length;if(!Ga)return Ja;na&&(Xo=tl(Xo,xl(na))),ha?(Va=gc,Ka=!1):Xo.length>=In&&(Va=Ys,Ka=!1,Xo=new Qs(Xo));e:for(;++CaCa?0:Ca+na),ha=ha===_n||ha>Ca?Ca:Di(ha),ha<0&&(ha+=Ca),ha=na>ha?0:ig(ha);na0&&na(Ga)?Xo>1?Sl(Ga,Xo-1,na,ha,Ca):ss(Ca,Ga):ha||(Ca[Ca.length]=Ga)}return Ca}var jd=hp(),Kf=hp(!0);function us(Un,Xo){return Un&&jd(Un,Xo,$l)}function Hd(Un,Xo){return Un&&Kf(Un,Xo,$l)}function zu(Un,Xo){return ls(Xo,function(na){return ws(Un[na])})}function ec(Un,Xo){Xo=Vs(Xo,Un);for(var na=0,ha=Xo.length;Un!=null&&naXo}function bm(Un,Xo){return Un!=null&&Gi.call(Un,Xo)}function $m(Un,Xo){return Un!=null&&Xo in qi(Un)}function Sm(Un,Xo,na){return Un>=wl(Xo,na)&&Un=120&&si.length>=120)?new Qs(Ka&&si):_n}si=Un[0];var pi=-1,vi=Ga[0];e:for(;++pi-1;)Ga!==Un&&Mu.call(Ga,Ja,1),Mu.call(Un,Ja,1);return Un}function np(Un,Xo){for(var na=Un?Xo.length:0,ha=na-1;na--;){var Ca=Xo[na];if(na==ha||Ca!==Va){var Va=Ca;xs(Ca)?Mu.call(Un,Ca,1):Qd(Un,Ca)}}return Un}function Xd(Un,Xo){return Un+Lu(kf()*(Xo-Un+1))}function Mm(Un,Xo,na,ha){for(var Ca=-1,Va=pl(ku((Xo-Un)/(na||1)),0),Ka=oi(Va);Va--;)Ka[ha?Va:++Ca]=Un,Un+=na;return Ka}function qd(Un,Xo){var na="";if(!Un||Xo<1||Xo>ia)return na;do Xo%2&&(na+=Un),Xo=Lu(Xo/2),Xo&&(Un+=Un);while(Xo);return na}function Li(Un,Xo){return gf(Rp(Un,Xo,Vl),Un+"")}function Dm(Un){return Ff(Rc(Un))}function km(Un,Xo){var na=Rc(Un);return ed(na,Js(Xo,0,na.length))}function ru(Un,Xo,na,ha){if(!ol(Un))return Un;Xo=Vs(Xo,Un);for(var Ca=-1,Va=Xo.length,Ka=Va-1,Ga=Un;Ga!=null&&++CaCa?0:Ca+Xo),na=na>Ca?Ca:na,na<0&&(na+=Ca),Ca=Xo>na?0:na-Xo>>>0,Xo>>>=0;for(var Va=oi(Ca);++ha>>1,Ka=Un[Va];Ka!==null&&!zl(Ka)&&(na?Ka<=Xo:Ka=In){var li=Xo?null:qm(Un);if(li)return vs(li);Ka=!1,Ca=Ys,Ja=new Qs}else Ja=Xo?[]:Ga;e:for(;++ha=ha?Un:Ql(Un,Xo,na)}var cp=Pg||function(Un){return dl.clearTimeout(Un)};function up(Un,Xo){if(Xo)return Un.slice();var na=Un.length,ha=Nf?Nf(na):new Un.constructor(na);return Un.copy(ha),ha}function nf(Un){var Xo=new Un.constructor(Un.byteLength);return new Ru(Xo).set(new Ru(Un)),Xo}function jm(Un,Xo){var na=Xo?nf(Un.buffer):Un.buffer;return new Un.constructor(na,Un.byteOffset,Un.byteLength)}function Hm(Un){var Xo=new Un.constructor(Un.source,ml.exec(Un));return Xo.lastIndex=Un.lastIndex,Xo}function zm(Un){return Jc?qi(Jc.call(Un)):{}}function dp(Un,Xo){var na=Xo?nf(Un.buffer):Un.buffer;return new Un.constructor(na,Un.byteOffset,Un.length)}function fp(Un,Xo){if(Un!==Xo){var na=Un!==_n,ha=Un===null,Ca=Un===Un,Va=zl(Un),Ka=Xo!==_n,Ga=Xo===null,Ja=Xo===Xo,li=zl(Xo);if(!Ga&&!li&&!Va&&Un>Xo||Va&&Ka&&Ja&&!Ga&&!li||ha&&Ka&&Ja||!na&&Ja||!Ca)return 1;if(!ha&&!Va&&!li&&Un=Ga)return Ja;var li=na[ha];return Ja*(li=="desc"?-1:1)}}return Un.index-Xo.index}function pp(Un,Xo,na,ha){for(var Ca=-1,Va=Un.length,Ka=na.length,Ga=-1,Ja=Xo.length,li=pl(Va-Ka,0),si=oi(Ja+li),pi=!ha;++Ga1?na[Ca-1]:_n,Ka=Ca>2?na[2]:_n;for(Va=Un.length>3&&typeof Va=="function"?(Ca--,Va):_n,Ka&&El(na[0],na[1],Ka)&&(Va=Ca<3?_n:Va,Ca=1),Xo=qi(Xo);++ha-1?Ca[Va?Xo[Ka]:Ka]:_n}}function bp(Un){return Cs(function(Xo){var na=Xo.length,ha=na,Ca=ql.prototype.thru;for(Un&&Xo.reverse();ha--;){var Va=Xo[ha];if(typeof Va!="function")throw new Xl(Rn);if(Ca&&!Ka&&Qu(Va)=="wrapper")var Ka=new ql([],!0)}for(ha=Ka?ha:na;++ha1&&Hi.reverse(),si&&JaGa))return!1;var li=Va.get(Un),si=Va.get(Xo);if(li&&si)return li==Xo&&si==Un;var pi=-1,vi=!0,xi=na&Gn?new Qs:_n;for(Va.set(Un,Xo),Va.set(Xo,Un);++pi1?"& ":"")+Xo[ha],Xo=Xo.join(na>2?", ":" "),Un.replace(bi,`{ -/* [wrapped with `+Xo+`] */ -`)}function ih(Un){return Mi(Un)||oc(Un)||!!(Mf&&Un&&Un[Mf])}function xs(Un,Xo){var na=typeof Un;return Xo=Xo??ia,!!Xo&&(na=="number"||na!="symbol"&&Fl.test(Un))&&Un>-1&&Un%1==0&&Un0){if(++Xo>=la)return arguments[0]}else Xo=0;return Un.apply(_n,arguments)}}function ed(Un,Xo){var na=-1,ha=Un.length,Ca=ha-1;for(Xo=Xo===_n?ha:Xo;++na1?Un[Xo-1]:_n;return na=typeof na=="function"?(Un.pop(),na):_n,Wp(Un,na)});function Kp(Un){var Xo=Da(Un);return Xo.__chain__=!0,Xo}function vv(Un,Xo){return Xo(Un),Un}function td(Un,Xo){return Xo(Un)}var yv=Cs(function(Un){var Xo=Un.length,na=Xo?Un[0]:0,ha=this.__wrapped__,Ca=function(Va){return Bd(Va,Un)};return Xo>1||this.__actions__.length||!(ha instanceof ji)||!xs(na)?this.thru(Ca):(ha=ha.slice(na,+na+(Xo?1:0)),ha.__actions__.push({func:td,args:[Ca],thisArg:_n}),new ql(ha,this.__chain__).thru(function(Va){return Xo&&!Va.length&&Va.push(_n),Va}))});function bv(){return Kp(this)}function $v(){return new ql(this.value(),this.__chain__)}function Sv(){this.__values__===_n&&(this.__values__=ag(this.value()));var Un=this.__index__>=this.__values__.length,Xo=Un?_n:this.__values__[this.__index__++];return{done:Un,value:Xo}}function Cv(){return this}function xv(Un){for(var Xo,na=this;na instanceof Bu;){var ha=Vp(na);ha.__index__=0,ha.__values__=_n,Xo?Ca.__wrapped__=ha:Xo=ha;var Ca=ha;na=na.__wrapped__}return Ca.__wrapped__=Un,Xo}function wv(){var Un=this.__wrapped__;if(Un instanceof ji){var Xo=Un;return this.__actions__.length&&(Xo=new ji(this)),Xo=Xo.reverse(),Xo.__actions__.push({func:td,args:[mf],thisArg:_n}),new ql(Xo,this.__chain__)}return this.thru(mf)}function _v(){return lp(this.__wrapped__,this.__actions__)}var Tv=Gu(function(Un,Xo,na){Gi.call(Un,na)?++Un[na]:$s(Un,na,1)});function Pv(Un,Xo,na){var ha=Mi(Un)?Fc:vm;return na&&El(Un,Xo,na)&&(Xo=_n),ha(Un,Pi(Xo,3))}function Iv(Un,Xo){var na=Mi(Un)?ls:Wf;return na(Un,Pi(Xo,3))}var Ov=yp(Fp),Ev=yp(Bp);function Nv(Un,Xo){return Sl(nd(Un,Xo),1)}function Rv(Un,Xo){return Sl(nd(Un,Xo),sa)}function Av(Un,Xo,na){return na=na===_n?1:Di(na),Sl(nd(Un,Xo),na)}function Up(Un,Xo){var na=Mi(Un)?Ml:ks;return na(Un,Pi(Xo,3))}function Gp(Un,Xo){var na=Mi(Un)?Pd:zf;return na(Un,Pi(Xo,3))}var Mv=Gu(function(Un,Xo,na){Gi.call(Un,na)?Un[na].push(Xo):$s(Un,na,[Xo])});function Dv(Un,Xo,na,ha){Un=kl(Un)?Un:Rc(Un),na=na&&!ha?Di(na):0;var Ca=Un.length;return na<0&&(na=pl(Ca+na,0)),ld(Un)?na<=Ca&&Un.indexOf(Xo,na)>-1:!!Ca&&Rs(Un,Xo,na)>-1}var kv=Li(function(Un,Xo,na){var ha=-1,Ca=typeof Xo=="function",Va=kl(Un)?oi(Un.length):[];return ks(Un,function(Ka){Va[++ha]=Ca?Il(Xo,Ka,na):nu(Ka,Xo,na)}),Va}),Lv=Gu(function(Un,Xo,na){$s(Un,na,Xo)});function nd(Un,Xo){var na=Mi(Un)?tl:qf;return na(Un,Pi(Xo,3))}function Vv(Un,Xo,na,ha){return Un==null?[]:(Mi(Xo)||(Xo=Xo==null?[]:[Xo]),na=ha?_n:na,Mi(na)||(na=na==null?[]:[na]),ep(Un,Xo,na))}var Fv=Gu(function(Un,Xo,na){Un[na?0:1].push(Xo)},function(){return[[],[]]});function Bv(Un,Xo,na){var ha=Mi(Un)?mc:Wc,Ca=arguments.length<3;return ha(Un,Pi(Xo,4),na,Ca,ks)}function jv(Un,Xo,na){var ha=Mi(Un)?Id:Wc,Ca=arguments.length<3;return ha(Un,Pi(Xo,4),na,Ca,zf)}function Hv(Un,Xo){var na=Mi(Un)?ls:Wf;return na(Un,ad(Pi(Xo,3)))}function zv(Un){var Xo=Mi(Un)?Ff:Dm;return Xo(Un)}function Wv(Un,Xo,na){(na?El(Un,Xo,na):Xo===_n)?Xo=1:Xo=Di(Xo);var ha=Mi(Un)?fm:km;return ha(Un,Xo)}function Kv(Un){var Xo=Mi(Un)?pm:Vm;return Xo(Un)}function Uv(Un){if(Un==null)return 0;if(kl(Un))return ld(Un)?Pa(Un):Un.length;var Xo=_l(Un);return Xo==pa||Xo==Ya?Un.size:Ud(Un).length}function Gv(Un,Xo,na){var ha=Mi(Un)?Bc:Fm;return na&&El(Un,Xo,na)&&(Xo=_n),ha(Un,Pi(Xo,3))}var Yv=Li(function(Un,Xo){if(Un==null)return[];var na=Xo.length;return na>1&&El(Un,Xo[0],Xo[1])?Xo=[]:na>2&&El(Xo[0],Xo[1],Xo[2])&&(Xo=[Xo[0]]),ep(Un,Sl(Xo,1),[])}),od=Ig||function(){return dl.Date.now()};function Xv(Un,Xo){if(typeof Xo!="function")throw new Xl(Rn);return Un=Di(Un),function(){if(--Un<1)return Xo.apply(this,arguments)}}function Yp(Un,Xo,na){return Xo=na?_n:Xo,Xo=Un&&Xo==null?Un.length:Xo,Ss(Un,nr,_n,_n,_n,_n,Xo)}function Xp(Un,Xo){var na;if(typeof Xo!="function")throw new Xl(Rn);return Un=Di(Un),function(){return--Un>0&&(na=Xo.apply(this,arguments)),Un<=1&&(Xo=_n),na}}var vf=Li(function(Un,Xo,na){var ha=Go;if(na.length){var Ca=Yl(na,Ec(vf));ha|=Zo}return Ss(Un,ha,Xo,na,Ca)}),qp=Li(function(Un,Xo,na){var ha=Go|Xn;if(na.length){var Ca=Yl(na,Ec(qp));ha|=Zo}return Ss(Xo,ha,Un,na,Ca)});function Zp(Un,Xo,na){Xo=na?_n:Xo;var ha=Ss(Un,qo,_n,_n,_n,_n,_n,Xo);return ha.placeholder=Zp.placeholder,ha}function Qp(Un,Xo,na){Xo=na?_n:Xo;var ha=Ss(Un,Jo,_n,_n,_n,_n,_n,Xo);return ha.placeholder=Qp.placeholder,ha}function Jp(Un,Xo,na){var ha,Ca,Va,Ka,Ga,Ja,li=0,si=!1,pi=!1,vi=!0;if(typeof Un!="function")throw new Xl(Rn);Xo=es(Xo)||0,ol(na)&&(si=!!na.leading,pi="maxWait"in na,Va=pi?pl(es(na.maxWait)||0,Xo):Va,vi="trailing"in na?!!na.trailing:vi);function xi(cl){var as=ha,Ts=Ca;return ha=Ca=_n,li=cl,Ka=Un.apply(Ts,as),Ka}function Ii(cl){return li=cl,Ga=lu(Fi,Xo),si?xi(cl):Ka}function ki(cl){var as=cl-Ja,Ts=cl-li,yg=Xo-as;return pi?wl(yg,Va-Ts):yg}function Oi(cl){var as=cl-Ja,Ts=cl-li;return Ja===_n||as>=Xo||as<0||pi&&Ts>=Va}function Fi(){var cl=od();if(Oi(cl))return Hi(cl);Ga=lu(Fi,ki(cl))}function Hi(cl){return Ga=_n,vi&&ha?xi(cl):(ha=Ca=_n,Ka)}function Wl(){Ga!==_n&&cp(Ga),li=0,ha=Ja=Ca=Ga=_n}function Nl(){return Ga===_n?Ka:Hi(od())}function Kl(){var cl=od(),as=Oi(cl);if(ha=arguments,Ca=this,Ja=cl,as){if(Ga===_n)return Ii(Ja);if(pi)return cp(Ga),Ga=lu(Fi,Xo),xi(Ja)}return Ga===_n&&(Ga=lu(Fi,Xo)),Ka}return Kl.cancel=Wl,Kl.flush=Nl,Kl}var qv=Li(function(Un,Xo){return Hf(Un,1,Xo)}),Zv=Li(function(Un,Xo,na){return Hf(Un,es(Xo)||0,na)});function Qv(Un){return Ss(Un,oa)}function rd(Un,Xo){if(typeof Un!="function"||Xo!=null&&typeof Xo!="function")throw new Xl(Rn);var na=function(){var ha=arguments,Ca=Xo?Xo.apply(this,ha):ha[0],Va=na.cache;if(Va.has(Ca))return Va.get(Ca);var Ka=Un.apply(this,ha);return na.cache=Va.set(Ca,Ka)||Va,Ka};return na.cache=new(rd.Cache||bs),na}rd.Cache=bs;function ad(Un){if(typeof Un!="function")throw new Xl(Rn);return function(){var Xo=arguments;switch(Xo.length){case 0:return!Un.call(this);case 1:return!Un.call(this,Xo[0]);case 2:return!Un.call(this,Xo[0],Xo[1]);case 3:return!Un.call(this,Xo[0],Xo[1],Xo[2])}return!Un.apply(this,Xo)}}function Jv(Un){return Xp(2,Un)}var e0=Bm(function(Un,Xo){Xo=Xo.length==1&&Mi(Xo[0])?tl(Xo[0],xl(Pi())):tl(Sl(Xo,1),xl(Pi()));var na=Xo.length;return Li(function(ha){for(var Ca=-1,Va=wl(ha.length,na);++Ca=Xo}),oc=Gf(function(){return arguments}())?Gf:function(Un){return al(Un)&&Gi.call(Un,"callee")&&!Af.call(Un,"callee")},Mi=oi.isArray,m0=vu?xl(vu):xm;function kl(Un){return Un!=null&&id(Un.length)&&!ws(Un)}function sl(Un){return al(Un)&&kl(Un)}function h0(Un){return Un===!0||Un===!1||al(Un)&&Ol(Un)==La}var Bs=Eg||Of,v0=Lc?xl(Lc):wm;function y0(Un){return al(Un)&&Un.nodeType===1&&!su(Un)}function b0(Un){if(Un==null)return!0;if(kl(Un)&&(Mi(Un)||typeof Un=="string"||typeof Un.splice=="function"||Bs(Un)||Nc(Un)||oc(Un)))return!Un.length;var Xo=_l(Un);if(Xo==pa||Xo==Ya)return!Un.size;if(iu(Un))return!Ud(Un).length;for(var na in Un)if(Gi.call(Un,na))return!1;return!0}function $0(Un,Xo){return ou(Un,Xo)}function S0(Un,Xo,na){na=typeof na=="function"?na:_n;var ha=na?na(Un,Xo):_n;return ha===_n?ou(Un,Xo,_n,na):!!ha}function bf(Un){if(!al(Un))return!1;var Xo=Ol(Un);return Xo==ka||Xo==$a||typeof Un.message=="string"&&typeof Un.name=="string"&&!su(Un)}function C0(Un){return typeof Un=="number"&&Df(Un)}function ws(Un){if(!ol(Un))return!1;var Xo=Ol(Un);return Xo==Ha||Xo==da||Xo==wa||Xo==za}function tg(Un){return typeof Un=="number"&&Un==Di(Un)}function id(Un){return typeof Un=="number"&&Un>-1&&Un%1==0&&Un<=ia}function ol(Un){var Xo=typeof Un;return Un!=null&&(Xo=="object"||Xo=="function")}function al(Un){return Un!=null&&typeof Un=="object"}var ng=yu?xl(yu):Tm;function x0(Un,Xo){return Un===Xo||Kd(Un,Xo,cf(Xo))}function w0(Un,Xo,na){return na=typeof na=="function"?na:_n,Kd(Un,Xo,cf(Xo),na)}function _0(Un){return og(Un)&&Un!=+Un}function T0(Un){if(ch(Un))throw new Ai(Nn);return Yf(Un)}function P0(Un){return Un===null}function I0(Un){return Un==null}function og(Un){return typeof Un=="number"||al(Un)&&Ol(Un)==Sa}function su(Un){if(!al(Un)||Ol(Un)!=Ra)return!1;var Xo=Au(Un);if(Xo===null)return!0;var na=Gi.call(Xo,"constructor")&&Xo.constructor;return typeof na=="function"&&na instanceof na&&Ou.call(na)==wg}var $f=bu?xl(bu):Pm;function O0(Un){return tg(Un)&&Un>=-ia&&Un<=ia}var rg=Vc?xl(Vc):Im;function ld(Un){return typeof Un=="string"||!Mi(Un)&&al(Un)&&Ol(Un)==ja}function zl(Un){return typeof Un=="symbol"||al(Un)&&Ol(Un)==qa}var Nc=$u?xl($u):Om;function E0(Un){return Un===_n}function N0(Un){return al(Un)&&_l(Un)==Oa}function R0(Un){return al(Un)&&Ol(Un)==Ma}var A0=Zu(Gd),M0=Zu(function(Un,Xo){return Un<=Xo});function ag(Un){if(!Un)return[];if(kl(Un))return ld(Un)?ai(Un):Dl(Un);if(Xc&&Un[Xc])return Ba(Un[Xc]());var Xo=_l(Un),na=Xo==pa?_i:Xo==Ya?vs:Rc;return na(Un)}function _s(Un){if(!Un)return Un===0?Un:0;if(Un=es(Un),Un===sa||Un===-sa){var Xo=Un<0?-1:1;return Xo*fa}return Un===Un?Un:0}function Di(Un){var Xo=_s(Un),na=Xo%1;return Xo===Xo?na?Xo-na:Xo:0}function ig(Un){return Un?Js(Di(Un),0,ya):0}function es(Un){if(typeof Un=="number")return Un;if(zl(Un))return ma;if(ol(Un)){var Xo=typeof Un.valueOf=="function"?Un.valueOf():Un;Un=ol(Xo)?Xo+"":Xo}if(typeof Un!="string")return Un===0?Un:+Un;Un=Gc(Un);var na=zi.test(Un);return na||Cl.test(Un)?_d(Un.slice(2),na?2:8):hl.test(Un)?ma:+Un}function lg(Un){return ds(Un,Ll(Un))}function D0(Un){return Un?Js(Di(Un),-ia,ia):Un===0?Un:0}function Ui(Un){return Un==null?"":Hl(Un)}var k0=Ic(function(Un,Xo){if(iu(Xo)||kl(Xo)){ds(Xo,$l(Xo),Un);return}for(var na in Xo)Gi.call(Xo,na)&&eu(Un,na,Xo[na])}),sg=Ic(function(Un,Xo){ds(Xo,Ll(Xo),Un)}),sd=Ic(function(Un,Xo,na,ha){ds(Xo,Ll(Xo),Un,ha)}),L0=Ic(function(Un,Xo,na,ha){ds(Xo,$l(Xo),Un,ha)}),V0=Cs(Bd);function F0(Un,Xo){var na=Pc(Un);return Xo==null?na:Bf(na,Xo)}var B0=Li(function(Un,Xo){Un=qi(Un);var na=-1,ha=Xo.length,Ca=ha>2?Xo[2]:_n;for(Ca&&El(Xo[0],Xo[1],Ca)&&(ha=1);++na1),Va}),ds(Un,lf(Un),na),ha&&(na=Zl(na,Hn|zn|Wn,Zm));for(var Ca=Xo.length;Ca--;)Qd(na,Xo[Ca]);return na});function r1(Un,Xo){return ug(Un,ad(Pi(Xo)))}var a1=Cs(function(Un,Xo){return Un==null?{}:Rm(Un,Xo)});function ug(Un,Xo){if(Un==null)return{};var na=tl(lf(Un),function(ha){return[ha]});return Xo=Pi(Xo),tp(Un,na,function(ha,Ca){return Xo(ha,Ca[0])})}function i1(Un,Xo,na){Xo=Vs(Xo,Un);var ha=-1,Ca=Xo.length;for(Ca||(Ca=1,Un=_n);++haXo){var ha=Un;Un=Xo,Xo=ha}if(na||Un%1||Xo%1){var Ca=kf();return wl(Un+Ca*(Xo-Un+wd("1e-"+((Ca+"").length-1))),Xo)}return Xd(Un,Xo)}var v1=Oc(function(Un,Xo,na){return Xo=Xo.toLowerCase(),Un+(na?pg(Xo):Xo)});function pg(Un){return xf(Ui(Un).toLowerCase())}function gg(Un){return Un=Ui(Un),Un&&Un.replace(Bl,Sc).replace(hd,"")}function y1(Un,Xo,na){Un=Ui(Un),Xo=Hl(Xo);var ha=Un.length;na=na===_n?ha:Js(Di(na),0,ha);var Ca=na;return na-=Xo.length,na>=0&&Un.slice(na,Ca)==Xo}function b1(Un){return Un=Ui(Un),Un&&Qi.test(Un)?Un.replace(Ri,Rd):Un}function $1(Un){return Un=Ui(Un),Un&&ts.test(Un)?Un.replace(ul,"\\$&"):Un}var S1=Oc(function(Un,Xo,na){return Un+(na?"-":"")+Xo.toLowerCase()}),C1=Oc(function(Un,Xo,na){return Un+(na?" ":"")+Xo.toLowerCase()}),x1=vp("toLowerCase");function w1(Un,Xo,na){Un=Ui(Un),Xo=Di(Xo);var ha=Xo?Pa(Un):0;if(!Xo||ha>=Xo)return Un;var Ca=(Xo-ha)/2;return qu(Lu(Ca),na)+Un+qu(ku(Ca),na)}function _1(Un,Xo,na){Un=Ui(Un),Xo=Di(Xo);var ha=Xo?Pa(Un):0;return Xo&&ha>>0,na?(Un=Ui(Un),Un&&(typeof Xo=="string"||Xo!=null&&!$f(Xo))&&(Xo=Hl(Xo),!Xo&&As(Un))?Fs(ai(Un),0,na):Un.split(Xo,na)):[]}var R1=Oc(function(Un,Xo,na){return Un+(na?" ":"")+xf(Xo)});function A1(Un,Xo,na){return Un=Ui(Un),na=na==null?0:Js(Di(na),0,Un.length),Xo=Hl(Xo),Un.slice(na,na+Xo.length)==Xo}function M1(Un,Xo,na){var ha=Da.templateSettings;na&&El(Un,Xo,na)&&(Xo=_n),Un=Ui(Un),Xo=sd({},Xo,ha,wp);var Ca=sd({},Xo.imports,ha.imports,wp),Va=$l(Ca),Ka=bc(Ca,Va),Ga,Ja,li=0,si=Xo.interpolate||vl,pi="__p += '",vi=Dd((Xo.escape||vl).source+"|"+si.source+"|"+(si===rl?Rl:vl).source+"|"+(Xo.evaluate||vl).source+"|$","g"),xi="//# sourceURL="+(Gi.call(Xo,"sourceURL")?(Xo.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Sd+"]")+` -`;Un.replace(vi,function(Oi,Fi,Hi,Wl,Nl,Kl){return Hi||(Hi=Wl),pi+=Un.slice(li,Kl).replace(ns,Tu),Fi&&(Ga=!0,pi+=`' + -__e(`+Fi+`) + -'`),Nl&&(Ja=!0,pi+=`'; -`+Nl+`; -__p += '`),Hi&&(pi+=`' + -((__t = (`+Hi+`)) == null ? '' : __t) + -'`),li=Kl+Oi.length,Oi}),pi+=`'; -`;var Ii=Gi.call(Xo,"variable")&&Xo.variable;if(!Ii)pi=`with (obj) { -`+pi+` -} -`;else if(gl.test(Ii))throw new Ai(Dn);pi=(Ja?pi.replace(wi,""):pi).replace(Ti,"$1").replace(Ei,"$1;"),pi="function("+(Ii||"obj")+`) { -`+(Ii?"":`obj || (obj = {}); -`)+"var __t, __p = ''"+(Ga?", __e = _.escape":"")+(Ja?`, __j = Array.prototype.join; -function print() { __p += __j.call(arguments, '') } -`:`; -`)+pi+`return __p -}`;var ki=hg(function(){return Ki(Va,xi+"return "+pi).apply(_n,Ka)});if(ki.source=pi,bf(ki))throw ki;return ki}function D1(Un){return Ui(Un).toLowerCase()}function k1(Un){return Ui(Un).toUpperCase()}function L1(Un,Xo,na){if(Un=Ui(Un),Un&&(na||Xo===_n))return Gc(Un);if(!Un||!(Xo=Hl(Xo)))return Un;var ha=ai(Un),Ca=ai(Xo),Va=Yc(ha,Ca),Ka=_u(ha,Ca)+1;return Fs(ha,Va,Ka).join("")}function V1(Un,Xo,na){if(Un=Ui(Un),Un&&(na||Xo===_n))return Un.slice(0,$i(Un)+1);if(!Un||!(Xo=Hl(Xo)))return Un;var ha=ai(Un),Ca=_u(ha,ai(Xo))+1;return Fs(ha,0,Ca).join("")}function F1(Un,Xo,na){if(Un=Ui(Un),Un&&(na||Xo===_n))return Un.replace(ci,"");if(!Un||!(Xo=Hl(Xo)))return Un;var ha=ai(Un),Ca=Yc(ha,ai(Xo));return Fs(ha,Ca).join("")}function B1(Un,Xo){var na=ra,ha=ea;if(ol(Xo)){var Ca="separator"in Xo?Xo.separator:Ca;na="length"in Xo?Di(Xo.length):na,ha="omission"in Xo?Hl(Xo.omission):ha}Un=Ui(Un);var Va=Un.length;if(As(Un)){var Ka=ai(Un);Va=Ka.length}if(na>=Va)return Un;var Ga=na-Pa(ha);if(Ga<1)return ha;var Ja=Ka?Fs(Ka,0,Ga).join(""):Un.slice(0,Ga);if(Ca===_n)return Ja+ha;if(Ka&&(Ga+=Ja.length-Ga),$f(Ca)){if(Un.slice(Ga).search(Ca)){var li,si=Ja;for(Ca.global||(Ca=Dd(Ca.source,Ui(ml.exec(Ca))+"g")),Ca.lastIndex=0;li=Ca.exec(si);)var pi=li.index;Ja=Ja.slice(0,pi===_n?Ga:pi)}}else if(Un.indexOf(Hl(Ca),Ga)!=Ga){var vi=Ja.lastIndexOf(Ca);vi>-1&&(Ja=Ja.slice(0,vi))}return Ja+ha}function j1(Un){return Un=Ui(Un),Un&&Zi.test(Un)?Un.replace(Ni,Vi):Un}var H1=Oc(function(Un,Xo,na){return Un+(na?" ":"")+Xo.toUpperCase()}),xf=vp("toUpperCase");function mg(Un,Xo,na){return Un=Ui(Un),Xo=na?_n:Xo,Xo===_n?Md(Un)?bg(Un):Ed(Un):Un.match(Xo)||[]}var hg=Li(function(Un,Xo){try{return Il(Un,_n,Xo)}catch(na){return bf(na)?na:new Ai(na)}}),z1=Cs(function(Un,Xo){return Ml(Xo,function(na){na=fs(na),$s(Un,na,vf(Un[na],Un))}),Un});function W1(Un){var Xo=Un==null?0:Un.length,na=Pi();return Un=Xo?tl(Un,function(ha){if(typeof ha[1]!="function")throw new Xl(Rn);return[na(ha[0]),ha[1]]}):[],Li(function(ha){for(var Ca=-1;++Caia)return[];var na=ya,ha=wl(Un,ya);Xo=Pi(Xo),Un-=ya;for(var Ca=Uc(ha,Xo);++na0||Xo<0)?new ji(na):(Un<0?na=na.takeRight(-Un):Un&&(na=na.drop(Un)),Xo!==_n&&(Xo=Di(Xo),na=Xo<0?na.dropRight(-Xo):na.take(Xo-Un)),na)},ji.prototype.takeRightWhile=function(Un){return this.reverse().takeWhile(Un).reverse()},ji.prototype.toArray=function(){return this.take(ya)},us(ji.prototype,function(Un,Xo){var na=/^(?:filter|find|map|reject)|While$/.test(Xo),ha=/^(?:head|last)$/.test(Xo),Ca=Da[ha?"take"+(Xo=="last"?"Right":""):Xo],Va=ha||/^find/.test(Xo);Ca&&(Da.prototype[Xo]=function(){var Ka=this.__wrapped__,Ga=ha?[1]:arguments,Ja=Ka instanceof ji,li=Ga[0],si=Ja||Mi(Ka),pi=function(Fi){var Hi=Ca.apply(Da,ss([Fi],Ga));return ha&&vi?Hi[0]:Hi};si&&na&&typeof li=="function"&&li.length!=1&&(Ja=si=!1);var vi=this.__chain__,xi=!!this.__actions__.length,Ii=Va&&!vi,ki=Ja&&!xi;if(!Va&&si){Ka=ki?Ka:new ji(this);var Oi=Un.apply(Ka,Ga);return Oi.__actions__.push({func:td,args:[pi],thisArg:_n}),new ql(Oi,vi)}return Ii&&ki?Un.apply(this,Ga):(Oi=this.thru(pi),Ii?ha?Oi.value()[0]:Oi.value():Oi)})}),Ml(["pop","push","shift","sort","splice","unshift"],function(Un){var Xo=Pu[Un],na=/^(?:push|sort|unshift)$/.test(Un)?"tap":"thru",ha=/^(?:pop|shift)$/.test(Un);Da.prototype[Un]=function(){var Ca=arguments;if(ha&&!this.__chain__){var Va=this.value();return Xo.apply(Mi(Va)?Va:[],Ca)}return this[na](function(Ka){return Xo.apply(Mi(Ka)?Ka:[],Ca)})}}),us(ji.prototype,function(Un,Xo){var na=Da[Xo];if(na){var ha=na.name+"";Gi.call(Tc,ha)||(Tc[ha]=[]),Tc[ha].push({name:Xo,func:na})}}),Tc[Yu(_n,Xn).name]=[{name:"wrapper",func:_n}],ji.prototype.clone=jg,ji.prototype.reverse=Hg,ji.prototype.value=zg,Da.prototype.at=yv,Da.prototype.chain=bv,Da.prototype.commit=$v,Da.prototype.next=Sv,Da.prototype.plant=xv,Da.prototype.reverse=wv,Da.prototype.toJSON=Da.prototype.valueOf=Da.prototype.value=_v,Da.prototype.first=Da.prototype.head,Xc&&(Da.prototype[Xc]=Cv),Da},xc=$g();hs?((hs.exports=xc)._=xc,dc._=xc):dl._=xc}).call(commonjsGlobal)})(lodash,lodash.exports);var lodashExports=lodash.exports;const _$2=getDefaultExportFromCjs(lodashExports),PRIMARY_COLOR_DEFAULT="#17b392",LOCAL_STORAGE_LOCALE="LOCAL_STORAGE_LOCALE",LOCAL_STORAGE_THEME="LOCAL_STORAGE_THEME";let item=localStorage.getItem(LOCAL_STORAGE_THEME);const PRIMARY_COLOR=ref(item||PRIMARY_COLOR_DEFAULT),PRIMARY_COLOR_T=$n=>computed(()=>PRIMARY_COLOR.value+$n),INSTANCE_REGISTER_COLOR={HEALTHY:"green",REGISTED:"green"},TAB_HEADER_TITLE={functional:!0,props:["route"],render:($n,Cn,_n)=>{var Nn,Rn,Dn;let Pn=_n.route,In=(Rn=(Nn=Pn.meta)==null?void 0:Nn.slots)==null?void 0:Rn.header;return h$3(In)||h$3("div",(Dn=Pn.params)==null?void 0:Dn.pathId)}},INSTANCE_DEPLOY_COLOR={RUNNING:"green",PENDING:"yellow",TERMINATING:"red",CRASHING:"darkRed"},KEY_PREFIX="__PROVIDE_INJECT_KEY_",PROVIDE_INJECT_KEY={LOCALE:KEY_PREFIX+"LOCALE",GRAFANA:KEY_PREFIX+"GRAFANA",SEARCH_DOMAIN:KEY_PREFIX+"SEARCH_DOMAIN",COLLAPSED:KEY_PREFIX+"COLLAPSED",TAB_LAYOUT_STATE:KEY_PREFIX+"TAB_LAYOUT_STATE"},_hoisted_1$a={class:"__container_router_tab_index"},_hoisted_2$a={key:0,class:"header"},_hoisted_3={id:"layout-tab-body",style:{transition:"scroll-top 0.5s ease",overflow:"auto",height:"calc(100vh - 300px)","padding-bottom":"20px"}},_sfc_main$b=defineComponent({__name:"layout_tab",setup($n){useCssVars(Fn=>({"6b871b3a":unref(PRIMARY_COLOR)}));const Cn=reactive({});provide(PROVIDE_INJECT_KEY.PROVIDE_INJECT_KEY,Cn);const _n=useRouter(),Pn=useRoute();Pn.meta;const In=computed(()=>{var Bn,Hn;let Fn=Pn.meta;return(Hn=(Bn=Fn==null?void 0:Fn.parent)==null?void 0:Bn.children)==null?void 0:Hn.filter(zn=>zn.meta.tab)}),Nn=computed(()=>Pn.name+"_"+_$2.uniqueId());let Rn=ref(Pn.name),Dn=ref(!1),Ln=_$2.uniqueId("__tab_page");return _n.beforeEach((Fn,Bn,Hn)=>{Ln=_$2.uniqueId("__tab_page"),Dn.value=!0,Rn.value=Fn.name,Hn(),setTimeout(()=>{Dn.value=!1},500)}),(Fn,Bn)=>{const Hn=resolveComponent("a-col"),zn=resolveComponent("a-row"),Wn=resolveComponent("a-tab-pane"),Yn=resolveComponent("a-tabs"),Gn=resolveComponent("router-view"),Go=resolveComponent("a-spin");return openBlock(),createElementBlock("div",_hoisted_1$a,[(openBlock(),createElementBlock("div",{key:unref(Ln)},[unref(Pn).meta.tab?(openBlock(),createElementBlock("div",_hoisted_2$a,[createVNode(zn,null,{default:withCtx(()=>[createVNode(Hn,{span:1},{default:withCtx(()=>[createBaseVNode("span",{onClick:Bn[0]||(Bn[0]=Xn=>unref(_n).replace(unref(Pn).meta.back||"../")),style:{float:"left"}},[createVNode(unref(Icon),{icon:"material-symbols:keyboard-backspace-rounded",class:"back"})])]),_:1}),createVNode(Hn,{span:18},{default:withCtx(()=>[createVNode(unref(TAB_HEADER_TITLE),{route:unref(Pn)},null,8,["route"])]),_:1})]),_:1}),createVNode(Yn,{onChange:Bn[1]||(Bn[1]=Xn=>unref(_n).push({name:unref(Rn)||""})),activeKey:unref(Rn),"onUpdate:activeKey":Bn[2]||(Bn[2]=Xn=>isRef(Rn)?Rn.value=Xn:Rn=Xn)},{default:withCtx(()=>[(openBlock(!0),createElementBlock(Fragment,null,renderList(In.value.filter(Xn=>!Xn.meta.hidden),Xn=>(openBlock(),createBlock(Wn,{key:Xn.name},{tab:withCtx(()=>[createBaseVNode("span",null,[createVNode(unref(Icon),{style:{"margin-bottom":"-2px"},icon:Xn.meta.icon},null,8,["icon"]),createTextVNode(" "+toDisplayString$1(Fn.$t(Xn.name)),1)])]),_:2},1024))),128))]),_:1},8,["activeKey"])])):createCommentVNode("",!0),createVNode(Go,{class:"tab-spin",spinning:unref(Dn)},{default:withCtx(()=>[createBaseVNode("div",_hoisted_3,[unref(Dn)?createCommentVNode("",!0):(openBlock(),createBlock(Gn,{key:Nn.value}))])]),_:1},8,["spinning"])]))])}}}),_export_sfc=($n,Cn)=>{const _n=$n.__vccOpts||$n;for(const[Pn,In]of Cn)_n[Pn]=In;return _n},LayoutTab=_export_sfc(_sfc_main$b,[["__scopeId","data-v-e3c1cda1"]]),_hoisted_1$9={class:"__container_AppTabHeaderSlot"},_hoisted_2$9={class:"header-desc"},_sfc_main$a=defineComponent({__name:"AppTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$9,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$9,toDisplayString$1(_n.$t("applicationDomain.name"))+": "+toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.pathId),1)]}),_:1})]),_:1})])}}}),AppTabHeaderSlot=_export_sfc(_sfc_main$a,[["__scopeId","data-v-d9202124"]]),_hoisted_1$8={class:"__container_ServiceTabHeaderSlot"},_hoisted_2$8={class:"header-desc"},_sfc_main$9=defineComponent({__name:"ServiceTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{var In;return openBlock(),createElementBlock("div",_hoisted_1$8,[createBaseVNode("span",_hoisted_2$8,toDisplayString$1(_n.$t("serviceDomain.name"))+": "+toDisplayString$1((In=unref(Cn).params)==null?void 0:In.pathId),1)])}}}),ServiceTabHeaderSlot=_export_sfc(_sfc_main$9,[["__scopeId","data-v-3de51f62"]]),_hoisted_1$7={class:"__container_AppTabHeaderSlot"},_hoisted_2$7={class:"header-desc"},_sfc_main$8=defineComponent({__name:"InstanceTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$7,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$7,toDisplayString$1(_n.$t("instanceDomain.name"))+": "+toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.pathId),1)]}),_:1})]),_:1})])}}}),InstanceTabHeaderSlot=_export_sfc(_sfc_main$8,[["__scopeId","data-v-945638c8"]]),_sfc_main$7={},_withScopeId$1=$n=>(pushScopeId("data-v-0f2e35af"),$n=$n(),popScopeId(),$n),_hoisted_1$6={class:"__container_AppTabHeaderSlot"},_hoisted_2$6=_withScopeId$1(()=>createBaseVNode("span",{class:"header-desc"}," 新增条件路由 ",-1));function _sfc_render$1($n,Cn){const _n=resolveComponent("a-col"),Pn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$6,[createVNode(Pn,null,{default:withCtx(()=>[createVNode(_n,{span:12},{default:withCtx(()=>[_hoisted_2$6]),_:1})]),_:1})])}const AddConditionRuleTabHeaderSlot=_export_sfc(_sfc_main$7,[["render",_sfc_render$1],["__scopeId","data-v-0f2e35af"]]),_hoisted_1$5={class:"__container_AppTabHeaderSlot"},_hoisted_2$5={class:"header-desc"},_sfc_main$6=defineComponent({__name:"conditionRuleDetailTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$5,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$5,toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.ruleName),1)]}),_:1})]),_:1})])}}}),ConditionRuleDetailTabHeaderSlot=_export_sfc(_sfc_main$6,[["__scopeId","data-v-8b847dc2"]]),_hoisted_1$4={class:"__container_AppTabHeaderSlot"},_hoisted_2$4={class:"header-desc"},_sfc_main$5=defineComponent({__name:"updateConditionRuleTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$4,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$4," 修改 "+toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.ruleName),1)]}),_:1})]),_:1})])}}}),UpdateConditionRuleTabHeaderSlot=_export_sfc(_sfc_main$5,[["__scopeId","data-v-9e571c17"]]),_sfc_main$4={},_withScopeId=$n=>(pushScopeId("data-v-0f780945"),$n=$n(),popScopeId(),$n),_hoisted_1$3={class:"__container_AppTabHeaderSlot"},_hoisted_2$3=_withScopeId(()=>createBaseVNode("span",{class:"header-desc"}," 新增标签路由 ",-1));function _sfc_render($n,Cn){const _n=resolveComponent("a-col"),Pn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$3,[createVNode(Pn,null,{default:withCtx(()=>[createVNode(_n,{span:12},{default:withCtx(()=>[_hoisted_2$3]),_:1})]),_:1})])}const AddTagRuleTabHeaderSlot=_export_sfc(_sfc_main$4,[["render",_sfc_render],["__scopeId","data-v-0f780945"]]),_hoisted_1$2={class:"__container_AppTabHeaderSlot"},_hoisted_2$2={class:"header-desc"},_sfc_main$3=defineComponent({__name:"tagRuleDetailTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$2,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$2,toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.ruleName),1)]}),_:1})]),_:1})])}}}),TagRuleDetailTabHeaderSlot=_export_sfc(_sfc_main$3,[["__scopeId","data-v-49f86476"]]),_hoisted_1$1={class:"__container_AppTabHeaderSlot"},_hoisted_2$1={class:"header-desc"},_sfc_main$2=defineComponent({__name:"updateTagRuleTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1$1,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:12},{default:withCtx(()=>{var Rn;return[createBaseVNode("span",_hoisted_2$1," 修改 "+toDisplayString$1((Rn=unref(Cn).params)==null?void 0:Rn.ruleName),1)]}),_:1})]),_:1})])}}}),UpdateTagRuleTabHeaderSlot=_export_sfc(_sfc_main$2,[["__scopeId","data-v-91777569"]]),_hoisted_1={class:"__container_AppTabHeaderSlot"},_hoisted_2={class:"header-desc"},_sfc_main$1=defineComponent({__name:"updateDCTabHeaderSlot",setup($n){const Cn=useRoute();return(_n,Pn)=>{const In=resolveComponent("a-col"),Nn=resolveComponent("a-row");return openBlock(),createElementBlock("div",_hoisted_1,[createVNode(Nn,null,{default:withCtx(()=>[createVNode(In,{span:20},{default:withCtx(()=>{var Rn,Dn;return[createBaseVNode("span",_hoisted_2,toDisplayString$1(((Rn=unref(Cn).params)==null?void 0:Rn.isEdit)==="1"?_n.$t("dynamicConfigDomain.updateByFormView"):_n.$t("dynamicConfigDomain.detailByFormView"))+" "+toDisplayString$1((Dn=unref(Cn).params)==null?void 0:Dn.pathId),1)]}),_:1})]),_:1})])}}}),UpdateDCTabHeaderSlot=_export_sfc(_sfc_main$1,[["__scopeId","data-v-4d4ee463"]]),routes=[{path:"/login",name:"Login",component:()=>__vitePreload(()=>import("./Login-imIhMlq6.js"),__vite__mapDeps([0,1,2,3])),meta:{skip:!0},children:[]},{path:"/",name:"Root",redirect:"/home",component:()=>__vitePreload(()=>import("./index-tgq9rPkt.js"),__vite__mapDeps([4,5,2,6,7,1,8])),meta:{skip:!0},children:[{path:"/home",name:"homePage",component:()=>__vitePreload(()=>import("./index-bidvosE-.js"),__vite__mapDeps([9,10,2,11])),meta:{icon:"carbon:web-services-cluster"}},{path:"/resources",name:"resources",meta:{icon:"carbon:web-services-cluster"},children:[{path:"/applications",name:"applications",component:LayoutTab,redirect:"list",meta:{tab_parent:!0,slots:{header:AppTabHeaderSlot}},children:[{path:"/list",name:"router.resource.app.list",component:()=>__vitePreload(()=>import("./index-1-DS2ySp.js"),__vite__mapDeps([12,5,2,13,14,15])),meta:{hidden:!0}},{path:"/detail/:pathId",name:"applicationDomain.detail",component:()=>__vitePreload(()=>import("./detail-c9-keEBq.js"),__vite__mapDeps([16,5,2,17])),meta:{tab:!0,icon:"tabler:list-details",back:"/resources/applications/list"}},{path:"/instance/:pathId",name:"applicationDomain.instance",component:()=>__vitePreload(()=>import("./instance-GgpcTYxF.js"),__vite__mapDeps([18,13,14,5,2,19,20,21,22])),meta:{tab:!0,icon:"ooui:instance-ltr",back:"/resources/applications/list"}},{path:"/service/:pathId",name:"applicationDomain.service",component:()=>__vitePreload(()=>import("./service-SHOGrh_I.js"),__vite__mapDeps([23,10,2,13,14,5,20,24])),meta:{tab:!0,icon:"carbon:web-services-definition",back:"/resources/applications/list"}},{path:"/monitor/:pathId",name:"applicationDomain.monitor",component:()=>__vitePreload(()=>import("./monitor-sGZqYA6v.js"),__vite__mapDeps([25,26,27,5,2])),meta:{tab:!0,icon:"material-symbols-light:monitor-heart-outline",back:"/resources/applications/list"}},{path:"/tracing/:pathId",name:"applicationDomain.tracing",component:()=>__vitePreload(()=>import("./tracing-92ETcaci.js"),__vite__mapDeps([28,26,27,5,2])),meta:{tab:!0,icon:"game-icons:digital-trace",back:"/resources/applications/list"}},{path:"/config/:pathId",name:"applicationDomain.config",component:()=>__vitePreload(()=>import("./config-Bcppce3q.js"),__vite__mapDeps([29,30,31,5,2,32])),meta:{tab:!0,icon:"material-symbols:settings",back:"/resources/applications/list"}},{path:"/event/:pathId",name:"applicationDomain.event",component:()=>__vitePreload(()=>import("./event-ympyACpm.js"),__vite__mapDeps([33,5,2,34])),meta:{tab:!0,hidden:!0,icon:"material-symbols:date-range",back:"/resources/applications/list"}}]},{path:"/instances",name:"instances",component:LayoutTab,redirect:"list",meta:{tab_parent:!0,slots:{header:InstanceTabHeaderSlot}},children:[{path:"/list",name:"router.resource.ins.list",component:()=>__vitePreload(()=>import("./index-VJs-1Ntn.js"),__vite__mapDeps([35,6,2,13,14,20,21,36])),meta:{hidden:!0}},{path:"/detail/:appName/:pathId?",name:"instanceDomain.details",component:()=>__vitePreload(()=>import("./detail-ZfcGZsJx.js"),__vite__mapDeps([37,17,6,2,19])),meta:{tab:!0,icon:"tabler:list-details",back:"/resources/instances/list"}},{path:"/monitor/:pathId/:appName",name:"instanceDomain.monitor",component:()=>__vitePreload(()=>import("./monitor-l-14_P1G.js"),__vite__mapDeps([38,26,27,6,2])),meta:{tab:!0,icon:"ooui:instance-ltr",back:"/resources/instances/list"}},{path:"/linktracking/:pathId/:appName",name:"instanceDomain.linkTracking",component:()=>__vitePreload(()=>import("./linkTracking-vLLhx3tk.js"),__vite__mapDeps([39,26,27,6,2])),meta:{tab:!0,icon:"material-symbols-light:monitor-heart-outline",back:"/resources/instances/list"}},{path:"/configuration/:pathId/:appName",name:"instanceDomain.configuration",component:()=>__vitePreload(()=>import("./configuration-c8iwuhKj.js"),__vite__mapDeps([40,30,31,6,2])),meta:{tab:!0,icon:"material-symbols:settings",back:"/resources/instances/list"}},{path:"/event/:pathId/:appName",name:"instanceDomain.event",component:()=>__vitePreload(()=>import("./event-WVUl-Hrs.js"),__vite__mapDeps([])),meta:{tab:!0,hidden:!0,icon:"material-symbols:date-range",back:"/resources/instances/list"}}]},{path:"/services",name:"services",redirect:"list",component:LayoutTab,meta:{tab_parent:!0,slots:{header:ServiceTabHeaderSlot}},children:[{path:"/list",name:"router.resource.svc.list",component:()=>__vitePreload(()=>import("./search-ZPtMszjO.js"),__vite__mapDeps([41,7,2,13,14,20,42])),meta:{hidden:!0}},{path:"/distribution/:pathId/:group?/:version?",name:"distribution",component:()=>__vitePreload(()=>import("./distribution-rzJg55IY.js"),__vite__mapDeps([43,7,2,19,44])),meta:{tab:!0,back:"/resources/services/list"}},{path:"/monitor/:pathId/:group?/:version?",name:"monitor",component:()=>__vitePreload(()=>import("./monitor-4PTw3Hnl.js"),__vite__mapDeps([45,26,27,7,2])),meta:{tab:!0,back:"/resources/services/list"}},{path:"/tracing/:pathId/:group?/:version?",name:"tracing",component:()=>__vitePreload(()=>import("./tracing-ga_5tnvN.js"),__vite__mapDeps([46,26,27,7,2])),meta:{tab:!0,back:"/resources/services/list"}},{path:"/sceneConfig/:pathId/:group?/:version?",name:"sceneConfig",component:()=>__vitePreload(()=>import("./sceneConfig-b6LJLlLg.js"),__vite__mapDeps([47,30,31,7,2,48])),meta:{tab:!0,back:"/resources/services/list"}},{path:"/event/:pathId/:group?/:version?",name:"event",component:()=>__vitePreload(()=>import("./event-PfSKfl9X.js"),__vite__mapDeps([49,50])),meta:{tab:!0,hidden:!0,back:"/resources/services/list"}}]}]},{path:"/traffic",name:"trafficManagement",meta:{icon:"eos-icons:cluster-management"},children:[{path:"/routingRule",name:"routingRule",redirect:"index",component:LayoutTab,meta:{tab_parent:!0,slots:{header:ConditionRuleDetailTabHeaderSlot}},children:[{path:"/index",name:"routingRuleIndex",component:()=>__vitePreload(()=>import("./index-3ObQClF5.js"),__vite__mapDeps([51,52,2,13,14,19,53])),meta:{hidden:!0}},{path:"/formview/:ruleName",name:"routingRuleDomain.formView",component:()=>__vitePreload(()=>import("./formView-dr6vkirR.js"),__vite__mapDeps([54,17,52,2,55])),meta:{tab:!0,icon:"oui:apm-trace"}},{path:"/yamlview/:ruleName",name:"routingRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./YAMLView-lT4dPq7F.js"),__vite__mapDeps([56,57,58,52,2,59])),meta:{tab:!0,icon:"oui:app-console"}}]},{path:"/addRoutingRule",name:"addRoutingRule",component:LayoutTab,redirect:"addByFormView",meta:{tab_parent:!0,hidden:!0,slots:{header:AddConditionRuleTabHeaderSlot}},children:[{path:"/addByFormView",name:"addRoutingRuleDomain.formView",component:()=>__vitePreload(()=>import("./addByFormView-PDTQ6Oi5.js"),__vite__mapDeps([60,17,52,2,61])),meta:{tab:!0,icon:"oui:apm-trace"}},{path:"/addByYamlView",name:"addRoutingRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./addByYAMLView-mp4IQp11.js"),__vite__mapDeps([62,57,58,52,2,63])),meta:{tab:!0,icon:"oui:app-console"}}]},{path:"/updateRoutingRule",name:"updateRoutingRule",component:LayoutTab,meta:{tab_parent:!0,hidden:!0,slots:{header:UpdateConditionRuleTabHeaderSlot}},children:[{path:"/updateByFormView/:ruleName",name:"updateRoutingRuleDomain.formView",component:()=>__vitePreload(()=>import("./updateByFormView-ykpq9Kli.js"),__vite__mapDeps([64,17,52,2,65])),meta:{tab:!0}},{path:"/updateByYAMLView/:ruleName",name:"updateRoutingRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./updateByYAMLView-C-qbsfZ8.js"),__vite__mapDeps([66,57,58,52,2,67])),meta:{tab:!0}}]},{path:"/tagRule",name:"tagRule",redirect:"index",component:LayoutTab,meta:{tab_parent:!0,slots:{header:TagRuleDetailTabHeaderSlot}},children:[{path:"/index",name:"tagRuleIndex",component:()=>__vitePreload(()=>import("./index-JAGQH17O.js"),__vite__mapDeps([68,52,2,13,14,19,69])),meta:{hidden:!0}},{path:"/formview/:ruleName",name:"tagRuleDomain.formView",component:()=>__vitePreload(()=>import("./formView-yOHva0ty.js"),__vite__mapDeps([70,17,52,2,71])),meta:{tab:!0,icon:"oui:apm-trace",back:"/traffic/tagRule"}},{path:"/yamlview/:ruleName",name:"tagRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./YAMLView-q7Cf5xIc.js"),__vite__mapDeps([72,57,58,52,2,73])),meta:{tab:!0,icon:"oui:app-console"}}]},{path:"/addTagRule",name:"addTagRule",component:LayoutTab,meta:{tab_parent:!0,hidden:!0,slots:{header:AddTagRuleTabHeaderSlot}},children:[{path:"/addByFormView",name:"addTagRuleDomain.formView",component:()=>__vitePreload(()=>import("./addByFormView-L619fQ34.js"),__vite__mapDeps([74,17,52,2,75])),meta:{tab:!0,icon:"oui:apm-trace"}},{path:"/addByYAMLView",name:"addTagRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./addByYAMLView-KSfwZr8J.js"),__vite__mapDeps([76,57,58,52,2,77])),meta:{tab:!0,icon:"oui:app-console"}}]},{path:"/updateTagRule",name:"updateTagRule",component:LayoutTab,meta:{tab_parent:!0,hidden:!0,slots:{header:UpdateTagRuleTabHeaderSlot}},children:[{path:"/updateByFormView/:ruleName",name:"updateTagRuleDomain.formView",component:()=>__vitePreload(()=>import("./updateByFormView-uqlnXIPo.js"),__vite__mapDeps([78,17,52,2,79])),meta:{tab:!0}},{path:"/updateByYAMLView/:ruleName",name:"updateTagRuleDomain.YAMLView",component:()=>__vitePreload(()=>import("./updateByYAMLView-CBQATUCs.js"),__vite__mapDeps([80,57,58,52,2,81])),meta:{tab:!0}}]},{path:"/dynamicConfig",name:"dynamicConfig",redirect:"index",component:LayoutTab,meta:{tab_parent:!0},children:[{path:"/index",name:"dynamicConfigIndex",component:()=>__vitePreload(()=>import("./index-6mDJigRo.js"),__vite__mapDeps([82,52,2,13,14,83])),meta:{hidden:!0}},{path:"/formview/:pathId/:isEdit",name:"dynamicConfigDomain.formView",component:()=>__vitePreload(()=>import("./formView--eWAQ02R.js"),__vite__mapDeps([84,17,52,2,85,86])),meta:{tab:!0,icon:"oui:apm-trace",back:"/traffic/dynamicConfig",slots:{header:UpdateDCTabHeaderSlot}}},{path:"/yamlview/:pathId/:isEdit",name:"dynamicConfigDomain.YAMLView",component:()=>__vitePreload(()=>import("./YAMLView-Kv0Zh07k.js"),__vite__mapDeps([87,57,58,52,2,85,88])),meta:{tab:!0,icon:"oui:app-console",back:"/traffic/dynamicConfig",slots:{header:UpdateDCTabHeaderSlot}}}]}]},{path:"/common",name:"commonDemo",redirect:"tab",meta:{hidden:!0,icon:"tdesign:play-demo"},children:[{path:"/tab",name:"tabDemo",component:LayoutTab,redirect:"index",meta:{tab_parent:!0},children:[{path:"/index",name:"tab_demo_index",component:()=>__vitePreload(()=>import("./index-BItwxFIb.js"),__vite__mapDeps([])),meta:{hidden:!0}},{path:"/tab1/:pathId",name:"tab1",component:()=>__vitePreload(()=>import("./tab1-y_fNgbfH.js"),__vite__mapDeps([])),meta:{icon:"simple-icons:podman",tab:!0}},{path:"/tab2/:pathId",name:"tab2",component:()=>__vitePreload(()=>import("./tab2-s33OHi_L.js"),__vite__mapDeps([])),meta:{icon:"fontisto:docker",tab:!0}}]},{path:"/placeholder",name:"placeholder_demo",component:()=>__vitePreload(()=>import("./index-PRmcKXGy.js"),__vite__mapDeps([])),meta:{}}]}]},{path:"/:catchAll(.*)",name:"notFound",component:()=>__vitePreload(()=>import("./notFound-gtHVn9y2.js"),__vite__mapDeps([89,90])),meta:{skip:!0}}];function handlePath(...$n){return $n.join("/").replace(/\/+/g,"/")}function handleRoutes($n,Cn){if($n)for(const _n of $n)Cn&&(_n.path=handlePath(Cn==null?void 0:Cn.path,_n.path)),_n.redirect&&(_n.redirect=handlePath(_n.path,_n.redirect||"")),_n.meta?(_n.meta._router_key=_$2.uniqueId("__router_key"),_n.meta.parent=Cn,_n.meta.skip=_n.meta.skip===!0):_n.meta={_router_key:_$2.uniqueId("__router_key"),skip:!1},handleRoutes(_n.children,_n)}handleRoutes(routes,void 0);const options={history:createWebHistory("/admin"),routes},router=createRouter(options),locale$2={locale:"zh_CN",today:"今天",now:"此刻",backToToday:"返回今天",ok:"确定",timeSelect:"选择时间",dateSelect:"选择日期",weekSelect:"选择周",clear:"清除",month:"月",year:"年",previousMonth:"上个月 (翻页上键)",nextMonth:"下个月 (翻页下键)",monthSelect:"选择月份",yearSelect:"选择年份",decadeSelect:"选择年代",yearFormat:"YYYY年",dayFormat:"D日",dateFormat:"YYYY年M月D日",dateTimeFormat:"YYYY年M月D日 HH时mm分ss秒",previousYear:"上一年 (Control键加左方向键)",nextYear:"下一年 (Control键加右方向键)",previousDecade:"上一年代",nextDecade:"下一年代",previousCentury:"上一世纪",nextCentury:"下一世纪"},CalendarLocale=locale$2,locale$1={placeholder:"请选择时间",rangePlaceholder:["开始时间","结束时间"]},TimePicker=locale$1,locale={lang:_extends$1({placeholder:"请选择日期",yearPlaceholder:"请选择年份",quarterPlaceholder:"请选择季度",monthPlaceholder:"请选择月份",weekPlaceholder:"请选择周",rangePlaceholder:["开始日期","结束日期"],rangeYearPlaceholder:["开始年份","结束年份"],rangeMonthPlaceholder:["开始月份","结束月份"],rangeQuarterPlaceholder:["开始季度","结束季度"],rangeWeekPlaceholder:["开始周","结束周"]},CalendarLocale),timePickerLocale:_extends$1({},TimePicker)};locale.lang.ok="确定";const DatePicker=locale,typeTemplate="${label}不是一个有效的${type}",localeValues={locale:"zh-cn",Pagination:Pagination$2,DatePicker,TimePicker,Calendar:DatePicker,global:{placeholder:"请选择"},Table:{filterTitle:"筛选",filterConfirm:"确定",filterReset:"重置",filterEmptyText:"无筛选项",filterCheckall:"全选",filterSearchPlaceholder:"在筛选项中搜索",selectAll:"全选当页",selectInvert:"反选当页",selectNone:"清空所有",selectionAll:"全选所有",sortTitle:"排序",expand:"展开行",collapse:"关闭行",triggerDesc:"点击降序",triggerAsc:"点击升序",cancelSort:"取消排序"},Tour:{Next:"下一步",Previous:"上一步",Finish:"结束导览"},Modal:{okText:"确定",cancelText:"取消",justOkText:"知道了"},Popconfirm:{cancelText:"取消",okText:"确定"},Transfer:{searchPlaceholder:"请输入搜索内容",itemUnit:"项",itemsUnit:"项",remove:"删除",selectCurrent:"全选当页",removeCurrent:"删除当页",selectAll:"全选所有",removeAll:"删除全部",selectInvert:"反选当页"},Upload:{uploading:"文件上传中",removeFile:"删除文件",uploadError:"上传错误",previewFile:"预览文件",downloadFile:"下载文件"},Empty:{description:"暂无数据"},Icon:{icon:"图标"},Text:{edit:"编辑",copy:"复制",copied:"复制成功",expand:"展开"},PageHeader:{back:"返回"},Form:{optional:"(可选)",defaultValidateMessages:{default:"字段验证错误${label}",required:"请输入${label}",enum:"${label}必须是其中一个[${enum}]",whitespace:"${label}不能为空字符",date:{format:"${label}日期格式无效",parse:"${label}不能转换为日期",invalid:"${label}是一个无效日期"},types:{string:typeTemplate,method:typeTemplate,array:typeTemplate,object:typeTemplate,number:typeTemplate,date:typeTemplate,boolean:typeTemplate,integer:typeTemplate,float:typeTemplate,regexp:typeTemplate,email:typeTemplate,url:typeTemplate,hex:typeTemplate},string:{len:"${label}须为${len}个字符",min:"${label}最少${min}个字符",max:"${label}最多${max}个字符",range:"${label}须在${min}-${max}字符之间"},number:{len:"${label}必须等于${len}",min:"${label}最小值为${min}",max:"${label}最大值为${max}",range:"${label}须在${min}-${max}之间"},array:{len:"须为${len}个${label}",min:"最少${min}个${label}",max:"最多${max}个${label}",range:"${label}数量须在${min}-${max}之间"},pattern:{mismatch:"${label}与模式不匹配${pattern}"}}},Image:{preview:"预览"},QRCode:{expired:"二维码已过期",refresh:"点击刷新",scanned:"已扫描"}},zhCN=localeValues;var dayjs_min={exports:{}};(function($n,Cn){(function(_n,Pn){$n.exports=Pn()})(commonjsGlobal,function(){var _n=1e3,Pn=6e4,In=36e5,Nn="millisecond",Rn="second",Dn="minute",Ln="hour",Fn="day",Bn="week",Hn="month",zn="quarter",Wn="year",Yn="date",Gn="Invalid Date",Go=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,Xn=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,Yo={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(ga){var aa=["th","st","nd","rd"],ca=ga%100;return"["+ga+(aa[(ca-20)%10]||aa[ca]||aa[0])+"]"}},qo=function(ga,aa,ca){var sa=String(ga);return!sa||sa.length>=aa?ga:""+Array(aa+1-sa.length).join(ca)+ga},Jo={s:qo,z:function(ga){var aa=-ga.utcOffset(),ca=Math.abs(aa),sa=Math.floor(ca/60),ia=ca%60;return(aa<=0?"+":"-")+qo(sa,2,"0")+":"+qo(ia,2,"0")},m:function ga(aa,ca){if(aa.date()1)return ga(ma[0])}else{var ya=aa.name;rr[ya]=aa,ia=ya}return!sa&&ia&&(Zo=ia),ia||!sa&&Zo},ra=function(ga,aa){if(ta(ga))return ga.clone();var ca=typeof aa=="object"?aa:{};return ca.date=ga,ca.args=arguments,new la(ca)},ea=Jo;ea.l=oa,ea.i=ta,ea.w=function(ga,aa){return ra(ga,{locale:aa.$L,utc:aa.$u,x:aa.$x,$offset:aa.$offset})};var la=function(){function ga(ca){this.$L=oa(ca.locale,null,!0),this.parse(ca),this.$x=this.$x||ca.x||{},this[nr]=!0}var aa=ga.prototype;return aa.parse=function(ca){this.$d=function(sa){var ia=sa.date,fa=sa.utc;if(ia===null)return new Date(NaN);if(ea.u(ia))return new Date;if(ia instanceof Date)return new Date(ia);if(typeof ia=="string"&&!/Z$/i.test(ia)){var ma=ia.match(Go);if(ma){var ya=ma[2]-1||0,ba=(ma[7]||"0").substring(0,3);return fa?new Date(Date.UTC(ma[1],ya,ma[3]||1,ma[4]||0,ma[5]||0,ma[6]||0,ba)):new Date(ma[1],ya,ma[3]||1,ma[4]||0,ma[5]||0,ma[6]||0,ba)}}return new Date(ia)}(ca),this.init()},aa.init=function(){var ca=this.$d;this.$y=ca.getFullYear(),this.$M=ca.getMonth(),this.$D=ca.getDate(),this.$W=ca.getDay(),this.$H=ca.getHours(),this.$m=ca.getMinutes(),this.$s=ca.getSeconds(),this.$ms=ca.getMilliseconds()},aa.$utils=function(){return ea},aa.isValid=function(){return this.$d.toString()!==Gn},aa.isSame=function(ca,sa){var ia=ra(ca);return this.startOf(sa)<=ia&&ia<=this.endOf(sa)},aa.isAfter=function(ca,sa){return ra(ca)Cn?Symbol.for($n):Symbol($n),generateFormatCacheKey=($n,Cn,_n)=>friendlyJSONstringify({l:$n,k:Cn,s:_n}),friendlyJSONstringify=$n=>JSON.stringify($n).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),isNumber=$n=>typeof $n=="number"&&isFinite($n),isDate=$n=>toTypeString($n)==="[object Date]",isRegExp=$n=>toTypeString($n)==="[object RegExp]",isEmptyObject=$n=>isPlainObject$1($n)&&Object.keys($n).length===0,assign$2=Object.assign;let _globalThis;const getGlobalThis=()=>_globalThis||(_globalThis=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function escapeHtml($n){return $n.replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}const hasOwnProperty=Object.prototype.hasOwnProperty;function hasOwn($n,Cn){return hasOwnProperty.call($n,Cn)}const isArray=Array.isArray,isFunction=$n=>typeof $n=="function",isString$1=$n=>typeof $n=="string",isBoolean=$n=>typeof $n=="boolean",isObject$3=$n=>$n!==null&&typeof $n=="object",isPromise=$n=>isObject$3($n)&&isFunction($n.then)&&isFunction($n.catch),objectToString=Object.prototype.toString,toTypeString=$n=>objectToString.call($n),isPlainObject$1=$n=>{if(!isObject$3($n))return!1;const Cn=Object.getPrototypeOf($n);return Cn===null||Cn.constructor===Object},toDisplayString=$n=>$n==null?"":isArray($n)||isPlainObject$1($n)&&$n.toString===objectToString?JSON.stringify($n,null,2):String($n);function join$1($n,Cn=""){return $n.reduce((_n,Pn,In)=>In===0?_n+Pn:_n+Cn+Pn,"")}function incrementer($n){let Cn=$n;return()=>++Cn}function warn($n,Cn){typeof console<"u"&&(console.warn("[intlify] "+$n),Cn&&console.warn(Cn.stack))}const isNotObjectOrIsArray=$n=>!isObject$3($n)||isArray($n);function deepCopy($n,Cn){if(isNotObjectOrIsArray($n)||isNotObjectOrIsArray(Cn))throw new Error("Invalid value");const _n=[{src:$n,des:Cn}];for(;_n.length;){const{src:Pn,des:In}=_n.pop();Object.keys(Pn).forEach(Nn=>{isNotObjectOrIsArray(Pn[Nn])||isNotObjectOrIsArray(In[Nn])?In[Nn]=Pn[Nn]:_n.push({src:Pn[Nn],des:In[Nn]})})}}/*! - * message-compiler v9.9.1 - * (c) 2024 kazuya kawaguchi - * Released under the MIT License. - */function createPosition($n,Cn,_n){return{line:$n,column:Cn,offset:_n}}function createLocation($n,Cn,_n){const Pn={start:$n,end:Cn};return _n!=null&&(Pn.source=_n),Pn}const RE_ARGS=/\{([0-9a-zA-Z]+)\}/g;function format$1($n,...Cn){return Cn.length===1&&isObject$2(Cn[0])&&(Cn=Cn[0]),(!Cn||!Cn.hasOwnProperty)&&(Cn={}),$n.replace(RE_ARGS,(_n,Pn)=>Cn.hasOwnProperty(Pn)?Cn[Pn]:"")}const assign$1=Object.assign,isString=$n=>typeof $n=="string",isObject$2=$n=>$n!==null&&typeof $n=="object";function join($n,Cn=""){return $n.reduce((_n,Pn,In)=>In===0?_n+Pn:_n+Cn+Pn,"")}const CompileErrorCodes={EXPECTED_TOKEN:1,INVALID_TOKEN_IN_PLACEHOLDER:2,UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER:3,UNKNOWN_ESCAPE_SEQUENCE:4,INVALID_UNICODE_ESCAPE_SEQUENCE:5,UNBALANCED_CLOSING_BRACE:6,UNTERMINATED_CLOSING_BRACE:7,EMPTY_PLACEHOLDER:8,NOT_ALLOW_NEST_PLACEHOLDER:9,INVALID_LINKED_FORMAT:10,MUST_HAVE_MESSAGES_IN_PLURAL:11,UNEXPECTED_EMPTY_LINKED_MODIFIER:12,UNEXPECTED_EMPTY_LINKED_KEY:13,UNEXPECTED_LEXICAL_ANALYSIS:14,UNHANDLED_CODEGEN_NODE_TYPE:15,UNHANDLED_MINIFIER_NODE_TYPE:16,__EXTEND_POINT__:17},errorMessages={[CompileErrorCodes.EXPECTED_TOKEN]:"Expected token: '{0}'",[CompileErrorCodes.INVALID_TOKEN_IN_PLACEHOLDER]:"Invalid token in placeholder: '{0}'",[CompileErrorCodes.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER]:"Unterminated single quote in placeholder",[CompileErrorCodes.UNKNOWN_ESCAPE_SEQUENCE]:"Unknown escape sequence: \\{0}",[CompileErrorCodes.INVALID_UNICODE_ESCAPE_SEQUENCE]:"Invalid unicode escape sequence: {0}",[CompileErrorCodes.UNBALANCED_CLOSING_BRACE]:"Unbalanced closing brace",[CompileErrorCodes.UNTERMINATED_CLOSING_BRACE]:"Unterminated closing brace",[CompileErrorCodes.EMPTY_PLACEHOLDER]:"Empty placeholder",[CompileErrorCodes.NOT_ALLOW_NEST_PLACEHOLDER]:"Not allowed nest placeholder",[CompileErrorCodes.INVALID_LINKED_FORMAT]:"Invalid linked format",[CompileErrorCodes.MUST_HAVE_MESSAGES_IN_PLURAL]:"Plural must have messages",[CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_MODIFIER]:"Unexpected empty linked modifier",[CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_KEY]:"Unexpected empty linked key",[CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS]:"Unexpected lexical analysis in token: '{0}'",[CompileErrorCodes.UNHANDLED_CODEGEN_NODE_TYPE]:"unhandled codegen node type: '{0}'",[CompileErrorCodes.UNHANDLED_MINIFIER_NODE_TYPE]:"unhandled mimifier node type: '{0}'"};function createCompileError($n,Cn,_n={}){const{domain:Pn,messages:In,args:Nn}=_n,Rn=format$1((In||errorMessages)[$n]||"",...Nn||[]),Dn=new SyntaxError(String(Rn));return Dn.code=$n,Cn&&(Dn.location=Cn),Dn.domain=Pn,Dn}function defaultOnError($n){throw $n}const CHAR_SP=" ",CHAR_CR="\r",CHAR_LF=` -`,CHAR_LS="\u2028",CHAR_PS="\u2029";function createScanner($n){const Cn=$n;let _n=0,Pn=1,In=1,Nn=0;const Rn=nr=>Cn[nr]===CHAR_CR&&Cn[nr+1]===CHAR_LF,Dn=nr=>Cn[nr]===CHAR_LF,Ln=nr=>Cn[nr]===CHAR_PS,Fn=nr=>Cn[nr]===CHAR_LS,Bn=nr=>Rn(nr)||Dn(nr)||Ln(nr)||Fn(nr),Hn=()=>_n,zn=()=>Pn,Wn=()=>In,Yn=()=>Nn,Gn=nr=>Rn(nr)||Ln(nr)||Fn(nr)?CHAR_LF:Cn[nr],Go=()=>Gn(_n),Xn=()=>Gn(_n+Nn);function Yo(){return Nn=0,Bn(_n)&&(Pn++,In=0),Rn(_n)&&_n++,_n++,In++,Cn[_n]}function qo(){return Rn(_n+Nn)&&Nn++,Nn++,Cn[_n+Nn]}function Jo(){_n=0,Pn=1,In=1,Nn=0}function Zo(nr=0){Nn=nr}function rr(){const nr=_n+Nn;for(;nr!==_n;)Yo();Nn=0}return{index:Hn,line:zn,column:Wn,peekOffset:Yn,charAt:Gn,currentChar:Go,currentPeek:Xn,next:Yo,peek:qo,reset:Jo,resetPeek:Zo,skipToPeek:rr}}const EOF=void 0,DOT=".",LITERAL_DELIMITER="'",ERROR_DOMAIN$3="tokenizer";function createTokenizer($n,Cn={}){const _n=Cn.location!==!1,Pn=createScanner($n),In=()=>Pn.index(),Nn=()=>createPosition(Pn.line(),Pn.column(),Pn.index()),Rn=Nn(),Dn=In(),Ln={currentType:14,offset:Dn,startLoc:Rn,endLoc:Rn,lastType:14,lastOffset:Dn,lastStartLoc:Rn,lastEndLoc:Rn,braceNest:0,inLinked:!1,text:""},Fn=()=>Ln,{onError:Bn}=Cn;function Hn(da,pa,Sa,...Aa){const Ra=Fn();if(pa.column+=Sa,pa.offset+=Sa,Bn){const Fa=_n?createLocation(Ra.startLoc,pa):null,za=createCompileError(da,Fa,{domain:ERROR_DOMAIN$3,args:Aa});Bn(za)}}function zn(da,pa,Sa){da.endLoc=Nn(),da.currentType=pa;const Aa={type:pa};return _n&&(Aa.loc=createLocation(da.startLoc,da.endLoc)),Sa!=null&&(Aa.value=Sa),Aa}const Wn=da=>zn(da,14);function Yn(da,pa){return da.currentChar()===pa?(da.next(),pa):(Hn(CompileErrorCodes.EXPECTED_TOKEN,Nn(),0,pa),"")}function Gn(da){let pa="";for(;da.currentPeek()===CHAR_SP||da.currentPeek()===CHAR_LF;)pa+=da.currentPeek(),da.peek();return pa}function Go(da){const pa=Gn(da);return da.skipToPeek(),pa}function Xn(da){if(da===EOF)return!1;const pa=da.charCodeAt(0);return pa>=97&&pa<=122||pa>=65&&pa<=90||pa===95}function Yo(da){if(da===EOF)return!1;const pa=da.charCodeAt(0);return pa>=48&&pa<=57}function qo(da,pa){const{currentType:Sa}=pa;if(Sa!==2)return!1;Gn(da);const Aa=Xn(da.currentPeek());return da.resetPeek(),Aa}function Jo(da,pa){const{currentType:Sa}=pa;if(Sa!==2)return!1;Gn(da);const Aa=da.currentPeek()==="-"?da.peek():da.currentPeek(),Ra=Yo(Aa);return da.resetPeek(),Ra}function Zo(da,pa){const{currentType:Sa}=pa;if(Sa!==2)return!1;Gn(da);const Aa=da.currentPeek()===LITERAL_DELIMITER;return da.resetPeek(),Aa}function rr(da,pa){const{currentType:Sa}=pa;if(Sa!==8)return!1;Gn(da);const Aa=da.currentPeek()===".";return da.resetPeek(),Aa}function nr(da,pa){const{currentType:Sa}=pa;if(Sa!==9)return!1;Gn(da);const Aa=Xn(da.currentPeek());return da.resetPeek(),Aa}function ta(da,pa){const{currentType:Sa}=pa;if(!(Sa===8||Sa===12))return!1;Gn(da);const Aa=da.currentPeek()===":";return da.resetPeek(),Aa}function oa(da,pa){const{currentType:Sa}=pa;if(Sa!==10)return!1;const Aa=()=>{const Fa=da.currentPeek();return Fa==="{"?Xn(da.peek()):Fa==="@"||Fa==="%"||Fa==="|"||Fa===":"||Fa==="."||Fa===CHAR_SP||!Fa?!1:Fa===CHAR_LF?(da.peek(),Aa()):Xn(Fa)},Ra=Aa();return da.resetPeek(),Ra}function ra(da){Gn(da);const pa=da.currentPeek()==="|";return da.resetPeek(),pa}function ea(da){const pa=Gn(da),Sa=da.currentPeek()==="%"&&da.peek()==="{";return da.resetPeek(),{isModulo:Sa,hasSpace:pa.length>0}}function la(da,pa=!0){const Sa=(Ra=!1,Fa="",za=!1)=>{const Wa=da.currentPeek();return Wa==="{"?Fa==="%"?!1:Ra:Wa==="@"||!Wa?Fa==="%"?!0:Ra:Wa==="%"?(da.peek(),Sa(Ra,"%",!0)):Wa==="|"?Fa==="%"||za?!0:!(Fa===CHAR_SP||Fa===CHAR_LF):Wa===CHAR_SP?(da.peek(),Sa(!0,CHAR_SP,za)):Wa===CHAR_LF?(da.peek(),Sa(!0,CHAR_LF,za)):!0},Aa=Sa();return pa&&da.resetPeek(),Aa}function ua(da,pa){const Sa=da.currentChar();return Sa===EOF?EOF:pa(Sa)?(da.next(),Sa):null}function ga(da){return ua(da,Sa=>{const Aa=Sa.charCodeAt(0);return Aa>=97&&Aa<=122||Aa>=65&&Aa<=90||Aa>=48&&Aa<=57||Aa===95||Aa===36})}function aa(da){return ua(da,Sa=>{const Aa=Sa.charCodeAt(0);return Aa>=48&&Aa<=57})}function ca(da){return ua(da,Sa=>{const Aa=Sa.charCodeAt(0);return Aa>=48&&Aa<=57||Aa>=65&&Aa<=70||Aa>=97&&Aa<=102})}function sa(da){let pa="",Sa="";for(;pa=aa(da);)Sa+=pa;return Sa}function ia(da){Go(da);const pa=da.currentChar();return pa!=="%"&&Hn(CompileErrorCodes.EXPECTED_TOKEN,Nn(),0,pa),da.next(),"%"}function fa(da){let pa="";for(;;){const Sa=da.currentChar();if(Sa==="{"||Sa==="}"||Sa==="@"||Sa==="|"||!Sa)break;if(Sa==="%")if(la(da))pa+=Sa,da.next();else break;else if(Sa===CHAR_SP||Sa===CHAR_LF)if(la(da))pa+=Sa,da.next();else{if(ra(da))break;pa+=Sa,da.next()}else pa+=Sa,da.next()}return pa}function ma(da){Go(da);let pa="",Sa="";for(;pa=ga(da);)Sa+=pa;return da.currentChar()===EOF&&Hn(CompileErrorCodes.UNTERMINATED_CLOSING_BRACE,Nn(),0),Sa}function ya(da){Go(da);let pa="";return da.currentChar()==="-"?(da.next(),pa+=`-${sa(da)}`):pa+=sa(da),da.currentChar()===EOF&&Hn(CompileErrorCodes.UNTERMINATED_CLOSING_BRACE,Nn(),0),pa}function ba(da){Go(da),Yn(da,"'");let pa="",Sa="";const Aa=Fa=>Fa!==LITERAL_DELIMITER&&Fa!==CHAR_LF;for(;pa=ua(da,Aa);)pa==="\\"?Sa+=Ia(da):Sa+=pa;const Ra=da.currentChar();return Ra===CHAR_LF||Ra===EOF?(Hn(CompileErrorCodes.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER,Nn(),0),Ra===CHAR_LF&&(da.next(),Yn(da,"'")),Sa):(Yn(da,"'"),Sa)}function Ia(da){const pa=da.currentChar();switch(pa){case"\\":case"'":return da.next(),`\\${pa}`;case"u":return Ea(da,pa,4);case"U":return Ea(da,pa,6);default:return Hn(CompileErrorCodes.UNKNOWN_ESCAPE_SEQUENCE,Nn(),0,pa),""}}function Ea(da,pa,Sa){Yn(da,pa);let Aa="";for(let Ra=0;RaRa!=="{"&&Ra!=="}"&&Ra!==CHAR_SP&&Ra!==CHAR_LF;for(;pa=ua(da,Aa);)Sa+=pa;return Sa}function Ta(da){let pa="",Sa="";for(;pa=ga(da);)Sa+=pa;return Sa}function wa(da){const pa=(Sa=!1,Aa)=>{const Ra=da.currentChar();return Ra==="{"||Ra==="%"||Ra==="@"||Ra==="|"||Ra==="("||Ra===")"||!Ra||Ra===CHAR_SP?Aa:Ra===CHAR_LF||Ra===DOT?(Aa+=Ra,da.next(),pa(Sa,Aa)):(Aa+=Ra,da.next(),pa(!0,Aa))};return pa(!1,"")}function La(da){Go(da);const pa=Yn(da,"|");return Go(da),pa}function Na(da,pa){let Sa=null;switch(da.currentChar()){case"{":return pa.braceNest>=1&&Hn(CompileErrorCodes.NOT_ALLOW_NEST_PLACEHOLDER,Nn(),0),da.next(),Sa=zn(pa,2,"{"),Go(da),pa.braceNest++,Sa;case"}":return pa.braceNest>0&&pa.currentType===2&&Hn(CompileErrorCodes.EMPTY_PLACEHOLDER,Nn(),0),da.next(),Sa=zn(pa,3,"}"),pa.braceNest--,pa.braceNest>0&&Go(da),pa.inLinked&&pa.braceNest===0&&(pa.inLinked=!1),Sa;case"@":return pa.braceNest>0&&Hn(CompileErrorCodes.UNTERMINATED_CLOSING_BRACE,Nn(),0),Sa=$a(da,pa)||Wn(pa),pa.braceNest=0,Sa;default:let Ra=!0,Fa=!0,za=!0;if(ra(da))return pa.braceNest>0&&Hn(CompileErrorCodes.UNTERMINATED_CLOSING_BRACE,Nn(),0),Sa=zn(pa,1,La(da)),pa.braceNest=0,pa.inLinked=!1,Sa;if(pa.braceNest>0&&(pa.currentType===5||pa.currentType===6||pa.currentType===7))return Hn(CompileErrorCodes.UNTERMINATED_CLOSING_BRACE,Nn(),0),pa.braceNest=0,ka(da,pa);if(Ra=qo(da,pa))return Sa=zn(pa,5,ma(da)),Go(da),Sa;if(Fa=Jo(da,pa))return Sa=zn(pa,6,ya(da)),Go(da),Sa;if(za=Zo(da,pa))return Sa=zn(pa,7,ba(da)),Go(da),Sa;if(!Ra&&!Fa&&!za)return Sa=zn(pa,13,xa(da)),Hn(CompileErrorCodes.INVALID_TOKEN_IN_PLACEHOLDER,Nn(),0,Sa.value),Go(da),Sa;break}return Sa}function $a(da,pa){const{currentType:Sa}=pa;let Aa=null;const Ra=da.currentChar();switch((Sa===8||Sa===9||Sa===12||Sa===10)&&(Ra===CHAR_LF||Ra===CHAR_SP)&&Hn(CompileErrorCodes.INVALID_LINKED_FORMAT,Nn(),0),Ra){case"@":return da.next(),Aa=zn(pa,8,"@"),pa.inLinked=!0,Aa;case".":return Go(da),da.next(),zn(pa,9,".");case":":return Go(da),da.next(),zn(pa,10,":");default:return ra(da)?(Aa=zn(pa,1,La(da)),pa.braceNest=0,pa.inLinked=!1,Aa):rr(da,pa)||ta(da,pa)?(Go(da),$a(da,pa)):nr(da,pa)?(Go(da),zn(pa,12,Ta(da))):oa(da,pa)?(Go(da),Ra==="{"?Na(da,pa)||Aa:zn(pa,11,wa(da))):(Sa===8&&Hn(CompileErrorCodes.INVALID_LINKED_FORMAT,Nn(),0),pa.braceNest=0,pa.inLinked=!1,ka(da,pa))}}function ka(da,pa){let Sa={type:14};if(pa.braceNest>0)return Na(da,pa)||Wn(pa);if(pa.inLinked)return $a(da,pa)||Wn(pa);switch(da.currentChar()){case"{":return Na(da,pa)||Wn(pa);case"}":return Hn(CompileErrorCodes.UNBALANCED_CLOSING_BRACE,Nn(),0),da.next(),zn(pa,3,"}");case"@":return $a(da,pa)||Wn(pa);default:if(ra(da))return Sa=zn(pa,1,La(da)),pa.braceNest=0,pa.inLinked=!1,Sa;const{isModulo:Ra,hasSpace:Fa}=ea(da);if(Ra)return Fa?zn(pa,0,fa(da)):zn(pa,4,ia(da));if(la(da))return zn(pa,0,fa(da));break}return Sa}function Ha(){const{currentType:da,offset:pa,startLoc:Sa,endLoc:Aa}=Ln;return Ln.lastType=da,Ln.lastOffset=pa,Ln.lastStartLoc=Sa,Ln.lastEndLoc=Aa,Ln.offset=In(),Ln.startLoc=Nn(),Pn.currentChar()===EOF?zn(Ln,14):ka(Pn,Ln)}return{nextToken:Ha,currentOffset:In,currentPosition:Nn,context:Fn}}const ERROR_DOMAIN$2="parser",KNOWN_ESCAPES=/(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g;function fromEscapeSequence($n,Cn,_n){switch($n){case"\\\\":return"\\";case"\\'":return"'";default:{const Pn=parseInt(Cn||_n,16);return Pn<=55295||Pn>=57344?String.fromCodePoint(Pn):"�"}}}function createParser($n={}){const Cn=$n.location!==!1,{onError:_n}=$n;function Pn(Xn,Yo,qo,Jo,...Zo){const rr=Xn.currentPosition();if(rr.offset+=Jo,rr.column+=Jo,_n){const nr=Cn?createLocation(qo,rr):null,ta=createCompileError(Yo,nr,{domain:ERROR_DOMAIN$2,args:Zo});_n(ta)}}function In(Xn,Yo,qo){const Jo={type:Xn};return Cn&&(Jo.start=Yo,Jo.end=Yo,Jo.loc={start:qo,end:qo}),Jo}function Nn(Xn,Yo,qo,Jo){Jo&&(Xn.type=Jo),Cn&&(Xn.end=Yo,Xn.loc&&(Xn.loc.end=qo))}function Rn(Xn,Yo){const qo=Xn.context(),Jo=In(3,qo.offset,qo.startLoc);return Jo.value=Yo,Nn(Jo,Xn.currentOffset(),Xn.currentPosition()),Jo}function Dn(Xn,Yo){const qo=Xn.context(),{lastOffset:Jo,lastStartLoc:Zo}=qo,rr=In(5,Jo,Zo);return rr.index=parseInt(Yo,10),Xn.nextToken(),Nn(rr,Xn.currentOffset(),Xn.currentPosition()),rr}function Ln(Xn,Yo){const qo=Xn.context(),{lastOffset:Jo,lastStartLoc:Zo}=qo,rr=In(4,Jo,Zo);return rr.key=Yo,Xn.nextToken(),Nn(rr,Xn.currentOffset(),Xn.currentPosition()),rr}function Fn(Xn,Yo){const qo=Xn.context(),{lastOffset:Jo,lastStartLoc:Zo}=qo,rr=In(9,Jo,Zo);return rr.value=Yo.replace(KNOWN_ESCAPES,fromEscapeSequence),Xn.nextToken(),Nn(rr,Xn.currentOffset(),Xn.currentPosition()),rr}function Bn(Xn){const Yo=Xn.nextToken(),qo=Xn.context(),{lastOffset:Jo,lastStartLoc:Zo}=qo,rr=In(8,Jo,Zo);return Yo.type!==12?(Pn(Xn,CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_MODIFIER,qo.lastStartLoc,0),rr.value="",Nn(rr,Jo,Zo),{nextConsumeToken:Yo,node:rr}):(Yo.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,qo.lastStartLoc,0,getTokenCaption(Yo)),rr.value=Yo.value||"",Nn(rr,Xn.currentOffset(),Xn.currentPosition()),{node:rr})}function Hn(Xn,Yo){const qo=Xn.context(),Jo=In(7,qo.offset,qo.startLoc);return Jo.value=Yo,Nn(Jo,Xn.currentOffset(),Xn.currentPosition()),Jo}function zn(Xn){const Yo=Xn.context(),qo=In(6,Yo.offset,Yo.startLoc);let Jo=Xn.nextToken();if(Jo.type===9){const Zo=Bn(Xn);qo.modifier=Zo.node,Jo=Zo.nextConsumeToken||Xn.nextToken()}switch(Jo.type!==10&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(Jo)),Jo=Xn.nextToken(),Jo.type===2&&(Jo=Xn.nextToken()),Jo.type){case 11:Jo.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(Jo)),qo.key=Hn(Xn,Jo.value||"");break;case 5:Jo.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(Jo)),qo.key=Ln(Xn,Jo.value||"");break;case 6:Jo.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(Jo)),qo.key=Dn(Xn,Jo.value||"");break;case 7:Jo.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(Jo)),qo.key=Fn(Xn,Jo.value||"");break;default:Pn(Xn,CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_KEY,Yo.lastStartLoc,0);const Zo=Xn.context(),rr=In(7,Zo.offset,Zo.startLoc);return rr.value="",Nn(rr,Zo.offset,Zo.startLoc),qo.key=rr,Nn(qo,Zo.offset,Zo.startLoc),{nextConsumeToken:Jo,node:qo}}return Nn(qo,Xn.currentOffset(),Xn.currentPosition()),{node:qo}}function Wn(Xn){const Yo=Xn.context(),qo=Yo.currentType===1?Xn.currentOffset():Yo.offset,Jo=Yo.currentType===1?Yo.endLoc:Yo.startLoc,Zo=In(2,qo,Jo);Zo.items=[];let rr=null;do{const oa=rr||Xn.nextToken();switch(rr=null,oa.type){case 0:oa.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(oa)),Zo.items.push(Rn(Xn,oa.value||""));break;case 6:oa.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(oa)),Zo.items.push(Dn(Xn,oa.value||""));break;case 5:oa.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(oa)),Zo.items.push(Ln(Xn,oa.value||""));break;case 7:oa.value==null&&Pn(Xn,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,Yo.lastStartLoc,0,getTokenCaption(oa)),Zo.items.push(Fn(Xn,oa.value||""));break;case 8:const ra=zn(Xn);Zo.items.push(ra.node),rr=ra.nextConsumeToken||null;break}}while(Yo.currentType!==14&&Yo.currentType!==1);const nr=Yo.currentType===1?Yo.lastOffset:Xn.currentOffset(),ta=Yo.currentType===1?Yo.lastEndLoc:Xn.currentPosition();return Nn(Zo,nr,ta),Zo}function Yn(Xn,Yo,qo,Jo){const Zo=Xn.context();let rr=Jo.items.length===0;const nr=In(1,Yo,qo);nr.cases=[],nr.cases.push(Jo);do{const ta=Wn(Xn);rr||(rr=ta.items.length===0),nr.cases.push(ta)}while(Zo.currentType!==14);return rr&&Pn(Xn,CompileErrorCodes.MUST_HAVE_MESSAGES_IN_PLURAL,qo,0),Nn(nr,Xn.currentOffset(),Xn.currentPosition()),nr}function Gn(Xn){const Yo=Xn.context(),{offset:qo,startLoc:Jo}=Yo,Zo=Wn(Xn);return Yo.currentType===14?Zo:Yn(Xn,qo,Jo,Zo)}function Go(Xn){const Yo=createTokenizer(Xn,assign$1({},$n)),qo=Yo.context(),Jo=In(0,qo.offset,qo.startLoc);return Cn&&Jo.loc&&(Jo.loc.source=Xn),Jo.body=Gn(Yo),$n.onCacheKey&&(Jo.cacheKey=$n.onCacheKey(Xn)),qo.currentType!==14&&Pn(Yo,CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS,qo.lastStartLoc,0,Xn[qo.offset]||""),Nn(Jo,Yo.currentOffset(),Yo.currentPosition()),Jo}return{parse:Go}}function getTokenCaption($n){if($n.type===14)return"EOF";const Cn=($n.value||"").replace(/\r?\n/gu,"\\n");return Cn.length>10?Cn.slice(0,9)+"…":Cn}function createTransformer($n,Cn={}){const _n={ast:$n,helpers:new Set};return{context:()=>_n,helper:Nn=>(_n.helpers.add(Nn),Nn)}}function traverseNodes($n,Cn){for(let _n=0;_n<$n.length;_n++)traverseNode($n[_n],Cn)}function traverseNode($n,Cn){switch($n.type){case 1:traverseNodes($n.cases,Cn),Cn.helper("plural");break;case 2:traverseNodes($n.items,Cn);break;case 6:traverseNode($n.key,Cn),Cn.helper("linked"),Cn.helper("type");break;case 5:Cn.helper("interpolate"),Cn.helper("list");break;case 4:Cn.helper("interpolate"),Cn.helper("named");break}}function transform($n,Cn={}){const _n=createTransformer($n);_n.helper("normalize"),$n.body&&traverseNode($n.body,_n);const Pn=_n.context();$n.helpers=Array.from(Pn.helpers)}function optimize($n){const Cn=$n.body;return Cn.type===2?optimizeMessageNode(Cn):Cn.cases.forEach(_n=>optimizeMessageNode(_n)),$n}function optimizeMessageNode($n){if($n.items.length===1){const Cn=$n.items[0];(Cn.type===3||Cn.type===9)&&($n.static=Cn.value,delete Cn.value)}else{const Cn=[];for(let _n=0;_n<$n.items.length;_n++){const Pn=$n.items[_n];if(!(Pn.type===3||Pn.type===9)||Pn.value==null)break;Cn.push(Pn.value)}if(Cn.length===$n.items.length){$n.static=join(Cn);for(let _n=0;_n<$n.items.length;_n++){const Pn=$n.items[_n];(Pn.type===3||Pn.type===9)&&delete Pn.value}}}}const ERROR_DOMAIN$1="minifier";function minify($n){switch($n.t=$n.type,$n.type){case 0:const Cn=$n;minify(Cn.body),Cn.b=Cn.body,delete Cn.body;break;case 1:const _n=$n,Pn=_n.cases;for(let Bn=0;BnDn;function Fn(Go,Xn){Dn.code+=Go}function Bn(Go,Xn=!0){const Yo=Xn?In:"";Fn(Nn?Yo+" ".repeat(Go):Yo)}function Hn(Go=!0){const Xn=++Dn.indentLevel;Go&&Bn(Xn)}function zn(Go=!0){const Xn=--Dn.indentLevel;Go&&Bn(Xn)}function Wn(){Bn(Dn.indentLevel)}return{context:Ln,push:Fn,indent:Hn,deindent:zn,newline:Wn,helper:Go=>`_${Go}`,needIndent:()=>Dn.needIndent}}function generateLinkedNode($n,Cn){const{helper:_n}=$n;$n.push(`${_n("linked")}(`),generateNode($n,Cn.key),Cn.modifier?($n.push(", "),generateNode($n,Cn.modifier),$n.push(", _type")):$n.push(", undefined, _type"),$n.push(")")}function generateMessageNode($n,Cn){const{helper:_n,needIndent:Pn}=$n;$n.push(`${_n("normalize")}([`),$n.indent(Pn());const In=Cn.items.length;for(let Nn=0;Nn1){$n.push(`${_n("plural")}([`),$n.indent(Pn());const In=Cn.cases.length;for(let Nn=0;Nn{const _n=isString(Cn.mode)?Cn.mode:"normal",Pn=isString(Cn.filename)?Cn.filename:"message.intl",In=!!Cn.sourceMap,Nn=Cn.breakLineCode!=null?Cn.breakLineCode:_n==="arrow"?";":` -`,Rn=Cn.needIndent?Cn.needIndent:_n!=="arrow",Dn=$n.helpers||[],Ln=createCodeGenerator($n,{mode:_n,filename:Pn,sourceMap:In,breakLineCode:Nn,needIndent:Rn});Ln.push(_n==="normal"?"function __msg__ (ctx) {":"(ctx) => {"),Ln.indent(Rn),Dn.length>0&&(Ln.push(`const { ${join(Dn.map(Hn=>`${Hn}: _${Hn}`),", ")} } = ctx`),Ln.newline()),Ln.push("return "),generateNode(Ln,$n),Ln.deindent(Rn),Ln.push("}"),delete $n.helpers;const{code:Fn,map:Bn}=Ln.context();return{ast:$n,code:Fn,map:Bn?Bn.toJSON():void 0}};function baseCompile$1($n,Cn={}){const _n=assign$1({},Cn),Pn=!!_n.jit,In=!!_n.minify,Nn=_n.optimize==null?!0:_n.optimize,Dn=createParser(_n).parse($n);return Pn?(Nn&&optimize(Dn),In&&minify(Dn),{ast:Dn,code:""}):(transform(Dn,_n),generate(Dn,_n))}/*! - * core-base v9.9.1 - * (c) 2024 kazuya kawaguchi - * Released under the MIT License. - */function initFeatureFlags$1(){typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(getGlobalThis().__INTLIFY_PROD_DEVTOOLS__=!1),typeof __INTLIFY_JIT_COMPILATION__!="boolean"&&(getGlobalThis().__INTLIFY_JIT_COMPILATION__=!1),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(getGlobalThis().__INTLIFY_DROP_MESSAGE_COMPILER__=!1)}const pathStateMachine=[];pathStateMachine[0]={w:[0],i:[3,0],"[":[4],o:[7]};pathStateMachine[1]={w:[1],".":[2],"[":[4],o:[7]};pathStateMachine[2]={w:[2],i:[3,0],0:[3,0]};pathStateMachine[3]={i:[3,0],0:[3,0],w:[1,1],".":[2,1],"[":[4,1],o:[7,1]};pathStateMachine[4]={"'":[5,0],'"':[6,0],"[":[4,2],"]":[1,3],o:8,l:[4,0]};pathStateMachine[5]={"'":[4,0],o:8,l:[5,0]};pathStateMachine[6]={'"':[4,0],o:8,l:[6,0]};const literalValueRE=/^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;function isLiteral($n){return literalValueRE.test($n)}function stripQuotes($n){const Cn=$n.charCodeAt(0),_n=$n.charCodeAt($n.length-1);return Cn===_n&&(Cn===34||Cn===39)?$n.slice(1,-1):$n}function getPathCharType($n){if($n==null)return"o";switch($n.charCodeAt(0)){case 91:case 93:case 46:case 34:case 39:return $n;case 95:case 36:case 45:return"i";case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"w"}return"i"}function formatSubPath($n){const Cn=$n.trim();return $n.charAt(0)==="0"&&isNaN(parseInt($n))?!1:isLiteral(Cn)?stripQuotes(Cn):"*"+Cn}function parse$1($n){const Cn=[];let _n=-1,Pn=0,In=0,Nn,Rn,Dn,Ln,Fn,Bn,Hn;const zn=[];zn[0]=()=>{Rn===void 0?Rn=Dn:Rn+=Dn},zn[1]=()=>{Rn!==void 0&&(Cn.push(Rn),Rn=void 0)},zn[2]=()=>{zn[0](),In++},zn[3]=()=>{if(In>0)In--,Pn=4,zn[0]();else{if(In=0,Rn===void 0||(Rn=formatSubPath(Rn),Rn===!1))return!1;zn[1]()}};function Wn(){const Yn=$n[_n+1];if(Pn===5&&Yn==="'"||Pn===6&&Yn==='"')return _n++,Dn="\\"+Yn,zn[0](),!0}for(;Pn!==null;)if(_n++,Nn=$n[_n],!(Nn==="\\"&&Wn())){if(Ln=getPathCharType(Nn),Hn=pathStateMachine[Pn],Fn=Hn[Ln]||Hn.l||8,Fn===8||(Pn=Fn[0],Fn[1]!==void 0&&(Bn=zn[Fn[1]],Bn&&(Dn=Nn,Bn()===!1))))return;if(Pn===7)return Cn}}const cache=new Map;function resolveWithKeyValue($n,Cn){return isObject$3($n)?$n[Cn]:null}function resolveValue($n,Cn){if(!isObject$3($n))return null;let _n=cache.get(Cn);if(_n||(_n=parse$1(Cn),_n&&cache.set(Cn,_n)),!_n)return null;const Pn=_n.length;let In=$n,Nn=0;for(;Nn$n,DEFAULT_MESSAGE=$n=>"",DEFAULT_MESSAGE_DATA_TYPE="text",DEFAULT_NORMALIZE=$n=>$n.length===0?"":join$1($n),DEFAULT_INTERPOLATE=toDisplayString;function pluralDefault($n,Cn){return $n=Math.abs($n),Cn===2?$n?$n>1?1:0:1:$n?Math.min($n,2):0}function getPluralIndex($n){const Cn=isNumber($n.pluralIndex)?$n.pluralIndex:-1;return $n.named&&(isNumber($n.named.count)||isNumber($n.named.n))?isNumber($n.named.count)?$n.named.count:isNumber($n.named.n)?$n.named.n:Cn:Cn}function normalizeNamed($n,Cn){Cn.count||(Cn.count=$n),Cn.n||(Cn.n=$n)}function createMessageContext($n={}){const Cn=$n.locale,_n=getPluralIndex($n),Pn=isObject$3($n.pluralRules)&&isString$1(Cn)&&isFunction($n.pluralRules[Cn])?$n.pluralRules[Cn]:pluralDefault,In=isObject$3($n.pluralRules)&&isString$1(Cn)&&isFunction($n.pluralRules[Cn])?pluralDefault:void 0,Nn=Xn=>Xn[Pn(_n,Xn.length,In)],Rn=$n.list||[],Dn=Xn=>Rn[Xn],Ln=$n.named||{};isNumber($n.pluralIndex)&&normalizeNamed(_n,Ln);const Fn=Xn=>Ln[Xn];function Bn(Xn){const Yo=isFunction($n.messages)?$n.messages(Xn):isObject$3($n.messages)?$n.messages[Xn]:!1;return Yo||($n.parent?$n.parent.message(Xn):DEFAULT_MESSAGE)}const Hn=Xn=>$n.modifiers?$n.modifiers[Xn]:DEFAULT_MODIFIER,zn=isPlainObject$1($n.processor)&&isFunction($n.processor.normalize)?$n.processor.normalize:DEFAULT_NORMALIZE,Wn=isPlainObject$1($n.processor)&&isFunction($n.processor.interpolate)?$n.processor.interpolate:DEFAULT_INTERPOLATE,Yn=isPlainObject$1($n.processor)&&isString$1($n.processor.type)?$n.processor.type:DEFAULT_MESSAGE_DATA_TYPE,Go={list:Dn,named:Fn,plural:Nn,linked:(Xn,...Yo)=>{const[qo,Jo]=Yo;let Zo="text",rr="";Yo.length===1?isObject$3(qo)?(rr=qo.modifier||rr,Zo=qo.type||Zo):isString$1(qo)&&(rr=qo||rr):Yo.length===2&&(isString$1(qo)&&(rr=qo||rr),isString$1(Jo)&&(Zo=Jo||Zo));const nr=Bn(Xn)(Go),ta=Zo==="vnode"&&isArray(nr)&&rr?nr[0]:nr;return rr?Hn(rr)(ta,Zo):ta},message:Bn,type:Yn,interpolate:Wn,normalize:zn,values:assign$2({},Rn,Ln)};return Go}let devtools=null;function setDevToolsHook($n){devtools=$n}function initI18nDevTools($n,Cn,_n){devtools&&devtools.emit("i18n:init",{timestamp:Date.now(),i18n:$n,version:Cn,meta:_n})}const translateDevTools=createDevToolsHook("function:translate");function createDevToolsHook($n){return Cn=>devtools&&devtools.emit($n,Cn)}const CoreWarnCodes={NOT_FOUND_KEY:1,FALLBACK_TO_TRANSLATE:2,CANNOT_FORMAT_NUMBER:3,FALLBACK_TO_NUMBER_FORMAT:4,CANNOT_FORMAT_DATE:5,FALLBACK_TO_DATE_FORMAT:6,EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER:7,__EXTEND_POINT__:8},code$2=CompileErrorCodes.__EXTEND_POINT__,inc$2=incrementer(code$2),CoreErrorCodes={INVALID_ARGUMENT:code$2,INVALID_DATE_ARGUMENT:inc$2(),INVALID_ISO_DATE_ARGUMENT:inc$2(),NOT_SUPPORT_NON_STRING_MESSAGE:inc$2(),NOT_SUPPORT_LOCALE_PROMISE_VALUE:inc$2(),NOT_SUPPORT_LOCALE_ASYNC_FUNCTION:inc$2(),NOT_SUPPORT_LOCALE_TYPE:inc$2(),__EXTEND_POINT__:inc$2()};function createCoreError($n){return createCompileError($n,null,void 0)}function getLocale($n,Cn){return Cn.locale!=null?resolveLocale(Cn.locale):resolveLocale($n.locale)}let _resolveLocale;function resolveLocale($n){if(isString$1($n))return $n;if(isFunction($n)){if($n.resolvedOnce&&_resolveLocale!=null)return _resolveLocale;if($n.constructor.name==="Function"){const Cn=$n();if(isPromise(Cn))throw createCoreError(CoreErrorCodes.NOT_SUPPORT_LOCALE_PROMISE_VALUE);return _resolveLocale=Cn}else throw createCoreError(CoreErrorCodes.NOT_SUPPORT_LOCALE_ASYNC_FUNCTION)}else throw createCoreError(CoreErrorCodes.NOT_SUPPORT_LOCALE_TYPE)}function fallbackWithSimple($n,Cn,_n){return[...new Set([_n,...isArray(Cn)?Cn:isObject$3(Cn)?Object.keys(Cn):isString$1(Cn)?[Cn]:[_n]])]}function fallbackWithLocaleChain($n,Cn,_n){const Pn=isString$1(_n)?_n:DEFAULT_LOCALE,In=$n;In.__localeChainCache||(In.__localeChainCache=new Map);let Nn=In.__localeChainCache.get(Pn);if(!Nn){Nn=[];let Rn=[_n];for(;isArray(Rn);)Rn=appendBlockToChain(Nn,Rn,Cn);const Dn=isArray(Cn)||!isPlainObject$1(Cn)?Cn:Cn.default?Cn.default:null;Rn=isString$1(Dn)?[Dn]:Dn,isArray(Rn)&&appendBlockToChain(Nn,Rn,!1),In.__localeChainCache.set(Pn,Nn)}return Nn}function appendBlockToChain($n,Cn,_n){let Pn=!0;for(let In=0;In`${$n.charAt(0).toLocaleUpperCase()}${$n.substr(1)}`;function getDefaultLinkedModifiers(){return{upper:($n,Cn)=>Cn==="text"&&isString$1($n)?$n.toUpperCase():Cn==="vnode"&&isObject$3($n)&&"__v_isVNode"in $n?$n.children.toUpperCase():$n,lower:($n,Cn)=>Cn==="text"&&isString$1($n)?$n.toLowerCase():Cn==="vnode"&&isObject$3($n)&&"__v_isVNode"in $n?$n.children.toLowerCase():$n,capitalize:($n,Cn)=>Cn==="text"&&isString$1($n)?capitalize($n):Cn==="vnode"&&isObject$3($n)&&"__v_isVNode"in $n?capitalize($n.children):$n}}let _compiler;function registerMessageCompiler($n){_compiler=$n}let _resolver;function registerMessageResolver($n){_resolver=$n}let _fallbacker;function registerLocaleFallbacker($n){_fallbacker=$n}let _additionalMeta=null;const setAdditionalMeta=$n=>{_additionalMeta=$n},getAdditionalMeta=()=>_additionalMeta;let _fallbackContext=null;const setFallbackContext=$n=>{_fallbackContext=$n},getFallbackContext=()=>_fallbackContext;let _cid=0;function createCoreContext($n={}){const Cn=isFunction($n.onWarn)?$n.onWarn:warn,_n=isString$1($n.version)?$n.version:VERSION$1,Pn=isString$1($n.locale)||isFunction($n.locale)?$n.locale:DEFAULT_LOCALE,In=isFunction(Pn)?DEFAULT_LOCALE:Pn,Nn=isArray($n.fallbackLocale)||isPlainObject$1($n.fallbackLocale)||isString$1($n.fallbackLocale)||$n.fallbackLocale===!1?$n.fallbackLocale:In,Rn=isPlainObject$1($n.messages)?$n.messages:{[In]:{}},Dn=isPlainObject$1($n.datetimeFormats)?$n.datetimeFormats:{[In]:{}},Ln=isPlainObject$1($n.numberFormats)?$n.numberFormats:{[In]:{}},Fn=assign$2({},$n.modifiers||{},getDefaultLinkedModifiers()),Bn=$n.pluralRules||{},Hn=isFunction($n.missing)?$n.missing:null,zn=isBoolean($n.missingWarn)||isRegExp($n.missingWarn)?$n.missingWarn:!0,Wn=isBoolean($n.fallbackWarn)||isRegExp($n.fallbackWarn)?$n.fallbackWarn:!0,Yn=!!$n.fallbackFormat,Gn=!!$n.unresolving,Go=isFunction($n.postTranslation)?$n.postTranslation:null,Xn=isPlainObject$1($n.processor)?$n.processor:null,Yo=isBoolean($n.warnHtmlMessage)?$n.warnHtmlMessage:!0,qo=!!$n.escapeParameter,Jo=isFunction($n.messageCompiler)?$n.messageCompiler:_compiler,Zo=isFunction($n.messageResolver)?$n.messageResolver:_resolver||resolveWithKeyValue,rr=isFunction($n.localeFallbacker)?$n.localeFallbacker:_fallbacker||fallbackWithSimple,nr=isObject$3($n.fallbackContext)?$n.fallbackContext:void 0,ta=$n,oa=isObject$3(ta.__datetimeFormatters)?ta.__datetimeFormatters:new Map,ra=isObject$3(ta.__numberFormatters)?ta.__numberFormatters:new Map,ea=isObject$3(ta.__meta)?ta.__meta:{};_cid++;const la={version:_n,cid:_cid,locale:Pn,fallbackLocale:Nn,messages:Rn,modifiers:Fn,pluralRules:Bn,missing:Hn,missingWarn:zn,fallbackWarn:Wn,fallbackFormat:Yn,unresolving:Gn,postTranslation:Go,processor:Xn,warnHtmlMessage:Yo,escapeParameter:qo,messageCompiler:Jo,messageResolver:Zo,localeFallbacker:rr,fallbackContext:nr,onWarn:Cn,__meta:ea};return la.datetimeFormats=Dn,la.numberFormats=Ln,la.__datetimeFormatters=oa,la.__numberFormatters=ra,__INTLIFY_PROD_DEVTOOLS__&&initI18nDevTools(la,_n,ea),la}function handleMissing($n,Cn,_n,Pn,In){const{missing:Nn,onWarn:Rn}=$n;if(Nn!==null){const Dn=Nn($n,_n,Cn,In);return isString$1(Dn)?Dn:Cn}else return Cn}function updateFallbackLocale($n,Cn,_n){const Pn=$n;Pn.__localeChainCache=new Map,$n.localeFallbacker($n,_n,Cn)}function format($n){return _n=>formatParts(_n,$n)}function formatParts($n,Cn){const _n=Cn.b||Cn.body;if((_n.t||_n.type)===1){const Pn=_n,In=Pn.c||Pn.cases;return $n.plural(In.reduce((Nn,Rn)=>[...Nn,formatMessageParts($n,Rn)],[]))}else return formatMessageParts($n,_n)}function formatMessageParts($n,Cn){const _n=Cn.s||Cn.static;if(_n)return $n.type==="text"?_n:$n.normalize([_n]);{const Pn=(Cn.i||Cn.items).reduce((In,Nn)=>[...In,formatMessagePart($n,Nn)],[]);return $n.normalize(Pn)}}function formatMessagePart($n,Cn){const _n=Cn.t||Cn.type;switch(_n){case 3:const Pn=Cn;return Pn.v||Pn.value;case 9:const In=Cn;return In.v||In.value;case 4:const Nn=Cn;return $n.interpolate($n.named(Nn.k||Nn.key));case 5:const Rn=Cn;return $n.interpolate($n.list(Rn.i!=null?Rn.i:Rn.index));case 6:const Dn=Cn,Ln=Dn.m||Dn.modifier;return $n.linked(formatMessagePart($n,Dn.k||Dn.key),Ln?formatMessagePart($n,Ln):void 0,$n.type);case 7:const Fn=Cn;return Fn.v||Fn.value;case 8:const Bn=Cn;return Bn.v||Bn.value;default:throw new Error(`unhandled node type on format message part: ${_n}`)}}const defaultOnCacheKey=$n=>$n;let compileCache=Object.create(null);const isMessageAST=$n=>isObject$3($n)&&($n.t===0||$n.type===0)&&("b"in $n||"body"in $n);function baseCompile($n,Cn={}){let _n=!1;const Pn=Cn.onError||defaultOnError;return Cn.onError=In=>{_n=!0,Pn(In)},{...baseCompile$1($n,Cn),detectError:_n}}const compileToFunction=($n,Cn)=>{if(!isString$1($n))throw createCoreError(CoreErrorCodes.NOT_SUPPORT_NON_STRING_MESSAGE);{isBoolean(Cn.warnHtmlMessage)&&Cn.warnHtmlMessage;const Pn=(Cn.onCacheKey||defaultOnCacheKey)($n),In=compileCache[Pn];if(In)return In;const{code:Nn,detectError:Rn}=baseCompile($n,Cn),Dn=new Function(`return ${Nn}`)();return Rn?Dn:compileCache[Pn]=Dn}};function compile($n,Cn){if(__INTLIFY_JIT_COMPILATION__&&!__INTLIFY_DROP_MESSAGE_COMPILER__&&isString$1($n)){isBoolean(Cn.warnHtmlMessage)&&Cn.warnHtmlMessage;const Pn=(Cn.onCacheKey||defaultOnCacheKey)($n),In=compileCache[Pn];if(In)return In;const{ast:Nn,detectError:Rn}=baseCompile($n,{...Cn,location:!1,jit:!0}),Dn=format(Nn);return Rn?Dn:compileCache[Pn]=Dn}else{const _n=$n.cacheKey;if(_n){const Pn=compileCache[_n];return Pn||(compileCache[_n]=format($n))}else return format($n)}}const NOOP_MESSAGE_FUNCTION=()=>"",isMessageFunction=$n=>isFunction($n);function translate($n,...Cn){const{fallbackFormat:_n,postTranslation:Pn,unresolving:In,messageCompiler:Nn,fallbackLocale:Rn,messages:Dn}=$n,[Ln,Fn]=parseTranslateArgs(...Cn),Bn=isBoolean(Fn.missingWarn)?Fn.missingWarn:$n.missingWarn,Hn=isBoolean(Fn.fallbackWarn)?Fn.fallbackWarn:$n.fallbackWarn,zn=isBoolean(Fn.escapeParameter)?Fn.escapeParameter:$n.escapeParameter,Wn=!!Fn.resolvedMessage,Yn=isString$1(Fn.default)||isBoolean(Fn.default)?isBoolean(Fn.default)?Nn?Ln:()=>Ln:Fn.default:_n?Nn?Ln:()=>Ln:"",Gn=_n||Yn!=="",Go=getLocale($n,Fn);zn&&escapeParams(Fn);let[Xn,Yo,qo]=Wn?[Ln,Go,Dn[Go]||{}]:resolveMessageFormat($n,Ln,Go,Rn,Hn,Bn),Jo=Xn,Zo=Ln;if(!Wn&&!(isString$1(Jo)||isMessageAST(Jo)||isMessageFunction(Jo))&&Gn&&(Jo=Yn,Zo=Jo),!Wn&&(!(isString$1(Jo)||isMessageAST(Jo)||isMessageFunction(Jo))||!isString$1(Yo)))return In?NOT_REOSLVED:Ln;let rr=!1;const nr=()=>{rr=!0},ta=isMessageFunction(Jo)?Jo:compileMessageFormat($n,Ln,Yo,Jo,Zo,nr);if(rr)return Jo;const oa=getMessageContextOptions($n,Yo,qo,Fn),ra=createMessageContext(oa),ea=evaluateMessage($n,ta,ra),la=Pn?Pn(ea,Ln):ea;if(__INTLIFY_PROD_DEVTOOLS__){const ua={timestamp:Date.now(),key:isString$1(Ln)?Ln:isMessageFunction(Jo)?Jo.key:"",locale:Yo||(isMessageFunction(Jo)?Jo.locale:""),format:isString$1(Jo)?Jo:isMessageFunction(Jo)?Jo.source:"",message:la};ua.meta=assign$2({},$n.__meta,getAdditionalMeta()||{}),translateDevTools(ua)}return la}function escapeParams($n){isArray($n.list)?$n.list=$n.list.map(Cn=>isString$1(Cn)?escapeHtml(Cn):Cn):isObject$3($n.named)&&Object.keys($n.named).forEach(Cn=>{isString$1($n.named[Cn])&&($n.named[Cn]=escapeHtml($n.named[Cn]))})}function resolveMessageFormat($n,Cn,_n,Pn,In,Nn){const{messages:Rn,onWarn:Dn,messageResolver:Ln,localeFallbacker:Fn}=$n,Bn=Fn($n,Pn,_n);let Hn={},zn,Wn=null;const Yn="translate";for(let Gn=0;GnPn;return Fn.locale=_n,Fn.key=Cn,Fn}const Ln=Rn(Pn,getCompileContext($n,_n,In,Pn,Dn,Nn));return Ln.locale=_n,Ln.key=Cn,Ln.source=Pn,Ln}function evaluateMessage($n,Cn,_n){return Cn(_n)}function parseTranslateArgs(...$n){const[Cn,_n,Pn]=$n,In={};if(!isString$1(Cn)&&!isNumber(Cn)&&!isMessageFunction(Cn)&&!isMessageAST(Cn))throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);const Nn=isNumber(Cn)?String(Cn):(isMessageFunction(Cn),Cn);return isNumber(_n)?In.plural=_n:isString$1(_n)?In.default=_n:isPlainObject$1(_n)&&!isEmptyObject(_n)?In.named=_n:isArray(_n)&&(In.list=_n),isNumber(Pn)?In.plural=Pn:isString$1(Pn)?In.default=Pn:isPlainObject$1(Pn)&&assign$2(In,Pn),[Nn,In]}function getCompileContext($n,Cn,_n,Pn,In,Nn){return{locale:Cn,key:_n,warnHtmlMessage:In,onError:Rn=>{throw Nn&&Nn(Rn),Rn},onCacheKey:Rn=>generateFormatCacheKey(Cn,_n,Rn)}}function getMessageContextOptions($n,Cn,_n,Pn){const{modifiers:In,pluralRules:Nn,messageResolver:Rn,fallbackLocale:Dn,fallbackWarn:Ln,missingWarn:Fn,fallbackContext:Bn}=$n,zn={locale:Cn,modifiers:In,pluralRules:Nn,messages:Wn=>{let Yn=Rn(_n,Wn);if(Yn==null&&Bn){const[,,Gn]=resolveMessageFormat(Bn,Wn,Cn,Dn,Ln,Fn);Yn=Rn(Gn,Wn)}if(isString$1(Yn)||isMessageAST(Yn)){let Gn=!1;const Xn=compileMessageFormat($n,Wn,Cn,Yn,Wn,()=>{Gn=!0});return Gn?NOOP_MESSAGE_FUNCTION:Xn}else return isMessageFunction(Yn)?Yn:NOOP_MESSAGE_FUNCTION}};return $n.processor&&(zn.processor=$n.processor),Pn.list&&(zn.list=Pn.list),Pn.named&&(zn.named=Pn.named),isNumber(Pn.plural)&&(zn.pluralIndex=Pn.plural),zn}function datetime($n,...Cn){const{datetimeFormats:_n,unresolving:Pn,fallbackLocale:In,onWarn:Nn,localeFallbacker:Rn}=$n,{__datetimeFormatters:Dn}=$n,[Ln,Fn,Bn,Hn]=parseDateTimeArgs(...Cn),zn=isBoolean(Bn.missingWarn)?Bn.missingWarn:$n.missingWarn;isBoolean(Bn.fallbackWarn)?Bn.fallbackWarn:$n.fallbackWarn;const Wn=!!Bn.part,Yn=getLocale($n,Bn),Gn=Rn($n,In,Yn);if(!isString$1(Ln)||Ln==="")return new Intl.DateTimeFormat(Yn,Hn).format(Fn);let Go={},Xn,Yo=null;const qo="datetime format";for(let rr=0;rr{DATETIME_FORMAT_OPTIONS_KEYS.includes(Ln)?Rn[Ln]=_n[Ln]:Nn[Ln]=_n[Ln]}),isString$1(Pn)?Nn.locale=Pn:isPlainObject$1(Pn)&&(Rn=Pn),isPlainObject$1(In)&&(Rn=In),[Nn.key||"",Dn,Nn,Rn]}function clearDateTimeFormat($n,Cn,_n){const Pn=$n;for(const In in _n){const Nn=`${Cn}__${In}`;Pn.__datetimeFormatters.has(Nn)&&Pn.__datetimeFormatters.delete(Nn)}}function number($n,...Cn){const{numberFormats:_n,unresolving:Pn,fallbackLocale:In,onWarn:Nn,localeFallbacker:Rn}=$n,{__numberFormatters:Dn}=$n,[Ln,Fn,Bn,Hn]=parseNumberArgs(...Cn),zn=isBoolean(Bn.missingWarn)?Bn.missingWarn:$n.missingWarn;isBoolean(Bn.fallbackWarn)?Bn.fallbackWarn:$n.fallbackWarn;const Wn=!!Bn.part,Yn=getLocale($n,Bn),Gn=Rn($n,In,Yn);if(!isString$1(Ln)||Ln==="")return new Intl.NumberFormat(Yn,Hn).format(Fn);let Go={},Xn,Yo=null;const qo="number format";for(let rr=0;rr{NUMBER_FORMAT_OPTIONS_KEYS.includes(Ln)?Rn[Ln]=_n[Ln]:Nn[Ln]=_n[Ln]}),isString$1(Pn)?Nn.locale=Pn:isPlainObject$1(Pn)&&(Rn=Pn),isPlainObject$1(In)&&(Rn=In),[Nn.key||"",Dn,Nn,Rn]}function clearNumberFormat($n,Cn,_n){const Pn=$n;for(const In in _n){const Nn=`${Cn}__${In}`;Pn.__numberFormatters.has(Nn)&&Pn.__numberFormatters.delete(Nn)}}initFeatureFlags$1();/*! - * vue-i18n v9.9.1 - * (c) 2024 kazuya kawaguchi - * Released under the MIT License. - */const VERSION="9.9.1";function initFeatureFlags(){typeof __VUE_I18N_FULL_INSTALL__!="boolean"&&(getGlobalThis().__VUE_I18N_FULL_INSTALL__=!0),typeof __VUE_I18N_LEGACY_API__!="boolean"&&(getGlobalThis().__VUE_I18N_LEGACY_API__=!0),typeof __INTLIFY_JIT_COMPILATION__!="boolean"&&(getGlobalThis().__INTLIFY_JIT_COMPILATION__=!1),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(getGlobalThis().__INTLIFY_DROP_MESSAGE_COMPILER__=!1),typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(getGlobalThis().__INTLIFY_PROD_DEVTOOLS__=!1)}const code$1=CoreWarnCodes.__EXTEND_POINT__,inc$1=incrementer(code$1);inc$1(),inc$1(),inc$1(),inc$1(),inc$1(),inc$1(),inc$1(),inc$1();const code=CoreErrorCodes.__EXTEND_POINT__,inc=incrementer(code),I18nErrorCodes={UNEXPECTED_RETURN_TYPE:code,INVALID_ARGUMENT:inc(),MUST_BE_CALL_SETUP_TOP:inc(),NOT_INSTALLED:inc(),NOT_AVAILABLE_IN_LEGACY_MODE:inc(),REQUIRED_VALUE:inc(),INVALID_VALUE:inc(),CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN:inc(),NOT_INSTALLED_WITH_PROVIDE:inc(),UNEXPECTED_ERROR:inc(),NOT_COMPATIBLE_LEGACY_VUE_I18N:inc(),BRIDGE_SUPPORT_VUE_2_ONLY:inc(),MUST_DEFINE_I18N_OPTION_IN_ALLOW_COMPOSITION:inc(),NOT_AVAILABLE_COMPOSITION_IN_LEGACY:inc(),__EXTEND_POINT__:inc()};function createI18nError($n,...Cn){return createCompileError($n,null,void 0)}const TranslateVNodeSymbol=makeSymbol("__translateVNode"),DatetimePartsSymbol=makeSymbol("__datetimeParts"),NumberPartsSymbol=makeSymbol("__numberParts"),SetPluralRulesSymbol=makeSymbol("__setPluralRules"),InejctWithOptionSymbol=makeSymbol("__injectWithOption"),DisposeSymbol=makeSymbol("__dispose");function handleFlatJson($n){if(!isObject$3($n))return $n;for(const Cn in $n)if(hasOwn($n,Cn))if(!Cn.includes("."))isObject$3($n[Cn])&&handleFlatJson($n[Cn]);else{const _n=Cn.split("."),Pn=_n.length-1;let In=$n,Nn=!1;for(let Rn=0;Rn{if("locale"in Dn&&"resource"in Dn){const{locale:Ln,resource:Fn}=Dn;Ln?(Rn[Ln]=Rn[Ln]||{},deepCopy(Fn,Rn[Ln])):deepCopy(Fn,Rn)}else isString$1(Dn)&&deepCopy(JSON.parse(Dn),Rn)}),In==null&&Nn)for(const Dn in Rn)hasOwn(Rn,Dn)&&handleFlatJson(Rn[Dn]);return Rn}function getComponentOptions($n){return $n.type}function adjustI18nResources($n,Cn,_n){let Pn=isObject$3(Cn.messages)?Cn.messages:{};"__i18nGlobal"in _n&&(Pn=getLocaleMessages($n.locale.value,{messages:Pn,__i18n:_n.__i18nGlobal}));const In=Object.keys(Pn);In.length&&In.forEach(Nn=>{$n.mergeLocaleMessage(Nn,Pn[Nn])});{if(isObject$3(Cn.datetimeFormats)){const Nn=Object.keys(Cn.datetimeFormats);Nn.length&&Nn.forEach(Rn=>{$n.mergeDateTimeFormat(Rn,Cn.datetimeFormats[Rn])})}if(isObject$3(Cn.numberFormats)){const Nn=Object.keys(Cn.numberFormats);Nn.length&&Nn.forEach(Rn=>{$n.mergeNumberFormat(Rn,Cn.numberFormats[Rn])})}}}function createTextNode($n){return createVNode(Text$2,null,$n,0)}const DEVTOOLS_META="__INTLIFY_META__",NOOP_RETURN_ARRAY=()=>[],NOOP_RETURN_FALSE=()=>!1;let composerID=0;function defineCoreMissingHandler($n){return(Cn,_n,Pn,In)=>$n(_n,Pn,getCurrentInstance()||void 0,In)}const getMetaInfo=()=>{const $n=getCurrentInstance();let Cn=null;return $n&&(Cn=getComponentOptions($n)[DEVTOOLS_META])?{[DEVTOOLS_META]:Cn}:null};function createComposer($n={},Cn){const{__root:_n,__injectWithOption:Pn}=$n,In=_n===void 0,Nn=$n.flatJson,Rn=inBrowser?ref:shallowRef;let Dn=isBoolean($n.inheritLocale)?$n.inheritLocale:!0;const Ln=Rn(_n&&Dn?_n.locale.value:isString$1($n.locale)?$n.locale:DEFAULT_LOCALE),Fn=Rn(_n&&Dn?_n.fallbackLocale.value:isString$1($n.fallbackLocale)||isArray($n.fallbackLocale)||isPlainObject$1($n.fallbackLocale)||$n.fallbackLocale===!1?$n.fallbackLocale:Ln.value),Bn=Rn(getLocaleMessages(Ln.value,$n)),Hn=Rn(isPlainObject$1($n.datetimeFormats)?$n.datetimeFormats:{[Ln.value]:{}}),zn=Rn(isPlainObject$1($n.numberFormats)?$n.numberFormats:{[Ln.value]:{}});let Wn=_n?_n.missingWarn:isBoolean($n.missingWarn)||isRegExp($n.missingWarn)?$n.missingWarn:!0,Yn=_n?_n.fallbackWarn:isBoolean($n.fallbackWarn)||isRegExp($n.fallbackWarn)?$n.fallbackWarn:!0,Gn=_n?_n.fallbackRoot:isBoolean($n.fallbackRoot)?$n.fallbackRoot:!0,Go=!!$n.fallbackFormat,Xn=isFunction($n.missing)?$n.missing:null,Yo=isFunction($n.missing)?defineCoreMissingHandler($n.missing):null,qo=isFunction($n.postTranslation)?$n.postTranslation:null,Jo=_n?_n.warnHtmlMessage:isBoolean($n.warnHtmlMessage)?$n.warnHtmlMessage:!0,Zo=!!$n.escapeParameter;const rr=_n?_n.modifiers:isPlainObject$1($n.modifiers)?$n.modifiers:{};let nr=$n.pluralRules||_n&&_n.pluralRules,ta;ta=(()=>{In&&setFallbackContext(null);const Oa={version:VERSION,locale:Ln.value,fallbackLocale:Fn.value,messages:Bn.value,modifiers:rr,pluralRules:nr,missing:Yo===null?void 0:Yo,missingWarn:Wn,fallbackWarn:Yn,fallbackFormat:Go,unresolving:!0,postTranslation:qo===null?void 0:qo,warnHtmlMessage:Jo,escapeParameter:Zo,messageResolver:$n.messageResolver,messageCompiler:$n.messageCompiler,__meta:{framework:"vue"}};Oa.datetimeFormats=Hn.value,Oa.numberFormats=zn.value,Oa.__datetimeFormatters=isPlainObject$1(ta)?ta.__datetimeFormatters:void 0,Oa.__numberFormatters=isPlainObject$1(ta)?ta.__numberFormatters:void 0;const Ma=createCoreContext(Oa);return In&&setFallbackContext(Ma),Ma})(),updateFallbackLocale(ta,Ln.value,Fn.value);function ra(){return[Ln.value,Fn.value,Bn.value,Hn.value,zn.value]}const ea=computed({get:()=>Ln.value,set:Oa=>{Ln.value=Oa,ta.locale=Ln.value}}),la=computed({get:()=>Fn.value,set:Oa=>{Fn.value=Oa,ta.fallbackLocale=Fn.value,updateFallbackLocale(ta,Ln.value,Oa)}}),ua=computed(()=>Bn.value),ga=computed(()=>Hn.value),aa=computed(()=>zn.value);function ca(){return isFunction(qo)?qo:null}function sa(Oa){qo=Oa,ta.postTranslation=Oa}function ia(){return Xn}function fa(Oa){Oa!==null&&(Yo=defineCoreMissingHandler(Oa)),Xn=Oa,ta.missing=Yo}const ma=(Oa,Ma,Ua,Qa,ri,fi)=>{ra();let ei;try{__INTLIFY_PROD_DEVTOOLS__,In||(ta.fallbackContext=_n?getFallbackContext():void 0),ei=Oa(ta)}finally{__INTLIFY_PROD_DEVTOOLS__,In||(ta.fallbackContext=void 0)}if(Ua!=="translate exists"&&isNumber(ei)&&ei===NOT_REOSLVED||Ua==="translate exists"&&!ei){const[ti,ni]=Ma();return _n&&Gn?Qa(_n):ri(ti)}else{if(fi(ei))return ei;throw createI18nError(I18nErrorCodes.UNEXPECTED_RETURN_TYPE)}};function ya(...Oa){return ma(Ma=>Reflect.apply(translate,null,[Ma,...Oa]),()=>parseTranslateArgs(...Oa),"translate",Ma=>Reflect.apply(Ma.t,Ma,[...Oa]),Ma=>Ma,Ma=>isString$1(Ma))}function ba(...Oa){const[Ma,Ua,Qa]=Oa;if(Qa&&!isObject$3(Qa))throw createI18nError(I18nErrorCodes.INVALID_ARGUMENT);return ya(Ma,Ua,assign$2({resolvedMessage:!0},Qa||{}))}function Ia(...Oa){return ma(Ma=>Reflect.apply(datetime,null,[Ma,...Oa]),()=>parseDateTimeArgs(...Oa),"datetime format",Ma=>Reflect.apply(Ma.d,Ma,[...Oa]),()=>MISSING_RESOLVE_VALUE,Ma=>isString$1(Ma))}function Ea(...Oa){return ma(Ma=>Reflect.apply(number,null,[Ma,...Oa]),()=>parseNumberArgs(...Oa),"number format",Ma=>Reflect.apply(Ma.n,Ma,[...Oa]),()=>MISSING_RESOLVE_VALUE,Ma=>isString$1(Ma))}function xa(Oa){return Oa.map(Ma=>isString$1(Ma)||isNumber(Ma)||isBoolean(Ma)?createTextNode(String(Ma)):Ma)}const wa={normalize:xa,interpolate:Oa=>Oa,type:"vnode"};function La(...Oa){return ma(Ma=>{let Ua;const Qa=Ma;try{Qa.processor=wa,Ua=Reflect.apply(translate,null,[Qa,...Oa])}finally{Qa.processor=null}return Ua},()=>parseTranslateArgs(...Oa),"translate",Ma=>Ma[TranslateVNodeSymbol](...Oa),Ma=>[createTextNode(Ma)],Ma=>isArray(Ma))}function Na(...Oa){return ma(Ma=>Reflect.apply(number,null,[Ma,...Oa]),()=>parseNumberArgs(...Oa),"number format",Ma=>Ma[NumberPartsSymbol](...Oa),NOOP_RETURN_ARRAY,Ma=>isString$1(Ma)||isArray(Ma))}function $a(...Oa){return ma(Ma=>Reflect.apply(datetime,null,[Ma,...Oa]),()=>parseDateTimeArgs(...Oa),"datetime format",Ma=>Ma[DatetimePartsSymbol](...Oa),NOOP_RETURN_ARRAY,Ma=>isString$1(Ma)||isArray(Ma))}function ka(Oa){nr=Oa,ta.pluralRules=nr}function Ha(Oa,Ma){return ma(()=>{if(!Oa)return!1;const Ua=isString$1(Ma)?Ma:Ln.value,Qa=Sa(Ua),ri=ta.messageResolver(Qa,Oa);return isMessageAST(ri)||isMessageFunction(ri)||isString$1(ri)},()=>[Oa],"translate exists",Ua=>Reflect.apply(Ua.te,Ua,[Oa,Ma]),NOOP_RETURN_FALSE,Ua=>isBoolean(Ua))}function da(Oa){let Ma=null;const Ua=fallbackWithLocaleChain(ta,Fn.value,Ln.value);for(let Qa=0;Qa{Dn&&(Ln.value=Oa,ta.locale=Oa,updateFallbackLocale(ta,Ln.value,Fn.value))}),watch(_n.fallbackLocale,Oa=>{Dn&&(Fn.value=Oa,ta.fallbackLocale=Oa,updateFallbackLocale(ta,Ln.value,Fn.value))}));const Xa={id:composerID,locale:ea,fallbackLocale:la,get inheritLocale(){return Dn},set inheritLocale(Oa){Dn=Oa,Oa&&_n&&(Ln.value=_n.locale.value,Fn.value=_n.fallbackLocale.value,updateFallbackLocale(ta,Ln.value,Fn.value))},get availableLocales(){return Object.keys(Bn.value).sort()},messages:ua,get modifiers(){return rr},get pluralRules(){return nr||{}},get isGlobal(){return In},get missingWarn(){return Wn},set missingWarn(Oa){Wn=Oa,ta.missingWarn=Wn},get fallbackWarn(){return Yn},set fallbackWarn(Oa){Yn=Oa,ta.fallbackWarn=Yn},get fallbackRoot(){return Gn},set fallbackRoot(Oa){Gn=Oa},get fallbackFormat(){return Go},set fallbackFormat(Oa){Go=Oa,ta.fallbackFormat=Go},get warnHtmlMessage(){return Jo},set warnHtmlMessage(Oa){Jo=Oa,ta.warnHtmlMessage=Oa},get escapeParameter(){return Zo},set escapeParameter(Oa){Zo=Oa,ta.escapeParameter=Oa},t:ya,getLocaleMessage:Sa,setLocaleMessage:Aa,mergeLocaleMessage:Ra,getPostTranslationHandler:ca,setPostTranslationHandler:sa,getMissingHandler:ia,setMissingHandler:fa,[SetPluralRulesSymbol]:ka};return Xa.datetimeFormats=ga,Xa.numberFormats=aa,Xa.rt=ba,Xa.te=Ha,Xa.tm=pa,Xa.d=Ia,Xa.n=Ea,Xa.getDateTimeFormat=Fa,Xa.setDateTimeFormat=za,Xa.mergeDateTimeFormat=Wa,Xa.getNumberFormat=Ya,Xa.setNumberFormat=ja,Xa.mergeNumberFormat=qa,Xa[InejctWithOptionSymbol]=Pn,Xa[TranslateVNodeSymbol]=La,Xa[DatetimePartsSymbol]=$a,Xa[NumberPartsSymbol]=Na,Xa}function convertComposerOptions($n){const Cn=isString$1($n.locale)?$n.locale:DEFAULT_LOCALE,_n=isString$1($n.fallbackLocale)||isArray($n.fallbackLocale)||isPlainObject$1($n.fallbackLocale)||$n.fallbackLocale===!1?$n.fallbackLocale:Cn,Pn=isFunction($n.missing)?$n.missing:void 0,In=isBoolean($n.silentTranslationWarn)||isRegExp($n.silentTranslationWarn)?!$n.silentTranslationWarn:!0,Nn=isBoolean($n.silentFallbackWarn)||isRegExp($n.silentFallbackWarn)?!$n.silentFallbackWarn:!0,Rn=isBoolean($n.fallbackRoot)?$n.fallbackRoot:!0,Dn=!!$n.formatFallbackMessages,Ln=isPlainObject$1($n.modifiers)?$n.modifiers:{},Fn=$n.pluralizationRules,Bn=isFunction($n.postTranslation)?$n.postTranslation:void 0,Hn=isString$1($n.warnHtmlInMessage)?$n.warnHtmlInMessage!=="off":!0,zn=!!$n.escapeParameterHtml,Wn=isBoolean($n.sync)?$n.sync:!0;let Yn=$n.messages;if(isPlainObject$1($n.sharedMessages)){const Zo=$n.sharedMessages;Yn=Object.keys(Zo).reduce((nr,ta)=>{const oa=nr[ta]||(nr[ta]={});return assign$2(oa,Zo[ta]),nr},Yn||{})}const{__i18n:Gn,__root:Go,__injectWithOption:Xn}=$n,Yo=$n.datetimeFormats,qo=$n.numberFormats,Jo=$n.flatJson;return{locale:Cn,fallbackLocale:_n,messages:Yn,flatJson:Jo,datetimeFormats:Yo,numberFormats:qo,missing:Pn,missingWarn:In,fallbackWarn:Nn,fallbackRoot:Rn,fallbackFormat:Dn,modifiers:Ln,pluralRules:Fn,postTranslation:Bn,warnHtmlMessage:Hn,escapeParameter:zn,messageResolver:$n.messageResolver,inheritLocale:Wn,__i18n:Gn,__root:Go,__injectWithOption:Xn}}function createVueI18n($n={},Cn){{const _n=createComposer(convertComposerOptions($n)),{__extender:Pn}=$n,In={id:_n.id,get locale(){return _n.locale.value},set locale(Nn){_n.locale.value=Nn},get fallbackLocale(){return _n.fallbackLocale.value},set fallbackLocale(Nn){_n.fallbackLocale.value=Nn},get messages(){return _n.messages.value},get datetimeFormats(){return _n.datetimeFormats.value},get numberFormats(){return _n.numberFormats.value},get availableLocales(){return _n.availableLocales},get formatter(){return{interpolate(){return[]}}},set formatter(Nn){},get missing(){return _n.getMissingHandler()},set missing(Nn){_n.setMissingHandler(Nn)},get silentTranslationWarn(){return isBoolean(_n.missingWarn)?!_n.missingWarn:_n.missingWarn},set silentTranslationWarn(Nn){_n.missingWarn=isBoolean(Nn)?!Nn:Nn},get silentFallbackWarn(){return isBoolean(_n.fallbackWarn)?!_n.fallbackWarn:_n.fallbackWarn},set silentFallbackWarn(Nn){_n.fallbackWarn=isBoolean(Nn)?!Nn:Nn},get modifiers(){return _n.modifiers},get formatFallbackMessages(){return _n.fallbackFormat},set formatFallbackMessages(Nn){_n.fallbackFormat=Nn},get postTranslation(){return _n.getPostTranslationHandler()},set postTranslation(Nn){_n.setPostTranslationHandler(Nn)},get sync(){return _n.inheritLocale},set sync(Nn){_n.inheritLocale=Nn},get warnHtmlInMessage(){return _n.warnHtmlMessage?"warn":"off"},set warnHtmlInMessage(Nn){_n.warnHtmlMessage=Nn!=="off"},get escapeParameterHtml(){return _n.escapeParameter},set escapeParameterHtml(Nn){_n.escapeParameter=Nn},get preserveDirectiveContent(){return!0},set preserveDirectiveContent(Nn){},get pluralizationRules(){return _n.pluralRules||{}},__composer:_n,t(...Nn){const[Rn,Dn,Ln]=Nn,Fn={};let Bn=null,Hn=null;if(!isString$1(Rn))throw createI18nError(I18nErrorCodes.INVALID_ARGUMENT);const zn=Rn;return isString$1(Dn)?Fn.locale=Dn:isArray(Dn)?Bn=Dn:isPlainObject$1(Dn)&&(Hn=Dn),isArray(Ln)?Bn=Ln:isPlainObject$1(Ln)&&(Hn=Ln),Reflect.apply(_n.t,_n,[zn,Bn||Hn||{},Fn])},rt(...Nn){return Reflect.apply(_n.rt,_n,[...Nn])},tc(...Nn){const[Rn,Dn,Ln]=Nn,Fn={plural:1};let Bn=null,Hn=null;if(!isString$1(Rn))throw createI18nError(I18nErrorCodes.INVALID_ARGUMENT);const zn=Rn;return isString$1(Dn)?Fn.locale=Dn:isNumber(Dn)?Fn.plural=Dn:isArray(Dn)?Bn=Dn:isPlainObject$1(Dn)&&(Hn=Dn),isString$1(Ln)?Fn.locale=Ln:isArray(Ln)?Bn=Ln:isPlainObject$1(Ln)&&(Hn=Ln),Reflect.apply(_n.t,_n,[zn,Bn||Hn||{},Fn])},te(Nn,Rn){return _n.te(Nn,Rn)},tm(Nn){return _n.tm(Nn)},getLocaleMessage(Nn){return _n.getLocaleMessage(Nn)},setLocaleMessage(Nn,Rn){_n.setLocaleMessage(Nn,Rn)},mergeLocaleMessage(Nn,Rn){_n.mergeLocaleMessage(Nn,Rn)},d(...Nn){return Reflect.apply(_n.d,_n,[...Nn])},getDateTimeFormat(Nn){return _n.getDateTimeFormat(Nn)},setDateTimeFormat(Nn,Rn){_n.setDateTimeFormat(Nn,Rn)},mergeDateTimeFormat(Nn,Rn){_n.mergeDateTimeFormat(Nn,Rn)},n(...Nn){return Reflect.apply(_n.n,_n,[...Nn])},getNumberFormat(Nn){return _n.getNumberFormat(Nn)},setNumberFormat(Nn,Rn){_n.setNumberFormat(Nn,Rn)},mergeNumberFormat(Nn,Rn){_n.mergeNumberFormat(Nn,Rn)},getChoiceIndex(Nn,Rn){return-1}};return In.__extender=Pn,In}}const baseFormatProps={tag:{type:[String,Object]},locale:{type:String},scope:{type:String,validator:$n=>$n==="parent"||$n==="global",default:"parent"},i18n:{type:Object}};function getInterpolateArg({slots:$n},Cn){return Cn.length===1&&Cn[0]==="default"?($n.default?$n.default():[]).reduce((Pn,In)=>[...Pn,...In.type===Fragment?In.children:[In]],[]):Cn.reduce((_n,Pn)=>{const In=$n[Pn];return In&&(_n[Pn]=In()),_n},{})}function getFragmentableTag($n){return Fragment}const TranslationImpl=defineComponent({name:"i18n-t",props:assign$2({keypath:{type:String,required:!0},plural:{type:[Number,String],validator:$n=>isNumber($n)||!isNaN($n)}},baseFormatProps),setup($n,Cn){const{slots:_n,attrs:Pn}=Cn,In=$n.i18n||useI18n({useScope:$n.scope,__useComponent:!0});return()=>{const Nn=Object.keys(_n).filter(Hn=>Hn!=="_"),Rn={};$n.locale&&(Rn.locale=$n.locale),$n.plural!==void 0&&(Rn.plural=isString$1($n.plural)?+$n.plural:$n.plural);const Dn=getInterpolateArg(Cn,Nn),Ln=In[TranslateVNodeSymbol]($n.keypath,Dn,Rn),Fn=assign$2({},Pn),Bn=isString$1($n.tag)||isObject$3($n.tag)?$n.tag:getFragmentableTag();return h$3(Bn,Fn,Ln)}}}),Translation=TranslationImpl;function isVNode($n){return isArray($n)&&!isString$1($n[0])}function renderFormatter($n,Cn,_n,Pn){const{slots:In,attrs:Nn}=Cn;return()=>{const Rn={part:!0};let Dn={};$n.locale&&(Rn.locale=$n.locale),isString$1($n.format)?Rn.key=$n.format:isObject$3($n.format)&&(isString$1($n.format.key)&&(Rn.key=$n.format.key),Dn=Object.keys($n.format).reduce((zn,Wn)=>_n.includes(Wn)?assign$2({},zn,{[Wn]:$n.format[Wn]}):zn,{}));const Ln=Pn($n.value,Rn,Dn);let Fn=[Rn.key];isArray(Ln)?Fn=Ln.map((zn,Wn)=>{const Yn=In[zn.type],Gn=Yn?Yn({[zn.type]:zn.value,index:Wn,parts:Ln}):[zn.value];return isVNode(Gn)&&(Gn[0].key=`${zn.type}-${Wn}`),Gn}):isString$1(Ln)&&(Fn=[Ln]);const Bn=assign$2({},Nn),Hn=isString$1($n.tag)||isObject$3($n.tag)?$n.tag:getFragmentableTag();return h$3(Hn,Bn,Fn)}}const NumberFormatImpl=defineComponent({name:"i18n-n",props:assign$2({value:{type:Number,required:!0},format:{type:[String,Object]}},baseFormatProps),setup($n,Cn){const _n=$n.i18n||useI18n({useScope:"parent",__useComponent:!0});return renderFormatter($n,Cn,NUMBER_FORMAT_OPTIONS_KEYS,(...Pn)=>_n[NumberPartsSymbol](...Pn))}}),NumberFormat=NumberFormatImpl,DatetimeFormatImpl=defineComponent({name:"i18n-d",props:assign$2({value:{type:[Number,Date],required:!0},format:{type:[String,Object]}},baseFormatProps),setup($n,Cn){const _n=$n.i18n||useI18n({useScope:"parent",__useComponent:!0});return renderFormatter($n,Cn,DATETIME_FORMAT_OPTIONS_KEYS,(...Pn)=>_n[DatetimePartsSymbol](...Pn))}}),DatetimeFormat=DatetimeFormatImpl;function getComposer$2($n,Cn){const _n=$n;if($n.mode==="composition")return _n.__getInstance(Cn)||$n.global;{const Pn=_n.__getInstance(Cn);return Pn!=null?Pn.__composer:$n.global.__composer}}function vTDirective($n){const Cn=Rn=>{const{instance:Dn,modifiers:Ln,value:Fn}=Rn;if(!Dn||!Dn.$)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);const Bn=getComposer$2($n,Dn.$),Hn=parseValue(Fn);return[Reflect.apply(Bn.t,Bn,[...makeParams(Hn)]),Bn]};return{created:(Rn,Dn)=>{const[Ln,Fn]=Cn(Dn);inBrowser&&$n.global===Fn&&(Rn.__i18nWatcher=watch(Fn.locale,()=>{Dn.instance&&Dn.instance.$forceUpdate()})),Rn.__composer=Fn,Rn.textContent=Ln},unmounted:Rn=>{inBrowser&&Rn.__i18nWatcher&&(Rn.__i18nWatcher(),Rn.__i18nWatcher=void 0,delete Rn.__i18nWatcher),Rn.__composer&&(Rn.__composer=void 0,delete Rn.__composer)},beforeUpdate:(Rn,{value:Dn})=>{if(Rn.__composer){const Ln=Rn.__composer,Fn=parseValue(Dn);Rn.textContent=Reflect.apply(Ln.t,Ln,[...makeParams(Fn)])}},getSSRProps:Rn=>{const[Dn]=Cn(Rn);return{textContent:Dn}}}}function parseValue($n){if(isString$1($n))return{path:$n};if(isPlainObject$1($n)){if(!("path"in $n))throw createI18nError(I18nErrorCodes.REQUIRED_VALUE,"path");return $n}else throw createI18nError(I18nErrorCodes.INVALID_VALUE)}function makeParams($n){const{path:Cn,locale:_n,args:Pn,choice:In,plural:Nn}=$n,Rn={},Dn=Pn||{};return isString$1(_n)&&(Rn.locale=_n),isNumber(In)&&(Rn.plural=In),isNumber(Nn)&&(Rn.plural=Nn),[Cn,Dn,Rn]}function apply($n,Cn,..._n){const Pn=isPlainObject$1(_n[0])?_n[0]:{},In=!!Pn.useI18nComponentName;(isBoolean(Pn.globalInstall)?Pn.globalInstall:!0)&&([In?"i18n":Translation.name,"I18nT"].forEach(Rn=>$n.component(Rn,Translation)),[NumberFormat.name,"I18nN"].forEach(Rn=>$n.component(Rn,NumberFormat)),[DatetimeFormat.name,"I18nD"].forEach(Rn=>$n.component(Rn,DatetimeFormat))),$n.directive("t",vTDirective(Cn))}function defineMixin($n,Cn,_n){return{beforeCreate(){const Pn=getCurrentInstance();if(!Pn)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);const In=this.$options;if(In.i18n){const Nn=In.i18n;if(In.__i18n&&(Nn.__i18n=In.__i18n),Nn.__root=Cn,this===this.$root)this.$i18n=mergeToGlobal($n,Nn);else{Nn.__injectWithOption=!0,Nn.__extender=_n.__vueI18nExtend,this.$i18n=createVueI18n(Nn);const Rn=this.$i18n;Rn.__extender&&(Rn.__disposer=Rn.__extender(this.$i18n))}}else if(In.__i18n)if(this===this.$root)this.$i18n=mergeToGlobal($n,In);else{this.$i18n=createVueI18n({__i18n:In.__i18n,__injectWithOption:!0,__extender:_n.__vueI18nExtend,__root:Cn});const Nn=this.$i18n;Nn.__extender&&(Nn.__disposer=Nn.__extender(this.$i18n))}else this.$i18n=$n;In.__i18nGlobal&&adjustI18nResources(Cn,In,In),this.$t=(...Nn)=>this.$i18n.t(...Nn),this.$rt=(...Nn)=>this.$i18n.rt(...Nn),this.$tc=(...Nn)=>this.$i18n.tc(...Nn),this.$te=(Nn,Rn)=>this.$i18n.te(Nn,Rn),this.$d=(...Nn)=>this.$i18n.d(...Nn),this.$n=(...Nn)=>this.$i18n.n(...Nn),this.$tm=Nn=>this.$i18n.tm(Nn),_n.__setInstance(Pn,this.$i18n)},mounted(){},unmounted(){const Pn=getCurrentInstance();if(!Pn)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);const In=this.$i18n;delete this.$t,delete this.$rt,delete this.$tc,delete this.$te,delete this.$d,delete this.$n,delete this.$tm,In.__disposer&&(In.__disposer(),delete In.__disposer,delete In.__extender),_n.__deleteInstance(Pn),delete this.$i18n}}}function mergeToGlobal($n,Cn){$n.locale=Cn.locale||$n.locale,$n.fallbackLocale=Cn.fallbackLocale||$n.fallbackLocale,$n.missing=Cn.missing||$n.missing,$n.silentTranslationWarn=Cn.silentTranslationWarn||$n.silentFallbackWarn,$n.silentFallbackWarn=Cn.silentFallbackWarn||$n.silentFallbackWarn,$n.formatFallbackMessages=Cn.formatFallbackMessages||$n.formatFallbackMessages,$n.postTranslation=Cn.postTranslation||$n.postTranslation,$n.warnHtmlInMessage=Cn.warnHtmlInMessage||$n.warnHtmlInMessage,$n.escapeParameterHtml=Cn.escapeParameterHtml||$n.escapeParameterHtml,$n.sync=Cn.sync||$n.sync,$n.__composer[SetPluralRulesSymbol](Cn.pluralizationRules||$n.pluralizationRules);const _n=getLocaleMessages($n.locale,{messages:Cn.messages,__i18n:Cn.__i18n});return Object.keys(_n).forEach(Pn=>$n.mergeLocaleMessage(Pn,_n[Pn])),Cn.datetimeFormats&&Object.keys(Cn.datetimeFormats).forEach(Pn=>$n.mergeDateTimeFormat(Pn,Cn.datetimeFormats[Pn])),Cn.numberFormats&&Object.keys(Cn.numberFormats).forEach(Pn=>$n.mergeNumberFormat(Pn,Cn.numberFormats[Pn])),$n}const I18nInjectionKey=makeSymbol("global-vue-i18n");function createI18n($n={},Cn){const _n=__VUE_I18N_LEGACY_API__&&isBoolean($n.legacy)?$n.legacy:__VUE_I18N_LEGACY_API__,Pn=isBoolean($n.globalInjection)?$n.globalInjection:!0,In=__VUE_I18N_LEGACY_API__&&_n?!!$n.allowComposition:!0,Nn=new Map,[Rn,Dn]=createGlobal($n,_n),Ln=makeSymbol("");function Fn(zn){return Nn.get(zn)||null}function Bn(zn,Wn){Nn.set(zn,Wn)}function Hn(zn){Nn.delete(zn)}{const zn={get mode(){return __VUE_I18N_LEGACY_API__&&_n?"legacy":"composition"},get allowComposition(){return In},async install(Wn,...Yn){if(Wn.__VUE_I18N_SYMBOL__=Ln,Wn.provide(Wn.__VUE_I18N_SYMBOL__,zn),isPlainObject$1(Yn[0])){const Xn=Yn[0];zn.__composerExtend=Xn.__composerExtend,zn.__vueI18nExtend=Xn.__vueI18nExtend}let Gn=null;!_n&&Pn&&(Gn=injectGlobalFields(Wn,zn.global)),__VUE_I18N_FULL_INSTALL__&&apply(Wn,zn,...Yn),__VUE_I18N_LEGACY_API__&&_n&&Wn.mixin(defineMixin(Dn,Dn.__composer,zn));const Go=Wn.unmount;Wn.unmount=()=>{Gn&&Gn(),zn.dispose(),Go()}},get global(){return Dn},dispose(){Rn.stop()},__instances:Nn,__getInstance:Fn,__setInstance:Bn,__deleteInstance:Hn};return zn}}function useI18n($n={}){const Cn=getCurrentInstance();if(Cn==null)throw createI18nError(I18nErrorCodes.MUST_BE_CALL_SETUP_TOP);if(!Cn.isCE&&Cn.appContext.app!=null&&!Cn.appContext.app.__VUE_I18N_SYMBOL__)throw createI18nError(I18nErrorCodes.NOT_INSTALLED);const _n=getI18nInstance(Cn),Pn=getGlobalComposer(_n),In=getComponentOptions(Cn),Nn=getScope($n,In);if(__VUE_I18N_LEGACY_API__&&_n.mode==="legacy"&&!$n.__useComponent){if(!_n.allowComposition)throw createI18nError(I18nErrorCodes.NOT_AVAILABLE_IN_LEGACY_MODE);return useI18nForLegacy(Cn,Nn,Pn,$n)}if(Nn==="global")return adjustI18nResources(Pn,$n,In),Pn;if(Nn==="parent"){let Ln=getComposer(_n,Cn,$n.__useComponent);return Ln==null&&(Ln=Pn),Ln}const Rn=_n;let Dn=Rn.__getInstance(Cn);if(Dn==null){const Ln=assign$2({},$n);"__i18n"in In&&(Ln.__i18n=In.__i18n),Pn&&(Ln.__root=Pn),Dn=createComposer(Ln),Rn.__composerExtend&&(Dn[DisposeSymbol]=Rn.__composerExtend(Dn)),setupLifeCycle(Rn,Cn,Dn),Rn.__setInstance(Cn,Dn)}return Dn}function createGlobal($n,Cn,_n){const Pn=effectScope();{const In=__VUE_I18N_LEGACY_API__&&Cn?Pn.run(()=>createVueI18n($n)):Pn.run(()=>createComposer($n));if(In==null)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);return[Pn,In]}}function getI18nInstance($n){{const Cn=inject($n.isCE?I18nInjectionKey:$n.appContext.app.__VUE_I18N_SYMBOL__);if(!Cn)throw createI18nError($n.isCE?I18nErrorCodes.NOT_INSTALLED_WITH_PROVIDE:I18nErrorCodes.UNEXPECTED_ERROR);return Cn}}function getScope($n,Cn){return isEmptyObject($n)?"__i18n"in Cn?"local":"global":$n.useScope?$n.useScope:"local"}function getGlobalComposer($n){return $n.mode==="composition"?$n.global:$n.global.__composer}function getComposer($n,Cn,_n=!1){let Pn=null;const In=Cn.root;let Nn=getParentComponentInstance(Cn,_n);for(;Nn!=null;){const Rn=$n;if($n.mode==="composition")Pn=Rn.__getInstance(Nn);else if(__VUE_I18N_LEGACY_API__){const Dn=Rn.__getInstance(Nn);Dn!=null&&(Pn=Dn.__composer,_n&&Pn&&!Pn[InejctWithOptionSymbol]&&(Pn=null))}if(Pn!=null||In===Nn)break;Nn=Nn.parent}return Pn}function getParentComponentInstance($n,Cn=!1){return $n==null?null:Cn&&$n.vnode.ctx||$n.parent}function setupLifeCycle($n,Cn,_n){onMounted(()=>{},Cn),onUnmounted(()=>{const Pn=_n;$n.__deleteInstance(Cn);const In=Pn[DisposeSymbol];In&&(In(),delete Pn[DisposeSymbol])},Cn)}function useI18nForLegacy($n,Cn,_n,Pn={}){const In=Cn==="local",Nn=shallowRef(null);if(In&&$n.proxy&&!($n.proxy.$options.i18n||$n.proxy.$options.__i18n))throw createI18nError(I18nErrorCodes.MUST_DEFINE_I18N_OPTION_IN_ALLOW_COMPOSITION);const Rn=isBoolean(Pn.inheritLocale)?Pn.inheritLocale:!isString$1(Pn.locale),Dn=ref(!In||Rn?_n.locale.value:isString$1(Pn.locale)?Pn.locale:DEFAULT_LOCALE),Ln=ref(!In||Rn?_n.fallbackLocale.value:isString$1(Pn.fallbackLocale)||isArray(Pn.fallbackLocale)||isPlainObject$1(Pn.fallbackLocale)||Pn.fallbackLocale===!1?Pn.fallbackLocale:Dn.value),Fn=ref(getLocaleMessages(Dn.value,Pn)),Bn=ref(isPlainObject$1(Pn.datetimeFormats)?Pn.datetimeFormats:{[Dn.value]:{}}),Hn=ref(isPlainObject$1(Pn.numberFormats)?Pn.numberFormats:{[Dn.value]:{}}),zn=In?_n.missingWarn:isBoolean(Pn.missingWarn)||isRegExp(Pn.missingWarn)?Pn.missingWarn:!0,Wn=In?_n.fallbackWarn:isBoolean(Pn.fallbackWarn)||isRegExp(Pn.fallbackWarn)?Pn.fallbackWarn:!0,Yn=In?_n.fallbackRoot:isBoolean(Pn.fallbackRoot)?Pn.fallbackRoot:!0,Gn=!!Pn.fallbackFormat,Go=isFunction(Pn.missing)?Pn.missing:null,Xn=isFunction(Pn.postTranslation)?Pn.postTranslation:null,Yo=In?_n.warnHtmlMessage:isBoolean(Pn.warnHtmlMessage)?Pn.warnHtmlMessage:!0,qo=!!Pn.escapeParameter,Jo=In?_n.modifiers:isPlainObject$1(Pn.modifiers)?Pn.modifiers:{},Zo=Pn.pluralRules||In&&_n.pluralRules;function rr(){return[Dn.value,Ln.value,Fn.value,Bn.value,Hn.value]}const nr=computed({get:()=>Nn.value?Nn.value.locale.value:Dn.value,set:pa=>{Nn.value&&(Nn.value.locale.value=pa),Dn.value=pa}}),ta=computed({get:()=>Nn.value?Nn.value.fallbackLocale.value:Ln.value,set:pa=>{Nn.value&&(Nn.value.fallbackLocale.value=pa),Ln.value=pa}}),oa=computed(()=>Nn.value?Nn.value.messages.value:Fn.value),ra=computed(()=>Bn.value),ea=computed(()=>Hn.value);function la(){return Nn.value?Nn.value.getPostTranslationHandler():Xn}function ua(pa){Nn.value&&Nn.value.setPostTranslationHandler(pa)}function ga(){return Nn.value?Nn.value.getMissingHandler():Go}function aa(pa){Nn.value&&Nn.value.setMissingHandler(pa)}function ca(pa){return rr(),pa()}function sa(...pa){return Nn.value?ca(()=>Reflect.apply(Nn.value.t,null,[...pa])):ca(()=>"")}function ia(...pa){return Nn.value?Reflect.apply(Nn.value.rt,null,[...pa]):""}function fa(...pa){return Nn.value?ca(()=>Reflect.apply(Nn.value.d,null,[...pa])):ca(()=>"")}function ma(...pa){return Nn.value?ca(()=>Reflect.apply(Nn.value.n,null,[...pa])):ca(()=>"")}function ya(pa){return Nn.value?Nn.value.tm(pa):{}}function ba(pa,Sa){return Nn.value?Nn.value.te(pa,Sa):!1}function Ia(pa){return Nn.value?Nn.value.getLocaleMessage(pa):{}}function Ea(pa,Sa){Nn.value&&(Nn.value.setLocaleMessage(pa,Sa),Fn.value[pa]=Sa)}function xa(pa,Sa){Nn.value&&Nn.value.mergeLocaleMessage(pa,Sa)}function Ta(pa){return Nn.value?Nn.value.getDateTimeFormat(pa):{}}function wa(pa,Sa){Nn.value&&(Nn.value.setDateTimeFormat(pa,Sa),Bn.value[pa]=Sa)}function La(pa,Sa){Nn.value&&Nn.value.mergeDateTimeFormat(pa,Sa)}function Na(pa){return Nn.value?Nn.value.getNumberFormat(pa):{}}function $a(pa,Sa){Nn.value&&(Nn.value.setNumberFormat(pa,Sa),Hn.value[pa]=Sa)}function ka(pa,Sa){Nn.value&&Nn.value.mergeNumberFormat(pa,Sa)}const Ha={get id(){return Nn.value?Nn.value.id:-1},locale:nr,fallbackLocale:ta,messages:oa,datetimeFormats:ra,numberFormats:ea,get inheritLocale(){return Nn.value?Nn.value.inheritLocale:Rn},set inheritLocale(pa){Nn.value&&(Nn.value.inheritLocale=pa)},get availableLocales(){return Nn.value?Nn.value.availableLocales:Object.keys(Fn.value)},get modifiers(){return Nn.value?Nn.value.modifiers:Jo},get pluralRules(){return Nn.value?Nn.value.pluralRules:Zo},get isGlobal(){return Nn.value?Nn.value.isGlobal:!1},get missingWarn(){return Nn.value?Nn.value.missingWarn:zn},set missingWarn(pa){Nn.value&&(Nn.value.missingWarn=pa)},get fallbackWarn(){return Nn.value?Nn.value.fallbackWarn:Wn},set fallbackWarn(pa){Nn.value&&(Nn.value.missingWarn=pa)},get fallbackRoot(){return Nn.value?Nn.value.fallbackRoot:Yn},set fallbackRoot(pa){Nn.value&&(Nn.value.fallbackRoot=pa)},get fallbackFormat(){return Nn.value?Nn.value.fallbackFormat:Gn},set fallbackFormat(pa){Nn.value&&(Nn.value.fallbackFormat=pa)},get warnHtmlMessage(){return Nn.value?Nn.value.warnHtmlMessage:Yo},set warnHtmlMessage(pa){Nn.value&&(Nn.value.warnHtmlMessage=pa)},get escapeParameter(){return Nn.value?Nn.value.escapeParameter:qo},set escapeParameter(pa){Nn.value&&(Nn.value.escapeParameter=pa)},t:sa,getPostTranslationHandler:la,setPostTranslationHandler:ua,getMissingHandler:ga,setMissingHandler:aa,rt:ia,d:fa,n:ma,tm:ya,te:ba,getLocaleMessage:Ia,setLocaleMessage:Ea,mergeLocaleMessage:xa,getDateTimeFormat:Ta,setDateTimeFormat:wa,mergeDateTimeFormat:La,getNumberFormat:Na,setNumberFormat:$a,mergeNumberFormat:ka};function da(pa){pa.locale.value=Dn.value,pa.fallbackLocale.value=Ln.value,Object.keys(Fn.value).forEach(Sa=>{pa.mergeLocaleMessage(Sa,Fn.value[Sa])}),Object.keys(Bn.value).forEach(Sa=>{pa.mergeDateTimeFormat(Sa,Bn.value[Sa])}),Object.keys(Hn.value).forEach(Sa=>{pa.mergeNumberFormat(Sa,Hn.value[Sa])}),pa.escapeParameter=qo,pa.fallbackFormat=Gn,pa.fallbackRoot=Yn,pa.fallbackWarn=Wn,pa.missingWarn=zn,pa.warnHtmlMessage=Yo}return onBeforeMount(()=>{if($n.proxy==null||$n.proxy.$i18n==null)throw createI18nError(I18nErrorCodes.NOT_AVAILABLE_COMPOSITION_IN_LEGACY);const pa=Nn.value=$n.proxy.$i18n.__composer;Cn==="global"?(Dn.value=pa.locale.value,Ln.value=pa.fallbackLocale.value,Fn.value=pa.messages.value,Bn.value=pa.datetimeFormats.value,Hn.value=pa.numberFormats.value):In&&da(pa)}),Ha}const globalExportProps=["locale","fallbackLocale","availableLocales"],globalExportMethods=["t","rt","d","n","tm","te"];function injectGlobalFields($n,Cn){const _n=Object.create(null);return globalExportProps.forEach(In=>{const Nn=Object.getOwnPropertyDescriptor(Cn,In);if(!Nn)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);const Rn=isRef(Nn.value)?{get(){return Nn.value.value},set(Dn){Nn.value.value=Dn}}:{get(){return Nn.get&&Nn.get()}};Object.defineProperty(_n,In,Rn)}),$n.config.globalProperties.$i18n=_n,globalExportMethods.forEach(In=>{const Nn=Object.getOwnPropertyDescriptor(Cn,In);if(!Nn||!Nn.value)throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);Object.defineProperty($n.config.globalProperties,`$${In}`,Nn)}),()=>{delete $n.config.globalProperties.$i18n,globalExportMethods.forEach(In=>{delete $n.config.globalProperties[`$${In}`]})}}initFeatureFlags();__INTLIFY_JIT_COMPILATION__?registerMessageCompiler(compile):registerMessageCompiler(compileToFunction);registerMessageResolver(resolveValue);registerLocaleFallbacker(fallbackWithLocaleChain);if(__INTLIFY_PROD_DEVTOOLS__){const $n=getGlobalThis();$n.__INTLIFY__=!0,setDevToolsHook($n.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__)}const words$1={destinationRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},virtualServiceDomain:{YAMLView:"YAML视图",formView:"表单视图"},loginDomain:{username:"用户名",password:"密码",login:"登录",authFail:"认证失败"},dynamicConfigDomain:{addConfig:"增加配置",addByFormView:"新增动态配置",updateByFormView:"修改动态配置",detailByFormView:"查看动态配置",addMatches:"增加匹配条件",matchType:"匹配条件类型",configType:"配置项类型",notSaved:"*改动未保存",saved:"配置无改动",YAMLView:"YAML视图",formView:"表单视图",event:"事件",save:"保存",reset:"重置"},routingRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},updateRoutingRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},addRoutingRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},tagRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},updateTagRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},addTagRuleDomain:{YAMLView:"YAML视图",formView:"表单视图"},flowControlDomain:{notSet:"未设置",versionRecords:"版本记录",YAMLView:"YAML视图",addConfiguration:"增加配置",addConfigurationItem:"增加配置项",addFilter:"增加筛选",configurationItem:"配置项",actuatingRange:"作用范围",matches:"作用范围",scopeScreening:"作用范围筛选",endOfAction:"作用端",side:"作用端",actions:"操作",filterType:"筛选类型",labelName:"标签名",formView:"表单视图",addMatch:"增加匹配",addRouter:"增加路由",addLabel:"增加标签",addressSubsetMatching:"地址子集匹配",value:"值",relation:"关系",requestParameterMatching:"请求参数匹配",matchingDimension:"匹配维度",parameter:"参数",ruleName:"规则名",actionObject:"作用对象",key:"作用对象",faultTolerantProtection:"容错保护",runTimeEffective:"运行时生效",ruleGranularity:"规则粒度",scope:"规则粒度",effectTime:"生效时间",enabledState:"启用状态",priority:"优先级",off:"关",on:"开",opened:"开启",closed:"关闭",enabled:"启用",disabled:"禁用"},instanceDomain:{flowDisabled:"流量禁用",operatorLog:"执行日志",CPU:"CPU",enableAppInstanceLogs:"开启该应用所有实例的访问日志",appServiceLoadBalance:"调整应用提供服务的负载均衡策略",appServiceNegativeClusteringMethod:"调整应用提供服务的的集群方式",appServiceRetries:"调整该应用提供服务的重试次数",appServiceTimeout:"调整应用提供服务的超时时间",close:"关闭",enable:"开启",executionLog:"执行日志",retryCount:"重试次数",clusterApproach:"集群方式",timeout_ms:"超时时间(ms)",details:"详情",loadBalance:"负载均衡",monitor:"监控",linkTracking:"链路追踪",configuration:"场景配置",event:"事件",healthExamination_k8s:"健康检查(k8s)",instanceLabel:"实例标签",instanceImage_k8s:"镜像(k8s)",owningWorkload_k8s:"所属工作负载(k8s)",node:"节点",whichApplication:"所属应用",registerCluster:"注册集群",dubboPort:"Dubbo端口",instanceIP:"实例IP",ip:"IP",name:"实例名称",deployState:"部署状态",deployCluster:"部署集群",deployClusters:"部署集群",registerState:"注册状态",registerClusters:"注册集群",registryClusters:"注册集群",cpu:"CPU",memory:"内存",startTime:"启动时间",registerTime:"注册时间",labels:"标签",instanceCount:"实例数量",instanceName:"实例名称",creationTime_k8s:"创建时间(k8s)",startTime_k8s:"启动时间(k8s)"},serviceDomain:{name:"服务名",notSpecified:"不指定",timeout:"超时时间",retryNum:"重试次数",sameAreaFirst:"同区域优先",closed:"关闭",opened:"开启",paramRoute:"参数路由"},service:"服务",versionGroup:"版本&分组",avgQPS:"QPS",avgRT:"RT",requestTotal:"近1min请求总量",serviceSearch:"服务查询",serviceGovernance:"路由规则",trafficManagement:"流量管控",serviceMetrics:"服务统计",serviceRelation:"服务关系",routingRule:"条件路由",tagRule:"标签路由",meshRule:"Mesh路由",dynamicConfig:"动态配置",accessControl:"黑白名单",weightAdjust:"权重调整",loadBalance:"负载均衡",serviceTest:"服务测试",serviceMock:"服务Mock",services:"服务",providers:"提供者",consumers:"消费者",application:"应用",instance:"实例",all:"全部",common:"通用",metrics:"可观测",relation:"关系",group:"组",version:"版本",app:"应用",ip:"IP地址",qps:"qps",rt:"rt",successRate:"成功率",serviceInfo:"服务信息",port:"端口",timeout:"超时(毫秒)",serialization:"序列化",appName:"应用名",instanceNum:"实例数量",deployCluster:"部署集群",registerClusters:"注册集群列表",serviceName:"服务名",provideServiceName:"提供服务",registrySource:"注册来源",instanceRegistry:"应用级",interfaceRegistry:"接口级",allRegistry:"应用级/接口级",operation:"操作",searchResult:"查询结果",search:"搜索",methodName:"方法名",enabled:"开启",disabled:"禁用",method:"方法",weight:"权重",create:"创建",save:"保存",cancel:"取消",close:"关闭",confirm:"确认",ruleContent:"规则内容",createNewRoutingRule:"创建新路由规则",createNewTagRule:"创建新标签规则",createMeshTagRule:"创建新mesh规则",createNewDynamicConfigRule:"创建新动态配置规则",createNewWeightRule:"新建权重规则",createNewLoadBalanceRule:"新建负载均衡规则",createTimeoutRule:"创建超时时间规则",createRetryRule:"创建重试规则",createRegionRule:"创建同区域优先规则",createArgumentRule:"创建参数路由规则",createMockCircuitRule:"创建调用降级规则",createAccesslogRule:"创建访问日志规则",createGrayRule:"创建灰度隔离规则",createWeightRule:"创建权重比例规则",serviceIdHint:"服务名",view:"查看",edit:"编辑",delete:"删除",searchRoutingRule:"搜索路由规则",searchAccessRule:"搜索黑白名单",searchWeightRule:"搜索权重调整规则",dataIdClassHint:"服务接口的类完整包路径",dataIdVersionHint:"服务接口的Version,根据接口实际情况选填",dataIdGroupHint:"服务接口的Group,根据接口实际情况选填",agree:"同意",disagree:"不同意",searchDynamicConfig:"搜索动态配置",appNameHint:"服务所属的应用名称",basicInfo:"基础信息",metaData:"元数据",methodMetrics:"服务方法统计",searchDubboService:"搜索Dubbo服务或应用",serviceSearchHint:"服务ID, org.apache.dubbo.demo.api.DemoService, * 代表所有服务",ipSearchHint:"在指定的IP地址上查找目标服务器提供的所有服务",appSearchHint:"输入应用名称以查找由一个特定应用提供的所有服务, * 代表所有",searchTagRule:"根据应用名搜索标签规则",searchMeshRule:"根据应用名搜索mesh规则",searchSingleMetrics:"输入IP搜索Metrics信息",searchBalanceRule:"搜索负载均衡规则",parameterList:"参数列表",returnType:"返回值",noMetadataHint:"无元数据信息,请升级至Dubbo2.7及以上版本,或者查看application.properties中关于config center的配置,详见",here:"这里",configAddress:"https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E",whiteList:"白名单",whiteListHint:"白名单IP列表, 多个地址用逗号分隔: 1.1.1.1,2.2.2.2",blackList:"黑名单",blackListHint:"黑名单IP列表, 多个地址用逗号分隔: 3.3.3.3,4.4.4.4",address:"地址列表",weightAddressHint:"此权重设置的IP地址,用逗号分隔: 1.1.1.1,2.2.2.2",weightHint:"权重值,默认100",methodHint:"负载均衡生效的方法,*代表所有方法",strategy:"策略",balanceStrategyHint:"负载均衡策略",goIndex:"返回首页",releaseLater:"在后续版本中发布,敬请期待",later:{metrics:"Metrics会在后续版本中发布,敬请期待",serviceTest:"服务测试会在后续版本中发布,敬请期待",serviceMock:"服务Mock会在后续版本中发布,敬请期待"},by:"按",$vuetify:{dataIterator:{rowsPerPageText:"每页记录数:",rowsPerPageAll:"全部",pageText:"{0}-{1} 共 {2} 条",noResultsText:"没有找到匹配记录",nextPage:"下一页",prevPage:"上一页"},dataTable:{rowsPerPageText:"每页行数:"},noDataText:"无可用数据"},configManage:"配置管理",configCenterAddress:"配置中心地址",searchDubboConfig:"搜索Dubbo配置",createNewDubboConfig:"新建Dubbo配置",scope:"范围",name:"名称",warnDeleteConfig:" 是否要删除Dubbo配置: ",warnDeleteRouteRule:"是否要删除路由规则",warnDeleteDynamicConfig:"是否要删除动态配置",warnDeleteBalancing:"是否要删除负载均衡规则",warnDeleteAccessControl:"是否要删除黑白名单",warnDeleteTagRule:"是否要删除标签路由",warnDeleteMeshRule:"是否要删除mesh路由",warnDeleteWeightAdjust:"是否要删除权重规则",configNameHint:"配置所属的应用名, global 表示全局配置",configContent:"配置内容",testMethod:"测试方法",execute:"执行",result:"结果: ",success:" 成功",fail:"失败",detail:"详情",more:"更多",copyUrl:"复制 URL",copy:"复制",url:"URL",copySuccessfully:"已复制",test:"测试",placeholders:{searchService:"通过服务名搜索服务"},methods:"方法列表",testModule:{searchServiceHint:"完整服务ID, org.apache.dubbo.demo.api.DemoService, 按回车键查询"},userName:"用户名",password:"密码",login:"登录",apiDocs:"接口文档",apiDocsRes:{dubboProviderIP:"Dubbo 提供者Ip",dubboProviderPort:"Dubbo 提供者端口",loadApiList:"加载接口列表",apiListText:"接口列表",apiForm:{missingInterfaceInfo:"缺少接口信息",getApiInfoErr:"获取接口信息异常",api404Err:"接口名称不正确,没有查找到接口参数和响应信息",apiRespDecShowLabel:"响应说明",apiNameShowLabel:"接口名称",apiPathShowLabel:"接口位置",apiMethodParamInfoLabel:"接口参数",apiVersionShowLabel:"接口版本",apiGroupShowLabel:"接口分组",apiDescriptionShowLabel:"接口说明",isAsyncFormLabel:"是否异步调用(此参数不可修改,根据接口定义的是否异步显示)",apiModuleFormLabel:"接口模块(此参数不可修改)",apiFunctionNameFormLabel:"接口方法名(此参数不可修改)",registryCenterUrlFormLabel:"注册中心地址, 如果为空将使用Dubbo 提供者Ip和端口进行直连",paramNameLabel:"参数名",paramPathLabel:"参数位置",paramDescriptionLabel:"说明",paramRequiredLabel:"该参数为必填",doTestBtn:"测试",responseLabel:"响应",responseExampleLabel:"响应示例",apiResponseLabel:"接口响应",LoadingLabel:"加载中...",requireTip:"有未填写的必填项",requireItemTip:"该项为必填!",requestApiErrorTip:"请求接口发生异常,请检查提交的数据,特别是JSON类数据和其中的枚举部分",unsupportedHtmlTypeTip:"暂不支持的表单类型",none:"无"}},authFailed:"权限验证失败",ruleList:"规则列表",mockRule:"规则配置",mockData:"模拟数据",globalDisable:"全局禁用",globalEnable:"全局启用",saveRuleSuccess:"保存规则成功",deleteRuleSuccess:"删除成功",disableRuleSuccess:"禁用成功",enableRuleSuccess:"启用成功",methodNameHint:"服务方法名",createMockRule:"创建规则",editMockRule:"修改规则",deleteRuleTitle:"确定要删除此服务Mock规则吗?",ruleName:"规则名",ruleGranularity:"规则粒度",createTime:"创建时间",lastModifiedTime:"最后修改时间",enable:"是否启用",protection:"容错保护",trafficTimeout:"超时时间",trafficRetry:"调用重试",trafficRegion:"同区域优先",trafficIsolation:"环境隔离",trafficWeight:"权重比例",trafficArguments:"参数路由",trafficMock:"调用降级",trafficAccesslog:"访问日志",trafficHost:"固定机器导流",trafficGray:"流量灰度",homePage:"集群概览",serviceManagement:"开发测试",groupInputPrompt:"请输入服务group(可选)",versionInputPrompt:"请输入服务version(可选)",resources:"资源详情",applications:"应用",instances:"实例",applicationDomain:{instanceCount:"实例数量",deployClusters:"部署集群",registryClusters:"注册集群",registerClusters:"注册集群",registerModes:"注册模式",operatorLog:"执行日志",flowWeight:"流量权重",gray:"灰度隔离",name:"应用名",detail:"详情",instance:"实例",service:"服务",monitor:"监控",tracing:"链路追踪",config:"配置",event:"事件",appName:"应用名",rpcProtocols:"RPC 协议",dubboVersions:"Dubbo 版本",dubboPorts:"Dubbo 端口",serialProtocols:"序列化协议",appTypes:"应用类型",images:"应用镜像",workloads:"工作负载",deployCluster:"部署集群",registerCluster:"注册集群",registerMode:"注册模式"},searchDomain:{total:"共计",unit:"条"},messageDomain:{success:{copy:"您已经成功复制一条信息"}},backHome:"回到首页",noPageTip:"抱歉,你访问的页面不存在",globalSearchTip:"搜索ip,应用,实例,服务",placeholder:{typeAppName:"请输入应用名,支持前缀搜索",typeDefault:"请输入",typeRoutingRules:"搜索路由规则,支持前缀过滤"},none:"无",details:"详情",debug:"调试",distribution:"分布",monitor:"监控",tracing:"链路追踪",sceneConfig:"场景配置",event:"事件",provideService:"提供服务",dependentService:"依赖服务",idx:"序号",submit:"提交",reset:"重置",router:{resource:{app:{list:"列表"},ins:{list:"列表"},svc:{list:"列表"}}},form:{save:"保存"}},words={loginDomain:{username:"Username",password:"Password",login:"Login",authFail:"Auth Fail"},destinationRuleDomain:{YAMLView:"YAML view",formView:"Form view"},virtualServiceDomain:{YAMLView:"YAML view",formView:"Form view"},dynamicConfigDomain:{YAMLView:"YAML view",formView:"Form view",event:"Event"},updateRoutingRuleDomain:{YAMLView:"YAML view",formView:"Form view"},routingRuleDomain:{YAMLView:"YAML view",formView:"Form view"},addRoutingRuleDomain:{YAMLView:"YAML view",formView:"Form view"},tagRuleDomain:{YAMLView:"YAML view",formView:"Form view"},updateTagRuleDomain:{YAMLView:"YAML view",formView:"Form view"},addTagRuleDomain:{YAMLView:"YAML view",formView:"Form view"},flowControlDomain:{actuatingRange:"Actuating range",notSet:"Not set",versionRecords:"Version records",YAMLView:"YAML View",addConfiguration:"Add configuration",addConfigurationItem:"Add configurationItem",addFilter:"Add filter",configurationItem:"Configuration item",scopeScreening:"Scope screening",endOfAction:"End of action",addLabel:"Add label",actions:"Actions",filterType:"Filter type",labelName:"Label name",formView:"Form view",addMatch:"Add match",addRouter:"Add router",addressSubsetMatching:"Address subset matching",value:"Value",relation:"Relation",parameter:"Parameter",matchingDimension:"Matching dimension",requestParameterMatching:"Request parameter matching",ruleName:"Rule name",actionObject:"Action object",faultTolerantProtection:"Fault-tolerant protection",runTimeEffective:"Run time effective",ruleGranularity:"Rule granularity",effectTime:"Time of taking effect",enabledState:"Enabled status",priority:"Priority",off:"off",on:"on",opened:"Opened",closed:"Closed",enabled:"Enabled",disabled:"Disabled"},instanceDomain:{flowDisabled:"Flow disabled",operatorLog:"Operator log",enableAppInstanceLogs:"Enable access logs for all instances of this application",appServiceRetries:"Adjust the number of retries for the service provided by this application",appServiceLoadBalance:"Adjusting the load balancing strategy for application service provision",appServiceNegativeClusteringMethod:"Adjusting the clustering approach for application service provision",appServiceTimeout:"Adjusting the timeout for application service provision",close:"Close",enable:"Enable",executionLog:"ExecutionLog",loadBalance:"LoadBalance",instanceIP:"InstanceIP",clusterApproach:"ClusterApproach",details:"Detail",retryCount:"RetryCount",timeout_ms:"Timeout(ms)",monitor:"Monitor",linkTracking:"LinkTracking",configuration:"Configuration",event:"Event",instanceName:"InstanceName",ip:"Ip",name:"Name",deployState:"Deploy State",deployCluster:"Deploy Cluster",deployClusters:"Deploy Clusters",registerState:"Register State",registerCluster:"Register Cluster",registryClusters:"Registry Clusters",CPU:"CPU",node:"Node",memory:"Memory",owningWorkload_k8s:"Owning Workload(k8s)",creationTime_k8s:"CreationTime(k8s)",startTime:"StartTime",dubboPort:"DubboPort",instanceImage_k8s:"Image(k8s)",instanceLabel:"Instance Label",whichApplication:"Owning Application",healthExamination_k8s:"Health Examination(k8s)",registerTime:"RegisterTime",labels:"Labels",startTime_k8s:"StartTime(k8s)",instanceCount:"Instance Count"},serviceDomain:{name:"Name",timeout:"Timeout",retryNum:"Retry Num",sameAreaFirst:"Same Area First",closed:"Closed",opened:"Opened",paramRoute:"Param Route"},appServiceTimeout:"Adjusting the timeout for application service provision",enableAppInstanceLogs:"Enable access logs for all instances of this application",appServiceLoadBalance:"Adjusting the load balancing strategy for application service provision",appServiceRetries:"Adjusting the number of retries for application provided services",appServiceNegativeClusteringMethod:"Adjusting the negative clustering method for application service provision",executionLog:"Execution Log",clusterApproach:"Cluster Approach",retryCount:"Retry Count",event:"Event",configuration:"Configuration",linkTracking:"Link Tracking",monitor:"Monitor",details:"Details",creationTime_k8s:"creationTime(k8s)",dubboPort:"Dubbo Port",whichApplication:"application",registerTime:"Register Time",startTime_k8s:"Start Time(k8s)",registerStates:"Register States",deployState:"Deployment Status",owningWorkload_k8s:"Owning Workload(k8s)",creationTime:"Creation Time",nodeIP:"Node IP",healthExamination:"Health Examination",instanceImage_k8s:"Image(k8s)",instanceLabel:"Instance Label",instanceDetail:"Instance Detail",state:"State",memory:"Memory",CPU:"CPU",node:"Node",labels:"Labels",instanceIP:"Instance IP",instanceName:"Instance Name",instance:"Instance",resourceDetails:"Resource Details",service:"Service",versionGroup:"Version & Group",avgQPS:"last 1min QPS",avgRT:"last 1min RT",requestTotal:"last 1min request total",serviceSearch:"Search Service",serviceGovernance:"Routing Rule",trafficManagement:"Traffic Management",routingRule:"Condition Rule",tagRule:"Tag Rule",meshRule:"Mesh Rule",dynamicConfig:"Dynamic Config",accessControl:"Black White List",weightAdjust:"Weight Adjust",loadBalance:"Load Balance",serviceTest:"Service Test",serviceMock:"Service Mock",serviceMetrics:"Service Metrics",serviceRelation:"Service Relation",metrics:"Metrics",relation:"Relation",group:"Group",serviceInfo:"Service Info",providers:"Providers",consumers:"Consumers",common:"Common",version:"Version",app:"Application",services:"Services",application:"Application",all:"All",ip:"IP",qps:"qps",rt:"rt",successRate:"success rate",port:"PORT",timeout:"timeout(ms)",serialization:"serialization",appName:"Application Name",instanceNum:"Instance Number",deployCluster:"Deploy Cluster",registerCluster:"Register Cluster",serviceName:"Service Name",registrySource:"Registry Source",instanceRegistry:"Instance Registry",interfaceRegistry:"Interface Registry",allRegistry:"Instance / Interface Registry",operation:"Operation",searchResult:"Search Result",search:"Search",methodName:"Method Name",enabled:"Enabled",disabled:"Disabled",method:"Method",weight:"Weight",create:"CREATE",save:"SAVE",cancel:"CANCEL",close:"CLOSE",confirm:"CONFIRM",ruleContent:"RULE CONTENT",createNewRoutingRule:"Create New Routing Rule",createNewTagRule:"Create New Tag Rule",createNewMeshRule:"Create New Mesh Rule",createNewDynamicConfigRule:"Create New Dynamic Config Rule",createNewWeightRule:"Create New Weight Rule",createNewLoadBalanceRule:"Create new load balancing rule",createTimeoutRule:"Create timeout rule",createRetryRule:"Create timeout rule",createRegionRule:"Create retry rule",createArgumentRule:"Create argument routing rule",createMockCircuitRule:"Create mock (circuit breaking) rule",createAccesslogRule:"Create accesslog rule",createGrayRule:"Create gray rule",createWeightRule:"Create weighting rule",serviceIdHint:"Service ID",view:"View",edit:"Edit",delete:"Delete",searchRoutingRule:"Search Routing Rule",searchAccess:"Search Access Rule",searchWeightRule:"Search Weight Adjust Rule",dataIdClassHint:"Complete package path of service interface class",dataIdVersionHint:"The version of the service interface, which can be filled in according to the actual situation of the interface",dataIdGroupHint:"The group of the service interface, which can be filled in according to the actual situation of the interface",agree:"Agree",disagree:"Disagree",searchDynamicConfig:"Search Dynamic Config",appNameHint:"Application name the service belongs to",basicInfo:"BasicInfo",metaData:"MetaData",methodMetrics:"Method Statistics",searchDubboService:"Search Dubbo Services or applications",serviceSearchHint:"Service ID, org.apache.dubbo.demo.api.DemoService, * for all services",ipSearchHint:"Find all services provided by the target server on the specified IP address",appSearchHint:"Input an application name to find all services provided by one particular application, * for all",searchTagRule:"Search Tag Rule by application name",searchMeshRule:"Search Mesh Rule by application name",searchSingleMetrics:"Search Metrics by IP",searchBalanceRule:"Search Balancing Rule",noMetadataHint:"There is no metadata available, please update to Dubbo2.7, or check your config center configuration in application.properties, please check ",parameterList:"parameterList",returnType:"returnType",here:"here",configAddress:"https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin-configuration",whiteList:"White List",whiteListHint:"White list IP address, divided by comma: 1.1.1.1,2.2.2.2",blackList:"Black List",blackListHint:"Black list IP address, divided by comma: 3.3.3.3,4.4.4.4",address:"Address",weightAddressHint:"IP addresses to set this weight, divided by comma: 1.1.1.1,2.2.2.2",weightHint:"weight value, default is 100",methodHint:"choose method of load balancing, * for all methods",strategy:"Strategy",balanceStrategyHint:"load balancing strategy",goIndex:"Go To Index",releaseLater:"will release later",later:{metrics:"Metrics will release later",serviceTest:"Service Test will release later",serviceMock:"Service Mock will release later"},by:"by ",$vuetify:{dataIterator:{rowsPerPageText:"Items per page:",rowsPerPageAll:"All",pageText:"{0}-{1} of {2}",noResultsText:"No matching records found",nextPage:"Next page",prevPage:"Previous page"},dataTable:{rowsPerPageText:"Rows per page:"},noDataText:"No data available"},configManage:"Configuration Management",configCenterAddress:"ConfigCenter Address",searchDubboConfig:"Search Dubbo Config",createNewDubboConfig:"Create New Dubbo Config",scope:"Scope",name:"Name",warnDeleteConfig:" Are you sure to Delete Dubbo Config: ",warnDeleteRouteRule:"Are you sure to Delete routing rule",warnDeleteDynamicConfig:"Are you sure to Delete dynamic config",warnDeleteBalancing:"Are you sure to Delete load balancing",warnDeleteAccessControl:"Are you sure to Delete access control",warnDeleteTagRule:"Are you sure to Delete tag rule",warnDeleteMeshRule:"Are you sure to Delete mesh rule",warnDeleteWeightAdjust:"Are you sure to Delete weight adjust",configNameHint:"Application name the config belongs to, use 'global'(without quotes) for global config",configContent:"Config Content",testMethod:"Test Method",execute:"EXECUTE",result:"Result: ",success:"SUCCESS",fail:"FAIL",detail:"Detail",more:"More",copyUrl:"Copy URL",copy:"Copy",url:"URL",copySuccessfully:"Copied",test:"Test",placeholders:{searchService:"Search by service name"},methods:"Methods",testModule:{searchServiceHint:"Entire service ID, org.apache.dubbo.demo.api.DemoService, press Enter to search"},userName:"User Name",password:"Password",login:"Login",apiDocs:"API Docs",apiDocsRes:{dubboProviderIP:"Dubbo Provider Ip",dubboProviderPort:"Dubbo Provider Port",loadApiList:"Load Api List",apiListText:"Api List",apiForm:{missingInterfaceInfo:"Missing interface information",getApiInfoErr:"Exception in obtaining interface information",api404Err:"Interface name is incorrect, interface parameters and response information are not found",apiRespDecShowLabel:"Response Description",apiNameShowLabel:"Api Name",apiPathShowLabel:"Api Path",apiMethodParamInfoLabel:"Api method parameters",apiVersionShowLabel:"Api Version",apiGroupShowLabel:"Api Group",apiDescriptionShowLabel:"Api Description",isAsyncFormLabel:"Whether to call asynchronously (this parameter cannot be modified, according to whether to display asynchronously defined by the interface)",apiModuleFormLabel:"Api module (this parameter cannot be modified)",apiFunctionNameFormLabel:"Api function name(this parameter cannot be modified)",registryCenterUrlFormLabel:"Registry address. If it is empty, Dubbo provider IP and port will be used for direct connection",paramNameLabel:"Parameter name",paramPathLabel:"Parameter path",paramDescriptionLabel:"Description",paramRequiredLabel:"This parameter is required",doTestBtn:"Do Test",responseLabel:"Response",responseExampleLabel:"Response Example",apiResponseLabel:"Api Response",LoadingLabel:"Loading...",requireTip:"There are required items not filled in",requireItemTip:"This field is required",requestApiErrorTip:"There is an exception in the request interface. Please check the submitted data, especially the JSON class data and the enumeration part",unsupportedHtmlTypeTip:"Temporarily unsupported form type",none:"none"}},authFailed:"Authorized failed,please login.",ruleList:"Rule List",mockRule:"Mock Rule",mockData:"Mock Data",globalDisable:"Global Disable",globalEnable:"Global Enable",saveRuleSuccess:"Save Rule Successfully",deleteRuleSuccess:"Delete Rule Successfully",disableRuleSuccess:"Disable Rule Successfully",enableRuleSuccess:"Enable Rule Successfully",methodNameHint:"The method name of Service",createMockRule:"Create Mock Rule",editMockRule:"Edit Mock Rule",deleteRuleTitle:"Are you sure to delete this mock rule?",createTime:"Create Time",lastModifiedTime:"Last Modified Time",trafficTimeout:"Timeout",trafficRetry:"Retry",trafficRegion:"Region Aware",trafficIsolation:"Isolation",trafficWeight:"Weight Percentage",trafficArguments:"Arg Routing",trafficMock:"Mock",trafficAccesslog:"Accesslog",trafficHost:"Host",homePage:"Cluster Overview",serviceManagement:"Dev & Test",resources:"Resources",applications:"Applications",instances:"Instances",applicationDomain:{instanceCount:"Instance Count",deployClusters:"Deploy Clusters",registryClusters:"Registry Clusters",registerClusters:"Registry Clusters",registerModes:"Register Modes",operatorLog:"OperatorLog",flowWeight:"FlowWeight",gray:"Gray",detail:"Detail",instance:"Instance",service:"Service",monitor:"Monitor",tracing:"Tracing",config:"Config",event:"Event",appName:"Application Name",rpcProtocols:"Rpc Protocols",dubboVersions:"Dubbo Versions",dubboPorts:"Dubbo Ports",serialProtocols:"Serial Protocols",appTypes:"Application Types",images:"Images",workloads:"Workloads",deployCluster:"Deploy Cluster",registerCluster:"Register Cluster",registerMode:"Register Mode"},searchDomain:{total:"Total",unit:"items"},messageDomain:{success:{copy:"You have successfully copied a piece of information"}},backHome:"Back Home",noPageTip:"Sorry, the page you visited does not exist.",globalSearchTip:"Search ip, application, instance, service",placeholder:{typeAppName:"please type appName, support for prefix",typeDefault:"please type "},none:"No Select",debug:"Debug",distribution:"Distribution",tracing:"Tracing",sceneConfig:"Scene Config",provideService:"Provide Service",dependentService:"Dependent Service",submit:"Submit",reset:"Reset",router:{resource:{app:{list:"List"},ins:{list:"List"},svc:{list:"List"}}},form:{save:"SAVE"}},messages={cn:{content:"内容",Home:"主页",home:"主页",...words$1},en:{content:"content",Home:"Home",home:"home",...words}},localeConfig=reactive({locale:localStorage.getItem(LOCAL_STORAGE_LOCALE)||"cn",opts:[{value:"en",title:"en"},{value:"cn",title:"中文"}]}),i18n=createI18n({locale:localeConfig.locale,legacy:!1,globalInjection:!0,messages}),changeLanguage=$n=>{localStorage.setItem(LOCAL_STORAGE_LOCALE,$n),i18n.global.locale.value=$n};function getCurrentFunctionLocation($n=0){try{throw new Error}catch(Cn){const _n=Cn.stack.split(` -`),Pn=2+$n;return Pn>=0&&_n.length>=Pn?_n[Pn].trim():"wrong location"}}const todo=$n=>{notification.warn({message:`TODO: ${$n} =>: ${devTool.getCurrentFunctionLocation(1)}`})},mockUrl=$n=>RegExp($n+".*"),devTool={getCurrentFunctionLocation,todo,mockUrl};/*! js-cookie v3.0.5 | MIT */function assign($n){for(var Cn=1;Cn"u")){Rn=assign({},Cn,Rn),typeof Rn.expires=="number"&&(Rn.expires=new Date(Date.now()+Rn.expires*864e5)),Rn.expires&&(Rn.expires=Rn.expires.toUTCString()),In=encodeURIComponent(In).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var Dn="";for(var Ln in Rn)Rn[Ln]&&(Dn+="; "+Ln,Rn[Ln]!==!0&&(Dn+="="+Rn[Ln].split(";")[0]));return document.cookie=In+"="+$n.write(Nn,In)+Dn}}function Pn(In){if(!(typeof document>"u"||arguments.length&&!In)){for(var Nn=document.cookie?document.cookie.split("; "):[],Rn={},Dn=0;Dn({"74d14fde":unref(PRIMARY_COLOR)})),dayjs.locale("en");const Cn=reactive(localeConfig);watch(Cn,In=>{dayjs.locale(In.locale)}),provide(PROVIDE_INJECT_KEY.LOCALE,Cn);function _n(){window.open("https://cn.dubbo.apache.org/zh-cn/overview/what/")}const Pn=reactive(i18n.global.locale);return useRouter(),(In,Nn)=>{const Rn=resolveComponent("a-float-button"),Dn=resolveComponent("a-config-provider");return openBlock(),createBlock(Dn,{locale:unref(Pn==="en"?localeValues$1:zhCN),theme:{token:{colorPrimary:unref(PRIMARY_COLOR)}}},{default:withCtx(()=>[createVNode(unref(RouterView)),createVNode(Rn,{type:"primary",class:"__global_float_button_question",onClick:_n},{icon:withCtx(()=>[createVNode(unref(QuestionCircleOutlined$1))]),_:1})]),_:1},8,["locale","theme"])}}});var mock={exports:{}};(function(module,exports){(function(Cn,_n){module.exports=_n()})(commonjsGlobal,function(){return function($n){var Cn={};function _n(Pn){if(Cn[Pn])return Cn[Pn].exports;var In=Cn[Pn]={exports:{},id:Pn,loaded:!1};return $n[Pn].call(In.exports,In,In.exports,_n),In.loaded=!0,In.exports}return _n.m=$n,_n.c=Cn,_n.p="",_n(0)}([function($n,Cn,_n){var Pn=_n(1),In=_n(3),Nn=_n(5),Rn=_n(20),Dn=_n(23),Ln=_n(25),Fn;typeof window<"u"&&(Fn=_n(27));/*! - Mock - 模拟请求 & 模拟数据 - https://github.com/nuysoft/Mock - 墨智 mozhi.gyy@taobao.com nuysoft@gmail.com -*/var Bn={Handler:Pn,Random:Nn,Util:In,XHR:Fn,RE:Rn,toJSONSchema:Dn,valid:Ln,heredoc:In.heredoc,setup:function(Hn){return Fn.setup(Hn)},_mocked:{}};Bn.version="1.0.1-beta3",Fn&&(Fn.Mock=Bn),Bn.mock=function(Hn,zn,Wn){return arguments.length===1?Pn.gen(Hn):(arguments.length===2&&(Wn=zn,zn=void 0),Fn&&(window.XMLHttpRequest=Fn),Bn._mocked[Hn+(zn||"")]={rurl:Hn,rtype:zn,template:Wn},Bn)},$n.exports=Bn},function(module,exports,__webpack_require__){var Constant=__webpack_require__(2),Util=__webpack_require__(3),Parser=__webpack_require__(4),Random=__webpack_require__(5),RE=__webpack_require__(20),Handler={extend:Util.extend};Handler.gen=function($n,Cn,_n){Cn=Cn==null?"":Cn+"",_n=_n||{},_n={path:_n.path||[Constant.GUID],templatePath:_n.templatePath||[Constant.GUID++],currentContext:_n.currentContext,templateCurrentContext:_n.templateCurrentContext||$n,root:_n.root||_n.currentContext,templateRoot:_n.templateRoot||_n.templateCurrentContext||$n};var Pn=Parser.parse(Cn),In=Util.type($n),Nn;return Handler[In]?(Nn=Handler[In]({type:In,template:$n,name:Cn,parsedName:Cn&&Cn.replace(Constant.RE_KEY,"$1"),rule:Pn,context:_n}),_n.root||(_n.root=Nn),Nn):$n},Handler.extend({array:function($n){var Cn=[],_n,Pn;if($n.template.length===0)return Cn;if($n.rule.parameters)if($n.rule.min===1&&$n.rule.max===void 0)$n.context.path.push($n.name),$n.context.templatePath.push($n.name),Cn=Random.pick(Handler.gen($n.template,void 0,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template})),$n.context.path.pop(),$n.context.templatePath.pop();else if($n.rule.parameters[2])$n.template.__order_index=$n.template.__order_index||0,$n.context.path.push($n.name),$n.context.templatePath.push($n.name),Cn=Handler.gen($n.template,void 0,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template})[$n.template.__order_index%$n.template.length],$n.template.__order_index+=+$n.rule.parameters[2],$n.context.path.pop(),$n.context.templatePath.pop();else for(_n=0;_n<$n.rule.count;_n++)for(Pn=0;Pn<$n.template.length;Pn++)$n.context.path.push(Cn.length),$n.context.templatePath.push(Pn),Cn.push(Handler.gen($n.template[Pn],Cn.length,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template})),$n.context.path.pop(),$n.context.templatePath.pop();else for(_n=0;_n<$n.template.length;_n++)$n.context.path.push(_n),$n.context.templatePath.push(_n),Cn.push(Handler.gen($n.template[_n],_n,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template})),$n.context.path.pop(),$n.context.templatePath.pop();return Cn},object:function($n){var Cn={},_n,Pn,In,Nn,Rn,Dn;if($n.rule.min!=null)for(_n=Util.keys($n.template),_n=Random.shuffle(_n),_n=_n.slice(0,$n.rule.count),Dn=0;Dn<_n.length;Dn++)In=_n[Dn],Nn=In.replace(Constant.RE_KEY,"$1"),$n.context.path.push(Nn),$n.context.templatePath.push(In),Cn[Nn]=Handler.gen($n.template[In],In,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template}),$n.context.path.pop(),$n.context.templatePath.pop();else{_n=[],Pn=[];for(In in $n.template)(typeof $n.template[In]=="function"?Pn:_n).push(In);for(_n=_n.concat(Pn),Dn=0;Dn<_n.length;Dn++)In=_n[Dn],Nn=In.replace(Constant.RE_KEY,"$1"),$n.context.path.push(Nn),$n.context.templatePath.push(In),Cn[Nn]=Handler.gen($n.template[In],In,{path:$n.context.path,templatePath:$n.context.templatePath,currentContext:Cn,templateCurrentContext:$n.template,root:$n.context.root||Cn,templateRoot:$n.context.templateRoot||$n.template}),$n.context.path.pop(),$n.context.templatePath.pop(),Rn=In.match(Constant.RE_KEY),Rn&&Rn[2]&&Util.type($n.template[In])==="number"&&($n.template[In]+=parseInt(Rn[2],10))}return Cn},number:function($n){var Cn,_n;if($n.rule.decimal){for($n.template+="",_n=$n.template.split("."),_n[0]=$n.rule.range?$n.rule.count:_n[0],_n[1]=(_n[1]||"").slice(0,$n.rule.dcount);_n[1].length<$n.rule.dcount;)_n[1]+=_n[1].length<$n.rule.dcount-1?Random.character("number"):Random.character("123456789");Cn=parseFloat(_n.join("."),10)}else Cn=$n.rule.range&&!$n.rule.parameters[2]?$n.rule.count:$n.template;return Cn},boolean:function($n){var Cn;return Cn=$n.rule.parameters?Random.bool($n.rule.min,$n.rule.max,$n.template):$n.template,Cn},string:function($n){var Cn="",_n,Pn,In,Nn;if($n.template.length){for($n.rule.count==null&&(Cn+=$n.template),_n=0;_n<$n.rule.count;_n++)Cn+=$n.template;for(Pn=Cn.match(Constant.RE_PLACEHOLDER)||[],_n=0;_n1)return this.getValueByKeyPath(key,options);if(templateContext&&typeof templateContext=="object"&&key in templateContext&&placeholder!==templateContext[key])return templateContext[key]=Handler.gen(templateContext[key],key,{currentContext:obj,templateCurrentContext:templateContext}),templateContext[key];if(!(key in Random)&&!(lkey in Random)&&!(okey in Random))return placeholder;for(var i=0;i1&&(In=Cn.context.path.slice(0),In.pop(),In=this.normalizePath(In.concat(Pn)));try{$n=Pn[Pn.length-1];for(var Nn=Cn.context.root,Rn=Cn.context.templateRoot,Dn=1;Dn1/(_n+Pn)*_n?!In:In):Math.random()>=.5},bool:function(_n,Pn,In){return this.boolean(_n,Pn,In)},natural:function(_n,Pn){return _n=typeof _n<"u"?parseInt(_n,10):0,Pn=typeof Pn<"u"?parseInt(Pn,10):9007199254740992,Math.round(Math.random()*(Pn-_n))+_n},integer:function(_n,Pn){return _n=typeof _n<"u"?parseInt(_n,10):-9007199254740992,Pn=typeof Pn<"u"?parseInt(Pn,10):9007199254740992,Math.round(Math.random()*(Pn-_n))+_n},int:function(_n,Pn){return this.integer(_n,Pn)},float:function(_n,Pn,In,Nn){In=In===void 0?0:In,In=Math.max(Math.min(In,17),0),Nn=Nn===void 0?17:Nn,Nn=Math.max(Math.min(Nn,17),0);for(var Rn=this.integer(_n,Pn)+".",Dn=0,Ln=this.natural(In,Nn);Dn1&&Fn--,6*Fn<1?Hn=Dn+(Ln-Dn)*6*Fn:2*Fn<1?Hn=Ln:3*Fn<2?Hn=Dn+(Ln-Dn)*(2/3-Fn)*6:Hn=Dn,Bn[zn]=Hn*255;return Bn},hsl2hsv:function(Pn){var In=Pn[0],Nn=Pn[1]/100,Rn=Pn[2]/100,Dn,Ln;return Rn*=2,Nn*=Rn<=1?Rn:2-Rn,Ln=(Rn+Nn)/2,Dn=2*Nn/(Rn+Nn),[In,Dn*100,Ln*100]},hsv2rgb:function(Pn){var In=Pn[0]/60,Nn=Pn[1]/100,Rn=Pn[2]/100,Dn=Math.floor(In)%6,Ln=In-Math.floor(In),Fn=255*Rn*(1-Nn),Bn=255*Rn*(1-Nn*Ln),Hn=255*Rn*(1-Nn*(1-Ln));switch(Rn=255*Rn,Dn){case 0:return[Rn,Hn,Fn];case 1:return[Bn,Rn,Fn];case 2:return[Fn,Rn,Hn];case 3:return[Fn,Bn,Rn];case 4:return[Hn,Fn,Rn];case 5:return[Rn,Fn,Bn]}},hsv2hsl:function(Pn){var In=Pn[0],Nn=Pn[1]/100,Rn=Pn[2]/100,Dn,Ln;return Ln=(2-Nn)*Rn,Dn=Nn*Rn,Dn/=Ln<=1?Ln:2-Ln,Ln/=2,[In,Dn*100,Ln*100]},rgb2hex:function(_n,Pn,In){return"#"+((256+_n<<8|Pn)<<8|In).toString(16).slice(1)},hex2rgb:function(_n){return _n="0x"+_n.slice(1).replace(_n.length>4?_n:/./g,"$&$&")|0,[_n>>16,_n>>8&255,_n&255]}}},function($n,Cn){$n.exports={navy:{value:"#000080",nicer:"#001F3F"},blue:{value:"#0000ff",nicer:"#0074D9"},aqua:{value:"#00ffff",nicer:"#7FDBFF"},teal:{value:"#008080",nicer:"#39CCCC"},olive:{value:"#008000",nicer:"#3D9970"},green:{value:"#008000",nicer:"#2ECC40"},lime:{value:"#00ff00",nicer:"#01FF70"},yellow:{value:"#ffff00",nicer:"#FFDC00"},orange:{value:"#ffa500",nicer:"#FF851B"},red:{value:"#ff0000",nicer:"#FF4136"},maroon:{value:"#800000",nicer:"#85144B"},fuchsia:{value:"#ff00ff",nicer:"#F012BE"},purple:{value:"#800080",nicer:"#B10DC9"},silver:{value:"#c0c0c0",nicer:"#DDDDDD"},gray:{value:"#808080",nicer:"#AAAAAA"},black:{value:"#000000",nicer:"#111111"},white:{value:"#FFFFFF",nicer:"#FFFFFF"}}},function($n,Cn,_n){var Pn=_n(6),In=_n(14);function Nn(Rn,Dn,Ln,Fn){return Ln===void 0?Pn.natural(Rn,Dn):Fn===void 0?Ln:Pn.natural(parseInt(Ln,10),parseInt(Fn,10))}$n.exports={paragraph:function(Rn,Dn){for(var Ln=Nn(3,7,Rn,Dn),Fn=[],Bn=0;Bn1&&(Nn=[].slice.call(arguments,0));var Rn=In.options,Dn=Rn.context.templatePath.join("."),Ln=In.cache[Dn]=In.cache[Dn]||{index:0,array:Nn};return Ln.array[Ln.index++%Ln.array.length]}}},function($n,Cn){$n.exports={first:function(){var _n=["James","John","Robert","Michael","William","David","Richard","Charles","Joseph","Thomas","Christopher","Daniel","Paul","Mark","Donald","George","Kenneth","Steven","Edward","Brian","Ronald","Anthony","Kevin","Jason","Matthew","Gary","Timothy","Jose","Larry","Jeffrey","Frank","Scott","Eric"].concat(["Mary","Patricia","Linda","Barbara","Elizabeth","Jennifer","Maria","Susan","Margaret","Dorothy","Lisa","Nancy","Karen","Betty","Helen","Sandra","Donna","Carol","Ruth","Sharon","Michelle","Laura","Sarah","Kimberly","Deborah","Jessica","Shirley","Cynthia","Angela","Melissa","Brenda","Amy","Anna"]);return this.pick(_n)},last:function(){var _n=["Smith","Johnson","Williams","Brown","Jones","Miller","Davis","Garcia","Rodriguez","Wilson","Martinez","Anderson","Taylor","Thomas","Hernandez","Moore","Martin","Jackson","Thompson","White","Lopez","Lee","Gonzalez","Harris","Clark","Lewis","Robinson","Walker","Perez","Hall","Young","Allen"];return this.pick(_n)},name:function(_n){return this.first()+" "+(_n?this.first()+" ":"")+this.last()},cfirst:function(){var _n="王 李 张 刘 陈 杨 赵 黄 周 吴 徐 孙 胡 朱 高 林 何 郭 马 罗 梁 宋 郑 谢 韩 唐 冯 于 董 萧 程 曹 袁 邓 许 傅 沈 曾 彭 吕 苏 卢 蒋 蔡 贾 丁 魏 薛 叶 阎 余 潘 杜 戴 夏 锺 汪 田 任 姜 范 方 石 姚 谭 廖 邹 熊 金 陆 郝 孔 白 崔 康 毛 邱 秦 江 史 顾 侯 邵 孟 龙 万 段 雷 钱 汤 尹 黎 易 常 武 乔 贺 赖 龚 文".split(" ");return this.pick(_n)},clast:function(){var _n="伟 芳 娜 秀英 敏 静 丽 强 磊 军 洋 勇 艳 杰 娟 涛 明 超 秀兰 霞 平 刚 桂英".split(" ");return this.pick(_n)},cname:function(){return this.cfirst()+this.clast()}}},function($n,Cn){$n.exports={url:function(_n,Pn){return(_n||this.protocol())+"://"+(Pn||this.domain())+"/"+this.word()},protocol:function(){return this.pick("http ftp gopher mailto mid cid news nntp prospero telnet rlogin tn3270 wais".split(" "))},domain:function(_n){return this.word()+"."+(_n||this.tld())},tld:function(){return this.pick("com net org edu gov int mil cn com.cn net.cn gov.cn org.cn 中国 中国互联.公司 中国互联.网络 tel biz cc tv info name hk mobi asia cd travel pro museum coop aero ad ae af ag ai al am an ao aq ar as at au aw az ba bb bd be bf bg bh bi bj bm bn bo br bs bt bv bw by bz ca cc cf cg ch ci ck cl cm cn co cq cr cu cv cx cy cz de dj dk dm do dz ec ee eg eh es et ev fi fj fk fm fo fr ga gb gd ge gf gh gi gl gm gn gp gr gt gu gw gy hk hm hn hr ht hu id ie il in io iq ir is it jm jo jp ke kg kh ki km kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly ma mc md mg mh ml mm mn mo mp mq mr ms mt mv mw mx my mz na nc ne nf ng ni nl no np nr nt nu nz om qa pa pe pf pg ph pk pl pm pn pr pt pw py re ro ru rw sa sb sc sd se sg sh si sj sk sl sm sn so sr st su sy sz tc td tf tg th tj tk tm tn to tp tr tt tv tw tz ua ug uk us uy va vc ve vg vn vu wf ws ye yu za zm zr zw".split(" "))},email:function(_n){return this.character("lower")+"."+this.word()+"@"+(_n||this.word()+"."+this.tld())},ip:function(){return this.natural(0,255)+"."+this.natural(0,255)+"."+this.natural(0,255)+"."+this.natural(0,255)}}},function($n,Cn,_n){var Pn=_n(18),In=["东北","华北","华东","华中","华南","西南","西北"];$n.exports={region:function(){return this.pick(In)},province:function(){return this.pick(Pn).name},city:function(Nn){var Rn=this.pick(Pn),Dn=this.pick(Rn.children);return Nn?[Rn.name,Dn.name].join(" "):Dn.name},county:function(Nn){var Rn=this.pick(Pn),Dn=this.pick(Rn.children),Ln=this.pick(Dn.children)||{name:"-"};return Nn?[Rn.name,Dn.name,Ln.name].join(" "):Ln.name},zip:function(Nn){for(var Rn="",Dn=0;Dn<(Nn||6);Dn++)Rn+=this.natural(0,9);return Rn}}},function($n,Cn){var _n={11e4:"北京",110100:"北京市",110101:"东城区",110102:"西城区",110105:"朝阳区",110106:"丰台区",110107:"石景山区",110108:"海淀区",110109:"门头沟区",110111:"房山区",110112:"通州区",110113:"顺义区",110114:"昌平区",110115:"大兴区",110116:"怀柔区",110117:"平谷区",110228:"密云县",110229:"延庆县",110230:"其它区",12e4:"天津",120100:"天津市",120101:"和平区",120102:"河东区",120103:"河西区",120104:"南开区",120105:"河北区",120106:"红桥区",120110:"东丽区",120111:"西青区",120112:"津南区",120113:"北辰区",120114:"武清区",120115:"宝坻区",120116:"滨海新区",120221:"宁河县",120223:"静海县",120225:"蓟县",120226:"其它区",13e4:"河北省",130100:"石家庄市",130102:"长安区",130103:"桥东区",130104:"桥西区",130105:"新华区",130107:"井陉矿区",130108:"裕华区",130121:"井陉县",130123:"正定县",130124:"栾城县",130125:"行唐县",130126:"灵寿县",130127:"高邑县",130128:"深泽县",130129:"赞皇县",130130:"无极县",130131:"平山县",130132:"元氏县",130133:"赵县",130181:"辛集市",130182:"藁城市",130183:"晋州市",130184:"新乐市",130185:"鹿泉市",130186:"其它区",130200:"唐山市",130202:"路南区",130203:"路北区",130204:"古冶区",130205:"开平区",130207:"丰南区",130208:"丰润区",130223:"滦县",130224:"滦南县",130225:"乐亭县",130227:"迁西县",130229:"玉田县",130230:"曹妃甸区",130281:"遵化市",130283:"迁安市",130284:"其它区",130300:"秦皇岛市",130302:"海港区",130303:"山海关区",130304:"北戴河区",130321:"青龙满族自治县",130322:"昌黎县",130323:"抚宁县",130324:"卢龙县",130398:"其它区",130400:"邯郸市",130402:"邯山区",130403:"丛台区",130404:"复兴区",130406:"峰峰矿区",130421:"邯郸县",130423:"临漳县",130424:"成安县",130425:"大名县",130426:"涉县",130427:"磁县",130428:"肥乡县",130429:"永年县",130430:"邱县",130431:"鸡泽县",130432:"广平县",130433:"馆陶县",130434:"魏县",130435:"曲周县",130481:"武安市",130482:"其它区",130500:"邢台市",130502:"桥东区",130503:"桥西区",130521:"邢台县",130522:"临城县",130523:"内丘县",130524:"柏乡县",130525:"隆尧县",130526:"任县",130527:"南和县",130528:"宁晋县",130529:"巨鹿县",130530:"新河县",130531:"广宗县",130532:"平乡县",130533:"威县",130534:"清河县",130535:"临西县",130581:"南宫市",130582:"沙河市",130583:"其它区",130600:"保定市",130602:"新市区",130603:"北市区",130604:"南市区",130621:"满城县",130622:"清苑县",130623:"涞水县",130624:"阜平县",130625:"徐水县",130626:"定兴县",130627:"唐县",130628:"高阳县",130629:"容城县",130630:"涞源县",130631:"望都县",130632:"安新县",130633:"易县",130634:"曲阳县",130635:"蠡县",130636:"顺平县",130637:"博野县",130638:"雄县",130681:"涿州市",130682:"定州市",130683:"安国市",130684:"高碑店市",130699:"其它区",130700:"张家口市",130702:"桥东区",130703:"桥西区",130705:"宣化区",130706:"下花园区",130721:"宣化县",130722:"张北县",130723:"康保县",130724:"沽源县",130725:"尚义县",130726:"蔚县",130727:"阳原县",130728:"怀安县",130729:"万全县",130730:"怀来县",130731:"涿鹿县",130732:"赤城县",130733:"崇礼县",130734:"其它区",130800:"承德市",130802:"双桥区",130803:"双滦区",130804:"鹰手营子矿区",130821:"承德县",130822:"兴隆县",130823:"平泉县",130824:"滦平县",130825:"隆化县",130826:"丰宁满族自治县",130827:"宽城满族自治县",130828:"围场满族蒙古族自治县",130829:"其它区",130900:"沧州市",130902:"新华区",130903:"运河区",130921:"沧县",130922:"青县",130923:"东光县",130924:"海兴县",130925:"盐山县",130926:"肃宁县",130927:"南皮县",130928:"吴桥县",130929:"献县",130930:"孟村回族自治县",130981:"泊头市",130982:"任丘市",130983:"黄骅市",130984:"河间市",130985:"其它区",131e3:"廊坊市",131002:"安次区",131003:"广阳区",131022:"固安县",131023:"永清县",131024:"香河县",131025:"大城县",131026:"文安县",131028:"大厂回族自治县",131081:"霸州市",131082:"三河市",131083:"其它区",131100:"衡水市",131102:"桃城区",131121:"枣强县",131122:"武邑县",131123:"武强县",131124:"饶阳县",131125:"安平县",131126:"故城县",131127:"景县",131128:"阜城县",131181:"冀州市",131182:"深州市",131183:"其它区",14e4:"山西省",140100:"太原市",140105:"小店区",140106:"迎泽区",140107:"杏花岭区",140108:"尖草坪区",140109:"万柏林区",140110:"晋源区",140121:"清徐县",140122:"阳曲县",140123:"娄烦县",140181:"古交市",140182:"其它区",140200:"大同市",140202:"城区",140203:"矿区",140211:"南郊区",140212:"新荣区",140221:"阳高县",140222:"天镇县",140223:"广灵县",140224:"灵丘县",140225:"浑源县",140226:"左云县",140227:"大同县",140228:"其它区",140300:"阳泉市",140302:"城区",140303:"矿区",140311:"郊区",140321:"平定县",140322:"盂县",140323:"其它区",140400:"长治市",140421:"长治县",140423:"襄垣县",140424:"屯留县",140425:"平顺县",140426:"黎城县",140427:"壶关县",140428:"长子县",140429:"武乡县",140430:"沁县",140431:"沁源县",140481:"潞城市",140482:"城区",140483:"郊区",140485:"其它区",140500:"晋城市",140502:"城区",140521:"沁水县",140522:"阳城县",140524:"陵川县",140525:"泽州县",140581:"高平市",140582:"其它区",140600:"朔州市",140602:"朔城区",140603:"平鲁区",140621:"山阴县",140622:"应县",140623:"右玉县",140624:"怀仁县",140625:"其它区",140700:"晋中市",140702:"榆次区",140721:"榆社县",140722:"左权县",140723:"和顺县",140724:"昔阳县",140725:"寿阳县",140726:"太谷县",140727:"祁县",140728:"平遥县",140729:"灵石县",140781:"介休市",140782:"其它区",140800:"运城市",140802:"盐湖区",140821:"临猗县",140822:"万荣县",140823:"闻喜县",140824:"稷山县",140825:"新绛县",140826:"绛县",140827:"垣曲县",140828:"夏县",140829:"平陆县",140830:"芮城县",140881:"永济市",140882:"河津市",140883:"其它区",140900:"忻州市",140902:"忻府区",140921:"定襄县",140922:"五台县",140923:"代县",140924:"繁峙县",140925:"宁武县",140926:"静乐县",140927:"神池县",140928:"五寨县",140929:"岢岚县",140930:"河曲县",140931:"保德县",140932:"偏关县",140981:"原平市",140982:"其它区",141e3:"临汾市",141002:"尧都区",141021:"曲沃县",141022:"翼城县",141023:"襄汾县",141024:"洪洞县",141025:"古县",141026:"安泽县",141027:"浮山县",141028:"吉县",141029:"乡宁县",141030:"大宁县",141031:"隰县",141032:"永和县",141033:"蒲县",141034:"汾西县",141081:"侯马市",141082:"霍州市",141083:"其它区",141100:"吕梁市",141102:"离石区",141121:"文水县",141122:"交城县",141123:"兴县",141124:"临县",141125:"柳林县",141126:"石楼县",141127:"岚县",141128:"方山县",141129:"中阳县",141130:"交口县",141181:"孝义市",141182:"汾阳市",141183:"其它区",15e4:"内蒙古自治区",150100:"呼和浩特市",150102:"新城区",150103:"回民区",150104:"玉泉区",150105:"赛罕区",150121:"土默特左旗",150122:"托克托县",150123:"和林格尔县",150124:"清水河县",150125:"武川县",150126:"其它区",150200:"包头市",150202:"东河区",150203:"昆都仑区",150204:"青山区",150205:"石拐区",150206:"白云鄂博矿区",150207:"九原区",150221:"土默特右旗",150222:"固阳县",150223:"达尔罕茂明安联合旗",150224:"其它区",150300:"乌海市",150302:"海勃湾区",150303:"海南区",150304:"乌达区",150305:"其它区",150400:"赤峰市",150402:"红山区",150403:"元宝山区",150404:"松山区",150421:"阿鲁科尔沁旗",150422:"巴林左旗",150423:"巴林右旗",150424:"林西县",150425:"克什克腾旗",150426:"翁牛特旗",150428:"喀喇沁旗",150429:"宁城县",150430:"敖汉旗",150431:"其它区",150500:"通辽市",150502:"科尔沁区",150521:"科尔沁左翼中旗",150522:"科尔沁左翼后旗",150523:"开鲁县",150524:"库伦旗",150525:"奈曼旗",150526:"扎鲁特旗",150581:"霍林郭勒市",150582:"其它区",150600:"鄂尔多斯市",150602:"东胜区",150621:"达拉特旗",150622:"准格尔旗",150623:"鄂托克前旗",150624:"鄂托克旗",150625:"杭锦旗",150626:"乌审旗",150627:"伊金霍洛旗",150628:"其它区",150700:"呼伦贝尔市",150702:"海拉尔区",150703:"扎赉诺尔区",150721:"阿荣旗",150722:"莫力达瓦达斡尔族自治旗",150723:"鄂伦春自治旗",150724:"鄂温克族自治旗",150725:"陈巴尔虎旗",150726:"新巴尔虎左旗",150727:"新巴尔虎右旗",150781:"满洲里市",150782:"牙克石市",150783:"扎兰屯市",150784:"额尔古纳市",150785:"根河市",150786:"其它区",150800:"巴彦淖尔市",150802:"临河区",150821:"五原县",150822:"磴口县",150823:"乌拉特前旗",150824:"乌拉特中旗",150825:"乌拉特后旗",150826:"杭锦后旗",150827:"其它区",150900:"乌兰察布市",150902:"集宁区",150921:"卓资县",150922:"化德县",150923:"商都县",150924:"兴和县",150925:"凉城县",150926:"察哈尔右翼前旗",150927:"察哈尔右翼中旗",150928:"察哈尔右翼后旗",150929:"四子王旗",150981:"丰镇市",150982:"其它区",152200:"兴安盟",152201:"乌兰浩特市",152202:"阿尔山市",152221:"科尔沁右翼前旗",152222:"科尔沁右翼中旗",152223:"扎赉特旗",152224:"突泉县",152225:"其它区",152500:"锡林郭勒盟",152501:"二连浩特市",152502:"锡林浩特市",152522:"阿巴嘎旗",152523:"苏尼特左旗",152524:"苏尼特右旗",152525:"东乌珠穆沁旗",152526:"西乌珠穆沁旗",152527:"太仆寺旗",152528:"镶黄旗",152529:"正镶白旗",152530:"正蓝旗",152531:"多伦县",152532:"其它区",152900:"阿拉善盟",152921:"阿拉善左旗",152922:"阿拉善右旗",152923:"额济纳旗",152924:"其它区",21e4:"辽宁省",210100:"沈阳市",210102:"和平区",210103:"沈河区",210104:"大东区",210105:"皇姑区",210106:"铁西区",210111:"苏家屯区",210112:"东陵区",210113:"新城子区",210114:"于洪区",210122:"辽中县",210123:"康平县",210124:"法库县",210181:"新民市",210184:"沈北新区",210185:"其它区",210200:"大连市",210202:"中山区",210203:"西岗区",210204:"沙河口区",210211:"甘井子区",210212:"旅顺口区",210213:"金州区",210224:"长海县",210281:"瓦房店市",210282:"普兰店市",210283:"庄河市",210298:"其它区",210300:"鞍山市",210302:"铁东区",210303:"铁西区",210304:"立山区",210311:"千山区",210321:"台安县",210323:"岫岩满族自治县",210381:"海城市",210382:"其它区",210400:"抚顺市",210402:"新抚区",210403:"东洲区",210404:"望花区",210411:"顺城区",210421:"抚顺县",210422:"新宾满族自治县",210423:"清原满族自治县",210424:"其它区",210500:"本溪市",210502:"平山区",210503:"溪湖区",210504:"明山区",210505:"南芬区",210521:"本溪满族自治县",210522:"桓仁满族自治县",210523:"其它区",210600:"丹东市",210602:"元宝区",210603:"振兴区",210604:"振安区",210624:"宽甸满族自治县",210681:"东港市",210682:"凤城市",210683:"其它区",210700:"锦州市",210702:"古塔区",210703:"凌河区",210711:"太和区",210726:"黑山县",210727:"义县",210781:"凌海市",210782:"北镇市",210783:"其它区",210800:"营口市",210802:"站前区",210803:"西市区",210804:"鲅鱼圈区",210811:"老边区",210881:"盖州市",210882:"大石桥市",210883:"其它区",210900:"阜新市",210902:"海州区",210903:"新邱区",210904:"太平区",210905:"清河门区",210911:"细河区",210921:"阜新蒙古族自治县",210922:"彰武县",210923:"其它区",211e3:"辽阳市",211002:"白塔区",211003:"文圣区",211004:"宏伟区",211005:"弓长岭区",211011:"太子河区",211021:"辽阳县",211081:"灯塔市",211082:"其它区",211100:"盘锦市",211102:"双台子区",211103:"兴隆台区",211121:"大洼县",211122:"盘山县",211123:"其它区",211200:"铁岭市",211202:"银州区",211204:"清河区",211221:"铁岭县",211223:"西丰县",211224:"昌图县",211281:"调兵山市",211282:"开原市",211283:"其它区",211300:"朝阳市",211302:"双塔区",211303:"龙城区",211321:"朝阳县",211322:"建平县",211324:"喀喇沁左翼蒙古族自治县",211381:"北票市",211382:"凌源市",211383:"其它区",211400:"葫芦岛市",211402:"连山区",211403:"龙港区",211404:"南票区",211421:"绥中县",211422:"建昌县",211481:"兴城市",211482:"其它区",22e4:"吉林省",220100:"长春市",220102:"南关区",220103:"宽城区",220104:"朝阳区",220105:"二道区",220106:"绿园区",220112:"双阳区",220122:"农安县",220181:"九台市",220182:"榆树市",220183:"德惠市",220188:"其它区",220200:"吉林市",220202:"昌邑区",220203:"龙潭区",220204:"船营区",220211:"丰满区",220221:"永吉县",220281:"蛟河市",220282:"桦甸市",220283:"舒兰市",220284:"磐石市",220285:"其它区",220300:"四平市",220302:"铁西区",220303:"铁东区",220322:"梨树县",220323:"伊通满族自治县",220381:"公主岭市",220382:"双辽市",220383:"其它区",220400:"辽源市",220402:"龙山区",220403:"西安区",220421:"东丰县",220422:"东辽县",220423:"其它区",220500:"通化市",220502:"东昌区",220503:"二道江区",220521:"通化县",220523:"辉南县",220524:"柳河县",220581:"梅河口市",220582:"集安市",220583:"其它区",220600:"白山市",220602:"浑江区",220621:"抚松县",220622:"靖宇县",220623:"长白朝鲜族自治县",220625:"江源区",220681:"临江市",220682:"其它区",220700:"松原市",220702:"宁江区",220721:"前郭尔罗斯蒙古族自治县",220722:"长岭县",220723:"乾安县",220724:"扶余市",220725:"其它区",220800:"白城市",220802:"洮北区",220821:"镇赉县",220822:"通榆县",220881:"洮南市",220882:"大安市",220883:"其它区",222400:"延边朝鲜族自治州",222401:"延吉市",222402:"图们市",222403:"敦化市",222404:"珲春市",222405:"龙井市",222406:"和龙市",222424:"汪清县",222426:"安图县",222427:"其它区",23e4:"黑龙江省",230100:"哈尔滨市",230102:"道里区",230103:"南岗区",230104:"道外区",230106:"香坊区",230108:"平房区",230109:"松北区",230111:"呼兰区",230123:"依兰县",230124:"方正县",230125:"宾县",230126:"巴彦县",230127:"木兰县",230128:"通河县",230129:"延寿县",230181:"阿城区",230182:"双城市",230183:"尚志市",230184:"五常市",230186:"其它区",230200:"齐齐哈尔市",230202:"龙沙区",230203:"建华区",230204:"铁锋区",230205:"昂昂溪区",230206:"富拉尔基区",230207:"碾子山区",230208:"梅里斯达斡尔族区",230221:"龙江县",230223:"依安县",230224:"泰来县",230225:"甘南县",230227:"富裕县",230229:"克山县",230230:"克东县",230231:"拜泉县",230281:"讷河市",230282:"其它区",230300:"鸡西市",230302:"鸡冠区",230303:"恒山区",230304:"滴道区",230305:"梨树区",230306:"城子河区",230307:"麻山区",230321:"鸡东县",230381:"虎林市",230382:"密山市",230383:"其它区",230400:"鹤岗市",230402:"向阳区",230403:"工农区",230404:"南山区",230405:"兴安区",230406:"东山区",230407:"兴山区",230421:"萝北县",230422:"绥滨县",230423:"其它区",230500:"双鸭山市",230502:"尖山区",230503:"岭东区",230505:"四方台区",230506:"宝山区",230521:"集贤县",230522:"友谊县",230523:"宝清县",230524:"饶河县",230525:"其它区",230600:"大庆市",230602:"萨尔图区",230603:"龙凤区",230604:"让胡路区",230605:"红岗区",230606:"大同区",230621:"肇州县",230622:"肇源县",230623:"林甸县",230624:"杜尔伯特蒙古族自治县",230625:"其它区",230700:"伊春市",230702:"伊春区",230703:"南岔区",230704:"友好区",230705:"西林区",230706:"翠峦区",230707:"新青区",230708:"美溪区",230709:"金山屯区",230710:"五营区",230711:"乌马河区",230712:"汤旺河区",230713:"带岭区",230714:"乌伊岭区",230715:"红星区",230716:"上甘岭区",230722:"嘉荫县",230781:"铁力市",230782:"其它区",230800:"佳木斯市",230803:"向阳区",230804:"前进区",230805:"东风区",230811:"郊区",230822:"桦南县",230826:"桦川县",230828:"汤原县",230833:"抚远县",230881:"同江市",230882:"富锦市",230883:"其它区",230900:"七台河市",230902:"新兴区",230903:"桃山区",230904:"茄子河区",230921:"勃利县",230922:"其它区",231e3:"牡丹江市",231002:"东安区",231003:"阳明区",231004:"爱民区",231005:"西安区",231024:"东宁县",231025:"林口县",231081:"绥芬河市",231083:"海林市",231084:"宁安市",231085:"穆棱市",231086:"其它区",231100:"黑河市",231102:"爱辉区",231121:"嫩江县",231123:"逊克县",231124:"孙吴县",231181:"北安市",231182:"五大连池市",231183:"其它区",231200:"绥化市",231202:"北林区",231221:"望奎县",231222:"兰西县",231223:"青冈县",231224:"庆安县",231225:"明水县",231226:"绥棱县",231281:"安达市",231282:"肇东市",231283:"海伦市",231284:"其它区",232700:"大兴安岭地区",232702:"松岭区",232703:"新林区",232704:"呼中区",232721:"呼玛县",232722:"塔河县",232723:"漠河县",232724:"加格达奇区",232725:"其它区",31e4:"上海",310100:"上海市",310101:"黄浦区",310104:"徐汇区",310105:"长宁区",310106:"静安区",310107:"普陀区",310108:"闸北区",310109:"虹口区",310110:"杨浦区",310112:"闵行区",310113:"宝山区",310114:"嘉定区",310115:"浦东新区",310116:"金山区",310117:"松江区",310118:"青浦区",310120:"奉贤区",310230:"崇明县",310231:"其它区",32e4:"江苏省",320100:"南京市",320102:"玄武区",320104:"秦淮区",320105:"建邺区",320106:"鼓楼区",320111:"浦口区",320113:"栖霞区",320114:"雨花台区",320115:"江宁区",320116:"六合区",320124:"溧水区",320125:"高淳区",320126:"其它区",320200:"无锡市",320202:"崇安区",320203:"南长区",320204:"北塘区",320205:"锡山区",320206:"惠山区",320211:"滨湖区",320281:"江阴市",320282:"宜兴市",320297:"其它区",320300:"徐州市",320302:"鼓楼区",320303:"云龙区",320305:"贾汪区",320311:"泉山区",320321:"丰县",320322:"沛县",320323:"铜山区",320324:"睢宁县",320381:"新沂市",320382:"邳州市",320383:"其它区",320400:"常州市",320402:"天宁区",320404:"钟楼区",320405:"戚墅堰区",320411:"新北区",320412:"武进区",320481:"溧阳市",320482:"金坛市",320483:"其它区",320500:"苏州市",320505:"虎丘区",320506:"吴中区",320507:"相城区",320508:"姑苏区",320581:"常熟市",320582:"张家港市",320583:"昆山市",320584:"吴江区",320585:"太仓市",320596:"其它区",320600:"南通市",320602:"崇川区",320611:"港闸区",320612:"通州区",320621:"海安县",320623:"如东县",320681:"启东市",320682:"如皋市",320684:"海门市",320694:"其它区",320700:"连云港市",320703:"连云区",320705:"新浦区",320706:"海州区",320721:"赣榆县",320722:"东海县",320723:"灌云县",320724:"灌南县",320725:"其它区",320800:"淮安市",320802:"清河区",320803:"淮安区",320804:"淮阴区",320811:"清浦区",320826:"涟水县",320829:"洪泽县",320830:"盱眙县",320831:"金湖县",320832:"其它区",320900:"盐城市",320902:"亭湖区",320903:"盐都区",320921:"响水县",320922:"滨海县",320923:"阜宁县",320924:"射阳县",320925:"建湖县",320981:"东台市",320982:"大丰市",320983:"其它区",321e3:"扬州市",321002:"广陵区",321003:"邗江区",321023:"宝应县",321081:"仪征市",321084:"高邮市",321088:"江都区",321093:"其它区",321100:"镇江市",321102:"京口区",321111:"润州区",321112:"丹徒区",321181:"丹阳市",321182:"扬中市",321183:"句容市",321184:"其它区",321200:"泰州市",321202:"海陵区",321203:"高港区",321281:"兴化市",321282:"靖江市",321283:"泰兴市",321284:"姜堰区",321285:"其它区",321300:"宿迁市",321302:"宿城区",321311:"宿豫区",321322:"沭阳县",321323:"泗阳县",321324:"泗洪县",321325:"其它区",33e4:"浙江省",330100:"杭州市",330102:"上城区",330103:"下城区",330104:"江干区",330105:"拱墅区",330106:"西湖区",330108:"滨江区",330109:"萧山区",330110:"余杭区",330122:"桐庐县",330127:"淳安县",330182:"建德市",330183:"富阳市",330185:"临安市",330186:"其它区",330200:"宁波市",330203:"海曙区",330204:"江东区",330205:"江北区",330206:"北仑区",330211:"镇海区",330212:"鄞州区",330225:"象山县",330226:"宁海县",330281:"余姚市",330282:"慈溪市",330283:"奉化市",330284:"其它区",330300:"温州市",330302:"鹿城区",330303:"龙湾区",330304:"瓯海区",330322:"洞头县",330324:"永嘉县",330326:"平阳县",330327:"苍南县",330328:"文成县",330329:"泰顺县",330381:"瑞安市",330382:"乐清市",330383:"其它区",330400:"嘉兴市",330402:"南湖区",330411:"秀洲区",330421:"嘉善县",330424:"海盐县",330481:"海宁市",330482:"平湖市",330483:"桐乡市",330484:"其它区",330500:"湖州市",330502:"吴兴区",330503:"南浔区",330521:"德清县",330522:"长兴县",330523:"安吉县",330524:"其它区",330600:"绍兴市",330602:"越城区",330621:"绍兴县",330624:"新昌县",330681:"诸暨市",330682:"上虞市",330683:"嵊州市",330684:"其它区",330700:"金华市",330702:"婺城区",330703:"金东区",330723:"武义县",330726:"浦江县",330727:"磐安县",330781:"兰溪市",330782:"义乌市",330783:"东阳市",330784:"永康市",330785:"其它区",330800:"衢州市",330802:"柯城区",330803:"衢江区",330822:"常山县",330824:"开化县",330825:"龙游县",330881:"江山市",330882:"其它区",330900:"舟山市",330902:"定海区",330903:"普陀区",330921:"岱山县",330922:"嵊泗县",330923:"其它区",331e3:"台州市",331002:"椒江区",331003:"黄岩区",331004:"路桥区",331021:"玉环县",331022:"三门县",331023:"天台县",331024:"仙居县",331081:"温岭市",331082:"临海市",331083:"其它区",331100:"丽水市",331102:"莲都区",331121:"青田县",331122:"缙云县",331123:"遂昌县",331124:"松阳县",331125:"云和县",331126:"庆元县",331127:"景宁畲族自治县",331181:"龙泉市",331182:"其它区",34e4:"安徽省",340100:"合肥市",340102:"瑶海区",340103:"庐阳区",340104:"蜀山区",340111:"包河区",340121:"长丰县",340122:"肥东县",340123:"肥西县",340192:"其它区",340200:"芜湖市",340202:"镜湖区",340203:"弋江区",340207:"鸠江区",340208:"三山区",340221:"芜湖县",340222:"繁昌县",340223:"南陵县",340224:"其它区",340300:"蚌埠市",340302:"龙子湖区",340303:"蚌山区",340304:"禹会区",340311:"淮上区",340321:"怀远县",340322:"五河县",340323:"固镇县",340324:"其它区",340400:"淮南市",340402:"大通区",340403:"田家庵区",340404:"谢家集区",340405:"八公山区",340406:"潘集区",340421:"凤台县",340422:"其它区",340500:"马鞍山市",340503:"花山区",340504:"雨山区",340506:"博望区",340521:"当涂县",340522:"其它区",340600:"淮北市",340602:"杜集区",340603:"相山区",340604:"烈山区",340621:"濉溪县",340622:"其它区",340700:"铜陵市",340702:"铜官山区",340703:"狮子山区",340711:"郊区",340721:"铜陵县",340722:"其它区",340800:"安庆市",340802:"迎江区",340803:"大观区",340811:"宜秀区",340822:"怀宁县",340823:"枞阳县",340824:"潜山县",340825:"太湖县",340826:"宿松县",340827:"望江县",340828:"岳西县",340881:"桐城市",340882:"其它区",341e3:"黄山市",341002:"屯溪区",341003:"黄山区",341004:"徽州区",341021:"歙县",341022:"休宁县",341023:"黟县",341024:"祁门县",341025:"其它区",341100:"滁州市",341102:"琅琊区",341103:"南谯区",341122:"来安县",341124:"全椒县",341125:"定远县",341126:"凤阳县",341181:"天长市",341182:"明光市",341183:"其它区",341200:"阜阳市",341202:"颍州区",341203:"颍东区",341204:"颍泉区",341221:"临泉县",341222:"太和县",341225:"阜南县",341226:"颍上县",341282:"界首市",341283:"其它区",341300:"宿州市",341302:"埇桥区",341321:"砀山县",341322:"萧县",341323:"灵璧县",341324:"泗县",341325:"其它区",341400:"巢湖市",341421:"庐江县",341422:"无为县",341423:"含山县",341424:"和县",341500:"六安市",341502:"金安区",341503:"裕安区",341521:"寿县",341522:"霍邱县",341523:"舒城县",341524:"金寨县",341525:"霍山县",341526:"其它区",341600:"亳州市",341602:"谯城区",341621:"涡阳县",341622:"蒙城县",341623:"利辛县",341624:"其它区",341700:"池州市",341702:"贵池区",341721:"东至县",341722:"石台县",341723:"青阳县",341724:"其它区",341800:"宣城市",341802:"宣州区",341821:"郎溪县",341822:"广德县",341823:"泾县",341824:"绩溪县",341825:"旌德县",341881:"宁国市",341882:"其它区",35e4:"福建省",350100:"福州市",350102:"鼓楼区",350103:"台江区",350104:"仓山区",350105:"马尾区",350111:"晋安区",350121:"闽侯县",350122:"连江县",350123:"罗源县",350124:"闽清县",350125:"永泰县",350128:"平潭县",350181:"福清市",350182:"长乐市",350183:"其它区",350200:"厦门市",350203:"思明区",350205:"海沧区",350206:"湖里区",350211:"集美区",350212:"同安区",350213:"翔安区",350214:"其它区",350300:"莆田市",350302:"城厢区",350303:"涵江区",350304:"荔城区",350305:"秀屿区",350322:"仙游县",350323:"其它区",350400:"三明市",350402:"梅列区",350403:"三元区",350421:"明溪县",350423:"清流县",350424:"宁化县",350425:"大田县",350426:"尤溪县",350427:"沙县",350428:"将乐县",350429:"泰宁县",350430:"建宁县",350481:"永安市",350482:"其它区",350500:"泉州市",350502:"鲤城区",350503:"丰泽区",350504:"洛江区",350505:"泉港区",350521:"惠安县",350524:"安溪县",350525:"永春县",350526:"德化县",350527:"金门县",350581:"石狮市",350582:"晋江市",350583:"南安市",350584:"其它区",350600:"漳州市",350602:"芗城区",350603:"龙文区",350622:"云霄县",350623:"漳浦县",350624:"诏安县",350625:"长泰县",350626:"东山县",350627:"南靖县",350628:"平和县",350629:"华安县",350681:"龙海市",350682:"其它区",350700:"南平市",350702:"延平区",350721:"顺昌县",350722:"浦城县",350723:"光泽县",350724:"松溪县",350725:"政和县",350781:"邵武市",350782:"武夷山市",350783:"建瓯市",350784:"建阳市",350785:"其它区",350800:"龙岩市",350802:"新罗区",350821:"长汀县",350822:"永定县",350823:"上杭县",350824:"武平县",350825:"连城县",350881:"漳平市",350882:"其它区",350900:"宁德市",350902:"蕉城区",350921:"霞浦县",350922:"古田县",350923:"屏南县",350924:"寿宁县",350925:"周宁县",350926:"柘荣县",350981:"福安市",350982:"福鼎市",350983:"其它区",36e4:"江西省",360100:"南昌市",360102:"东湖区",360103:"西湖区",360104:"青云谱区",360105:"湾里区",360111:"青山湖区",360121:"南昌县",360122:"新建县",360123:"安义县",360124:"进贤县",360128:"其它区",360200:"景德镇市",360202:"昌江区",360203:"珠山区",360222:"浮梁县",360281:"乐平市",360282:"其它区",360300:"萍乡市",360302:"安源区",360313:"湘东区",360321:"莲花县",360322:"上栗县",360323:"芦溪县",360324:"其它区",360400:"九江市",360402:"庐山区",360403:"浔阳区",360421:"九江县",360423:"武宁县",360424:"修水县",360425:"永修县",360426:"德安县",360427:"星子县",360428:"都昌县",360429:"湖口县",360430:"彭泽县",360481:"瑞昌市",360482:"其它区",360483:"共青城市",360500:"新余市",360502:"渝水区",360521:"分宜县",360522:"其它区",360600:"鹰潭市",360602:"月湖区",360622:"余江县",360681:"贵溪市",360682:"其它区",360700:"赣州市",360702:"章贡区",360721:"赣县",360722:"信丰县",360723:"大余县",360724:"上犹县",360725:"崇义县",360726:"安远县",360727:"龙南县",360728:"定南县",360729:"全南县",360730:"宁都县",360731:"于都县",360732:"兴国县",360733:"会昌县",360734:"寻乌县",360735:"石城县",360781:"瑞金市",360782:"南康市",360783:"其它区",360800:"吉安市",360802:"吉州区",360803:"青原区",360821:"吉安县",360822:"吉水县",360823:"峡江县",360824:"新干县",360825:"永丰县",360826:"泰和县",360827:"遂川县",360828:"万安县",360829:"安福县",360830:"永新县",360881:"井冈山市",360882:"其它区",360900:"宜春市",360902:"袁州区",360921:"奉新县",360922:"万载县",360923:"上高县",360924:"宜丰县",360925:"靖安县",360926:"铜鼓县",360981:"丰城市",360982:"樟树市",360983:"高安市",360984:"其它区",361e3:"抚州市",361002:"临川区",361021:"南城县",361022:"黎川县",361023:"南丰县",361024:"崇仁县",361025:"乐安县",361026:"宜黄县",361027:"金溪县",361028:"资溪县",361029:"东乡县",361030:"广昌县",361031:"其它区",361100:"上饶市",361102:"信州区",361121:"上饶县",361122:"广丰县",361123:"玉山县",361124:"铅山县",361125:"横峰县",361126:"弋阳县",361127:"余干县",361128:"鄱阳县",361129:"万年县",361130:"婺源县",361181:"德兴市",361182:"其它区",37e4:"山东省",370100:"济南市",370102:"历下区",370103:"市中区",370104:"槐荫区",370105:"天桥区",370112:"历城区",370113:"长清区",370124:"平阴县",370125:"济阳县",370126:"商河县",370181:"章丘市",370182:"其它区",370200:"青岛市",370202:"市南区",370203:"市北区",370211:"黄岛区",370212:"崂山区",370213:"李沧区",370214:"城阳区",370281:"胶州市",370282:"即墨市",370283:"平度市",370285:"莱西市",370286:"其它区",370300:"淄博市",370302:"淄川区",370303:"张店区",370304:"博山区",370305:"临淄区",370306:"周村区",370321:"桓台县",370322:"高青县",370323:"沂源县",370324:"其它区",370400:"枣庄市",370402:"市中区",370403:"薛城区",370404:"峄城区",370405:"台儿庄区",370406:"山亭区",370481:"滕州市",370482:"其它区",370500:"东营市",370502:"东营区",370503:"河口区",370521:"垦利县",370522:"利津县",370523:"广饶县",370591:"其它区",370600:"烟台市",370602:"芝罘区",370611:"福山区",370612:"牟平区",370613:"莱山区",370634:"长岛县",370681:"龙口市",370682:"莱阳市",370683:"莱州市",370684:"蓬莱市",370685:"招远市",370686:"栖霞市",370687:"海阳市",370688:"其它区",370700:"潍坊市",370702:"潍城区",370703:"寒亭区",370704:"坊子区",370705:"奎文区",370724:"临朐县",370725:"昌乐县",370781:"青州市",370782:"诸城市",370783:"寿光市",370784:"安丘市",370785:"高密市",370786:"昌邑市",370787:"其它区",370800:"济宁市",370802:"市中区",370811:"任城区",370826:"微山县",370827:"鱼台县",370828:"金乡县",370829:"嘉祥县",370830:"汶上县",370831:"泗水县",370832:"梁山县",370881:"曲阜市",370882:"兖州市",370883:"邹城市",370884:"其它区",370900:"泰安市",370902:"泰山区",370903:"岱岳区",370921:"宁阳县",370923:"东平县",370982:"新泰市",370983:"肥城市",370984:"其它区",371e3:"威海市",371002:"环翠区",371081:"文登市",371082:"荣成市",371083:"乳山市",371084:"其它区",371100:"日照市",371102:"东港区",371103:"岚山区",371121:"五莲县",371122:"莒县",371123:"其它区",371200:"莱芜市",371202:"莱城区",371203:"钢城区",371204:"其它区",371300:"临沂市",371302:"兰山区",371311:"罗庄区",371312:"河东区",371321:"沂南县",371322:"郯城县",371323:"沂水县",371324:"苍山县",371325:"费县",371326:"平邑县",371327:"莒南县",371328:"蒙阴县",371329:"临沭县",371330:"其它区",371400:"德州市",371402:"德城区",371421:"陵县",371422:"宁津县",371423:"庆云县",371424:"临邑县",371425:"齐河县",371426:"平原县",371427:"夏津县",371428:"武城县",371481:"乐陵市",371482:"禹城市",371483:"其它区",371500:"聊城市",371502:"东昌府区",371521:"阳谷县",371522:"莘县",371523:"茌平县",371524:"东阿县",371525:"冠县",371526:"高唐县",371581:"临清市",371582:"其它区",371600:"滨州市",371602:"滨城区",371621:"惠民县",371622:"阳信县",371623:"无棣县",371624:"沾化县",371625:"博兴县",371626:"邹平县",371627:"其它区",371700:"菏泽市",371702:"牡丹区",371721:"曹县",371722:"单县",371723:"成武县",371724:"巨野县",371725:"郓城县",371726:"鄄城县",371727:"定陶县",371728:"东明县",371729:"其它区",41e4:"河南省",410100:"郑州市",410102:"中原区",410103:"二七区",410104:"管城回族区",410105:"金水区",410106:"上街区",410108:"惠济区",410122:"中牟县",410181:"巩义市",410182:"荥阳市",410183:"新密市",410184:"新郑市",410185:"登封市",410188:"其它区",410200:"开封市",410202:"龙亭区",410203:"顺河回族区",410204:"鼓楼区",410205:"禹王台区",410211:"金明区",410221:"杞县",410222:"通许县",410223:"尉氏县",410224:"开封县",410225:"兰考县",410226:"其它区",410300:"洛阳市",410302:"老城区",410303:"西工区",410304:"瀍河回族区",410305:"涧西区",410306:"吉利区",410307:"洛龙区",410322:"孟津县",410323:"新安县",410324:"栾川县",410325:"嵩县",410326:"汝阳县",410327:"宜阳县",410328:"洛宁县",410329:"伊川县",410381:"偃师市",410400:"平顶山市",410402:"新华区",410403:"卫东区",410404:"石龙区",410411:"湛河区",410421:"宝丰县",410422:"叶县",410423:"鲁山县",410425:"郏县",410481:"舞钢市",410482:"汝州市",410483:"其它区",410500:"安阳市",410502:"文峰区",410503:"北关区",410505:"殷都区",410506:"龙安区",410522:"安阳县",410523:"汤阴县",410526:"滑县",410527:"内黄县",410581:"林州市",410582:"其它区",410600:"鹤壁市",410602:"鹤山区",410603:"山城区",410611:"淇滨区",410621:"浚县",410622:"淇县",410623:"其它区",410700:"新乡市",410702:"红旗区",410703:"卫滨区",410704:"凤泉区",410711:"牧野区",410721:"新乡县",410724:"获嘉县",410725:"原阳县",410726:"延津县",410727:"封丘县",410728:"长垣县",410781:"卫辉市",410782:"辉县市",410783:"其它区",410800:"焦作市",410802:"解放区",410803:"中站区",410804:"马村区",410811:"山阳区",410821:"修武县",410822:"博爱县",410823:"武陟县",410825:"温县",410881:"济源市",410882:"沁阳市",410883:"孟州市",410884:"其它区",410900:"濮阳市",410902:"华龙区",410922:"清丰县",410923:"南乐县",410926:"范县",410927:"台前县",410928:"濮阳县",410929:"其它区",411e3:"许昌市",411002:"魏都区",411023:"许昌县",411024:"鄢陵县",411025:"襄城县",411081:"禹州市",411082:"长葛市",411083:"其它区",411100:"漯河市",411102:"源汇区",411103:"郾城区",411104:"召陵区",411121:"舞阳县",411122:"临颍县",411123:"其它区",411200:"三门峡市",411202:"湖滨区",411221:"渑池县",411222:"陕县",411224:"卢氏县",411281:"义马市",411282:"灵宝市",411283:"其它区",411300:"南阳市",411302:"宛城区",411303:"卧龙区",411321:"南召县",411322:"方城县",411323:"西峡县",411324:"镇平县",411325:"内乡县",411326:"淅川县",411327:"社旗县",411328:"唐河县",411329:"新野县",411330:"桐柏县",411381:"邓州市",411382:"其它区",411400:"商丘市",411402:"梁园区",411403:"睢阳区",411421:"民权县",411422:"睢县",411423:"宁陵县",411424:"柘城县",411425:"虞城县",411426:"夏邑县",411481:"永城市",411482:"其它区",411500:"信阳市",411502:"浉河区",411503:"平桥区",411521:"罗山县",411522:"光山县",411523:"新县",411524:"商城县",411525:"固始县",411526:"潢川县",411527:"淮滨县",411528:"息县",411529:"其它区",411600:"周口市",411602:"川汇区",411621:"扶沟县",411622:"西华县",411623:"商水县",411624:"沈丘县",411625:"郸城县",411626:"淮阳县",411627:"太康县",411628:"鹿邑县",411681:"项城市",411682:"其它区",411700:"驻马店市",411702:"驿城区",411721:"西平县",411722:"上蔡县",411723:"平舆县",411724:"正阳县",411725:"确山县",411726:"泌阳县",411727:"汝南县",411728:"遂平县",411729:"新蔡县",411730:"其它区",42e4:"湖北省",420100:"武汉市",420102:"江岸区",420103:"江汉区",420104:"硚口区",420105:"汉阳区",420106:"武昌区",420107:"青山区",420111:"洪山区",420112:"东西湖区",420113:"汉南区",420114:"蔡甸区",420115:"江夏区",420116:"黄陂区",420117:"新洲区",420118:"其它区",420200:"黄石市",420202:"黄石港区",420203:"西塞山区",420204:"下陆区",420205:"铁山区",420222:"阳新县",420281:"大冶市",420282:"其它区",420300:"十堰市",420302:"茅箭区",420303:"张湾区",420321:"郧县",420322:"郧西县",420323:"竹山县",420324:"竹溪县",420325:"房县",420381:"丹江口市",420383:"其它区",420500:"宜昌市",420502:"西陵区",420503:"伍家岗区",420504:"点军区",420505:"猇亭区",420506:"夷陵区",420525:"远安县",420526:"兴山县",420527:"秭归县",420528:"长阳土家族自治县",420529:"五峰土家族自治县",420581:"宜都市",420582:"当阳市",420583:"枝江市",420584:"其它区",420600:"襄阳市",420602:"襄城区",420606:"樊城区",420607:"襄州区",420624:"南漳县",420625:"谷城县",420626:"保康县",420682:"老河口市",420683:"枣阳市",420684:"宜城市",420685:"其它区",420700:"鄂州市",420702:"梁子湖区",420703:"华容区",420704:"鄂城区",420705:"其它区",420800:"荆门市",420802:"东宝区",420804:"掇刀区",420821:"京山县",420822:"沙洋县",420881:"钟祥市",420882:"其它区",420900:"孝感市",420902:"孝南区",420921:"孝昌县",420922:"大悟县",420923:"云梦县",420981:"应城市",420982:"安陆市",420984:"汉川市",420985:"其它区",421e3:"荆州市",421002:"沙市区",421003:"荆州区",421022:"公安县",421023:"监利县",421024:"江陵县",421081:"石首市",421083:"洪湖市",421087:"松滋市",421088:"其它区",421100:"黄冈市",421102:"黄州区",421121:"团风县",421122:"红安县",421123:"罗田县",421124:"英山县",421125:"浠水县",421126:"蕲春县",421127:"黄梅县",421181:"麻城市",421182:"武穴市",421183:"其它区",421200:"咸宁市",421202:"咸安区",421221:"嘉鱼县",421222:"通城县",421223:"崇阳县",421224:"通山县",421281:"赤壁市",421283:"其它区",421300:"随州市",421302:"曾都区",421321:"随县",421381:"广水市",421382:"其它区",422800:"恩施土家族苗族自治州",422801:"恩施市",422802:"利川市",422822:"建始县",422823:"巴东县",422825:"宣恩县",422826:"咸丰县",422827:"来凤县",422828:"鹤峰县",422829:"其它区",429004:"仙桃市",429005:"潜江市",429006:"天门市",429021:"神农架林区",43e4:"湖南省",430100:"长沙市",430102:"芙蓉区",430103:"天心区",430104:"岳麓区",430105:"开福区",430111:"雨花区",430121:"长沙县",430122:"望城区",430124:"宁乡县",430181:"浏阳市",430182:"其它区",430200:"株洲市",430202:"荷塘区",430203:"芦淞区",430204:"石峰区",430211:"天元区",430221:"株洲县",430223:"攸县",430224:"茶陵县",430225:"炎陵县",430281:"醴陵市",430282:"其它区",430300:"湘潭市",430302:"雨湖区",430304:"岳塘区",430321:"湘潭县",430381:"湘乡市",430382:"韶山市",430383:"其它区",430400:"衡阳市",430405:"珠晖区",430406:"雁峰区",430407:"石鼓区",430408:"蒸湘区",430412:"南岳区",430421:"衡阳县",430422:"衡南县",430423:"衡山县",430424:"衡东县",430426:"祁东县",430481:"耒阳市",430482:"常宁市",430483:"其它区",430500:"邵阳市",430502:"双清区",430503:"大祥区",430511:"北塔区",430521:"邵东县",430522:"新邵县",430523:"邵阳县",430524:"隆回县",430525:"洞口县",430527:"绥宁县",430528:"新宁县",430529:"城步苗族自治县",430581:"武冈市",430582:"其它区",430600:"岳阳市",430602:"岳阳楼区",430603:"云溪区",430611:"君山区",430621:"岳阳县",430623:"华容县",430624:"湘阴县",430626:"平江县",430681:"汨罗市",430682:"临湘市",430683:"其它区",430700:"常德市",430702:"武陵区",430703:"鼎城区",430721:"安乡县",430722:"汉寿县",430723:"澧县",430724:"临澧县",430725:"桃源县",430726:"石门县",430781:"津市市",430782:"其它区",430800:"张家界市",430802:"永定区",430811:"武陵源区",430821:"慈利县",430822:"桑植县",430823:"其它区",430900:"益阳市",430902:"资阳区",430903:"赫山区",430921:"南县",430922:"桃江县",430923:"安化县",430981:"沅江市",430982:"其它区",431e3:"郴州市",431002:"北湖区",431003:"苏仙区",431021:"桂阳县",431022:"宜章县",431023:"永兴县",431024:"嘉禾县",431025:"临武县",431026:"汝城县",431027:"桂东县",431028:"安仁县",431081:"资兴市",431082:"其它区",431100:"永州市",431102:"零陵区",431103:"冷水滩区",431121:"祁阳县",431122:"东安县",431123:"双牌县",431124:"道县",431125:"江永县",431126:"宁远县",431127:"蓝山县",431128:"新田县",431129:"江华瑶族自治县",431130:"其它区",431200:"怀化市",431202:"鹤城区",431221:"中方县",431222:"沅陵县",431223:"辰溪县",431224:"溆浦县",431225:"会同县",431226:"麻阳苗族自治县",431227:"新晃侗族自治县",431228:"芷江侗族自治县",431229:"靖州苗族侗族自治县",431230:"通道侗族自治县",431281:"洪江市",431282:"其它区",431300:"娄底市",431302:"娄星区",431321:"双峰县",431322:"新化县",431381:"冷水江市",431382:"涟源市",431383:"其它区",433100:"湘西土家族苗族自治州",433101:"吉首市",433122:"泸溪县",433123:"凤凰县",433124:"花垣县",433125:"保靖县",433126:"古丈县",433127:"永顺县",433130:"龙山县",433131:"其它区",44e4:"广东省",440100:"广州市",440103:"荔湾区",440104:"越秀区",440105:"海珠区",440106:"天河区",440111:"白云区",440112:"黄埔区",440113:"番禺区",440114:"花都区",440115:"南沙区",440116:"萝岗区",440183:"增城市",440184:"从化市",440189:"其它区",440200:"韶关市",440203:"武江区",440204:"浈江区",440205:"曲江区",440222:"始兴县",440224:"仁化县",440229:"翁源县",440232:"乳源瑶族自治县",440233:"新丰县",440281:"乐昌市",440282:"南雄市",440283:"其它区",440300:"深圳市",440303:"罗湖区",440304:"福田区",440305:"南山区",440306:"宝安区",440307:"龙岗区",440308:"盐田区",440309:"其它区",440320:"光明新区",440321:"坪山新区",440322:"大鹏新区",440323:"龙华新区",440400:"珠海市",440402:"香洲区",440403:"斗门区",440404:"金湾区",440488:"其它区",440500:"汕头市",440507:"龙湖区",440511:"金平区",440512:"濠江区",440513:"潮阳区",440514:"潮南区",440515:"澄海区",440523:"南澳县",440524:"其它区",440600:"佛山市",440604:"禅城区",440605:"南海区",440606:"顺德区",440607:"三水区",440608:"高明区",440609:"其它区",440700:"江门市",440703:"蓬江区",440704:"江海区",440705:"新会区",440781:"台山市",440783:"开平市",440784:"鹤山市",440785:"恩平市",440786:"其它区",440800:"湛江市",440802:"赤坎区",440803:"霞山区",440804:"坡头区",440811:"麻章区",440823:"遂溪县",440825:"徐闻县",440881:"廉江市",440882:"雷州市",440883:"吴川市",440884:"其它区",440900:"茂名市",440902:"茂南区",440903:"茂港区",440923:"电白县",440981:"高州市",440982:"化州市",440983:"信宜市",440984:"其它区",441200:"肇庆市",441202:"端州区",441203:"鼎湖区",441223:"广宁县",441224:"怀集县",441225:"封开县",441226:"德庆县",441283:"高要市",441284:"四会市",441285:"其它区",441300:"惠州市",441302:"惠城区",441303:"惠阳区",441322:"博罗县",441323:"惠东县",441324:"龙门县",441325:"其它区",441400:"梅州市",441402:"梅江区",441421:"梅县",441422:"大埔县",441423:"丰顺县",441424:"五华县",441426:"平远县",441427:"蕉岭县",441481:"兴宁市",441482:"其它区",441500:"汕尾市",441502:"城区",441521:"海丰县",441523:"陆河县",441581:"陆丰市",441582:"其它区",441600:"河源市",441602:"源城区",441621:"紫金县",441622:"龙川县",441623:"连平县",441624:"和平县",441625:"东源县",441626:"其它区",441700:"阳江市",441702:"江城区",441721:"阳西县",441723:"阳东县",441781:"阳春市",441782:"其它区",441800:"清远市",441802:"清城区",441821:"佛冈县",441823:"阳山县",441825:"连山壮族瑶族自治县",441826:"连南瑶族自治县",441827:"清新区",441881:"英德市",441882:"连州市",441883:"其它区",441900:"东莞市",442e3:"中山市",442101:"东沙群岛",445100:"潮州市",445102:"湘桥区",445121:"潮安区",445122:"饶平县",445186:"其它区",445200:"揭阳市",445202:"榕城区",445221:"揭东区",445222:"揭西县",445224:"惠来县",445281:"普宁市",445285:"其它区",445300:"云浮市",445302:"云城区",445321:"新兴县",445322:"郁南县",445323:"云安县",445381:"罗定市",445382:"其它区",45e4:"广西壮族自治区",450100:"南宁市",450102:"兴宁区",450103:"青秀区",450105:"江南区",450107:"西乡塘区",450108:"良庆区",450109:"邕宁区",450122:"武鸣县",450123:"隆安县",450124:"马山县",450125:"上林县",450126:"宾阳县",450127:"横县",450128:"其它区",450200:"柳州市",450202:"城中区",450203:"鱼峰区",450204:"柳南区",450205:"柳北区",450221:"柳江县",450222:"柳城县",450223:"鹿寨县",450224:"融安县",450225:"融水苗族自治县",450226:"三江侗族自治县",450227:"其它区",450300:"桂林市",450302:"秀峰区",450303:"叠彩区",450304:"象山区",450305:"七星区",450311:"雁山区",450321:"阳朔县",450322:"临桂区",450323:"灵川县",450324:"全州县",450325:"兴安县",450326:"永福县",450327:"灌阳县",450328:"龙胜各族自治县",450329:"资源县",450330:"平乐县",450331:"荔浦县",450332:"恭城瑶族自治县",450333:"其它区",450400:"梧州市",450403:"万秀区",450405:"长洲区",450406:"龙圩区",450421:"苍梧县",450422:"藤县",450423:"蒙山县",450481:"岑溪市",450482:"其它区",450500:"北海市",450502:"海城区",450503:"银海区",450512:"铁山港区",450521:"合浦县",450522:"其它区",450600:"防城港市",450602:"港口区",450603:"防城区",450621:"上思县",450681:"东兴市",450682:"其它区",450700:"钦州市",450702:"钦南区",450703:"钦北区",450721:"灵山县",450722:"浦北县",450723:"其它区",450800:"贵港市",450802:"港北区",450803:"港南区",450804:"覃塘区",450821:"平南县",450881:"桂平市",450882:"其它区",450900:"玉林市",450902:"玉州区",450903:"福绵区",450921:"容县",450922:"陆川县",450923:"博白县",450924:"兴业县",450981:"北流市",450982:"其它区",451e3:"百色市",451002:"右江区",451021:"田阳县",451022:"田东县",451023:"平果县",451024:"德保县",451025:"靖西县",451026:"那坡县",451027:"凌云县",451028:"乐业县",451029:"田林县",451030:"西林县",451031:"隆林各族自治县",451032:"其它区",451100:"贺州市",451102:"八步区",451119:"平桂管理区",451121:"昭平县",451122:"钟山县",451123:"富川瑶族自治县",451124:"其它区",451200:"河池市",451202:"金城江区",451221:"南丹县",451222:"天峨县",451223:"凤山县",451224:"东兰县",451225:"罗城仫佬族自治县",451226:"环江毛南族自治县",451227:"巴马瑶族自治县",451228:"都安瑶族自治县",451229:"大化瑶族自治县",451281:"宜州市",451282:"其它区",451300:"来宾市",451302:"兴宾区",451321:"忻城县",451322:"象州县",451323:"武宣县",451324:"金秀瑶族自治县",451381:"合山市",451382:"其它区",451400:"崇左市",451402:"江州区",451421:"扶绥县",451422:"宁明县",451423:"龙州县",451424:"大新县",451425:"天等县",451481:"凭祥市",451482:"其它区",46e4:"海南省",460100:"海口市",460105:"秀英区",460106:"龙华区",460107:"琼山区",460108:"美兰区",460109:"其它区",460200:"三亚市",460300:"三沙市",460321:"西沙群岛",460322:"南沙群岛",460323:"中沙群岛的岛礁及其海域",469001:"五指山市",469002:"琼海市",469003:"儋州市",469005:"文昌市",469006:"万宁市",469007:"东方市",469025:"定安县",469026:"屯昌县",469027:"澄迈县",469028:"临高县",469030:"白沙黎族自治县",469031:"昌江黎族自治县",469033:"乐东黎族自治县",469034:"陵水黎族自治县",469035:"保亭黎族苗族自治县",469036:"琼中黎族苗族自治县",471005:"其它区",5e5:"重庆",500100:"重庆市",500101:"万州区",500102:"涪陵区",500103:"渝中区",500104:"大渡口区",500105:"江北区",500106:"沙坪坝区",500107:"九龙坡区",500108:"南岸区",500109:"北碚区",500110:"万盛区",500111:"双桥区",500112:"渝北区",500113:"巴南区",500114:"黔江区",500115:"长寿区",500222:"綦江区",500223:"潼南县",500224:"铜梁县",500225:"大足区",500226:"荣昌县",500227:"璧山县",500228:"梁平县",500229:"城口县",500230:"丰都县",500231:"垫江县",500232:"武隆县",500233:"忠县",500234:"开县",500235:"云阳县",500236:"奉节县",500237:"巫山县",500238:"巫溪县",500240:"石柱土家族自治县",500241:"秀山土家族苗族自治县",500242:"酉阳土家族苗族自治县",500243:"彭水苗族土家族自治县",500381:"江津区",500382:"合川区",500383:"永川区",500384:"南川区",500385:"其它区",51e4:"四川省",510100:"成都市",510104:"锦江区",510105:"青羊区",510106:"金牛区",510107:"武侯区",510108:"成华区",510112:"龙泉驿区",510113:"青白江区",510114:"新都区",510115:"温江区",510121:"金堂县",510122:"双流县",510124:"郫县",510129:"大邑县",510131:"蒲江县",510132:"新津县",510181:"都江堰市",510182:"彭州市",510183:"邛崃市",510184:"崇州市",510185:"其它区",510300:"自贡市",510302:"自流井区",510303:"贡井区",510304:"大安区",510311:"沿滩区",510321:"荣县",510322:"富顺县",510323:"其它区",510400:"攀枝花市",510402:"东区",510403:"西区",510411:"仁和区",510421:"米易县",510422:"盐边县",510423:"其它区",510500:"泸州市",510502:"江阳区",510503:"纳溪区",510504:"龙马潭区",510521:"泸县",510522:"合江县",510524:"叙永县",510525:"古蔺县",510526:"其它区",510600:"德阳市",510603:"旌阳区",510623:"中江县",510626:"罗江县",510681:"广汉市",510682:"什邡市",510683:"绵竹市",510684:"其它区",510700:"绵阳市",510703:"涪城区",510704:"游仙区",510722:"三台县",510723:"盐亭县",510724:"安县",510725:"梓潼县",510726:"北川羌族自治县",510727:"平武县",510781:"江油市",510782:"其它区",510800:"广元市",510802:"利州区",510811:"昭化区",510812:"朝天区",510821:"旺苍县",510822:"青川县",510823:"剑阁县",510824:"苍溪县",510825:"其它区",510900:"遂宁市",510903:"船山区",510904:"安居区",510921:"蓬溪县",510922:"射洪县",510923:"大英县",510924:"其它区",511e3:"内江市",511002:"市中区",511011:"东兴区",511024:"威远县",511025:"资中县",511028:"隆昌县",511029:"其它区",511100:"乐山市",511102:"市中区",511111:"沙湾区",511112:"五通桥区",511113:"金口河区",511123:"犍为县",511124:"井研县",511126:"夹江县",511129:"沐川县",511132:"峨边彝族自治县",511133:"马边彝族自治县",511181:"峨眉山市",511182:"其它区",511300:"南充市",511302:"顺庆区",511303:"高坪区",511304:"嘉陵区",511321:"南部县",511322:"营山县",511323:"蓬安县",511324:"仪陇县",511325:"西充县",511381:"阆中市",511382:"其它区",511400:"眉山市",511402:"东坡区",511421:"仁寿县",511422:"彭山县",511423:"洪雅县",511424:"丹棱县",511425:"青神县",511426:"其它区",511500:"宜宾市",511502:"翠屏区",511521:"宜宾县",511522:"南溪区",511523:"江安县",511524:"长宁县",511525:"高县",511526:"珙县",511527:"筠连县",511528:"兴文县",511529:"屏山县",511530:"其它区",511600:"广安市",511602:"广安区",511603:"前锋区",511621:"岳池县",511622:"武胜县",511623:"邻水县",511681:"华蓥市",511683:"其它区",511700:"达州市",511702:"通川区",511721:"达川区",511722:"宣汉县",511723:"开江县",511724:"大竹县",511725:"渠县",511781:"万源市",511782:"其它区",511800:"雅安市",511802:"雨城区",511821:"名山区",511822:"荥经县",511823:"汉源县",511824:"石棉县",511825:"天全县",511826:"芦山县",511827:"宝兴县",511828:"其它区",511900:"巴中市",511902:"巴州区",511903:"恩阳区",511921:"通江县",511922:"南江县",511923:"平昌县",511924:"其它区",512e3:"资阳市",512002:"雁江区",512021:"安岳县",512022:"乐至县",512081:"简阳市",512082:"其它区",513200:"阿坝藏族羌族自治州",513221:"汶川县",513222:"理县",513223:"茂县",513224:"松潘县",513225:"九寨沟县",513226:"金川县",513227:"小金县",513228:"黑水县",513229:"马尔康县",513230:"壤塘县",513231:"阿坝县",513232:"若尔盖县",513233:"红原县",513234:"其它区",513300:"甘孜藏族自治州",513321:"康定县",513322:"泸定县",513323:"丹巴县",513324:"九龙县",513325:"雅江县",513326:"道孚县",513327:"炉霍县",513328:"甘孜县",513329:"新龙县",513330:"德格县",513331:"白玉县",513332:"石渠县",513333:"色达县",513334:"理塘县",513335:"巴塘县",513336:"乡城县",513337:"稻城县",513338:"得荣县",513339:"其它区",513400:"凉山彝族自治州",513401:"西昌市",513422:"木里藏族自治县",513423:"盐源县",513424:"德昌县",513425:"会理县",513426:"会东县",513427:"宁南县",513428:"普格县",513429:"布拖县",513430:"金阳县",513431:"昭觉县",513432:"喜德县",513433:"冕宁县",513434:"越西县",513435:"甘洛县",513436:"美姑县",513437:"雷波县",513438:"其它区",52e4:"贵州省",520100:"贵阳市",520102:"南明区",520103:"云岩区",520111:"花溪区",520112:"乌当区",520113:"白云区",520121:"开阳县",520122:"息烽县",520123:"修文县",520151:"观山湖区",520181:"清镇市",520182:"其它区",520200:"六盘水市",520201:"钟山区",520203:"六枝特区",520221:"水城县",520222:"盘县",520223:"其它区",520300:"遵义市",520302:"红花岗区",520303:"汇川区",520321:"遵义县",520322:"桐梓县",520323:"绥阳县",520324:"正安县",520325:"道真仡佬族苗族自治县",520326:"务川仡佬族苗族自治县",520327:"凤冈县",520328:"湄潭县",520329:"余庆县",520330:"习水县",520381:"赤水市",520382:"仁怀市",520383:"其它区",520400:"安顺市",520402:"西秀区",520421:"平坝县",520422:"普定县",520423:"镇宁布依族苗族自治县",520424:"关岭布依族苗族自治县",520425:"紫云苗族布依族自治县",520426:"其它区",522200:"铜仁市",522201:"碧江区",522222:"江口县",522223:"玉屏侗族自治县",522224:"石阡县",522225:"思南县",522226:"印江土家族苗族自治县",522227:"德江县",522228:"沿河土家族自治县",522229:"松桃苗族自治县",522230:"万山区",522231:"其它区",522300:"黔西南布依族苗族自治州",522301:"兴义市",522322:"兴仁县",522323:"普安县",522324:"晴隆县",522325:"贞丰县",522326:"望谟县",522327:"册亨县",522328:"安龙县",522329:"其它区",522400:"毕节市",522401:"七星关区",522422:"大方县",522423:"黔西县",522424:"金沙县",522425:"织金县",522426:"纳雍县",522427:"威宁彝族回族苗族自治县",522428:"赫章县",522429:"其它区",522600:"黔东南苗族侗族自治州",522601:"凯里市",522622:"黄平县",522623:"施秉县",522624:"三穗县",522625:"镇远县",522626:"岑巩县",522627:"天柱县",522628:"锦屏县",522629:"剑河县",522630:"台江县",522631:"黎平县",522632:"榕江县",522633:"从江县",522634:"雷山县",522635:"麻江县",522636:"丹寨县",522637:"其它区",522700:"黔南布依族苗族自治州",522701:"都匀市",522702:"福泉市",522722:"荔波县",522723:"贵定县",522725:"瓮安县",522726:"独山县",522727:"平塘县",522728:"罗甸县",522729:"长顺县",522730:"龙里县",522731:"惠水县",522732:"三都水族自治县",522733:"其它区",53e4:"云南省",530100:"昆明市",530102:"五华区",530103:"盘龙区",530111:"官渡区",530112:"西山区",530113:"东川区",530121:"呈贡区",530122:"晋宁县",530124:"富民县",530125:"宜良县",530126:"石林彝族自治县",530127:"嵩明县",530128:"禄劝彝族苗族自治县",530129:"寻甸回族彝族自治县",530181:"安宁市",530182:"其它区",530300:"曲靖市",530302:"麒麟区",530321:"马龙县",530322:"陆良县",530323:"师宗县",530324:"罗平县",530325:"富源县",530326:"会泽县",530328:"沾益县",530381:"宣威市",530382:"其它区",530400:"玉溪市",530402:"红塔区",530421:"江川县",530422:"澄江县",530423:"通海县",530424:"华宁县",530425:"易门县",530426:"峨山彝族自治县",530427:"新平彝族傣族自治县",530428:"元江哈尼族彝族傣族自治县",530429:"其它区",530500:"保山市",530502:"隆阳区",530521:"施甸县",530522:"腾冲县",530523:"龙陵县",530524:"昌宁县",530525:"其它区",530600:"昭通市",530602:"昭阳区",530621:"鲁甸县",530622:"巧家县",530623:"盐津县",530624:"大关县",530625:"永善县",530626:"绥江县",530627:"镇雄县",530628:"彝良县",530629:"威信县",530630:"水富县",530631:"其它区",530700:"丽江市",530702:"古城区",530721:"玉龙纳西族自治县",530722:"永胜县",530723:"华坪县",530724:"宁蒗彝族自治县",530725:"其它区",530800:"普洱市",530802:"思茅区",530821:"宁洱哈尼族彝族自治县",530822:"墨江哈尼族自治县",530823:"景东彝族自治县",530824:"景谷傣族彝族自治县",530825:"镇沅彝族哈尼族拉祜族自治县",530826:"江城哈尼族彝族自治县",530827:"孟连傣族拉祜族佤族自治县",530828:"澜沧拉祜族自治县",530829:"西盟佤族自治县",530830:"其它区",530900:"临沧市",530902:"临翔区",530921:"凤庆县",530922:"云县",530923:"永德县",530924:"镇康县",530925:"双江拉祜族佤族布朗族傣族自治县",530926:"耿马傣族佤族自治县",530927:"沧源佤族自治县",530928:"其它区",532300:"楚雄彝族自治州",532301:"楚雄市",532322:"双柏县",532323:"牟定县",532324:"南华县",532325:"姚安县",532326:"大姚县",532327:"永仁县",532328:"元谋县",532329:"武定县",532331:"禄丰县",532332:"其它区",532500:"红河哈尼族彝族自治州",532501:"个旧市",532502:"开远市",532522:"蒙自市",532523:"屏边苗族自治县",532524:"建水县",532525:"石屏县",532526:"弥勒市",532527:"泸西县",532528:"元阳县",532529:"红河县",532530:"金平苗族瑶族傣族自治县",532531:"绿春县",532532:"河口瑶族自治县",532533:"其它区",532600:"文山壮族苗族自治州",532621:"文山市",532622:"砚山县",532623:"西畴县",532624:"麻栗坡县",532625:"马关县",532626:"丘北县",532627:"广南县",532628:"富宁县",532629:"其它区",532800:"西双版纳傣族自治州",532801:"景洪市",532822:"勐海县",532823:"勐腊县",532824:"其它区",532900:"大理白族自治州",532901:"大理市",532922:"漾濞彝族自治县",532923:"祥云县",532924:"宾川县",532925:"弥渡县",532926:"南涧彝族自治县",532927:"巍山彝族回族自治县",532928:"永平县",532929:"云龙县",532930:"洱源县",532931:"剑川县",532932:"鹤庆县",532933:"其它区",533100:"德宏傣族景颇族自治州",533102:"瑞丽市",533103:"芒市",533122:"梁河县",533123:"盈江县",533124:"陇川县",533125:"其它区",533300:"怒江傈僳族自治州",533321:"泸水县",533323:"福贡县",533324:"贡山独龙族怒族自治县",533325:"兰坪白族普米族自治县",533326:"其它区",533400:"迪庆藏族自治州",533421:"香格里拉县",533422:"德钦县",533423:"维西傈僳族自治县",533424:"其它区",54e4:"西藏自治区",540100:"拉萨市",540102:"城关区",540121:"林周县",540122:"当雄县",540123:"尼木县",540124:"曲水县",540125:"堆龙德庆县",540126:"达孜县",540127:"墨竹工卡县",540128:"其它区",542100:"昌都地区",542121:"昌都县",542122:"江达县",542123:"贡觉县",542124:"类乌齐县",542125:"丁青县",542126:"察雅县",542127:"八宿县",542128:"左贡县",542129:"芒康县",542132:"洛隆县",542133:"边坝县",542134:"其它区",542200:"山南地区",542221:"乃东县",542222:"扎囊县",542223:"贡嘎县",542224:"桑日县",542225:"琼结县",542226:"曲松县",542227:"措美县",542228:"洛扎县",542229:"加查县",542231:"隆子县",542232:"错那县",542233:"浪卡子县",542234:"其它区",542300:"日喀则地区",542301:"日喀则市",542322:"南木林县",542323:"江孜县",542324:"定日县",542325:"萨迦县",542326:"拉孜县",542327:"昂仁县",542328:"谢通门县",542329:"白朗县",542330:"仁布县",542331:"康马县",542332:"定结县",542333:"仲巴县",542334:"亚东县",542335:"吉隆县",542336:"聂拉木县",542337:"萨嘎县",542338:"岗巴县",542339:"其它区",542400:"那曲地区",542421:"那曲县",542422:"嘉黎县",542423:"比如县",542424:"聂荣县",542425:"安多县",542426:"申扎县",542427:"索县",542428:"班戈县",542429:"巴青县",542430:"尼玛县",542431:"其它区",542432:"双湖县",542500:"阿里地区",542521:"普兰县",542522:"札达县",542523:"噶尔县",542524:"日土县",542525:"革吉县",542526:"改则县",542527:"措勤县",542528:"其它区",542600:"林芝地区",542621:"林芝县",542622:"工布江达县",542623:"米林县",542624:"墨脱县",542625:"波密县",542626:"察隅县",542627:"朗县",542628:"其它区",61e4:"陕西省",610100:"西安市",610102:"新城区",610103:"碑林区",610104:"莲湖区",610111:"灞桥区",610112:"未央区",610113:"雁塔区",610114:"阎良区",610115:"临潼区",610116:"长安区",610122:"蓝田县",610124:"周至县",610125:"户县",610126:"高陵县",610127:"其它区",610200:"铜川市",610202:"王益区",610203:"印台区",610204:"耀州区",610222:"宜君县",610223:"其它区",610300:"宝鸡市",610302:"渭滨区",610303:"金台区",610304:"陈仓区",610322:"凤翔县",610323:"岐山县",610324:"扶风县",610326:"眉县",610327:"陇县",610328:"千阳县",610329:"麟游县",610330:"凤县",610331:"太白县",610332:"其它区",610400:"咸阳市",610402:"秦都区",610403:"杨陵区",610404:"渭城区",610422:"三原县",610423:"泾阳县",610424:"乾县",610425:"礼泉县",610426:"永寿县",610427:"彬县",610428:"长武县",610429:"旬邑县",610430:"淳化县",610431:"武功县",610481:"兴平市",610482:"其它区",610500:"渭南市",610502:"临渭区",610521:"华县",610522:"潼关县",610523:"大荔县",610524:"合阳县",610525:"澄城县",610526:"蒲城县",610527:"白水县",610528:"富平县",610581:"韩城市",610582:"华阴市",610583:"其它区",610600:"延安市",610602:"宝塔区",610621:"延长县",610622:"延川县",610623:"子长县",610624:"安塞县",610625:"志丹县",610626:"吴起县",610627:"甘泉县",610628:"富县",610629:"洛川县",610630:"宜川县",610631:"黄龙县",610632:"黄陵县",610633:"其它区",610700:"汉中市",610702:"汉台区",610721:"南郑县",610722:"城固县",610723:"洋县",610724:"西乡县",610725:"勉县",610726:"宁强县",610727:"略阳县",610728:"镇巴县",610729:"留坝县",610730:"佛坪县",610731:"其它区",610800:"榆林市",610802:"榆阳区",610821:"神木县",610822:"府谷县",610823:"横山县",610824:"靖边县",610825:"定边县",610826:"绥德县",610827:"米脂县",610828:"佳县",610829:"吴堡县",610830:"清涧县",610831:"子洲县",610832:"其它区",610900:"安康市",610902:"汉滨区",610921:"汉阴县",610922:"石泉县",610923:"宁陕县",610924:"紫阳县",610925:"岚皋县",610926:"平利县",610927:"镇坪县",610928:"旬阳县",610929:"白河县",610930:"其它区",611e3:"商洛市",611002:"商州区",611021:"洛南县",611022:"丹凤县",611023:"商南县",611024:"山阳县",611025:"镇安县",611026:"柞水县",611027:"其它区",62e4:"甘肃省",620100:"兰州市",620102:"城关区",620103:"七里河区",620104:"西固区",620105:"安宁区",620111:"红古区",620121:"永登县",620122:"皋兰县",620123:"榆中县",620124:"其它区",620200:"嘉峪关市",620300:"金昌市",620302:"金川区",620321:"永昌县",620322:"其它区",620400:"白银市",620402:"白银区",620403:"平川区",620421:"靖远县",620422:"会宁县",620423:"景泰县",620424:"其它区",620500:"天水市",620502:"秦州区",620503:"麦积区",620521:"清水县",620522:"秦安县",620523:"甘谷县",620524:"武山县",620525:"张家川回族自治县",620526:"其它区",620600:"武威市",620602:"凉州区",620621:"民勤县",620622:"古浪县",620623:"天祝藏族自治县",620624:"其它区",620700:"张掖市",620702:"甘州区",620721:"肃南裕固族自治县",620722:"民乐县",620723:"临泽县",620724:"高台县",620725:"山丹县",620726:"其它区",620800:"平凉市",620802:"崆峒区",620821:"泾川县",620822:"灵台县",620823:"崇信县",620824:"华亭县",620825:"庄浪县",620826:"静宁县",620827:"其它区",620900:"酒泉市",620902:"肃州区",620921:"金塔县",620922:"瓜州县",620923:"肃北蒙古族自治县",620924:"阿克塞哈萨克族自治县",620981:"玉门市",620982:"敦煌市",620983:"其它区",621e3:"庆阳市",621002:"西峰区",621021:"庆城县",621022:"环县",621023:"华池县",621024:"合水县",621025:"正宁县",621026:"宁县",621027:"镇原县",621028:"其它区",621100:"定西市",621102:"安定区",621121:"通渭县",621122:"陇西县",621123:"渭源县",621124:"临洮县",621125:"漳县",621126:"岷县",621127:"其它区",621200:"陇南市",621202:"武都区",621221:"成县",621222:"文县",621223:"宕昌县",621224:"康县",621225:"西和县",621226:"礼县",621227:"徽县",621228:"两当县",621229:"其它区",622900:"临夏回族自治州",622901:"临夏市",622921:"临夏县",622922:"康乐县",622923:"永靖县",622924:"广河县",622925:"和政县",622926:"东乡族自治县",622927:"积石山保安族东乡族撒拉族自治县",622928:"其它区",623e3:"甘南藏族自治州",623001:"合作市",623021:"临潭县",623022:"卓尼县",623023:"舟曲县",623024:"迭部县",623025:"玛曲县",623026:"碌曲县",623027:"夏河县",623028:"其它区",63e4:"青海省",630100:"西宁市",630102:"城东区",630103:"城中区",630104:"城西区",630105:"城北区",630121:"大通回族土族自治县",630122:"湟中县",630123:"湟源县",630124:"其它区",632100:"海东市",632121:"平安县",632122:"民和回族土族自治县",632123:"乐都区",632126:"互助土族自治县",632127:"化隆回族自治县",632128:"循化撒拉族自治县",632129:"其它区",632200:"海北藏族自治州",632221:"门源回族自治县",632222:"祁连县",632223:"海晏县",632224:"刚察县",632225:"其它区",632300:"黄南藏族自治州",632321:"同仁县",632322:"尖扎县",632323:"泽库县",632324:"河南蒙古族自治县",632325:"其它区",632500:"海南藏族自治州",632521:"共和县",632522:"同德县",632523:"贵德县",632524:"兴海县",632525:"贵南县",632526:"其它区",632600:"果洛藏族自治州",632621:"玛沁县",632622:"班玛县",632623:"甘德县",632624:"达日县",632625:"久治县",632626:"玛多县",632627:"其它区",632700:"玉树藏族自治州",632721:"玉树市",632722:"杂多县",632723:"称多县",632724:"治多县",632725:"囊谦县",632726:"曲麻莱县",632727:"其它区",632800:"海西蒙古族藏族自治州",632801:"格尔木市",632802:"德令哈市",632821:"乌兰县",632822:"都兰县",632823:"天峻县",632824:"其它区",64e4:"宁夏回族自治区",640100:"银川市",640104:"兴庆区",640105:"西夏区",640106:"金凤区",640121:"永宁县",640122:"贺兰县",640181:"灵武市",640182:"其它区",640200:"石嘴山市",640202:"大武口区",640205:"惠农区",640221:"平罗县",640222:"其它区",640300:"吴忠市",640302:"利通区",640303:"红寺堡区",640323:"盐池县",640324:"同心县",640381:"青铜峡市",640382:"其它区",640400:"固原市",640402:"原州区",640422:"西吉县",640423:"隆德县",640424:"泾源县",640425:"彭阳县",640426:"其它区",640500:"中卫市",640502:"沙坡头区",640521:"中宁县",640522:"海原县",640523:"其它区",65e4:"新疆维吾尔自治区",650100:"乌鲁木齐市",650102:"天山区",650103:"沙依巴克区",650104:"新市区",650105:"水磨沟区",650106:"头屯河区",650107:"达坂城区",650109:"米东区",650121:"乌鲁木齐县",650122:"其它区",650200:"克拉玛依市",650202:"独山子区",650203:"克拉玛依区",650204:"白碱滩区",650205:"乌尔禾区",650206:"其它区",652100:"吐鲁番地区",652101:"吐鲁番市",652122:"鄯善县",652123:"托克逊县",652124:"其它区",652200:"哈密地区",652201:"哈密市",652222:"巴里坤哈萨克自治县",652223:"伊吾县",652224:"其它区",652300:"昌吉回族自治州",652301:"昌吉市",652302:"阜康市",652323:"呼图壁县",652324:"玛纳斯县",652325:"奇台县",652327:"吉木萨尔县",652328:"木垒哈萨克自治县",652329:"其它区",652700:"博尔塔拉蒙古自治州",652701:"博乐市",652702:"阿拉山口市",652722:"精河县",652723:"温泉县",652724:"其它区",652800:"巴音郭楞蒙古自治州",652801:"库尔勒市",652822:"轮台县",652823:"尉犁县",652824:"若羌县",652825:"且末县",652826:"焉耆回族自治县",652827:"和静县",652828:"和硕县",652829:"博湖县",652830:"其它区",652900:"阿克苏地区",652901:"阿克苏市",652922:"温宿县",652923:"库车县",652924:"沙雅县",652925:"新和县",652926:"拜城县",652927:"乌什县",652928:"阿瓦提县",652929:"柯坪县",652930:"其它区",653e3:"克孜勒苏柯尔克孜自治州",653001:"阿图什市",653022:"阿克陶县",653023:"阿合奇县",653024:"乌恰县",653025:"其它区",653100:"喀什地区",653101:"喀什市",653121:"疏附县",653122:"疏勒县",653123:"英吉沙县",653124:"泽普县",653125:"莎车县",653126:"叶城县",653127:"麦盖提县",653128:"岳普湖县",653129:"伽师县",653130:"巴楚县",653131:"塔什库尔干塔吉克自治县",653132:"其它区",653200:"和田地区",653201:"和田市",653221:"和田县",653222:"墨玉县",653223:"皮山县",653224:"洛浦县",653225:"策勒县",653226:"于田县",653227:"民丰县",653228:"其它区",654e3:"伊犁哈萨克自治州",654002:"伊宁市",654003:"奎屯市",654021:"伊宁县",654022:"察布查尔锡伯自治县",654023:"霍城县",654024:"巩留县",654025:"新源县",654026:"昭苏县",654027:"特克斯县",654028:"尼勒克县",654029:"其它区",654200:"塔城地区",654201:"塔城市",654202:"乌苏市",654221:"额敏县",654223:"沙湾县",654224:"托里县",654225:"裕民县",654226:"和布克赛尔蒙古自治县",654227:"其它区",654300:"阿勒泰地区",654301:"阿勒泰市",654321:"布尔津县",654322:"富蕴县",654323:"福海县",654324:"哈巴河县",654325:"青河县",654326:"吉木乃县",654327:"其它区",659001:"石河子市",659002:"阿拉尔市",659003:"图木舒克市",659004:"五家渠市",71e4:"台湾",710100:"台北市",710101:"中正区",710102:"大同区",710103:"中山区",710104:"松山区",710105:"大安区",710106:"万华区",710107:"信义区",710108:"士林区",710109:"北投区",710110:"内湖区",710111:"南港区",710112:"文山区",710113:"其它区",710200:"高雄市",710201:"新兴区",710202:"前金区",710203:"芩雅区",710204:"盐埕区",710205:"鼓山区",710206:"旗津区",710207:"前镇区",710208:"三民区",710209:"左营区",710210:"楠梓区",710211:"小港区",710212:"其它区",710241:"苓雅区",710242:"仁武区",710243:"大社区",710244:"冈山区",710245:"路竹区",710246:"阿莲区",710247:"田寮区",710248:"燕巢区",710249:"桥头区",710250:"梓官区",710251:"弥陀区",710252:"永安区",710253:"湖内区",710254:"凤山区",710255:"大寮区",710256:"林园区",710257:"鸟松区",710258:"大树区",710259:"旗山区",710260:"美浓区",710261:"六龟区",710262:"内门区",710263:"杉林区",710264:"甲仙区",710265:"桃源区",710266:"那玛夏区",710267:"茂林区",710268:"茄萣区",710300:"台南市",710301:"中西区",710302:"东区",710303:"南区",710304:"北区",710305:"安平区",710306:"安南区",710307:"其它区",710339:"永康区",710340:"归仁区",710341:"新化区",710342:"左镇区",710343:"玉井区",710344:"楠西区",710345:"南化区",710346:"仁德区",710347:"关庙区",710348:"龙崎区",710349:"官田区",710350:"麻豆区",710351:"佳里区",710352:"西港区",710353:"七股区",710354:"将军区",710355:"学甲区",710356:"北门区",710357:"新营区",710358:"后壁区",710359:"白河区",710360:"东山区",710361:"六甲区",710362:"下营区",710363:"柳营区",710364:"盐水区",710365:"善化区",710366:"大内区",710367:"山上区",710368:"新市区",710369:"安定区",710400:"台中市",710401:"中区",710402:"东区",710403:"南区",710404:"西区",710405:"北区",710406:"北屯区",710407:"西屯区",710408:"南屯区",710409:"其它区",710431:"太平区",710432:"大里区",710433:"雾峰区",710434:"乌日区",710435:"丰原区",710436:"后里区",710437:"石冈区",710438:"东势区",710439:"和平区",710440:"新社区",710441:"潭子区",710442:"大雅区",710443:"神冈区",710444:"大肚区",710445:"沙鹿区",710446:"龙井区",710447:"梧栖区",710448:"清水区",710449:"大甲区",710450:"外埔区",710451:"大安区",710500:"金门县",710507:"金沙镇",710508:"金湖镇",710509:"金宁乡",710510:"金城镇",710511:"烈屿乡",710512:"乌坵乡",710600:"南投县",710614:"南投市",710615:"中寮乡",710616:"草屯镇",710617:"国姓乡",710618:"埔里镇",710619:"仁爱乡",710620:"名间乡",710621:"集集镇",710622:"水里乡",710623:"鱼池乡",710624:"信义乡",710625:"竹山镇",710626:"鹿谷乡",710700:"基隆市",710701:"仁爱区",710702:"信义区",710703:"中正区",710704:"中山区",710705:"安乐区",710706:"暖暖区",710707:"七堵区",710708:"其它区",710800:"新竹市",710801:"东区",710802:"北区",710803:"香山区",710804:"其它区",710900:"嘉义市",710901:"东区",710902:"西区",710903:"其它区",711100:"新北市",711130:"万里区",711131:"金山区",711132:"板桥区",711133:"汐止区",711134:"深坑区",711135:"石碇区",711136:"瑞芳区",711137:"平溪区",711138:"双溪区",711139:"贡寮区",711140:"新店区",711141:"坪林区",711142:"乌来区",711143:"永和区",711144:"中和区",711145:"土城区",711146:"三峡区",711147:"树林区",711148:"莺歌区",711149:"三重区",711150:"新庄区",711151:"泰山区",711152:"林口区",711153:"芦洲区",711154:"五股区",711155:"八里区",711156:"淡水区",711157:"三芝区",711158:"石门区",711200:"宜兰县",711214:"宜兰市",711215:"头城镇",711216:"礁溪乡",711217:"壮围乡",711218:"员山乡",711219:"罗东镇",711220:"三星乡",711221:"大同乡",711222:"五结乡",711223:"冬山乡",711224:"苏澳镇",711225:"南澳乡",711226:"钓鱼台",711300:"新竹县",711314:"竹北市",711315:"湖口乡",711316:"新丰乡",711317:"新埔镇",711318:"关西镇",711319:"芎林乡",711320:"宝山乡",711321:"竹东镇",711322:"五峰乡",711323:"横山乡",711324:"尖石乡",711325:"北埔乡",711326:"峨眉乡",711400:"桃园县",711414:"中坜市",711415:"平镇市",711416:"龙潭乡",711417:"杨梅市",711418:"新屋乡",711419:"观音乡",711420:"桃园市",711421:"龟山乡",711422:"八德市",711423:"大溪镇",711424:"复兴乡",711425:"大园乡",711426:"芦竹乡",711500:"苗栗县",711519:"竹南镇",711520:"头份镇",711521:"三湾乡",711522:"南庄乡",711523:"狮潭乡",711524:"后龙镇",711525:"通霄镇",711526:"苑里镇",711527:"苗栗市",711528:"造桥乡",711529:"头屋乡",711530:"公馆乡",711531:"大湖乡",711532:"泰安乡",711533:"铜锣乡",711534:"三义乡",711535:"西湖乡",711536:"卓兰镇",711700:"彰化县",711727:"彰化市",711728:"芬园乡",711729:"花坛乡",711730:"秀水乡",711731:"鹿港镇",711732:"福兴乡",711733:"线西乡",711734:"和美镇",711735:"伸港乡",711736:"员林镇",711737:"社头乡",711738:"永靖乡",711739:"埔心乡",711740:"溪湖镇",711741:"大村乡",711742:"埔盐乡",711743:"田中镇",711744:"北斗镇",711745:"田尾乡",711746:"埤头乡",711747:"溪州乡",711748:"竹塘乡",711749:"二林镇",711750:"大城乡",711751:"芳苑乡",711752:"二水乡",711900:"嘉义县",711919:"番路乡",711920:"梅山乡",711921:"竹崎乡",711922:"阿里山乡",711923:"中埔乡",711924:"大埔乡",711925:"水上乡",711926:"鹿草乡",711927:"太保市",711928:"朴子市",711929:"东石乡",711930:"六脚乡",711931:"新港乡",711932:"民雄乡",711933:"大林镇",711934:"溪口乡",711935:"义竹乡",711936:"布袋镇",712100:"云林县",712121:"斗南镇",712122:"大埤乡",712123:"虎尾镇",712124:"土库镇",712125:"褒忠乡",712126:"东势乡",712127:"台西乡",712128:"仑背乡",712129:"麦寮乡",712130:"斗六市",712131:"林内乡",712132:"古坑乡",712133:"莿桐乡",712134:"西螺镇",712135:"二仑乡",712136:"北港镇",712137:"水林乡",712138:"口湖乡",712139:"四湖乡",712140:"元长乡",712400:"屏东县",712434:"屏东市",712435:"三地门乡",712436:"雾台乡",712437:"玛家乡",712438:"九如乡",712439:"里港乡",712440:"高树乡",712441:"盐埔乡",712442:"长治乡",712443:"麟洛乡",712444:"竹田乡",712445:"内埔乡",712446:"万丹乡",712447:"潮州镇",712448:"泰武乡",712449:"来义乡",712450:"万峦乡",712451:"崁顶乡",712452:"新埤乡",712453:"南州乡",712454:"林边乡",712455:"东港镇",712456:"琉球乡",712457:"佳冬乡",712458:"新园乡",712459:"枋寮乡",712460:"枋山乡",712461:"春日乡",712462:"狮子乡",712463:"车城乡",712464:"牡丹乡",712465:"恒春镇",712466:"满州乡",712500:"台东县",712517:"台东市",712518:"绿岛乡",712519:"兰屿乡",712520:"延平乡",712521:"卑南乡",712522:"鹿野乡",712523:"关山镇",712524:"海端乡",712525:"池上乡",712526:"东河乡",712527:"成功镇",712528:"长滨乡",712529:"金峰乡",712530:"大武乡",712531:"达仁乡",712532:"太麻里乡",712600:"花莲县",712615:"花莲市",712616:"新城乡",712617:"太鲁阁",712618:"秀林乡",712619:"吉安乡",712620:"寿丰乡",712621:"凤林镇",712622:"光复乡",712623:"丰滨乡",712624:"瑞穗乡",712625:"万荣乡",712626:"玉里镇",712627:"卓溪乡",712628:"富里乡",712700:"澎湖县",712707:"马公市",712708:"西屿乡",712709:"望安乡",712710:"七美乡",712711:"白沙乡",712712:"湖西乡",712800:"连江县",712805:"南竿乡",712806:"北竿乡",712807:"莒光乡",712808:"东引乡",81e4:"香港特别行政区",810100:"香港岛",810101:"中西区",810102:"湾仔",810103:"东区",810104:"南区",810200:"九龙",810201:"九龙城区",810202:"油尖旺区",810203:"深水埗区",810204:"黄大仙区",810205:"观塘区",810300:"新界",810301:"北区",810302:"大埔区",810303:"沙田区",810304:"西贡区",810305:"元朗区",810306:"屯门区",810307:"荃湾区",810308:"葵青区",810309:"离岛区",82e4:"澳门特别行政区",820100:"澳门半岛",820200:"离岛",99e4:"海外",990100:"海外"};function Pn(Nn){for(var Rn={},Dn=0,Ln;Dncs;cs++)Xs=nr.charAt(cs),Xs===` -`?(ai.seenCR||ai.line++,ai.column=1,ai.seenCR=!1):Xs==="\r"||Xs==="\u2028"||Xs==="\u2029"?(ai.line++,ai.column=1,ai.seenCR=!0):(ai.column++,ai.seenCR=!1)}return Ms!==va&&(Ms>va&&(Ms=0,Yl={line:1,column:1,seenCR:!1}),Pa(Yl,Ms,va),Ms=va),Yl}function ea(va){vs>Ba||(Ba>vs&&(vs=Ba,Cc=[]),Cc.push(va))}function la(va){var Pa=0;for(va.sort();PaBa?(ai=nr.charAt(Ba),Ba++):(ai=null,hi===0&&ea(Hc)),ai!==null?(_i=va,Pa=zc(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)):(Ba=va,va=yi),va}function wi(){var va,Pa,ai;return va=Ba,nr.charCodeAt(Ba)===92?(Pa=vc,Ba++):(Pa=null,hi===0&&ea(Wc)),Pa!==null?(Nd.test(nr.charAt(Ba))?(ai=nr.charAt(Ba),Ba++):(ai=null,hi===0&&ea(Kc)),ai!==null?(_i=va,Pa=Uc(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)):(Ba=va,va=yi),va}function Ti(){var va,Pa,ai,$i;if(va=Ba,nr.substr(Ba,2)===yc?(Pa=yc,Ba+=2):(Pa=null,hi===0&&ea(Gc)),Pa!==null){if(ai=[],xl.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(bc)),$i!==null)for(;$i!==null;)ai.push($i),xl.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(bc));else ai=yi;ai!==null?(_i=va,Pa=Ys(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)}else Ba=va,va=yi;return va}function Ei(){var va,Pa,ai,$i;if(va=Ba,nr.substr(Ba,2)===Yc?(Pa=Yc,Ba+=2):(Pa=null,hi===0&&ea(_u)),Pa!==null){if(ai=[],$c.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(Sc)),$i!==null)for(;$i!==null;)ai.push($i),$c.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(Sc));else ai=yi;ai!==null?(_i=va,Pa=Rd(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)}else Ba=va,va=yi;return va}function Ni(){var va,Pa,ai,$i;if(va=Ba,nr.substr(Ba,2)===Tu?(Pa=Tu,Ba+=2):(Pa=null,hi===0&&ea(Ad)),Pa!==null){if(ai=[],$c.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(Sc)),$i!==null)for(;$i!==null;)ai.push($i),$c.test(nr.charAt(Ba))?($i=nr.charAt(Ba),Ba++):($i=null,hi===0&&ea(Sc));else ai=yi;ai!==null?(_i=va,Pa=As(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)}else Ba=va,va=yi;return va}function Ri(){var va,Pa;return va=Ba,nr.substr(Ba,2)===yc?(Pa=yc,Ba+=2):(Pa=null,hi===0&&ea(Gc)),Pa!==null&&(_i=va,Pa=Md()),Pa===null&&(Ba=va),va=Pa,va}function Zi(){var va,Pa,ai;return va=Ba,nr.charCodeAt(Ba)===92?(Pa=vc,Ba++):(Pa=null,hi===0&&ea(Wc)),Pa!==null?(nr.length>Ba?(ai=nr.charAt(Ba),Ba++):(ai=null,hi===0&&ea(Hc)),ai!==null?(_i=va,Pa=Gs(ai),Pa===null&&(Ba=va),va=Pa):(Ba=va,va=yi)):(Ba=va,va=yi),va}var Qi,Ji=arguments.length>1?arguments[1]:{},Yi={regexp:ua},rl=ua,yi=null,il="",Tl="|",ul='"|"',ts=function(va,Pa){return Pa?new Pn(va,Pa[1]):va},ci=function(va,Pa,ai){return new In([va].concat(Pa).concat([ai]))},Ci="^",bi='"^"',Bi=function(){return new _n("start")},nl="$",el='"$"',gl=function(){return new _n("end")},ll=function(va,Pa){return new Dn(va,Pa)},Rl="Quantifier",ml=function(va,Pa){return Pa&&(va.greedy=!1),va},hl="{",zi='"{"',Pl=",",Cl='","',Fl="}",Bl='"}"',vl=function(va,Pa){return new Ln(va,Pa)},ns=",}",yl='",}"',js=function(va){return new Ln(va,1/0)},Ac=function(va){return new Ln(va,va)},Mc="+",rc='"+"',ac=function(){return new Ln(1,1/0)},Hs="*",Dc='"*"',ps=function(){return new Ln(0,1/0)},zs="?",ic='"?"',lc=function(){return new Ln(0,1)},Ws=/^[0-9]/,Ps="[0-9]",Is=function(va){return+va.join("")},sc="(",Os='"("',is=")",cc='")"',bl=function(va){return va},jl=function(va){return new Rn(va)},Es="?:",gs='"?:"',Ul=function(va){return new Nn("non-capture-group",va)},Ks="?=",uc='"?="',ms=function(va){return new Nn("positive-lookahead",va)},Gl="?!",Us='"?!"',Ns=function(va){return new Nn("negative-lookahead",va)},cd="CharacterSet",cu="[",uu='"["',du="]",fu='"]"',ud=function(va,Pa){return new Fn(!!va,Pa)},dd="CharacterRange",fd="-",pu='"-"',pd=function(va,Pa){return new Bn(va,Pa)},gd="Character",md=/^[^\\\]]/,hd="[^\\\\\\]]",Gs=function(va){return new Hn(va)},vd=".",yd='"."',bd=function(){return new _n("any-character")},$d="Literal",Sd=/^[^|\\\/.[()?+*$\^]/,Xi="[^|\\\\\\/.[()?+*$\\^]",Wi="\\b",gu='"\\\\b"',Cd=function(){return new _n("backspace")},xd=function(){return new _n("word-boundary")},mu="\\B",wd='"\\\\B"',_d=function(){return new _n("non-word-boundary")},kc="\\d",Td='"\\\\d"',dl=function(){return new _n("digit")},dc="\\D",hs='"\\\\D"',hu=function(){return new _n("non-digit")},fc="\\f",Al='"\\\\f"',vu=function(){return new _n("form-feed")},Lc="\\n",yu='"\\\\n"',bu=function(){return new _n("line-feed")},Vc="\\r",$u='"\\\\r"',Il=function(){return new _n("carriage-return")},Su="\\s",Ml='"\\\\s"',Pd=function(){return new _n("white-space")},Fc="\\S",ls='"\\\\S"',pc=function(){return new _n("non-white-space")},gc="\\t",tl='"\\\\t"',ss=function(){return new _n("tab")},mc="\\v",Id='"\\\\v"',Bc=function(){return new _n("vertical-tab")},Cu="\\w",Od='"\\\\w"',Ed=function(){return new _n("word")},jc="\\W",hc='"\\\\W"',Rs=function(){return new _n("non-word")},xu="\\c",wu='"\\\\c"',Hc="any character",zc=function(va){return new Go(va)},vc="\\",Wc='"\\\\"',Nd=/^[1-9]/,Kc="[1-9]",Uc=function(va){return new Gn(va)},yc="\\0",Gc='"\\\\0"',xl=/^[0-7]/,bc="[0-7]",Ys=function(va){return new Yn(va.join(""))},Yc="\\x",_u='"\\\\x"',$c=/^[0-9a-fA-F]/,Sc="[0-9a-fA-F]",Rd=function(va){return new Wn(va.join(""))},Tu="\\u",Ad='"\\\\u"',As=function(va){return new zn(va.join(""))},Md=function(){return new _n("null-character")},Ba=0,_i=0,Ms=0,Yl={line:1,column:1,seenCR:!1},vs=0,Cc=[],hi=0;if("startRule"in Ji){if(!(Ji.startRule in Yi))throw new Error(`Can't start parsing from rule "`+Ji.startRule+'".');rl=Yi[Ji.startRule]}if(_n.offset=oa,_n.text=ta,Qi=rl(),Qi!==null&&Ba===nr.length)return Qi;throw la(Cc),_i=Math.max(Ba,vs),new Zo(Cc,_izn)return!0;var Gn={path:Bn,type:Fn,actual:Hn,expected:zn,action:"is greater than",message:Yn};return Gn.message=Ln.message(Gn),Wn.push(Gn),!1},lessThan:function(Fn,Bn,Hn,zn,Wn,Yn){if(Hn=zn)return!0;var Gn={path:Bn,type:Fn,actual:Hn,expected:zn,action:"is greater than or equal to",message:Yn};return Gn.message=Ln.message(Gn),Wn.push(Gn),!1},lessThanOrEqualTo:function(Fn,Bn,Hn,zn,Wn,Yn){if(Hn<=zn)return!0;var Gn={path:Bn,type:Fn,actual:Hn,expected:zn,action:"is less than or equal to",message:Yn};return Gn.message=Ln.message(Gn),Wn.push(Gn),!1}};Rn.Diff=Dn,Rn.Assert=Ln,$n.exports=Rn},function($n,Cn,_n){$n.exports=_n(28)},function($n,Cn,_n){var Pn=_n(3);window._XMLHttpRequest=window.XMLHttpRequest,window._ActiveXObject=window.ActiveXObject;try{new window.Event("custom")}catch{window.Event=function(Yn,Gn,Go,Xn){var Yo=document.createEvent("CustomEvent");return Yo.initCustomEvent(Yn,Gn,Go,Xn),Yo}}var In={UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4},Nn="readystatechange loadstart progress abort error load timeout loadend".split(" "),Rn="timeout withCredentials".split(" "),Dn="readyState responseURL status statusText responseType response responseText responseXML".split(" "),Ln={100:"Continue",101:"Switching Protocols",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",300:"Multiple Choice",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported"};function Fn(){this.custom={events:{},requestHeaders:{},responseHeaders:{}}}Fn._settings={timeout:"10-100"},Fn.setup=function(Wn){return Pn.extend(Fn._settings,Wn),Fn._settings},Pn.extend(Fn,In),Pn.extend(Fn.prototype,In),Fn.prototype.mock=!0,Fn.prototype.match=!1,Pn.extend(Fn.prototype,{open:function(Wn,Yn,Gn,Go,Xn){var Yo=this;Pn.extend(this.custom,{method:Wn,url:Yn,async:typeof Gn=="boolean"?Gn:!0,username:Go,password:Xn,options:{url:Yn,type:Wn}}),this.custom.timeout=function(ta){if(typeof ta=="number")return ta;if(typeof ta=="string"&&!~ta.indexOf("-"))return parseInt(ta,10);if(typeof ta=="string"&&~ta.indexOf("-")){var oa=ta.split("-"),ra=parseInt(oa[0],10),ea=parseInt(oa[1],10);return Math.round(Math.random()*(ea-ra))+ra}}(Fn._settings.timeout);var qo=Hn(this.custom.options);function Jo(ta){for(var oa=0;oa({code:200,message:"success",data:"http://8.147.104.101:3000/d/a0b114ca-edf7-4dfe-ac2c-34a4fc545fed/application?orgId=1&refresh=1m&from=1711855893859&to=1711877493859&theme=light"}));Mock.mock(devTool.mockUrl("/mock/application/search"),"get",()=>{const $n=Mock.mock("@integer(3, 20)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({appName:Mock.Random.pick(["QuickStartApplication","shop-comment","shop-detail","shop-order","shop-user"]),deployClusters:[Mock.Random.pick(["default","prod","test"])],instanceCount:Mock.mock("@integer(1, 5)"),registryClusters:[`${Mock.mock("@ip")}:8848`]});return{code:200,msg:"success",data:{list:Cn,pageInfo:{Total:$n,NextOffset:""}}}});Mock.mock("/mock/application/instance/statistics","get",()=>({code:1e3,message:"success",data:{instanceTotal:43,versionTotal:4,cpuTotal:"56c",memoryTotal:"108.2GB"}}));Mock.mock(devTool.mockUrl("/mock/application/instance/info"),"get",()=>{let $n=Mock.mock("@integer(8, 100)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ip:"121.90.211.162",name:"shop-user",deployState:Mock.Random.pick(["Running","Pending","Terminating","Crashing"]),deployCluster:"tx-shanghai-1",registerState:"Registed",registerClusters:["ali-hangzhou-1","ali-hangzhou-2"],cpu:"1.2c",memory:"2349MB",startTime:"2023-06-09 03:47:10",registerTime:"2023-06-09 03:48:20",labels:{region:"beijing",version:"v1"}});return{code:200,msg:"success",data:Mock.mock({pageInfo:{Total:Cn.length,NextOffset:0},list:Cn})}});Mock.mock(devTool.mockUrl("/mock/application/detail"),"get",()=>({code:200,msg:"success",data:{appName:Mock.mock("@word(10,20)"),appTypes:Mock.mock({"array|2-5":["@word(5,10)"]}).array,deployClusters:Mock.mock({"array|3-6":["@word(8,15)"]}).array,dubboPorts:Mock.mock({"array|1-3":["@integer(10000,65535)"]}).array,dubboVersions:Mock.mock({"array|2-4":["@word(3,8)"]}).array,images:Mock.mock({"array|2-5":["@word(10,20)"]}).array,registerClusters:Mock.mock({"array|2-4":["@word(8,15)"]}).array,registerModes:Mock.mock({"array|1-3":["@word(5,10)"]}).array,rpcProtocols:Mock.mock({"array|2-4":["@word(3,8)"]}).array,serialProtocols:Mock.mock({"array|2-4":["@word(4,8)"]}).array,workloads:Mock.mock({"array|3-6":["@word(6,12)"]}).array}}));Mock.mock("/mock/application/event","get",()=>({code:200,message:"success",data:{...Mock.mock({"list|10":[{desc:"Scaled down replica set shop-detail-v1-5847b7cdfd to @integer(3,10) from @integer(3,10)",time:'@DATETIME("yyyy-MM-dd HH:mm:ss")',type:"deployment-controller"}]})}}));Mock.mock(devTool.mockUrl("/mock/application/service/form"),"get",()=>({code:200,message:"success",data:{list:[],pageInfo:{Total:0,NextOffset:""}}}));const __vite_glob_0_0=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/metrics/cluster","get",{code:200,message:"成功",data:{all:Mock.mock("@integer(100, 500)"),application:Mock.mock("@integer(80, 200)"),consumers:Mock.mock("@integer(80, 200)"),providers:Mock.mock("@integer(80, 200)"),services:Mock.mock("@integer(80, 200)")}});const __vite_glob_0_1=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/destinationRule/search","get",()=>{const $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ruleName:"app_"+Mock.mock("@string(2,10)"),createTime:Mock.mock("@datetime")});return{code:200,message:"success",data:Mock.mock({total:$n,curPage:1,pageSize:10,data:Cn})}});const __vite_glob_0_2=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/dynamicConfig/search","get",()=>{const $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ruleName:"app_"+Mock.mock("@string(2,10)"),ruleGranularity:Mock.mock("@boolean"),enable:Mock.mock("@boolean"),createTime:Mock.mock("@datetime")});return{code:200,message:"success",data:Mock.mock({total:$n,curPage:1,pageSize:10,data:Cn})}});const __vite_glob_0_3=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(/\/search\?searchType=\w+&keywords=\w*/,"get",{code:200,message:"成功",data:{find:!0,candidates:["test1","test2","tset3"]}});const __vite_glob_0_4=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(devTool.mockUrl("/mock/instance/search"),"get",()=>{let $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ip:"121.90.211.162",name:"shop-user",deployState:Mock.Random.pick(["Running","Pending","Terminating","Crashing"]),deployCluster:"tx-shanghai-1",registerState:"Registed",registerClusters:["ali-hangzhou-1","ali-hangzhou-2"],cpu:"1.2c",memory:"2349MB",startTime_k8s:"2023-06-09 03:47:10",registerTime:"2023-06-09 03:48:20",labels:{region:"beijing",version:"v1"}});return{code:200,msg:"success",data:Mock.mock({pageInfo:{Total:$n,NextOffset:"0"},list:Cn})}});Mock.mock(devTool.mockUrl("/mock/instance/detail"),"get",()=>({code:200,msg:"success",data:{deployState:"Running",registerStates:"Unregisted",ip:"45.7.37.227",rpcPort:"20880",appName:"shop-user",workloadName:"shop-user-prod(deployment)",labels:{app:"shop-user",version:"v1",region:"beijing"},createTime:"2023/12/19 22:09:34",readyTime:"2023/12/19 22:12:34",registerTime:"2023/12/19 22:16:56",registerClusters:["sz-ali-zk-f8otyo4r","hz-ali-zk-oqgiq9gq"],deployCluster:"tx-shanghai-1",node:"hz-ali-30.33.0.1",image:"apache/org.apahce.dubbo.samples.shop-user:v1",probes:{startupProbe:{type:"http",open:!0},readinessProbe:{type:"http",open:!0},livenessProbe:{type:"http",open:!0}}}}));Mock.mock("/mock/instance/metrics","get",()=>({code:200,message:"success",data:"http://8.147.104.101:3000/d/dcf5defe-d198-4704-9edf-6520838880e9/instance?orgId=1&refresh=1m&from=1710644821536&to=1710731221536&theme=light"}));const __vite_glob_0_5=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(devTool.mockUrl("/mock/condition-rule/search"),"get",()=>{const $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ruleName:"app_"+Mock.mock("@string(2,10)"),ruleGranularity:Mock.mock("@boolean"),enable:Mock.mock("@boolean"),createTime:Mock.mock("@datetime")});return{code:200,msg:"success",data:{pageInfo:{Total:$n,NextOffset:"0"},list:Cn}}});const __vite_glob_0_6=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(devTool.mockUrl("/mock/metadata"),"get",{code:200,msg:"success",data:{registry:"nacos://47.101.215.139:8848?username=nacos&password=nacos",metadata:"nacos://47.101.215.139:8848?username=nacos&password=nacos",config:"nacos://47.101.215.139:8848?username=nacos&password=nacos",prometheus:"http://prometheus.observability.svc.cluster.local:9090/",grafana:"http://47.251.100.138:3000/d/a0b114ca-edf7-4dfe-ac2c-34a4fc545fed/application",tracing:"http://47.251.100.138:3000/d/e968a89b-f03d-42e3-8ad3-930ae815cb0f/application"}});Mock.mock(devTool.mockUrl("/mock/overview"),"get",{code:200,msg:"success",data:{appCount:0,serviceCount:0,insCount:0,protocols:{},releases:{},discoveries:{}}});const __vite_glob_0_7=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(devTool.mockUrl("/mock/service/search"),"get",{code:200,msg:"success",data:{pageInfo:{Total:8,NextOffset:"0"},list:[{serviceName:"org.apache.dubbo.samples.UserService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:6,avgRT:"194ms",requestTotal:200},{serviceName:"org.apache.dubbo.samples.OrderService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:13,avgRT:"189ms",requestTotal:164},{serviceName:"org.apache.dubbo.samples.DetailService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:.5,avgRT:"268ms",requestTotal:1324},{serviceName:"org.apache.dubbo.samples.PayService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:9,avgRT:"346ms",requestTotal:189},{serviceName:"org.apache.dubbo.samples.CommentService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:8,avgRT:"936ms",requestTotal:200},{serviceName:"org.apache.dubbo.samples.RepayService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:17,avgRT:"240ms",requestTotal:146},{serviceName:"org.apche.dubbo.samples.TransportService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:43,avgRT:"89ms",requestTotal:367},{serviceName:"org.apche.dubbo.samples.DistributionService",versionGroups:[{version:"1.0.0",group:"group1"},{version:"1.0.0",group:null},{version:null,group:"group1"},{version:null,group:null}],avgQPS:4,avgRT:"78ms",requestTotal:145}]}});Mock.mock(devTool.mockUrl("/mock/service/distribution"),"get",()=>({code:200,msg:"success",data:{pageInfo:{Total:8,NextOffset:"0"},list:[]}}));const __vite_glob_0_8=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/service/detail","get",{code:200,message:"success",data:{total:8,curPage:1,pageSize:1,data:{serviceName:"org.apache.dubbo.samples.UserService",versionGroup:["version=v1","version=2.0,group=group1"],protocol:"triple",delay:"3000ms",timeOut:"3000ms",retry:3,requestTotal:1384,avgRT:"96ms",avgQPS:12,obsolete:!1}}});const __vite_glob_0_9=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/service/distribution","get",{code:200,message:"success",data:{total:8,curPage:1,pageSize:1,data:[{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order0",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=beijing"},{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order1",rpcPort:"172.168.45.24:20888",timeout:"500ms",retryNum:"1",label:"region=wuhan"},{applicationName:"shop-user",instanceNum:12,instanceName:"shop-order2",rpcPort:"172.161.23.89:20888",timeout:"200ms",retryNum:"1",label:"region=shanghai"},{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order3",rpcPort:"172.168.45.89:12423",timeout:"2000ms",retryNum:"2",label:"region=hangzhou"},{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order4",rpcPort:"172.168.45.89:20888",timeout:"100ms",retryNum:"0",label:"region=wuxi"},{applicationName:"shop-user",instanceNum:12,instanceName:"shop-order5",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=beijing"},{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order6",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=ningbo"},{applicationName:"shop-user",instanceNum:12,instanceName:"shop-order7",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=shenzhen"},{applicationName:"shop-user",instanceNum:12,instanceName:"shop-order8",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=guangzhou"},{applicationName:"shop-order",instanceNum:15,instanceName:"shop-order9",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=nanjing"},{applicationName:"shop-user",instanceNum:12,instanceName:"shop-order10",rpcPort:"172.168.45.89:20888",timeout:"1000ms",retryNum:"2",label:"region=beijing"}]}});const __vite_glob_0_10=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock(devTool.mockUrl("/mock/tag-rule/search"),"get",()=>{const $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ruleName:"app_"+Mock.mock("@string(2,10)"),enable:Mock.mock("@boolean"),createTime:Mock.mock("@datetime")});return{code:200,msg:"success",data:{pageInfo:{Total:$n,NextOffset:"0"},list:Cn}}});const __vite_glob_0_11=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/version","get",{code:200,message:"成功",data:{gitVersion:"dubbo-admin-",gitCommit:"$Format:%H$",gitTreeState:"",buildDate:"1970-01-01T00:00:00Z",goVersion:"go1.20.4",compiler:"gc",platform:"darwin/arm64"}});const __vite_glob_0_12=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));Mock.mock("/mock/virtualService/search","get",()=>{const $n=Mock.mock("@integer(8, 1000)"),Cn=[];for(let _n=0;_n<$n;_n++)Cn.push({ruleName:"app_"+Mock.mock("@string(2,10)"),createTime:Mock.mock("@datetime"),lastModifiedTime:Mock.mock("@datetime")});return{code:200,message:"success",data:Mock.mock({total:$n,curPage:1,pageSize:10,data:Cn})}});const __vite_glob_0_13=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),modulesFiles=Object.assign({"./mockApp.ts":__vite_glob_0_0,"./mockCluster.ts":__vite_glob_0_1,"./mockDestinationRule.ts":__vite_glob_0_2,"./mockDynamicConfig.ts":__vite_glob_0_3,"./mockGlobalSearch.ts":__vite_glob_0_4,"./mockInstance.ts":__vite_glob_0_5,"./mockRoutingRule.ts":__vite_glob_0_6,"./mockServer.ts":__vite_glob_0_7,"./mockService.ts":__vite_glob_0_8,"./mockServiceDetail.ts":__vite_glob_0_9,"./mockServiceDistribution.ts":__vite_glob_0_10,"./mockTagRule.ts":__vite_glob_0_11,"./mockVersion.ts":__vite_glob_0_12,"./mockVirtualService.ts":__vite_glob_0_13}),fileList=[];for(const $n of Object.keys(modulesFiles))fileList.push(modulesFiles[$n].default);function tryOnScopeDispose($n){return getCurrentScope()?(onScopeDispose($n),!0):!1}function toValue($n){return typeof $n=="function"?$n():unref($n)}const isClient=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const toString=Object.prototype.toString,isObject$1=$n=>toString.call($n)==="[object Object]",noop=()=>{},isIOS=getIsIOS();function getIsIOS(){var $n,Cn;return isClient&&(($n=window==null?void 0:window.navigator)==null?void 0:$n.userAgent)&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||((Cn=window==null?void 0:window.navigator)==null?void 0:Cn.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function createFilterWrapper($n,Cn){function _n(...Pn){return new Promise((In,Nn)=>{Promise.resolve($n(()=>Cn.apply(this,Pn),{fn:Cn,thisArg:this,args:Pn})).then(In).catch(Nn)})}return _n}const bypassFilter=$n=>$n();function debounceFilter($n,Cn={}){let _n,Pn,In=noop;const Nn=Dn=>{clearTimeout(Dn),In(),In=noop};return Dn=>{const Ln=toValue($n),Fn=toValue(Cn.maxWait);return _n&&Nn(_n),Ln<=0||Fn!==void 0&&Fn<=0?(Pn&&(Nn(Pn),Pn=null),Promise.resolve(Dn())):new Promise((Bn,Hn)=>{In=Cn.rejectOnCancel?Hn:Bn,Fn&&!Pn&&(Pn=setTimeout(()=>{_n&&Nn(_n),Pn=null,Bn(Dn())},Fn)),_n=setTimeout(()=>{Pn&&Nn(Pn),Pn=null,Bn(Dn())},Ln)})}}function pausableFilter($n=bypassFilter){const Cn=ref(!0);function _n(){Cn.value=!1}function Pn(){Cn.value=!0}const In=(...Nn)=>{Cn.value&&$n(...Nn)};return{isActive:readonly(Cn),pause:_n,resume:Pn,eventFilter:In}}function getLifeCycleTarget($n){return $n||getCurrentInstance()}function useDebounceFn($n,Cn=200,_n={}){return createFilterWrapper(debounceFilter(Cn,_n),$n)}function watchWithFilter($n,Cn,_n={}){const{eventFilter:Pn=bypassFilter,...In}=_n;return watch($n,createFilterWrapper(Pn,Cn),In)}function watchPausable($n,Cn,_n={}){const{eventFilter:Pn,...In}=_n,{eventFilter:Nn,pause:Rn,resume:Dn,isActive:Ln}=pausableFilter(Pn);return{stop:watchWithFilter($n,Cn,{...In,eventFilter:Nn}),pause:Rn,resume:Dn,isActive:Ln}}function tryOnMounted($n,Cn=!0,_n){getLifeCycleTarget()?onMounted($n,_n):Cn?$n():nextTick($n)}function whenever($n,Cn,_n){return watch($n,(Pn,In,Nn)=>{Pn&&Cn(Pn,In,Nn)},_n)}function unrefElement($n){var Cn;const _n=toValue($n);return(Cn=_n==null?void 0:_n.$el)!=null?Cn:_n}const defaultWindow=isClient?window:void 0;function useEventListener(...$n){let Cn,_n,Pn,In;if(typeof $n[0]=="string"||Array.isArray($n[0])?([_n,Pn,In]=$n,Cn=defaultWindow):[Cn,_n,Pn,In]=$n,!Cn)return noop;Array.isArray(_n)||(_n=[_n]),Array.isArray(Pn)||(Pn=[Pn]);const Nn=[],Rn=()=>{Nn.forEach(Bn=>Bn()),Nn.length=0},Dn=(Bn,Hn,zn,Wn)=>(Bn.addEventListener(Hn,zn,Wn),()=>Bn.removeEventListener(Hn,zn,Wn)),Ln=watch(()=>[unrefElement(Cn),toValue(In)],([Bn,Hn])=>{if(Rn(),!Bn)return;const zn=isObject$1(Hn)?{...Hn}:Hn;Nn.push(..._n.flatMap(Wn=>Pn.map(Yn=>Dn(Bn,Wn,Yn,zn))))},{immediate:!0,flush:"post"}),Fn=()=>{Ln(),Rn()};return tryOnScopeDispose(Fn),Fn}let _iOSWorkaround=!1;function onClickOutside($n,Cn,_n={}){const{window:Pn=defaultWindow,ignore:In=[],capture:Nn=!0,detectIframe:Rn=!1}=_n;if(!Pn)return noop;isIOS&&!_iOSWorkaround&&(_iOSWorkaround=!0,Array.from(Pn.document.body.children).forEach(zn=>zn.addEventListener("click",noop)),Pn.document.documentElement.addEventListener("click",noop));let Dn=!0;const Ln=zn=>In.some(Wn=>{if(typeof Wn=="string")return Array.from(Pn.document.querySelectorAll(Wn)).some(Yn=>Yn===zn.target||zn.composedPath().includes(Yn));{const Yn=unrefElement(Wn);return Yn&&(zn.target===Yn||zn.composedPath().includes(Yn))}}),Bn=[useEventListener(Pn,"click",zn=>{const Wn=unrefElement($n);if(!(!Wn||Wn===zn.target||zn.composedPath().includes(Wn))){if(zn.detail===0&&(Dn=!Ln(zn)),!Dn){Dn=!0;return}Cn(zn)}},{passive:!0,capture:Nn}),useEventListener(Pn,"pointerdown",zn=>{const Wn=unrefElement($n);Dn=!Ln(zn)&&!!(Wn&&!zn.composedPath().includes(Wn))},{passive:!0}),Rn&&useEventListener(Pn,"blur",zn=>{setTimeout(()=>{var Wn;const Yn=unrefElement($n);((Wn=Pn.document.activeElement)==null?void 0:Wn.tagName)==="IFRAME"&&!(Yn!=null&&Yn.contains(Pn.document.activeElement))&&Cn(zn)},0)})].filter(Boolean);return()=>Bn.forEach(zn=>zn())}const _global=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},globalKey="__vueuse_ssr_handlers__",handlers=getHandlers();function getHandlers(){return globalKey in _global||(_global[globalKey]=_global[globalKey]||{}),_global[globalKey]}function getSSRHandler($n,Cn){return handlers[$n]||Cn}function guessSerializerType($n){return $n==null?"any":$n instanceof Set?"set":$n instanceof Map?"map":$n instanceof Date?"date":typeof $n=="boolean"?"boolean":typeof $n=="string"?"string":typeof $n=="object"?"object":Number.isNaN($n)?"any":"number"}const StorageSerializers={boolean:{read:$n=>$n==="true",write:$n=>String($n)},object:{read:$n=>JSON.parse($n),write:$n=>JSON.stringify($n)},number:{read:$n=>Number.parseFloat($n),write:$n=>String($n)},any:{read:$n=>$n,write:$n=>String($n)},string:{read:$n=>$n,write:$n=>String($n)},map:{read:$n=>new Map(JSON.parse($n)),write:$n=>JSON.stringify(Array.from($n.entries()))},set:{read:$n=>new Set(JSON.parse($n)),write:$n=>JSON.stringify(Array.from($n))},date:{read:$n=>new Date($n),write:$n=>$n.toISOString()}},customStorageEventName="vueuse-storage";function useStorage($n,Cn,_n,Pn={}){var In;const{flush:Nn="pre",deep:Rn=!0,listenToStorageChanges:Dn=!0,writeDefaults:Ln=!0,mergeDefaults:Fn=!1,shallow:Bn,window:Hn=defaultWindow,eventFilter:zn,onError:Wn=oa=>{console.error(oa)},initOnMounted:Yn}=Pn,Gn=(Bn?shallowRef:ref)(typeof Cn=="function"?Cn():Cn);if(!_n)try{_n=getSSRHandler("getDefaultStorage",()=>{var oa;return(oa=defaultWindow)==null?void 0:oa.localStorage})()}catch(oa){Wn(oa)}if(!_n)return Gn;const Go=toValue(Cn),Xn=guessSerializerType(Go),Yo=(In=Pn.serializer)!=null?In:StorageSerializers[Xn],{pause:qo,resume:Jo}=watchPausable(Gn,()=>Zo(Gn.value),{flush:Nn,deep:Rn,eventFilter:zn});return Hn&&Dn&&tryOnMounted(()=>{useEventListener(Hn,"storage",ta),useEventListener(Hn,customStorageEventName,nr),Yn&&ta()}),Yn||ta(),Gn;function Zo(oa){try{if(oa==null)_n.removeItem($n);else{const ra=Yo.write(oa),ea=_n.getItem($n);ea!==ra&&(_n.setItem($n,ra),Hn&&Hn.dispatchEvent(new CustomEvent(customStorageEventName,{detail:{key:$n,oldValue:ea,newValue:ra,storageArea:_n}})))}}catch(ra){Wn(ra)}}function rr(oa){const ra=oa?oa.newValue:_n.getItem($n);if(ra==null)return Ln&&Go!=null&&_n.setItem($n,Yo.write(Go)),Go;if(!oa&&Fn){const ea=Yo.read(ra);return typeof Fn=="function"?Fn(ea,Go):Xn==="object"&&!Array.isArray(ea)?{...Go,...ea}:ea}else return typeof ra!="string"?ra:Yo.read(ra)}function nr(oa){ta(oa.detail)}function ta(oa){if(!(oa&&oa.storageArea!==_n)){if(oa&&oa.key==null){Gn.value=Go;return}if(!(oa&&oa.key!==$n)){qo();try{(oa==null?void 0:oa.newValue)!==Yo.write(Gn.value)&&(Gn.value=rr(oa))}catch(ra){Wn(ra)}finally{oa?nextTick(Jo):Jo()}}}}}function useLocalStorage($n,Cn,_n={}){const{window:Pn=defaultWindow}=_n;return useStorage($n,Cn,Pn==null?void 0:Pn.localStorage,_n)}function _typeof($n){"@babel/helpers - typeof";return _typeof=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(Cn){return typeof Cn}:function(Cn){return Cn&&typeof Symbol=="function"&&Cn.constructor===Symbol&&Cn!==Symbol.prototype?"symbol":typeof Cn},_typeof($n)}var trimLeft=/^\s+/,trimRight=/\s+$/;function tinycolor($n,Cn){if($n=$n||"",Cn=Cn||{},$n instanceof tinycolor)return $n;if(!(this instanceof tinycolor))return new tinycolor($n,Cn);var _n=inputToRGB($n);this._originalInput=$n,this._r=_n.r,this._g=_n.g,this._b=_n.b,this._a=_n.a,this._roundA=Math.round(100*this._a)/100,this._format=Cn.format||_n.format,this._gradientType=Cn.gradientType,this._r<1&&(this._r=Math.round(this._r)),this._g<1&&(this._g=Math.round(this._g)),this._b<1&&(this._b=Math.round(this._b)),this._ok=_n.ok}tinycolor.prototype={isDark:function $n(){return this.getBrightness()<128},isLight:function $n(){return!this.isDark()},isValid:function $n(){return this._ok},getOriginalInput:function $n(){return this._originalInput},getFormat:function $n(){return this._format},getAlpha:function $n(){return this._a},getBrightness:function $n(){var Cn=this.toRgb();return(Cn.r*299+Cn.g*587+Cn.b*114)/1e3},getLuminance:function $n(){var Cn=this.toRgb(),_n,Pn,In,Nn,Rn,Dn;return _n=Cn.r/255,Pn=Cn.g/255,In=Cn.b/255,_n<=.03928?Nn=_n/12.92:Nn=Math.pow((_n+.055)/1.055,2.4),Pn<=.03928?Rn=Pn/12.92:Rn=Math.pow((Pn+.055)/1.055,2.4),In<=.03928?Dn=In/12.92:Dn=Math.pow((In+.055)/1.055,2.4),.2126*Nn+.7152*Rn+.0722*Dn},setAlpha:function $n(Cn){return this._a=boundAlpha(Cn),this._roundA=Math.round(100*this._a)/100,this},toHsv:function $n(){var Cn=rgbToHsv(this._r,this._g,this._b);return{h:Cn.h*360,s:Cn.s,v:Cn.v,a:this._a}},toHsvString:function $n(){var Cn=rgbToHsv(this._r,this._g,this._b),_n=Math.round(Cn.h*360),Pn=Math.round(Cn.s*100),In=Math.round(Cn.v*100);return this._a==1?"hsv("+_n+", "+Pn+"%, "+In+"%)":"hsva("+_n+", "+Pn+"%, "+In+"%, "+this._roundA+")"},toHsl:function $n(){var Cn=rgbToHsl(this._r,this._g,this._b);return{h:Cn.h*360,s:Cn.s,l:Cn.l,a:this._a}},toHslString:function $n(){var Cn=rgbToHsl(this._r,this._g,this._b),_n=Math.round(Cn.h*360),Pn=Math.round(Cn.s*100),In=Math.round(Cn.l*100);return this._a==1?"hsl("+_n+", "+Pn+"%, "+In+"%)":"hsla("+_n+", "+Pn+"%, "+In+"%, "+this._roundA+")"},toHex:function $n(Cn){return rgbToHex(this._r,this._g,this._b,Cn)},toHexString:function $n(Cn){return"#"+this.toHex(Cn)},toHex8:function $n(Cn){return rgbaToHex(this._r,this._g,this._b,this._a,Cn)},toHex8String:function $n(Cn){return"#"+this.toHex8(Cn)},toRgb:function $n(){return{r:Math.round(this._r),g:Math.round(this._g),b:Math.round(this._b),a:this._a}},toRgbString:function $n(){return this._a==1?"rgb("+Math.round(this._r)+", "+Math.round(this._g)+", "+Math.round(this._b)+")":"rgba("+Math.round(this._r)+", "+Math.round(this._g)+", "+Math.round(this._b)+", "+this._roundA+")"},toPercentageRgb:function $n(){return{r:Math.round(bound01(this._r,255)*100)+"%",g:Math.round(bound01(this._g,255)*100)+"%",b:Math.round(bound01(this._b,255)*100)+"%",a:this._a}},toPercentageRgbString:function $n(){return this._a==1?"rgb("+Math.round(bound01(this._r,255)*100)+"%, "+Math.round(bound01(this._g,255)*100)+"%, "+Math.round(bound01(this._b,255)*100)+"%)":"rgba("+Math.round(bound01(this._r,255)*100)+"%, "+Math.round(bound01(this._g,255)*100)+"%, "+Math.round(bound01(this._b,255)*100)+"%, "+this._roundA+")"},toName:function $n(){return this._a===0?"transparent":this._a<1?!1:hexNames[rgbToHex(this._r,this._g,this._b,!0)]||!1},toFilter:function $n(Cn){var _n="#"+rgbaToArgbHex(this._r,this._g,this._b,this._a),Pn=_n,In=this._gradientType?"GradientType = 1, ":"";if(Cn){var Nn=tinycolor(Cn);Pn="#"+rgbaToArgbHex(Nn._r,Nn._g,Nn._b,Nn._a)}return"progid:DXImageTransform.Microsoft.gradient("+In+"startColorstr="+_n+",endColorstr="+Pn+")"},toString:function $n(Cn){var _n=!!Cn;Cn=Cn||this._format;var Pn=!1,In=this._a<1&&this._a>=0,Nn=!_n&&In&&(Cn==="hex"||Cn==="hex6"||Cn==="hex3"||Cn==="hex4"||Cn==="hex8"||Cn==="name");return Nn?Cn==="name"&&this._a===0?this.toName():this.toRgbString():(Cn==="rgb"&&(Pn=this.toRgbString()),Cn==="prgb"&&(Pn=this.toPercentageRgbString()),(Cn==="hex"||Cn==="hex6")&&(Pn=this.toHexString()),Cn==="hex3"&&(Pn=this.toHexString(!0)),Cn==="hex4"&&(Pn=this.toHex8String(!0)),Cn==="hex8"&&(Pn=this.toHex8String()),Cn==="name"&&(Pn=this.toName()),Cn==="hsl"&&(Pn=this.toHslString()),Cn==="hsv"&&(Pn=this.toHsvString()),Pn||this.toHexString())},clone:function $n(){return tinycolor(this.toString())},_applyModification:function $n(Cn,_n){var Pn=Cn.apply(null,[this].concat([].slice.call(_n)));return this._r=Pn._r,this._g=Pn._g,this._b=Pn._b,this.setAlpha(Pn._a),this},lighten:function $n(){return this._applyModification(_lighten,arguments)},brighten:function $n(){return this._applyModification(_brighten,arguments)},darken:function $n(){return this._applyModification(_darken,arguments)},desaturate:function $n(){return this._applyModification(_desaturate,arguments)},saturate:function $n(){return this._applyModification(_saturate,arguments)},greyscale:function $n(){return this._applyModification(_greyscale,arguments)},spin:function $n(){return this._applyModification(_spin,arguments)},_applyCombination:function $n(Cn,_n){return Cn.apply(null,[this].concat([].slice.call(_n)))},analogous:function $n(){return this._applyCombination(_analogous,arguments)},complement:function $n(){return this._applyCombination(_complement,arguments)},monochromatic:function $n(){return this._applyCombination(_monochromatic,arguments)},splitcomplement:function $n(){return this._applyCombination(_splitcomplement,arguments)},triad:function $n(){return this._applyCombination(polyad,[3])},tetrad:function $n(){return this._applyCombination(polyad,[4])}};tinycolor.fromRatio=function($n,Cn){if(_typeof($n)=="object"){var _n={};for(var Pn in $n)$n.hasOwnProperty(Pn)&&(Pn==="a"?_n[Pn]=$n[Pn]:_n[Pn]=convertToPercentage($n[Pn]));$n=_n}return tinycolor($n,Cn)};function inputToRGB($n){var Cn={r:0,g:0,b:0},_n=1,Pn=null,In=null,Nn=null,Rn=!1,Dn=!1;return typeof $n=="string"&&($n=stringInputToObject($n)),_typeof($n)=="object"&&(isValidCSSUnit($n.r)&&isValidCSSUnit($n.g)&&isValidCSSUnit($n.b)?(Cn=rgbToRgb($n.r,$n.g,$n.b),Rn=!0,Dn=String($n.r).substr(-1)==="%"?"prgb":"rgb"):isValidCSSUnit($n.h)&&isValidCSSUnit($n.s)&&isValidCSSUnit($n.v)?(Pn=convertToPercentage($n.s),In=convertToPercentage($n.v),Cn=hsvToRgb($n.h,Pn,In),Rn=!0,Dn="hsv"):isValidCSSUnit($n.h)&&isValidCSSUnit($n.s)&&isValidCSSUnit($n.l)&&(Pn=convertToPercentage($n.s),Nn=convertToPercentage($n.l),Cn=hslToRgb($n.h,Pn,Nn),Rn=!0,Dn="hsl"),$n.hasOwnProperty("a")&&(_n=$n.a)),_n=boundAlpha(_n),{ok:Rn,format:$n.format||Dn,r:Math.min(255,Math.max(Cn.r,0)),g:Math.min(255,Math.max(Cn.g,0)),b:Math.min(255,Math.max(Cn.b,0)),a:_n}}function rgbToRgb($n,Cn,_n){return{r:bound01($n,255)*255,g:bound01(Cn,255)*255,b:bound01(_n,255)*255}}function rgbToHsl($n,Cn,_n){$n=bound01($n,255),Cn=bound01(Cn,255),_n=bound01(_n,255);var Pn=Math.max($n,Cn,_n),In=Math.min($n,Cn,_n),Nn,Rn,Dn=(Pn+In)/2;if(Pn==In)Nn=Rn=0;else{var Ln=Pn-In;switch(Rn=Dn>.5?Ln/(2-Pn-In):Ln/(Pn+In),Pn){case $n:Nn=(Cn-_n)/Ln+(Cn<_n?6:0);break;case Cn:Nn=(_n-$n)/Ln+2;break;case _n:Nn=($n-Cn)/Ln+4;break}Nn/=6}return{h:Nn,s:Rn,l:Dn}}function hslToRgb($n,Cn,_n){var Pn,In,Nn;$n=bound01($n,360),Cn=bound01(Cn,100),_n=bound01(_n,100);function Rn(Fn,Bn,Hn){return Hn<0&&(Hn+=1),Hn>1&&(Hn-=1),Hn<1/6?Fn+(Bn-Fn)*6*Hn:Hn<1/2?Bn:Hn<2/3?Fn+(Bn-Fn)*(2/3-Hn)*6:Fn}if(Cn===0)Pn=In=Nn=_n;else{var Dn=_n<.5?_n*(1+Cn):_n+Cn-_n*Cn,Ln=2*_n-Dn;Pn=Rn(Ln,Dn,$n+1/3),In=Rn(Ln,Dn,$n),Nn=Rn(Ln,Dn,$n-1/3)}return{r:Pn*255,g:In*255,b:Nn*255}}function rgbToHsv($n,Cn,_n){$n=bound01($n,255),Cn=bound01(Cn,255),_n=bound01(_n,255);var Pn=Math.max($n,Cn,_n),In=Math.min($n,Cn,_n),Nn,Rn,Dn=Pn,Ln=Pn-In;if(Rn=Pn===0?0:Ln/Pn,Pn==In)Nn=0;else{switch(Pn){case $n:Nn=(Cn-_n)/Ln+(Cn<_n?6:0);break;case Cn:Nn=(_n-$n)/Ln+2;break;case _n:Nn=($n-Cn)/Ln+4;break}Nn/=6}return{h:Nn,s:Rn,v:Dn}}function hsvToRgb($n,Cn,_n){$n=bound01($n,360)*6,Cn=bound01(Cn,100),_n=bound01(_n,100);var Pn=Math.floor($n),In=$n-Pn,Nn=_n*(1-Cn),Rn=_n*(1-In*Cn),Dn=_n*(1-(1-In)*Cn),Ln=Pn%6,Fn=[_n,Rn,Nn,Nn,Dn,_n][Ln],Bn=[Dn,_n,_n,Rn,Nn,Nn][Ln],Hn=[Nn,Nn,Dn,_n,_n,Rn][Ln];return{r:Fn*255,g:Bn*255,b:Hn*255}}function rgbToHex($n,Cn,_n,Pn){var In=[pad2(Math.round($n).toString(16)),pad2(Math.round(Cn).toString(16)),pad2(Math.round(_n).toString(16))];return Pn&&In[0].charAt(0)==In[0].charAt(1)&&In[1].charAt(0)==In[1].charAt(1)&&In[2].charAt(0)==In[2].charAt(1)?In[0].charAt(0)+In[1].charAt(0)+In[2].charAt(0):In.join("")}function rgbaToHex($n,Cn,_n,Pn,In){var Nn=[pad2(Math.round($n).toString(16)),pad2(Math.round(Cn).toString(16)),pad2(Math.round(_n).toString(16)),pad2(convertDecimalToHex(Pn))];return In&&Nn[0].charAt(0)==Nn[0].charAt(1)&&Nn[1].charAt(0)==Nn[1].charAt(1)&&Nn[2].charAt(0)==Nn[2].charAt(1)&&Nn[3].charAt(0)==Nn[3].charAt(1)?Nn[0].charAt(0)+Nn[1].charAt(0)+Nn[2].charAt(0)+Nn[3].charAt(0):Nn.join("")}function rgbaToArgbHex($n,Cn,_n,Pn){var In=[pad2(convertDecimalToHex(Pn)),pad2(Math.round($n).toString(16)),pad2(Math.round(Cn).toString(16)),pad2(Math.round(_n).toString(16))];return In.join("")}tinycolor.equals=function($n,Cn){return!$n||!Cn?!1:tinycolor($n).toRgbString()==tinycolor(Cn).toRgbString()};tinycolor.random=function(){return tinycolor.fromRatio({r:Math.random(),g:Math.random(),b:Math.random()})};function _desaturate($n,Cn){Cn=Cn===0?0:Cn||10;var _n=tinycolor($n).toHsl();return _n.s-=Cn/100,_n.s=clamp01(_n.s),tinycolor(_n)}function _saturate($n,Cn){Cn=Cn===0?0:Cn||10;var _n=tinycolor($n).toHsl();return _n.s+=Cn/100,_n.s=clamp01(_n.s),tinycolor(_n)}function _greyscale($n){return tinycolor($n).desaturate(100)}function _lighten($n,Cn){Cn=Cn===0?0:Cn||10;var _n=tinycolor($n).toHsl();return _n.l+=Cn/100,_n.l=clamp01(_n.l),tinycolor(_n)}function _brighten($n,Cn){Cn=Cn===0?0:Cn||10;var _n=tinycolor($n).toRgb();return _n.r=Math.max(0,Math.min(255,_n.r-Math.round(255*-(Cn/100)))),_n.g=Math.max(0,Math.min(255,_n.g-Math.round(255*-(Cn/100)))),_n.b=Math.max(0,Math.min(255,_n.b-Math.round(255*-(Cn/100)))),tinycolor(_n)}function _darken($n,Cn){Cn=Cn===0?0:Cn||10;var _n=tinycolor($n).toHsl();return _n.l-=Cn/100,_n.l=clamp01(_n.l),tinycolor(_n)}function _spin($n,Cn){var _n=tinycolor($n).toHsl(),Pn=(_n.h+Cn)%360;return _n.h=Pn<0?360+Pn:Pn,tinycolor(_n)}function _complement($n){var Cn=tinycolor($n).toHsl();return Cn.h=(Cn.h+180)%360,tinycolor(Cn)}function polyad($n,Cn){if(isNaN(Cn)||Cn<=0)throw new Error("Argument to polyad must be a positive number");for(var _n=tinycolor($n).toHsl(),Pn=[tinycolor($n)],In=360/Cn,Nn=1;Nn>1)+720)%360;--Cn;)Pn.h=(Pn.h+In)%360,Nn.push(tinycolor(Pn));return Nn}function _monochromatic($n,Cn){Cn=Cn||6;for(var _n=tinycolor($n).toHsv(),Pn=_n.h,In=_n.s,Nn=_n.v,Rn=[],Dn=1/Cn;Cn--;)Rn.push(tinycolor({h:Pn,s:In,v:Nn})),Nn=(Nn+Dn)%1;return Rn}tinycolor.mix=function($n,Cn,_n){_n=_n===0?0:_n||50;var Pn=tinycolor($n).toRgb(),In=tinycolor(Cn).toRgb(),Nn=_n/100,Rn={r:(In.r-Pn.r)*Nn+Pn.r,g:(In.g-Pn.g)*Nn+Pn.g,b:(In.b-Pn.b)*Nn+Pn.b,a:(In.a-Pn.a)*Nn+Pn.a};return tinycolor(Rn)};tinycolor.readability=function($n,Cn){var _n=tinycolor($n),Pn=tinycolor(Cn);return(Math.max(_n.getLuminance(),Pn.getLuminance())+.05)/(Math.min(_n.getLuminance(),Pn.getLuminance())+.05)};tinycolor.isReadable=function($n,Cn,_n){var Pn=tinycolor.readability($n,Cn),In,Nn;switch(Nn=!1,In=validateWCAG2Parms(_n),In.level+In.size){case"AAsmall":case"AAAlarge":Nn=Pn>=4.5;break;case"AAlarge":Nn=Pn>=3;break;case"AAAsmall":Nn=Pn>=7;break}return Nn};tinycolor.mostReadable=function($n,Cn,_n){var Pn=null,In=0,Nn,Rn,Dn,Ln;_n=_n||{},Rn=_n.includeFallbackColors,Dn=_n.level,Ln=_n.size;for(var Fn=0;FnIn&&(In=Nn,Pn=tinycolor(Cn[Fn]));return tinycolor.isReadable($n,Pn,{level:Dn,size:Ln})||!Rn?Pn:(_n.includeFallbackColors=!1,tinycolor.mostReadable($n,["#fff","#000"],_n))};var names=tinycolor.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},hexNames=tinycolor.hexNames=flip$2(names);function flip$2($n){var Cn={};for(var _n in $n)$n.hasOwnProperty(_n)&&(Cn[$n[_n]]=_n);return Cn}function boundAlpha($n){return $n=parseFloat($n),(isNaN($n)||$n<0||$n>1)&&($n=1),$n}function bound01($n,Cn){isOnePointZero($n)&&($n="100%");var _n=isPercentage($n);return $n=Math.min(Cn,Math.max(0,parseFloat($n))),_n&&($n=parseInt($n*Cn,10)/100),Math.abs($n-Cn)<1e-6?1:$n%Cn/parseFloat(Cn)}function clamp01($n){return Math.min(1,Math.max(0,$n))}function parseIntFromHex($n){return parseInt($n,16)}function isOnePointZero($n){return typeof $n=="string"&&$n.indexOf(".")!=-1&&parseFloat($n)===1}function isPercentage($n){return typeof $n=="string"&&$n.indexOf("%")!=-1}function pad2($n){return $n.length==1?"0"+$n:""+$n}function convertToPercentage($n){return $n<=1&&($n=$n*100+"%"),$n}function convertDecimalToHex($n){return Math.round(parseFloat($n)*255).toString(16)}function convertHexToDecimal($n){return parseIntFromHex($n)/255}var matchers=function(){var $n="[-\\+]?\\d+%?",Cn="[-\\+]?\\d*\\.\\d+%?",_n="(?:"+Cn+")|(?:"+$n+")",Pn="[\\s|\\(]+("+_n+")[,|\\s]+("+_n+")[,|\\s]+("+_n+")\\s*\\)?",In="[\\s|\\(]+("+_n+")[,|\\s]+("+_n+")[,|\\s]+("+_n+")[,|\\s]+("+_n+")\\s*\\)?";return{CSS_UNIT:new RegExp(_n),rgb:new RegExp("rgb"+Pn),rgba:new RegExp("rgba"+In),hsl:new RegExp("hsl"+Pn),hsla:new RegExp("hsla"+In),hsv:new RegExp("hsv"+Pn),hsva:new RegExp("hsva"+In),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();function isValidCSSUnit($n){return!!matchers.CSS_UNIT.exec($n)}function stringInputToObject($n){$n=$n.replace(trimLeft,"").replace(trimRight,"").toLowerCase();var Cn=!1;if(names[$n])$n=names[$n],Cn=!0;else if($n=="transparent")return{r:0,g:0,b:0,a:0,format:"name"};var _n;return(_n=matchers.rgb.exec($n))?{r:_n[1],g:_n[2],b:_n[3]}:(_n=matchers.rgba.exec($n))?{r:_n[1],g:_n[2],b:_n[3],a:_n[4]}:(_n=matchers.hsl.exec($n))?{h:_n[1],s:_n[2],l:_n[3]}:(_n=matchers.hsla.exec($n))?{h:_n[1],s:_n[2],l:_n[3],a:_n[4]}:(_n=matchers.hsv.exec($n))?{h:_n[1],s:_n[2],v:_n[3]}:(_n=matchers.hsva.exec($n))?{h:_n[1],s:_n[2],v:_n[3],a:_n[4]}:(_n=matchers.hex8.exec($n))?{r:parseIntFromHex(_n[1]),g:parseIntFromHex(_n[2]),b:parseIntFromHex(_n[3]),a:convertHexToDecimal(_n[4]),format:Cn?"name":"hex8"}:(_n=matchers.hex6.exec($n))?{r:parseIntFromHex(_n[1]),g:parseIntFromHex(_n[2]),b:parseIntFromHex(_n[3]),format:Cn?"name":"hex"}:(_n=matchers.hex4.exec($n))?{r:parseIntFromHex(_n[1]+""+_n[1]),g:parseIntFromHex(_n[2]+""+_n[2]),b:parseIntFromHex(_n[3]+""+_n[3]),a:convertHexToDecimal(_n[4]+""+_n[4]),format:Cn?"name":"hex8"}:(_n=matchers.hex3.exec($n))?{r:parseIntFromHex(_n[1]+""+_n[1]),g:parseIntFromHex(_n[2]+""+_n[2]),b:parseIntFromHex(_n[3]+""+_n[3]),format:Cn?"name":"hex"}:!1}function validateWCAG2Parms($n){var Cn,_n;return $n=$n||{level:"AA",size:"small"},Cn=($n.level||"AA").toUpperCase(),_n=($n.size||"small").toLowerCase(),Cn!=="AA"&&Cn!=="AAA"&&(Cn="AA"),_n!=="small"&&_n!=="large"&&(_n="small"),{level:Cn,size:_n}}var GradientParser=GradientParser||{};GradientParser.stringify=function(){var $n={"visit_linear-gradient":function(Cn){return $n.visit_gradient(Cn)},"visit_repeating-linear-gradient":function(Cn){return $n.visit_gradient(Cn)},"visit_radial-gradient":function(Cn){return $n.visit_gradient(Cn)},"visit_repeating-radial-gradient":function(Cn){return $n.visit_gradient(Cn)},visit_gradient:function(Cn){var _n=$n.visit(Cn.orientation);return _n&&(_n+=", "),Cn.type+"("+_n+$n.visit(Cn.colorStops)+")"},visit_shape:function(Cn){var _n=Cn.value,Pn=$n.visit(Cn.at),In=$n.visit(Cn.style);return In&&(_n+=" "+In),Pn&&(_n+=" at "+Pn),_n},"visit_default-radial":function(Cn){var _n="",Pn=$n.visit(Cn.at);return Pn&&(_n+=Pn),_n},"visit_extent-keyword":function(Cn){var _n=Cn.value,Pn=$n.visit(Cn.at);return Pn&&(_n+=" at "+Pn),_n},"visit_position-keyword":function(Cn){return Cn.value},visit_position:function(Cn){return $n.visit(Cn.value.x)+" "+$n.visit(Cn.value.y)},"visit_%":function(Cn){return Cn.value+"%"},visit_em:function(Cn){return Cn.value+"em"},visit_px:function(Cn){return Cn.value+"px"},visit_literal:function(Cn){return $n.visit_color(Cn.value,Cn)},visit_hex:function(Cn){return $n.visit_color("#"+Cn.value,Cn)},visit_rgb:function(Cn){return $n.visit_color("rgb("+Cn.value.join(", ")+")",Cn)},visit_rgba:function(Cn){return $n.visit_color("rgba("+Cn.value.join(", ")+")",Cn)},visit_color:function(Cn,_n){var Pn=Cn,In=$n.visit(_n.length);return In&&(Pn+=" "+In),Pn},visit_angular:function(Cn){return Cn.value+"deg"},visit_directional:function(Cn){return"to "+Cn.value},visit_array:function(Cn){var _n="",Pn=Cn.length;return Cn.forEach(function(In,Nn){_n+=$n.visit(In),Nn0&&_n("Invalid input not EOF"),sa}function In(){return qo(Nn)}function Nn(){return Rn("linear-gradient",$n.linearGradient,Ln)||Rn("repeating-linear-gradient",$n.repeatingLinearGradient,Ln)||Rn("radial-gradient",$n.radialGradient,Hn)||Rn("repeating-radial-gradient",$n.repeatingRadialGradient,Hn)}function Rn(sa,ia,fa){return Dn(ia,function(ma){var ya=fa();return ya&&(aa($n.comma)||_n("Missing comma before color stops")),{type:sa,orientation:ya,colorStops:qo(Jo)}})}function Dn(sa,ia){var fa=aa(sa);if(fa){aa($n.startCall)||_n("Missing (");var ma=ia(fa);return aa($n.endCall)||_n("Missing )"),ma}}function Ln(){return Fn()||Bn()}function Fn(){return ga("directional",$n.sideOrCorner,1)}function Bn(){return ga("angular",$n.angleValue,1)}function Hn(){var sa,ia=zn(),fa;return ia&&(sa=[],sa.push(ia),fa=Cn,aa($n.comma)&&(ia=zn(),ia?sa.push(ia):Cn=fa)),sa}function zn(){var sa=Wn()||Yn();if(sa)sa.at=Go();else{var ia=Gn();if(ia){sa=ia;var fa=Go();fa&&(sa.at=fa)}else{var ma=Xn();ma&&(sa={type:"default-radial",at:ma})}}return sa}function Wn(){var sa=ga("shape",/^(circle)/i,0);return sa&&(sa.style=ua()||Gn()),sa}function Yn(){var sa=ga("shape",/^(ellipse)/i,0);return sa&&(sa.style=ea()||Gn()),sa}function Gn(){return ga("extent-keyword",$n.extentKeywords,1)}function Go(){if(ga("position",/^at/,0)){var sa=Xn();return sa||_n("Missing positioning value"),sa}}function Xn(){var sa=Yo();if(sa.x||sa.y)return{type:"position",value:sa}}function Yo(){return{x:ea(),y:ea()}}function qo(sa){var ia=sa(),fa=[];if(ia)for(fa.push(ia);aa($n.comma);)ia=sa(),ia?fa.push(ia):_n("One extra comma");return fa}function Jo(){var sa=Zo();return sa||_n("Expected color definition"),sa.length=ea(),sa}function Zo(){return nr()||oa()||ta()||rr()}function rr(){return ga("literal",$n.literalColor,0)}function nr(){return ga("hex",$n.hexColor,1)}function ta(){return Dn($n.rgbColor,function(){return{type:"rgb",value:qo(ra)}})}function oa(){return Dn($n.rgbaColor,function(){return{type:"rgba",value:qo(ra)}})}function ra(){return aa($n.number)[1]}function ea(){return ga("%",$n.percentageValue,1)||la()||ua()}function la(){return ga("position-keyword",$n.positionKeywords,1)}function ua(){return ga("px",$n.pixelValue,1)||ga("em",$n.emValue,1)}function ga(sa,ia,fa){var ma=aa(ia);if(ma)return{type:sa,value:ma[fa]}}function aa(sa){var ia,fa;return fa=/^[\n\r\t\s]+/.exec(Cn),fa&&ca(fa[0].length),ia=sa.exec(Cn),ia&&ca(ia[0].length),ia}function ca(sa){Cn=Cn.substr(sa)}return function(sa){return Cn=sa.toString(),Pn()}}();var parse=GradientParser.parse,stringify=GradientParser.stringify,top="top",bottom="bottom",right="right",left="left",auto="auto",basePlacements=[top,bottom,right,left],start="start",end="end",clippingParents="clippingParents",viewport="viewport",popper="popper",reference="reference",variationPlacements=basePlacements.reduce(function($n,Cn){return $n.concat([Cn+"-"+start,Cn+"-"+end])},[]),placements=[].concat(basePlacements,[auto]).reduce(function($n,Cn){return $n.concat([Cn,Cn+"-"+start,Cn+"-"+end])},[]),beforeRead="beforeRead",read="read",afterRead="afterRead",beforeMain="beforeMain",main="main",afterMain="afterMain",beforeWrite="beforeWrite",write="write",afterWrite="afterWrite",modifierPhases=[beforeRead,read,afterRead,beforeMain,main,afterMain,beforeWrite,write,afterWrite];function getNodeName($n){return $n?($n.nodeName||"").toLowerCase():null}function getWindow($n){if($n==null)return window;if($n.toString()!=="[object Window]"){var Cn=$n.ownerDocument;return Cn&&Cn.defaultView||window}return $n}function isElement($n){var Cn=getWindow($n).Element;return $n instanceof Cn||$n instanceof Element}function isHTMLElement($n){var Cn=getWindow($n).HTMLElement;return $n instanceof Cn||$n instanceof HTMLElement}function isShadowRoot($n){if(typeof ShadowRoot>"u")return!1;var Cn=getWindow($n).ShadowRoot;return $n instanceof Cn||$n instanceof ShadowRoot}function applyStyles($n){var Cn=$n.state;Object.keys(Cn.elements).forEach(function(_n){var Pn=Cn.styles[_n]||{},In=Cn.attributes[_n]||{},Nn=Cn.elements[_n];!isHTMLElement(Nn)||!getNodeName(Nn)||(Object.assign(Nn.style,Pn),Object.keys(In).forEach(function(Rn){var Dn=In[Rn];Dn===!1?Nn.removeAttribute(Rn):Nn.setAttribute(Rn,Dn===!0?"":Dn)}))})}function effect$2($n){var Cn=$n.state,_n={popper:{position:Cn.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(Cn.elements.popper.style,_n.popper),Cn.styles=_n,Cn.elements.arrow&&Object.assign(Cn.elements.arrow.style,_n.arrow),function(){Object.keys(Cn.elements).forEach(function(Pn){var In=Cn.elements[Pn],Nn=Cn.attributes[Pn]||{},Rn=Object.keys(Cn.styles.hasOwnProperty(Pn)?Cn.styles[Pn]:_n[Pn]),Dn=Rn.reduce(function(Ln,Fn){return Ln[Fn]="",Ln},{});!isHTMLElement(In)||!getNodeName(In)||(Object.assign(In.style,Dn),Object.keys(Nn).forEach(function(Ln){In.removeAttribute(Ln)}))})}}const applyStyles$1={name:"applyStyles",enabled:!0,phase:"write",fn:applyStyles,effect:effect$2,requires:["computeStyles"]};function getBasePlacement($n){return $n.split("-")[0]}var max=Math.max,min=Math.min,round=Math.round;function getUAString(){var $n=navigator.userAgentData;return $n!=null&&$n.brands&&Array.isArray($n.brands)?$n.brands.map(function(Cn){return Cn.brand+"/"+Cn.version}).join(" "):navigator.userAgent}function isLayoutViewport(){return!/^((?!chrome|android).)*safari/i.test(getUAString())}function getBoundingClientRect($n,Cn,_n){Cn===void 0&&(Cn=!1),_n===void 0&&(_n=!1);var Pn=$n.getBoundingClientRect(),In=1,Nn=1;Cn&&isHTMLElement($n)&&(In=$n.offsetWidth>0&&round(Pn.width)/$n.offsetWidth||1,Nn=$n.offsetHeight>0&&round(Pn.height)/$n.offsetHeight||1);var Rn=isElement($n)?getWindow($n):window,Dn=Rn.visualViewport,Ln=!isLayoutViewport()&&_n,Fn=(Pn.left+(Ln&&Dn?Dn.offsetLeft:0))/In,Bn=(Pn.top+(Ln&&Dn?Dn.offsetTop:0))/Nn,Hn=Pn.width/In,zn=Pn.height/Nn;return{width:Hn,height:zn,top:Bn,right:Fn+Hn,bottom:Bn+zn,left:Fn,x:Fn,y:Bn}}function getLayoutRect($n){var Cn=getBoundingClientRect($n),_n=$n.offsetWidth,Pn=$n.offsetHeight;return Math.abs(Cn.width-_n)<=1&&(_n=Cn.width),Math.abs(Cn.height-Pn)<=1&&(Pn=Cn.height),{x:$n.offsetLeft,y:$n.offsetTop,width:_n,height:Pn}}function contains($n,Cn){var _n=Cn.getRootNode&&Cn.getRootNode();if($n.contains(Cn))return!0;if(_n&&isShadowRoot(_n)){var Pn=Cn;do{if(Pn&&$n.isSameNode(Pn))return!0;Pn=Pn.parentNode||Pn.host}while(Pn)}return!1}function getComputedStyle$1($n){return getWindow($n).getComputedStyle($n)}function isTableElement($n){return["table","td","th"].indexOf(getNodeName($n))>=0}function getDocumentElement($n){return((isElement($n)?$n.ownerDocument:$n.document)||window.document).documentElement}function getParentNode($n){return getNodeName($n)==="html"?$n:$n.assignedSlot||$n.parentNode||(isShadowRoot($n)?$n.host:null)||getDocumentElement($n)}function getTrueOffsetParent($n){return!isHTMLElement($n)||getComputedStyle$1($n).position==="fixed"?null:$n.offsetParent}function getContainingBlock($n){var Cn=/firefox/i.test(getUAString()),_n=/Trident/i.test(getUAString());if(_n&&isHTMLElement($n)){var Pn=getComputedStyle$1($n);if(Pn.position==="fixed")return null}var In=getParentNode($n);for(isShadowRoot(In)&&(In=In.host);isHTMLElement(In)&&["html","body"].indexOf(getNodeName(In))<0;){var Nn=getComputedStyle$1(In);if(Nn.transform!=="none"||Nn.perspective!=="none"||Nn.contain==="paint"||["transform","perspective"].indexOf(Nn.willChange)!==-1||Cn&&Nn.willChange==="filter"||Cn&&Nn.filter&&Nn.filter!=="none")return In;In=In.parentNode}return null}function getOffsetParent($n){for(var Cn=getWindow($n),_n=getTrueOffsetParent($n);_n&&isTableElement(_n)&&getComputedStyle$1(_n).position==="static";)_n=getTrueOffsetParent(_n);return _n&&(getNodeName(_n)==="html"||getNodeName(_n)==="body"&&getComputedStyle$1(_n).position==="static")?Cn:_n||getContainingBlock($n)||Cn}function getMainAxisFromPlacement($n){return["top","bottom"].indexOf($n)>=0?"x":"y"}function within($n,Cn,_n){return max($n,min(Cn,_n))}function withinMaxClamp($n,Cn,_n){var Pn=within($n,Cn,_n);return Pn>_n?_n:Pn}function getFreshSideObject(){return{top:0,right:0,bottom:0,left:0}}function mergePaddingObject($n){return Object.assign({},getFreshSideObject(),$n)}function expandToHashMap($n,Cn){return Cn.reduce(function(_n,Pn){return _n[Pn]=$n,_n},{})}var toPaddingObject=function $n(Cn,_n){return Cn=typeof Cn=="function"?Cn(Object.assign({},_n.rects,{placement:_n.placement})):Cn,mergePaddingObject(typeof Cn!="number"?Cn:expandToHashMap(Cn,basePlacements))};function arrow($n){var Cn,_n=$n.state,Pn=$n.name,In=$n.options,Nn=_n.elements.arrow,Rn=_n.modifiersData.popperOffsets,Dn=getBasePlacement(_n.placement),Ln=getMainAxisFromPlacement(Dn),Fn=[left,right].indexOf(Dn)>=0,Bn=Fn?"height":"width";if(!(!Nn||!Rn)){var Hn=toPaddingObject(In.padding,_n),zn=getLayoutRect(Nn),Wn=Ln==="y"?top:left,Yn=Ln==="y"?bottom:right,Gn=_n.rects.reference[Bn]+_n.rects.reference[Ln]-Rn[Ln]-_n.rects.popper[Bn],Go=Rn[Ln]-_n.rects.reference[Ln],Xn=getOffsetParent(Nn),Yo=Xn?Ln==="y"?Xn.clientHeight||0:Xn.clientWidth||0:0,qo=Gn/2-Go/2,Jo=Hn[Wn],Zo=Yo-zn[Bn]-Hn[Yn],rr=Yo/2-zn[Bn]/2+qo,nr=within(Jo,rr,Zo),ta=Ln;_n.modifiersData[Pn]=(Cn={},Cn[ta]=nr,Cn.centerOffset=nr-rr,Cn)}}function effect$1($n){var Cn=$n.state,_n=$n.options,Pn=_n.element,In=Pn===void 0?"[data-popper-arrow]":Pn;In!=null&&(typeof In=="string"&&(In=Cn.elements.popper.querySelector(In),!In)||contains(Cn.elements.popper,In)&&(Cn.elements.arrow=In))}const arrow$1={name:"arrow",enabled:!0,phase:"main",fn:arrow,effect:effect$1,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function getVariation($n){return $n.split("-")[1]}var unsetSides={top:"auto",right:"auto",bottom:"auto",left:"auto"};function roundOffsetsByDPR($n,Cn){var _n=$n.x,Pn=$n.y,In=Cn.devicePixelRatio||1;return{x:round(_n*In)/In||0,y:round(Pn*In)/In||0}}function mapToStyles($n){var Cn,_n=$n.popper,Pn=$n.popperRect,In=$n.placement,Nn=$n.variation,Rn=$n.offsets,Dn=$n.position,Ln=$n.gpuAcceleration,Fn=$n.adaptive,Bn=$n.roundOffsets,Hn=$n.isFixed,zn=Rn.x,Wn=zn===void 0?0:zn,Yn=Rn.y,Gn=Yn===void 0?0:Yn,Go=typeof Bn=="function"?Bn({x:Wn,y:Gn}):{x:Wn,y:Gn};Wn=Go.x,Gn=Go.y;var Xn=Rn.hasOwnProperty("x"),Yo=Rn.hasOwnProperty("y"),qo=left,Jo=top,Zo=window;if(Fn){var rr=getOffsetParent(_n),nr="clientHeight",ta="clientWidth";if(rr===getWindow(_n)&&(rr=getDocumentElement(_n),getComputedStyle$1(rr).position!=="static"&&Dn==="absolute"&&(nr="scrollHeight",ta="scrollWidth")),rr=rr,In===top||(In===left||In===right)&&Nn===end){Jo=bottom;var oa=Hn&&rr===Zo&&Zo.visualViewport?Zo.visualViewport.height:rr[nr];Gn-=oa-Pn.height,Gn*=Ln?1:-1}if(In===left||(In===top||In===bottom)&&Nn===end){qo=right;var ra=Hn&&rr===Zo&&Zo.visualViewport?Zo.visualViewport.width:rr[ta];Wn-=ra-Pn.width,Wn*=Ln?1:-1}}var ea=Object.assign({position:Dn},Fn&&unsetSides),la=Bn===!0?roundOffsetsByDPR({x:Wn,y:Gn},getWindow(_n)):{x:Wn,y:Gn};if(Wn=la.x,Gn=la.y,Ln){var ua;return Object.assign({},ea,(ua={},ua[Jo]=Yo?"0":"",ua[qo]=Xn?"0":"",ua.transform=(Zo.devicePixelRatio||1)<=1?"translate("+Wn+"px, "+Gn+"px)":"translate3d("+Wn+"px, "+Gn+"px, 0)",ua))}return Object.assign({},ea,(Cn={},Cn[Jo]=Yo?Gn+"px":"",Cn[qo]=Xn?Wn+"px":"",Cn.transform="",Cn))}function computeStyles($n){var Cn=$n.state,_n=$n.options,Pn=_n.gpuAcceleration,In=Pn===void 0?!0:Pn,Nn=_n.adaptive,Rn=Nn===void 0?!0:Nn,Dn=_n.roundOffsets,Ln=Dn===void 0?!0:Dn,Fn={placement:getBasePlacement(Cn.placement),variation:getVariation(Cn.placement),popper:Cn.elements.popper,popperRect:Cn.rects.popper,gpuAcceleration:In,isFixed:Cn.options.strategy==="fixed"};Cn.modifiersData.popperOffsets!=null&&(Cn.styles.popper=Object.assign({},Cn.styles.popper,mapToStyles(Object.assign({},Fn,{offsets:Cn.modifiersData.popperOffsets,position:Cn.options.strategy,adaptive:Rn,roundOffsets:Ln})))),Cn.modifiersData.arrow!=null&&(Cn.styles.arrow=Object.assign({},Cn.styles.arrow,mapToStyles(Object.assign({},Fn,{offsets:Cn.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:Ln})))),Cn.attributes.popper=Object.assign({},Cn.attributes.popper,{"data-popper-placement":Cn.placement})}const computeStyles$1={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:computeStyles,data:{}};var passive={passive:!0};function effect($n){var Cn=$n.state,_n=$n.instance,Pn=$n.options,In=Pn.scroll,Nn=In===void 0?!0:In,Rn=Pn.resize,Dn=Rn===void 0?!0:Rn,Ln=getWindow(Cn.elements.popper),Fn=[].concat(Cn.scrollParents.reference,Cn.scrollParents.popper);return Nn&&Fn.forEach(function(Bn){Bn.addEventListener("scroll",_n.update,passive)}),Dn&&Ln.addEventListener("resize",_n.update,passive),function(){Nn&&Fn.forEach(function(Bn){Bn.removeEventListener("scroll",_n.update,passive)}),Dn&&Ln.removeEventListener("resize",_n.update,passive)}}const eventListeners={name:"eventListeners",enabled:!0,phase:"write",fn:function $n(){},effect,data:{}};var hash$1={left:"right",right:"left",bottom:"top",top:"bottom"};function getOppositePlacement($n){return $n.replace(/left|right|bottom|top/g,function(Cn){return hash$1[Cn]})}var hash={start:"end",end:"start"};function getOppositeVariationPlacement($n){return $n.replace(/start|end/g,function(Cn){return hash[Cn]})}function getWindowScroll($n){var Cn=getWindow($n),_n=Cn.pageXOffset,Pn=Cn.pageYOffset;return{scrollLeft:_n,scrollTop:Pn}}function getWindowScrollBarX($n){return getBoundingClientRect(getDocumentElement($n)).left+getWindowScroll($n).scrollLeft}function getViewportRect($n,Cn){var _n=getWindow($n),Pn=getDocumentElement($n),In=_n.visualViewport,Nn=Pn.clientWidth,Rn=Pn.clientHeight,Dn=0,Ln=0;if(In){Nn=In.width,Rn=In.height;var Fn=isLayoutViewport();(Fn||!Fn&&Cn==="fixed")&&(Dn=In.offsetLeft,Ln=In.offsetTop)}return{width:Nn,height:Rn,x:Dn+getWindowScrollBarX($n),y:Ln}}function getDocumentRect($n){var Cn,_n=getDocumentElement($n),Pn=getWindowScroll($n),In=(Cn=$n.ownerDocument)==null?void 0:Cn.body,Nn=max(_n.scrollWidth,_n.clientWidth,In?In.scrollWidth:0,In?In.clientWidth:0),Rn=max(_n.scrollHeight,_n.clientHeight,In?In.scrollHeight:0,In?In.clientHeight:0),Dn=-Pn.scrollLeft+getWindowScrollBarX($n),Ln=-Pn.scrollTop;return getComputedStyle$1(In||_n).direction==="rtl"&&(Dn+=max(_n.clientWidth,In?In.clientWidth:0)-Nn),{width:Nn,height:Rn,x:Dn,y:Ln}}function isScrollParent($n){var Cn=getComputedStyle$1($n),_n=Cn.overflow,Pn=Cn.overflowX,In=Cn.overflowY;return/auto|scroll|overlay|hidden/.test(_n+In+Pn)}function getScrollParent($n){return["html","body","#document"].indexOf(getNodeName($n))>=0?$n.ownerDocument.body:isHTMLElement($n)&&isScrollParent($n)?$n:getScrollParent(getParentNode($n))}function listScrollParents($n,Cn){var _n;Cn===void 0&&(Cn=[]);var Pn=getScrollParent($n),In=Pn===((_n=$n.ownerDocument)==null?void 0:_n.body),Nn=getWindow(Pn),Rn=In?[Nn].concat(Nn.visualViewport||[],isScrollParent(Pn)?Pn:[]):Pn,Dn=Cn.concat(Rn);return In?Dn:Dn.concat(listScrollParents(getParentNode(Rn)))}function rectToClientRect($n){return Object.assign({},$n,{left:$n.x,top:$n.y,right:$n.x+$n.width,bottom:$n.y+$n.height})}function getInnerBoundingClientRect($n,Cn){var _n=getBoundingClientRect($n,!1,Cn==="fixed");return _n.top=_n.top+$n.clientTop,_n.left=_n.left+$n.clientLeft,_n.bottom=_n.top+$n.clientHeight,_n.right=_n.left+$n.clientWidth,_n.width=$n.clientWidth,_n.height=$n.clientHeight,_n.x=_n.left,_n.y=_n.top,_n}function getClientRectFromMixedType($n,Cn,_n){return Cn===viewport?rectToClientRect(getViewportRect($n,_n)):isElement(Cn)?getInnerBoundingClientRect(Cn,_n):rectToClientRect(getDocumentRect(getDocumentElement($n)))}function getClippingParents($n){var Cn=listScrollParents(getParentNode($n)),_n=["absolute","fixed"].indexOf(getComputedStyle$1($n).position)>=0,Pn=_n&&isHTMLElement($n)?getOffsetParent($n):$n;return isElement(Pn)?Cn.filter(function(In){return isElement(In)&&contains(In,Pn)&&getNodeName(In)!=="body"}):[]}function getClippingRect($n,Cn,_n,Pn){var In=Cn==="clippingParents"?getClippingParents($n):[].concat(Cn),Nn=[].concat(In,[_n]),Rn=Nn[0],Dn=Nn.reduce(function(Ln,Fn){var Bn=getClientRectFromMixedType($n,Fn,Pn);return Ln.top=max(Bn.top,Ln.top),Ln.right=min(Bn.right,Ln.right),Ln.bottom=min(Bn.bottom,Ln.bottom),Ln.left=max(Bn.left,Ln.left),Ln},getClientRectFromMixedType($n,Rn,Pn));return Dn.width=Dn.right-Dn.left,Dn.height=Dn.bottom-Dn.top,Dn.x=Dn.left,Dn.y=Dn.top,Dn}function computeOffsets($n){var Cn=$n.reference,_n=$n.element,Pn=$n.placement,In=Pn?getBasePlacement(Pn):null,Nn=Pn?getVariation(Pn):null,Rn=Cn.x+Cn.width/2-_n.width/2,Dn=Cn.y+Cn.height/2-_n.height/2,Ln;switch(In){case top:Ln={x:Rn,y:Cn.y-_n.height};break;case bottom:Ln={x:Rn,y:Cn.y+Cn.height};break;case right:Ln={x:Cn.x+Cn.width,y:Dn};break;case left:Ln={x:Cn.x-_n.width,y:Dn};break;default:Ln={x:Cn.x,y:Cn.y}}var Fn=In?getMainAxisFromPlacement(In):null;if(Fn!=null){var Bn=Fn==="y"?"height":"width";switch(Nn){case start:Ln[Fn]=Ln[Fn]-(Cn[Bn]/2-_n[Bn]/2);break;case end:Ln[Fn]=Ln[Fn]+(Cn[Bn]/2-_n[Bn]/2);break}}return Ln}function detectOverflow($n,Cn){Cn===void 0&&(Cn={});var _n=Cn,Pn=_n.placement,In=Pn===void 0?$n.placement:Pn,Nn=_n.strategy,Rn=Nn===void 0?$n.strategy:Nn,Dn=_n.boundary,Ln=Dn===void 0?clippingParents:Dn,Fn=_n.rootBoundary,Bn=Fn===void 0?viewport:Fn,Hn=_n.elementContext,zn=Hn===void 0?popper:Hn,Wn=_n.altBoundary,Yn=Wn===void 0?!1:Wn,Gn=_n.padding,Go=Gn===void 0?0:Gn,Xn=mergePaddingObject(typeof Go!="number"?Go:expandToHashMap(Go,basePlacements)),Yo=zn===popper?reference:popper,qo=$n.rects.popper,Jo=$n.elements[Yn?Yo:zn],Zo=getClippingRect(isElement(Jo)?Jo:Jo.contextElement||getDocumentElement($n.elements.popper),Ln,Bn,Rn),rr=getBoundingClientRect($n.elements.reference),nr=computeOffsets({reference:rr,element:qo,strategy:"absolute",placement:In}),ta=rectToClientRect(Object.assign({},qo,nr)),oa=zn===popper?ta:rr,ra={top:Zo.top-oa.top+Xn.top,bottom:oa.bottom-Zo.bottom+Xn.bottom,left:Zo.left-oa.left+Xn.left,right:oa.right-Zo.right+Xn.right},ea=$n.modifiersData.offset;if(zn===popper&&ea){var la=ea[In];Object.keys(ra).forEach(function(ua){var ga=[right,bottom].indexOf(ua)>=0?1:-1,aa=[top,bottom].indexOf(ua)>=0?"y":"x";ra[ua]+=la[aa]*ga})}return ra}function computeAutoPlacement($n,Cn){Cn===void 0&&(Cn={});var _n=Cn,Pn=_n.placement,In=_n.boundary,Nn=_n.rootBoundary,Rn=_n.padding,Dn=_n.flipVariations,Ln=_n.allowedAutoPlacements,Fn=Ln===void 0?placements:Ln,Bn=getVariation(Pn),Hn=Bn?Dn?variationPlacements:variationPlacements.filter(function(Yn){return getVariation(Yn)===Bn}):basePlacements,zn=Hn.filter(function(Yn){return Fn.indexOf(Yn)>=0});zn.length===0&&(zn=Hn);var Wn=zn.reduce(function(Yn,Gn){return Yn[Gn]=detectOverflow($n,{placement:Gn,boundary:In,rootBoundary:Nn,padding:Rn})[getBasePlacement(Gn)],Yn},{});return Object.keys(Wn).sort(function(Yn,Gn){return Wn[Yn]-Wn[Gn]})}function getExpandedFallbackPlacements($n){if(getBasePlacement($n)===auto)return[];var Cn=getOppositePlacement($n);return[getOppositeVariationPlacement($n),Cn,getOppositeVariationPlacement(Cn)]}function flip($n){var Cn=$n.state,_n=$n.options,Pn=$n.name;if(!Cn.modifiersData[Pn]._skip){for(var In=_n.mainAxis,Nn=In===void 0?!0:In,Rn=_n.altAxis,Dn=Rn===void 0?!0:Rn,Ln=_n.fallbackPlacements,Fn=_n.padding,Bn=_n.boundary,Hn=_n.rootBoundary,zn=_n.altBoundary,Wn=_n.flipVariations,Yn=Wn===void 0?!0:Wn,Gn=_n.allowedAutoPlacements,Go=Cn.options.placement,Xn=getBasePlacement(Go),Yo=Xn===Go,qo=Ln||(Yo||!Yn?[getOppositePlacement(Go)]:getExpandedFallbackPlacements(Go)),Jo=[Go].concat(qo).reduce(function(Ea,xa){return Ea.concat(getBasePlacement(xa)===auto?computeAutoPlacement(Cn,{placement:xa,boundary:Bn,rootBoundary:Hn,padding:Fn,flipVariations:Yn,allowedAutoPlacements:Gn}):xa)},[]),Zo=Cn.rects.reference,rr=Cn.rects.popper,nr=new Map,ta=!0,oa=Jo[0],ra=0;ra=0,aa=ga?"width":"height",ca=detectOverflow(Cn,{placement:ea,boundary:Bn,rootBoundary:Hn,altBoundary:zn,padding:Fn}),sa=ga?ua?right:left:ua?bottom:top;Zo[aa]>rr[aa]&&(sa=getOppositePlacement(sa));var ia=getOppositePlacement(sa),fa=[];if(Nn&&fa.push(ca[la]<=0),Dn&&fa.push(ca[sa]<=0,ca[ia]<=0),fa.every(function(Ea){return Ea})){oa=ea,ta=!1;break}nr.set(ea,fa)}if(ta)for(var ma=Yn?3:1,ya=function(xa){var Ta=Jo.find(function(wa){var La=nr.get(wa);if(La)return La.slice(0,xa).every(function(Na){return Na})});if(Ta)return oa=Ta,"break"},ba=ma;ba>0;ba--){var Ia=ya(ba);if(Ia==="break")break}Cn.placement!==oa&&(Cn.modifiersData[Pn]._skip=!0,Cn.placement=oa,Cn.reset=!0)}}const flip$1={name:"flip",enabled:!0,phase:"main",fn:flip,requiresIfExists:["offset"],data:{_skip:!1}};function getSideOffsets($n,Cn,_n){return _n===void 0&&(_n={x:0,y:0}),{top:$n.top-Cn.height-_n.y,right:$n.right-Cn.width+_n.x,bottom:$n.bottom-Cn.height+_n.y,left:$n.left-Cn.width-_n.x}}function isAnySideFullyClipped($n){return[top,right,bottom,left].some(function(Cn){return $n[Cn]>=0})}function hide($n){var Cn=$n.state,_n=$n.name,Pn=Cn.rects.reference,In=Cn.rects.popper,Nn=Cn.modifiersData.preventOverflow,Rn=detectOverflow(Cn,{elementContext:"reference"}),Dn=detectOverflow(Cn,{altBoundary:!0}),Ln=getSideOffsets(Rn,Pn),Fn=getSideOffsets(Dn,In,Nn),Bn=isAnySideFullyClipped(Ln),Hn=isAnySideFullyClipped(Fn);Cn.modifiersData[_n]={referenceClippingOffsets:Ln,popperEscapeOffsets:Fn,isReferenceHidden:Bn,hasPopperEscaped:Hn},Cn.attributes.popper=Object.assign({},Cn.attributes.popper,{"data-popper-reference-hidden":Bn,"data-popper-escaped":Hn})}const hide$1={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:hide};function distanceAndSkiddingToXY($n,Cn,_n){var Pn=getBasePlacement($n),In=[left,top].indexOf(Pn)>=0?-1:1,Nn=typeof _n=="function"?_n(Object.assign({},Cn,{placement:$n})):_n,Rn=Nn[0],Dn=Nn[1];return Rn=Rn||0,Dn=(Dn||0)*In,[left,right].indexOf(Pn)>=0?{x:Dn,y:Rn}:{x:Rn,y:Dn}}function offset($n){var Cn=$n.state,_n=$n.options,Pn=$n.name,In=_n.offset,Nn=In===void 0?[0,0]:In,Rn=placements.reduce(function(Bn,Hn){return Bn[Hn]=distanceAndSkiddingToXY(Hn,Cn.rects,Nn),Bn},{}),Dn=Rn[Cn.placement],Ln=Dn.x,Fn=Dn.y;Cn.modifiersData.popperOffsets!=null&&(Cn.modifiersData.popperOffsets.x+=Ln,Cn.modifiersData.popperOffsets.y+=Fn),Cn.modifiersData[Pn]=Rn}const offset$1={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:offset};function popperOffsets($n){var Cn=$n.state,_n=$n.name;Cn.modifiersData[_n]=computeOffsets({reference:Cn.rects.reference,element:Cn.rects.popper,strategy:"absolute",placement:Cn.placement})}const popperOffsets$1={name:"popperOffsets",enabled:!0,phase:"read",fn:popperOffsets,data:{}};function getAltAxis($n){return $n==="x"?"y":"x"}function preventOverflow($n){var Cn=$n.state,_n=$n.options,Pn=$n.name,In=_n.mainAxis,Nn=In===void 0?!0:In,Rn=_n.altAxis,Dn=Rn===void 0?!1:Rn,Ln=_n.boundary,Fn=_n.rootBoundary,Bn=_n.altBoundary,Hn=_n.padding,zn=_n.tether,Wn=zn===void 0?!0:zn,Yn=_n.tetherOffset,Gn=Yn===void 0?0:Yn,Go=detectOverflow(Cn,{boundary:Ln,rootBoundary:Fn,padding:Hn,altBoundary:Bn}),Xn=getBasePlacement(Cn.placement),Yo=getVariation(Cn.placement),qo=!Yo,Jo=getMainAxisFromPlacement(Xn),Zo=getAltAxis(Jo),rr=Cn.modifiersData.popperOffsets,nr=Cn.rects.reference,ta=Cn.rects.popper,oa=typeof Gn=="function"?Gn(Object.assign({},Cn.rects,{placement:Cn.placement})):Gn,ra=typeof oa=="number"?{mainAxis:oa,altAxis:oa}:Object.assign({mainAxis:0,altAxis:0},oa),ea=Cn.modifiersData.offset?Cn.modifiersData.offset[Cn.placement]:null,la={x:0,y:0};if(rr){if(Nn){var ua,ga=Jo==="y"?top:left,aa=Jo==="y"?bottom:right,ca=Jo==="y"?"height":"width",sa=rr[Jo],ia=sa+Go[ga],fa=sa-Go[aa],ma=Wn?-ta[ca]/2:0,ya=Yo===start?nr[ca]:ta[ca],ba=Yo===start?-ta[ca]:-nr[ca],Ia=Cn.elements.arrow,Ea=Wn&&Ia?getLayoutRect(Ia):{width:0,height:0},xa=Cn.modifiersData["arrow#persistent"]?Cn.modifiersData["arrow#persistent"].padding:getFreshSideObject(),Ta=xa[ga],wa=xa[aa],La=within(0,nr[ca],Ea[ca]),Na=qo?nr[ca]/2-ma-La-Ta-ra.mainAxis:ya-La-Ta-ra.mainAxis,$a=qo?-nr[ca]/2+ma+La+wa+ra.mainAxis:ba+La+wa+ra.mainAxis,ka=Cn.elements.arrow&&getOffsetParent(Cn.elements.arrow),Ha=ka?Jo==="y"?ka.clientTop||0:ka.clientLeft||0:0,da=(ua=ea==null?void 0:ea[Jo])!=null?ua:0,pa=sa+Na-da-Ha,Sa=sa+$a-da,Aa=within(Wn?min(ia,pa):ia,sa,Wn?max(fa,Sa):fa);rr[Jo]=Aa,la[Jo]=Aa-sa}if(Dn){var Ra,Fa=Jo==="x"?top:left,za=Jo==="x"?bottom:right,Wa=rr[Zo],Ya=Zo==="y"?"height":"width",ja=Wa+Go[Fa],qa=Wa-Go[za],Xa=[top,left].indexOf(Xn)!==-1,Oa=(Ra=ea==null?void 0:ea[Zo])!=null?Ra:0,Ma=Xa?ja:Wa-nr[Ya]-ta[Ya]-Oa+ra.altAxis,Ua=Xa?Wa+nr[Ya]+ta[Ya]-Oa-ra.altAxis:qa,Qa=Wn&&Xa?withinMaxClamp(Ma,Wa,Ua):within(Wn?Ma:ja,Wa,Wn?Ua:qa);rr[Zo]=Qa,la[Zo]=Qa-Wa}Cn.modifiersData[Pn]=la}}const preventOverflow$1={name:"preventOverflow",enabled:!0,phase:"main",fn:preventOverflow,requiresIfExists:["offset"]};function getHTMLElementScroll($n){return{scrollLeft:$n.scrollLeft,scrollTop:$n.scrollTop}}function getNodeScroll($n){return $n===getWindow($n)||!isHTMLElement($n)?getWindowScroll($n):getHTMLElementScroll($n)}function isElementScaled($n){var Cn=$n.getBoundingClientRect(),_n=round(Cn.width)/$n.offsetWidth||1,Pn=round(Cn.height)/$n.offsetHeight||1;return _n!==1||Pn!==1}function getCompositeRect($n,Cn,_n){_n===void 0&&(_n=!1);var Pn=isHTMLElement(Cn),In=isHTMLElement(Cn)&&isElementScaled(Cn),Nn=getDocumentElement(Cn),Rn=getBoundingClientRect($n,In,_n),Dn={scrollLeft:0,scrollTop:0},Ln={x:0,y:0};return(Pn||!Pn&&!_n)&&((getNodeName(Cn)!=="body"||isScrollParent(Nn))&&(Dn=getNodeScroll(Cn)),isHTMLElement(Cn)?(Ln=getBoundingClientRect(Cn,!0),Ln.x+=Cn.clientLeft,Ln.y+=Cn.clientTop):Nn&&(Ln.x=getWindowScrollBarX(Nn))),{x:Rn.left+Dn.scrollLeft-Ln.x,y:Rn.top+Dn.scrollTop-Ln.y,width:Rn.width,height:Rn.height}}function order($n){var Cn=new Map,_n=new Set,Pn=[];$n.forEach(function(Nn){Cn.set(Nn.name,Nn)});function In(Nn){_n.add(Nn.name);var Rn=[].concat(Nn.requires||[],Nn.requiresIfExists||[]);Rn.forEach(function(Dn){if(!_n.has(Dn)){var Ln=Cn.get(Dn);Ln&&In(Ln)}}),Pn.push(Nn)}return $n.forEach(function(Nn){_n.has(Nn.name)||In(Nn)}),Pn}function orderModifiers($n){var Cn=order($n);return modifierPhases.reduce(function(_n,Pn){return _n.concat(Cn.filter(function(In){return In.phase===Pn}))},[])}function debounce($n){var Cn;return function(){return Cn||(Cn=new Promise(function(_n){Promise.resolve().then(function(){Cn=void 0,_n($n())})})),Cn}}function mergeByName($n){var Cn=$n.reduce(function(_n,Pn){var In=_n[Pn.name];return _n[Pn.name]=In?Object.assign({},In,Pn,{options:Object.assign({},In.options,Pn.options),data:Object.assign({},In.data,Pn.data)}):Pn,_n},{});return Object.keys(Cn).map(function(_n){return Cn[_n]})}var DEFAULT_OPTIONS={placement:"bottom",modifiers:[],strategy:"absolute"};function areValidElements(){for(var $n=arguments.length,Cn=new Array($n),_n=0;_n<$n;_n++)Cn[_n]=arguments[_n];return!Cn.some(function(Pn){return!(Pn&&typeof Pn.getBoundingClientRect=="function")})}function popperGenerator($n){$n===void 0&&($n={});var Cn=$n,_n=Cn.defaultModifiers,Pn=_n===void 0?[]:_n,In=Cn.defaultOptions,Nn=In===void 0?DEFAULT_OPTIONS:In;return function(Dn,Ln,Fn){Fn===void 0&&(Fn=Nn);var Bn={placement:"bottom",orderedModifiers:[],options:Object.assign({},DEFAULT_OPTIONS,Nn),modifiersData:{},elements:{reference:Dn,popper:Ln},attributes:{},styles:{}},Hn=[],zn=!1,Wn={state:Bn,setOptions:function(Xn){var Yo=typeof Xn=="function"?Xn(Bn.options):Xn;Gn(),Bn.options=Object.assign({},Nn,Bn.options,Yo),Bn.scrollParents={reference:isElement(Dn)?listScrollParents(Dn):Dn.contextElement?listScrollParents(Dn.contextElement):[],popper:listScrollParents(Ln)};var qo=orderModifiers(mergeByName([].concat(Pn,Bn.options.modifiers)));return Bn.orderedModifiers=qo.filter(function(Jo){return Jo.enabled}),Yn(),Wn.update()},forceUpdate:function(){if(!zn){var Xn=Bn.elements,Yo=Xn.reference,qo=Xn.popper;if(areValidElements(Yo,qo)){Bn.rects={reference:getCompositeRect(Yo,getOffsetParent(qo),Bn.options.strategy==="fixed"),popper:getLayoutRect(qo)},Bn.reset=!1,Bn.placement=Bn.options.placement,Bn.orderedModifiers.forEach(function(ra){return Bn.modifiersData[ra.name]=Object.assign({},ra.data)});for(var Jo=0;Jo - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */function isObject($n){return Object.prototype.toString.call($n)==="[object Object]"}function isPlainObject($n){var Cn,_n;return isObject($n)===!1?!1:(Cn=$n.constructor,Cn===void 0?!0:(_n=Cn.prototype,!(isObject(_n)===!1||_n.hasOwnProperty("isPrototypeOf")===!1)))}function t$1(){return t$1=Object.assign?Object.assign.bind():function($n){for(var Cn=1;Cn=0||(In[_n]=$n[_n]);return In}const n$1={silent:!1,logLevel:"warn"},i$1=["validator"],o$1=Object.prototype,a$1=o$1.toString,s$1=o$1.hasOwnProperty,u$1=/^\s*function (\w+)/;function l$1($n){var Cn;const _n=(Cn=$n==null?void 0:$n.type)!==null&&Cn!==void 0?Cn:$n;if(_n){const Pn=_n.toString().match(u$1);return Pn?Pn[1]:""}return""}const c$1=isPlainObject,f$1=$n=>$n;let d$1=f$1;const p$1=($n,Cn)=>s$1.call($n,Cn),y$1=Number.isInteger||function($n){return typeof $n=="number"&&isFinite($n)&&Math.floor($n)===$n},v$1=Array.isArray||function($n){return a$1.call($n)==="[object Array]"},h$1=$n=>a$1.call($n)==="[object Function]",b$1=$n=>c$1($n)&&p$1($n,"_vueTypes_name"),g$1=$n=>c$1($n)&&(p$1($n,"type")||["_vueTypes_name","validator","default","required"].some(Cn=>p$1($n,Cn)));function O$1($n,Cn){return Object.defineProperty($n.bind(Cn),"__original",{value:$n})}function m$1($n,Cn,_n=!1){let Pn,In=!0,Nn="";Pn=c$1($n)?$n:{type:$n};const Rn=b$1(Pn)?Pn._vueTypes_name+" - ":"";if(g$1(Pn)&&Pn.type!==null){if(Pn.type===void 0||Pn.type===!0||!Pn.required&&Cn===void 0)return In;v$1(Pn.type)?(In=Pn.type.some(Dn=>m$1(Dn,Cn,!0)===!0),Nn=Pn.type.map(Dn=>l$1(Dn)).join(" or ")):(Nn=l$1(Pn),In=Nn==="Array"?v$1(Cn):Nn==="Object"?c$1(Cn):Nn==="String"||Nn==="Number"||Nn==="Boolean"||Nn==="Function"?function(Dn){if(Dn==null)return"";const Ln=Dn.constructor.toString().match(u$1);return Ln?Ln[1]:""}(Cn)===Nn:Cn instanceof Pn.type)}if(!In){const Dn=`${Rn}value "${Cn}" should be of type "${Nn}"`;return _n===!1?(d$1(Dn),!1):Dn}if(p$1(Pn,"validator")&&h$1(Pn.validator)){const Dn=d$1,Ln=[];if(d$1=Fn=>{Ln.push(Fn)},In=Pn.validator(Cn),d$1=Dn,!In){const Fn=(Ln.length>1?"* ":"")+Ln.join(` -* `);return Ln.length=0,_n===!1?(d$1(Fn),In):Fn}}return In}function j$1($n,Cn){const _n=Object.defineProperties(Cn,{_vueTypes_name:{value:$n,writable:!0},isRequired:{get(){return this.required=!0,this}},def:{value(In){return In===void 0?(p$1(this,"default")&&delete this.default,this):h$1(In)||m$1(this,In,!0)===!0?(this.default=v$1(In)?()=>[...In]:c$1(In)?()=>Object.assign({},In):In,this):(d$1(`${this._vueTypes_name} - invalid default value: "${In}"`),this)}}}),{validator:Pn}=_n;return h$1(Pn)&&(_n.validator=O$1(Pn,_n)),_n}function _$1($n,Cn){const _n=j$1($n,Cn);return Object.defineProperty(_n,"validate",{value(Pn){return h$1(this.validator)&&d$1(`${this._vueTypes_name} - calling .validate() will overwrite the current custom validator function. Validator info: -${JSON.stringify(this)}`),this.validator=O$1(Pn,this),this}})}function T$1($n,Cn,_n){const Pn=function(Ln){const Fn={};return Object.getOwnPropertyNames(Ln).forEach(Bn=>{Fn[Bn]=Object.getOwnPropertyDescriptor(Ln,Bn)}),Object.defineProperties({},Fn)}(Cn);if(Pn._vueTypes_name=$n,!c$1(_n))return Pn;const{validator:In}=_n,Nn=r$1(_n,i$1);if(h$1(In)){let{validator:Ln}=Pn;Ln&&(Ln=(Dn=(Rn=Ln).__original)!==null&&Dn!==void 0?Dn:Rn),Pn.validator=O$1(Ln?function(Fn){return Ln.call(this,Fn)&&In.call(this,Fn)}:In,Pn)}var Rn,Dn;return Object.assign(Pn,Nn)}function $$1($n){return $n.replace(/^(?!\s*$)/gm," ")}const w$1=()=>_$1("any",{}),P$1=()=>_$1("function",{type:Function}),x$1=()=>_$1("boolean",{type:Boolean}),E$1=()=>_$1("string",{type:String}),N$1=()=>_$1("number",{type:Number}),q$1=()=>_$1("array",{type:Array}),A$1=()=>_$1("object",{type:Object}),V$2=()=>j$1("integer",{type:Number,validator:$n=>y$1($n)}),S$1=()=>j$1("symbol",{validator:$n=>typeof $n=="symbol"});function D$1($n,Cn="custom validation failed"){if(typeof $n!="function")throw new TypeError("[VueTypes error]: You must provide a function as argument");return j$1($n.name||"<>",{type:null,validator(_n){const Pn=$n(_n);return Pn||d$1(`${this._vueTypes_name} - ${Cn}`),Pn}})}function L$2($n){if(!v$1($n))throw new TypeError("[VueTypes error]: You must provide an array as argument.");const Cn=`oneOf - value should be one of "${$n.join('", "')}".`,_n=$n.reduce((Pn,In)=>{if(In!=null){const Nn=In.constructor;Pn.indexOf(Nn)===-1&&Pn.push(Nn)}return Pn},[]);return j$1("oneOf",{type:_n.length>0?_n:void 0,validator(Pn){const In=$n.indexOf(Pn)!==-1;return In||d$1(Cn),In}})}function F$1($n){if(!v$1($n))throw new TypeError("[VueTypes error]: You must provide an array as argument");let Cn=!1,_n=[];for(let In=0;In<$n.length;In+=1){const Nn=$n[In];if(g$1(Nn)){if(b$1(Nn)&&Nn._vueTypes_name==="oneOf"&&Nn.type){_n=_n.concat(Nn.type);continue}if(h$1(Nn.validator)&&(Cn=!0),Nn.type===!0||!Nn.type){d$1('oneOfType - invalid usage of "true" or "null" as types.');continue}_n=_n.concat(Nn.type)}else _n.push(Nn)}_n=_n.filter((In,Nn)=>_n.indexOf(In)===Nn);const Pn=_n.length>0?_n:null;return j$1("oneOfType",Cn?{type:Pn,validator(In){const Nn=[],Rn=$n.some(Dn=>{const Ln=m$1(b$1(Dn)&&Dn._vueTypes_name==="oneOf"?Dn.type||null:Dn,In,!0);return typeof Ln=="string"&&Nn.push(Ln),Ln===!0});return Rn||d$1(`oneOfType - provided value does not match any of the ${Nn.length} passed-in validators: -${$$1(Nn.join(` -`))}`),Rn}}:{type:Pn})}function Y$1($n){return j$1("arrayOf",{type:Array,validator(Cn){let _n="";const Pn=Cn.every(In=>(_n=m$1($n,In,!0),_n===!0));return Pn||d$1(`arrayOf - value validation error: -${$$1(_n)}`),Pn}})}function B$2($n){return j$1("instanceOf",{type:$n})}function I$1($n){return j$1("objectOf",{type:Object,validator(Cn){let _n="";const Pn=Object.keys(Cn).every(In=>(_n=m$1($n,Cn[In],!0),_n===!0));return Pn||d$1(`objectOf - value validation error: -${$$1(_n)}`),Pn}})}function J$1($n){const Cn=Object.keys($n),_n=Cn.filter(In=>{var Nn;return!((Nn=$n[In])===null||Nn===void 0||!Nn.required)}),Pn=j$1("shape",{type:Object,validator(In){if(!c$1(In))return!1;const Nn=Object.keys(In);if(_n.length>0&&_n.some(Rn=>Nn.indexOf(Rn)===-1)){const Rn=_n.filter(Dn=>Nn.indexOf(Dn)===-1);return d$1(Rn.length===1?`shape - required property "${Rn[0]}" is not defined.`:`shape - required properties "${Rn.join('", "')}" are not defined.`),!1}return Nn.every(Rn=>{if(Cn.indexOf(Rn)===-1)return this._vueTypes_isLoose===!0||(d$1(`shape - shape definition does not include a "${Rn}" property. Allowed keys: "${Cn.join('", "')}".`),!1);const Dn=m$1($n[Rn],In[Rn],!0);return typeof Dn=="string"&&d$1(`shape - "${Rn}" property validation error: - ${$$1(Dn)}`),Dn===!0})}});return Object.defineProperty(Pn,"_vueTypes_isLoose",{writable:!0,value:!1}),Object.defineProperty(Pn,"loose",{get(){return this._vueTypes_isLoose=!0,this}}),Pn}const M$1=["name","validate","getter"],R$1=(()=>{var $n;return($n=class{static get any(){return w$1()}static get func(){return P$1().def(this.defaults.func)}static get bool(){return x$1().def(this.defaults.bool)}static get string(){return E$1().def(this.defaults.string)}static get number(){return N$1().def(this.defaults.number)}static get array(){return q$1().def(this.defaults.array)}static get object(){return A$1().def(this.defaults.object)}static get integer(){return V$2().def(this.defaults.integer)}static get symbol(){return S$1()}static get nullable(){return{type:null}}static extend(Cn){if(v$1(Cn))return Cn.forEach(Ln=>this.extend(Ln)),this;const{name:_n,validate:Pn=!1,getter:In=!1}=Cn,Nn=r$1(Cn,M$1);if(p$1(this,_n))throw new TypeError(`[VueTypes error]: Type "${_n}" already defined`);const{type:Rn}=Nn;if(b$1(Rn))return delete Nn.type,Object.defineProperty(this,_n,In?{get:()=>T$1(_n,Rn,Nn)}:{value(...Ln){const Fn=T$1(_n,Rn,Nn);return Fn.validator&&(Fn.validator=Fn.validator.bind(Fn,...Ln)),Fn}});let Dn;return Dn=In?{get(){const Ln=Object.assign({},Nn);return Pn?_$1(_n,Ln):j$1(_n,Ln)},enumerable:!0}:{value(...Ln){const Fn=Object.assign({},Nn);let Bn;return Bn=Pn?_$1(_n,Fn):j$1(_n,Fn),Fn.validator&&(Bn.validator=Fn.validator.bind(Bn,...Ln)),Bn},enumerable:!0},Object.defineProperty(this,_n,Dn)}}).defaults={},$n.sensibleDefaults=void 0,$n.config=n$1,$n.custom=D$1,$n.oneOf=L$2,$n.instanceOf=B$2,$n.oneOfType=F$1,$n.arrayOf=Y$1,$n.objectOf=I$1,$n.shape=J$1,$n.utils={validate:(Cn,_n)=>m$1(_n,Cn,!0)===!0,toType:(Cn,_n,Pn=!1)=>Pn?_$1(Cn,_n):j$1(Cn,_n)},$n})();function z$1($n={func:()=>{},bool:!0,string:"",number:0,array:()=>[],object:()=>({}),integer:0}){var Cn;return(Cn=class extends R$1{static get sensibleDefaults(){return t$1({},this.defaults)}static set sensibleDefaults(_n){this.defaults=_n!==!1?t$1({},_n!==!0?_n:$n):{}}}).defaults=t$1({},$n),Cn}let C$1=class extends z$1(){};var t=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function e($n){var Cn={exports:{}};return $n(Cn,Cn.exports),Cn.exports}var n=function($n){return $n&&$n.Math==Math&&$n},r=n(typeof globalThis=="object"&&globalThis)||n(typeof window=="object"&&window)||n(typeof self=="object"&&self)||n(typeof t=="object"&&t)||function(){return this}()||Function("return this")(),o=function($n){try{return!!$n()}catch{return!0}},i=!o(function(){return Object.defineProperty({},1,{get:function(){return 7}})[1]!=7}),u={}.propertyIsEnumerable,a=Object.getOwnPropertyDescriptor,c={f:a&&!u.call({1:2},1)?function($n){var Cn=a(this,$n);return!!Cn&&Cn.enumerable}:u},l=function($n,Cn){return{enumerable:!(1&$n),configurable:!(2&$n),writable:!(4&$n),value:Cn}},f={}.toString,s=function($n){return f.call($n).slice(8,-1)},d="".split,v=o(function(){return!Object("z").propertyIsEnumerable(0)})?function($n){return s($n)=="String"?d.call($n,""):Object($n)}:Object,p=function($n){if($n==null)throw TypeError("Can't call method on "+$n);return $n},g=function($n){return v(p($n))},h=function($n){return typeof $n=="object"?$n!==null:typeof $n=="function"},y=function($n,Cn){if(!h($n))return $n;var _n,Pn;if(Cn&&typeof(_n=$n.toString)=="function"&&!h(Pn=_n.call($n))||typeof(_n=$n.valueOf)=="function"&&!h(Pn=_n.call($n))||!Cn&&typeof(_n=$n.toString)=="function"&&!h(Pn=_n.call($n)))return Pn;throw TypeError("Can't convert object to primitive value")},m={}.hasOwnProperty,S=function($n,Cn){return m.call($n,Cn)},x=r.document,b=h(x)&&h(x.createElement),E=function($n){return b?x.createElement($n):{}},w=!i&&!o(function(){return Object.defineProperty(E("div"),"a",{get:function(){return 7}}).a!=7}),O=Object.getOwnPropertyDescriptor,T={f:i?O:function($n,Cn){if($n=g($n),Cn=y(Cn,!0),w)try{return O($n,Cn)}catch{}if(S($n,Cn))return l(!c.f.call($n,Cn),$n[Cn])}},A=function($n){if(!h($n))throw TypeError(String($n)+" is not an object");return $n},k=Object.defineProperty,R={f:i?k:function($n,Cn,_n){if(A($n),Cn=y(Cn,!0),A(_n),w)try{return k($n,Cn,_n)}catch{}if("get"in _n||"set"in _n)throw TypeError("Accessors not supported");return"value"in _n&&($n[Cn]=_n.value),$n}},I=i?function($n,Cn,_n){return R.f($n,Cn,l(1,_n))}:function($n,Cn,_n){return $n[Cn]=_n,$n},j=function($n,Cn){try{I(r,$n,Cn)}catch{r[$n]=Cn}return Cn},C=r["__core-js_shared__"]||j("__core-js_shared__",{}),L$1=Function.toString;typeof C.inspectSource!="function"&&(C.inspectSource=function($n){return L$1.call($n)});var P,M,_,D=C.inspectSource,U=r.WeakMap,N=typeof U=="function"&&/native code/.test(D(U)),F=e(function($n){($n.exports=function(Cn,_n){return C[Cn]||(C[Cn]=_n!==void 0?_n:{})})("versions",[]).push({version:"3.8.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})}),W=0,z=Math.random(),$=function($n){return"Symbol("+String($n===void 0?"":$n)+")_"+(++W+z).toString(36)},B$1=F("keys"),Y=function($n){return B$1[$n]||(B$1[$n]=$($n))},G={},H=r.WeakMap;if(N){var X$1=C.state||(C.state=new H),V$1=X$1.get,K=X$1.has,q=X$1.set;P=function($n,Cn){return Cn.facade=$n,q.call(X$1,$n,Cn),Cn},M=function($n){return V$1.call(X$1,$n)||{}},_=function($n){return K.call(X$1,$n)}}else{var Q=Y("state");G[Q]=!0,P=function($n,Cn){return Cn.facade=$n,I($n,Q,Cn),Cn},M=function($n){return S($n,Q)?$n[Q]:{}},_=function($n){return S($n,Q)}}var J={set:P,get:M,has:_,enforce:function($n){return _($n)?M($n):P($n,{})},getterFor:function($n){return function(Cn){var _n;if(!h(Cn)||(_n=M(Cn)).type!==$n)throw TypeError("Incompatible receiver, "+$n+" required");return _n}}},Z=e(function($n){var Cn=J.get,_n=J.enforce,Pn=String(String).split("String");($n.exports=function(In,Nn,Rn,Dn){var Ln,Fn=!!Dn&&!!Dn.unsafe,Bn=!!Dn&&!!Dn.enumerable,Hn=!!Dn&&!!Dn.noTargetGet;typeof Rn=="function"&&(typeof Nn!="string"||S(Rn,"name")||I(Rn,"name",Nn),(Ln=_n(Rn)).source||(Ln.source=Pn.join(typeof Nn=="string"?Nn:""))),In!==r?(Fn?!Hn&&In[Nn]&&(Bn=!0):delete In[Nn],Bn?In[Nn]=Rn:I(In,Nn,Rn)):Bn?In[Nn]=Rn:j(Nn,Rn)})(Function.prototype,"toString",function(){return typeof this=="function"&&Cn(this).source||D(this)})}),tt$1=r,et=function($n){return typeof $n=="function"?$n:void 0},nt$1=function($n,Cn){return arguments.length<2?et(tt$1[$n])||et(r[$n]):tt$1[$n]&&tt$1[$n][Cn]||r[$n]&&r[$n][Cn]},rt$1=Math.ceil,ot$1=Math.floor,it$1=function($n){return isNaN($n=+$n)?0:($n>0?ot$1:rt$1)($n)},ut$1=Math.min,at$1=function($n){return $n>0?ut$1(it$1($n),9007199254740991):0},ct$1=Math.max,lt$1=Math.min,ft$1=function($n,Cn){var _n=it$1($n);return _n<0?ct$1(_n+Cn,0):lt$1(_n,Cn)},st$1=function($n){return function(Cn,_n,Pn){var In,Nn=g(Cn),Rn=at$1(Nn.length),Dn=ft$1(Pn,Rn);if($n&&_n!=_n){for(;Rn>Dn;)if((In=Nn[Dn++])!=In)return!0}else for(;Rn>Dn;Dn++)if(($n||Dn in Nn)&&Nn[Dn]===_n)return $n||Dn||0;return!$n&&-1}},dt$1={includes:st$1(!0),indexOf:st$1(!1)},vt$1=dt$1.indexOf,pt$1=function($n,Cn){var _n,Pn=g($n),In=0,Nn=[];for(_n in Pn)!S(G,_n)&&S(Pn,_n)&&Nn.push(_n);for(;Cn.length>In;)S(Pn,_n=Cn[In++])&&(~vt$1(Nn,_n)||Nn.push(_n));return Nn},gt$1=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],ht$1=gt$1.concat("length","prototype"),yt$1={f:Object.getOwnPropertyNames||function($n){return pt$1($n,ht$1)}},mt$1={f:Object.getOwnPropertySymbols},St$1=nt$1("Reflect","ownKeys")||function($n){var Cn=yt$1.f(A($n)),_n=mt$1.f;return _n?Cn.concat(_n($n)):Cn},xt$1=function($n,Cn){for(var _n=St$1(Cn),Pn=R.f,In=T.f,Nn=0;Nn<_n.length;Nn++){var Rn=_n[Nn];S($n,Rn)||Pn($n,Rn,In(Cn,Rn))}},bt$1=/#|\.prototype\./,Et$1=function($n,Cn){var _n=Ot$1[wt$1($n)];return _n==At$1||_n!=Tt$1&&(typeof Cn=="function"?o(Cn):!!Cn)},wt$1=Et$1.normalize=function($n){return String($n).replace(bt$1,".").toLowerCase()},Ot$1=Et$1.data={},Tt$1=Et$1.NATIVE="N",At$1=Et$1.POLYFILL="P",kt$1=Et$1,Rt$1=T.f,It$1=function($n,Cn){var _n,Pn,In,Nn,Rn,Dn=$n.target,Ln=$n.global,Fn=$n.stat;if(_n=Ln?r:Fn?r[Dn]||j(Dn,{}):(r[Dn]||{}).prototype)for(Pn in Cn){if(Nn=Cn[Pn],In=$n.noTargetGet?(Rn=Rt$1(_n,Pn))&&Rn.value:_n[Pn],!kt$1(Ln?Pn:Dn+(Fn?".":"#")+Pn,$n.forced)&&In!==void 0){if(typeof Nn==typeof In)continue;xt$1(Nn,In)}($n.sham||In&&In.sham)&&I(Nn,"sham",!0),Z(_n,Pn,Nn,$n)}},jt$1=function($n,Cn){var _n=[][$n];return!!_n&&o(function(){_n.call(null,Cn||function(){throw 1},1)})},Ct$1=Object.defineProperty,Lt$1={},Pt$1=function($n){throw $n},Mt$1=function($n,Cn){if(S(Lt$1,$n))return Lt$1[$n];Cn||(Cn={});var _n=[][$n],Pn=!!S(Cn,"ACCESSORS")&&Cn.ACCESSORS,In=S(Cn,0)?Cn[0]:Pt$1,Nn=S(Cn,1)?Cn[1]:void 0;return Lt$1[$n]=!!_n&&!o(function(){if(Pn&&!i)return!0;var Rn={length:-1};Pn?Ct$1(Rn,1,{enumerable:!0,get:Pt$1}):Rn[1]=1,_n.call(Rn,In,Nn)})},_t$1=dt$1.indexOf,Dt$1=[].indexOf,Ut$1=!!Dt$1&&1/[1].indexOf(1,-0)<0,Nt$1=jt$1("indexOf"),Ft$1=Mt$1("indexOf",{ACCESSORS:!0,1:0});function Wt$1($n,Cn){if(!($n instanceof Cn))throw new TypeError("Cannot call a class as a function")}function zt$1($n,Cn){for(var _n=0;_n1?arguments[1]:void 0)}});(function(){function $n(){Wt$1(this,$n)}return $t$1($n,null,[{key:"isInBrowser",value:function(){return typeof window<"u"}},{key:"isServer",value:function(){return typeof window>"u"}},{key:"getUA",value:function(){return $n.isInBrowser()?window.navigator.userAgent.toLowerCase():""}},{key:"isMobile",value:function(){return/Mobile|mini|Fennec|Android|iP(ad|od|hone)/.test(navigator.appVersion)}},{key:"isOpera",value:function(){return navigator.userAgent.indexOf("Opera")!==-1}},{key:"isIE",value:function(){var Cn=$n.getUA();return Cn!==""&&Cn.indexOf("msie")>0}},{key:"isIE9",value:function(){var Cn=$n.getUA();return Cn!==""&&Cn.indexOf("msie 9.0")>0}},{key:"isEdge",value:function(){var Cn=$n.getUA();return Cn!==""&&Cn.indexOf("edge/")>0}},{key:"isChrome",value:function(){var Cn=$n.getUA();return Cn!==""&&/chrome\/\d+/.test(Cn)&&!$n.isEdge()}},{key:"isPhantomJS",value:function(){var Cn=$n.getUA();return Cn!==""&&/phantomjs/.test(Cn)}},{key:"isFirefox",value:function(){var Cn=$n.getUA();return Cn!==""&&/firefox/.test(Cn)}}]),$n})();var Yt$1=[].join,Gt$1=v!=Object,Ht$1=jt$1("join",",");It$1({target:"Array",proto:!0,forced:Gt$1||!Ht$1},{join:function($n){return Yt$1.call(g(this),$n===void 0?",":$n)}});var Xt$1,Vt$1,Kt$1=function($n){return Object(p($n))},qt$1=Array.isArray||function($n){return s($n)=="Array"},Qt$1=!!Object.getOwnPropertySymbols&&!o(function(){return!String(Symbol())}),Jt$1=Qt$1&&!Symbol.sham&&typeof Symbol.iterator=="symbol",Zt$1=F("wks"),te=r.Symbol,ee=Jt$1?te:te&&te.withoutSetter||$,ne=function($n){return S(Zt$1,$n)||(Qt$1&&S(te,$n)?Zt$1[$n]=te[$n]:Zt$1[$n]=ee("Symbol."+$n)),Zt$1[$n]},re=ne("species"),oe=function($n,Cn){var _n;return qt$1($n)&&(typeof(_n=$n.constructor)!="function"||_n!==Array&&!qt$1(_n.prototype)?h(_n)&&(_n=_n[re])===null&&(_n=void 0):_n=void 0),new(_n===void 0?Array:_n)(Cn===0?0:Cn)},ie$1=function($n,Cn,_n){var Pn=y(Cn);Pn in $n?R.f($n,Pn,l(0,_n)):$n[Pn]=_n},ue=nt$1("navigator","userAgent")||"",ae$1=r.process,ce$1=ae$1&&ae$1.versions,le=ce$1&&ce$1.v8;le?Vt$1=(Xt$1=le.split("."))[0]+Xt$1[1]:ue&&(!(Xt$1=ue.match(/Edge\/(\d+)/))||Xt$1[1]>=74)&&(Xt$1=ue.match(/Chrome\/(\d+)/))&&(Vt$1=Xt$1[1]);var fe$1=Vt$1&&+Vt$1,se=ne("species"),de=function($n){return fe$1>=51||!o(function(){var Cn=[];return(Cn.constructor={})[se]=function(){return{foo:1}},Cn[$n](Boolean).foo!==1})},ve$1=de("splice"),pe$1=Mt$1("splice",{ACCESSORS:!0,0:0,1:2}),ge=Math.max,he$1=Math.min;It$1({target:"Array",proto:!0,forced:!ve$1||!pe$1},{splice:function($n,Cn){var _n,Pn,In,Nn,Rn,Dn,Ln=Kt$1(this),Fn=at$1(Ln.length),Bn=ft$1($n,Fn),Hn=arguments.length;if(Hn===0?_n=Pn=0:Hn===1?(_n=0,Pn=Fn-Bn):(_n=Hn-2,Pn=he$1(ge(it$1(Cn),0),Fn-Bn)),Fn+_n-Pn>9007199254740991)throw TypeError("Maximum allowed length exceeded");for(In=oe(Ln,Pn),Nn=0;NnFn-Pn+_n;Nn--)delete Ln[Nn-1]}else if(_n>Pn)for(Nn=Fn-Pn;Nn>Bn;Nn--)Dn=Nn+_n-1,(Rn=Nn+Pn-1)in Ln?Ln[Dn]=Ln[Rn]:delete Ln[Dn];for(Nn=0;Nn<_n;Nn++)Ln[Nn+Bn]=arguments[Nn+2];return Ln.length=Fn-Pn+_n,In}});var ye$1={};ye$1[ne("toStringTag")]="z";var me$1=String(ye$1)==="[object z]",Se=ne("toStringTag"),xe=s(function(){return arguments}())=="Arguments",be$1=me$1?s:function($n){var Cn,_n,Pn;return $n===void 0?"Undefined":$n===null?"Null":typeof(_n=function(In,Nn){try{return In[Nn]}catch{}}(Cn=Object($n),Se))=="string"?_n:xe?s(Cn):(Pn=s(Cn))=="Object"&&typeof Cn.callee=="function"?"Arguments":Pn},Ee=me$1?{}.toString:function(){return"[object "+be$1(this)+"]"};me$1||Z(Object.prototype,"toString",Ee,{unsafe:!0});var we=function(){var $n=A(this),Cn="";return $n.global&&(Cn+="g"),$n.ignoreCase&&(Cn+="i"),$n.multiline&&(Cn+="m"),$n.dotAll&&(Cn+="s"),$n.unicode&&(Cn+="u"),$n.sticky&&(Cn+="y"),Cn};function Oe($n,Cn){return RegExp($n,Cn)}var Te,Ae$1,ke={UNSUPPORTED_Y:o(function(){var $n=Oe("a","y");return $n.lastIndex=2,$n.exec("abcd")!=null}),BROKEN_CARET:o(function(){var $n=Oe("^r","gy");return $n.lastIndex=2,$n.exec("str")!=null})},Re$1=RegExp.prototype.exec,Ie$1=String.prototype.replace,je=Re$1,Ce$1=(Te=/a/,Ae$1=/b*/g,Re$1.call(Te,"a"),Re$1.call(Ae$1,"a"),Te.lastIndex!==0||Ae$1.lastIndex!==0),Le=ke.UNSUPPORTED_Y||ke.BROKEN_CARET,Pe=/()??/.exec("")[1]!==void 0;(Ce$1||Pe||Le)&&(je=function($n){var Cn,_n,Pn,In,Nn=this,Rn=Le&&Nn.sticky,Dn=we.call(Nn),Ln=Nn.source,Fn=0,Bn=$n;return Rn&&((Dn=Dn.replace("y","")).indexOf("g")===-1&&(Dn+="g"),Bn=String($n).slice(Nn.lastIndex),Nn.lastIndex>0&&(!Nn.multiline||Nn.multiline&&$n[Nn.lastIndex-1]!==` -`)&&(Ln="(?: "+Ln+")",Bn=" "+Bn,Fn++),_n=new RegExp("^(?:"+Ln+")",Dn)),Pe&&(_n=new RegExp("^"+Ln+"$(?!\\s)",Dn)),Ce$1&&(Cn=Nn.lastIndex),Pn=Re$1.call(Rn?_n:Nn,Bn),Rn?Pn?(Pn.input=Pn.input.slice(Fn),Pn[0]=Pn[0].slice(Fn),Pn.index=Nn.lastIndex,Nn.lastIndex+=Pn[0].length):Nn.lastIndex=0:Ce$1&&Pn&&(Nn.lastIndex=Nn.global?Pn.index+Pn[0].length:Cn),Pe&&Pn&&Pn.length>1&&Ie$1.call(Pn[0],_n,function(){for(In=1;In")!=="7"}),ze$1="a".replace(/./,"$0")==="$0",$e=ne("replace"),Be$1=!!/./[$e]&&/./[$e]("a","$0")==="",Ye=!o(function(){var $n=/(?:)/,Cn=$n.exec;$n.exec=function(){return Cn.apply(this,arguments)};var _n="ab".split($n);return _n.length!==2||_n[0]!=="a"||_n[1]!=="b"}),Ge$1=function($n,Cn,_n,Pn){var In=ne($n),Nn=!o(function(){var Hn={};return Hn[In]=function(){return 7},""[$n](Hn)!=7}),Rn=Nn&&!o(function(){var Hn=!1,zn=/a/;return $n==="split"&&((zn={}).constructor={},zn.constructor[Fe]=function(){return zn},zn.flags="",zn[In]=/./[In]),zn.exec=function(){return Hn=!0,null},zn[In](""),!Hn});if(!Nn||!Rn||$n==="replace"&&(!We||!ze$1||Be$1)||$n==="split"&&!Ye){var Dn=/./[In],Ln=_n(In,""[$n],function(Hn,zn,Wn,Yn,Gn){return zn.exec===Me$1?Nn&&!Gn?{done:!0,value:Dn.call(zn,Wn,Yn)}:{done:!0,value:Hn.call(Wn,zn,Yn)}:{done:!1}},{REPLACE_KEEPS_$0:ze$1,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:Be$1}),Fn=Ln[0],Bn=Ln[1];Z(String.prototype,$n,Fn),Z(RegExp.prototype,In,Cn==2?function(Hn,zn){return Bn.call(Hn,this,zn)}:function(Hn){return Bn.call(Hn,this)})}Pn&&I(RegExp.prototype[In],"sham",!0)},He$1=ne("match"),Xe=function($n){var Cn;return h($n)&&((Cn=$n[He$1])!==void 0?!!Cn:s($n)=="RegExp")},Ve$1=function($n){if(typeof $n!="function")throw TypeError(String($n)+" is not a function");return $n},Ke=ne("species"),qe=function($n){return function(Cn,_n){var Pn,In,Nn=String(p(Cn)),Rn=it$1(_n),Dn=Nn.length;return Rn<0||Rn>=Dn?$n?"":void 0:(Pn=Nn.charCodeAt(Rn))<55296||Pn>56319||Rn+1===Dn||(In=Nn.charCodeAt(Rn+1))<56320||In>57343?$n?Nn.charAt(Rn):Pn:$n?Nn.slice(Rn,Rn+2):In-56320+(Pn-55296<<10)+65536}},Qe={codeAt:qe(!1),charAt:qe(!0)},Je=Qe.charAt,Ze=function($n,Cn,_n){return Cn+(_n?Je($n,Cn).length:1)},tn=function($n,Cn){var _n=$n.exec;if(typeof _n=="function"){var Pn=_n.call($n,Cn);if(typeof Pn!="object")throw TypeError("RegExp exec method returned something other than an Object or null");return Pn}if(s($n)!=="RegExp")throw TypeError("RegExp#exec called on incompatible receiver");return Me$1.call($n,Cn)},en=[].push,nn=Math.min,rn=!o(function(){return!RegExp(4294967295,"y")});Ge$1("split",2,function($n,Cn,_n){var Pn;return Pn="abbc".split(/(b)*/)[1]=="c"||"test".split(/(?:)/,-1).length!=4||"ab".split(/(?:ab)*/).length!=2||".".split(/(.?)(.?)/).length!=4||".".split(/()()/).length>1||"".split(/.?/).length?function(In,Nn){var Rn=String(p(this)),Dn=Nn===void 0?4294967295:Nn>>>0;if(Dn===0)return[];if(In===void 0)return[Rn];if(!Xe(In))return Cn.call(Rn,In,Dn);for(var Ln,Fn,Bn,Hn=[],zn=(In.ignoreCase?"i":"")+(In.multiline?"m":"")+(In.unicode?"u":"")+(In.sticky?"y":""),Wn=0,Yn=new RegExp(In.source,zn+"g");(Ln=Me$1.call(Yn,Rn))&&!((Fn=Yn.lastIndex)>Wn&&(Hn.push(Rn.slice(Wn,Ln.index)),Ln.length>1&&Ln.index=Dn));)Yn.lastIndex===Ln.index&&Yn.lastIndex++;return Wn===Rn.length?!Bn&&Yn.test("")||Hn.push(""):Hn.push(Rn.slice(Wn)),Hn.length>Dn?Hn.slice(0,Dn):Hn}:"0".split(void 0,0).length?function(In,Nn){return In===void 0&&Nn===0?[]:Cn.call(this,In,Nn)}:Cn,[function(In,Nn){var Rn=p(this),Dn=In==null?void 0:In[$n];return Dn!==void 0?Dn.call(In,Rn,Nn):Pn.call(String(Rn),In,Nn)},function(In,Nn){var Rn=_n(Pn,In,this,Nn,Pn!==Cn);if(Rn.done)return Rn.value;var Dn=A(In),Ln=String(this),Fn=function(Jo,Zo){var rr,nr=A(Jo).constructor;return nr===void 0||(rr=A(nr)[Ke])==null?Zo:Ve$1(rr)}(Dn,RegExp),Bn=Dn.unicode,Hn=(Dn.ignoreCase?"i":"")+(Dn.multiline?"m":"")+(Dn.unicode?"u":"")+(rn?"y":"g"),zn=new Fn(rn?Dn:"^(?:"+Dn.source+")",Hn),Wn=Nn===void 0?4294967295:Nn>>>0;if(Wn===0)return[];if(Ln.length===0)return tn(zn,Ln)===null?[Ln]:[];for(var Yn=0,Gn=0,Go=[];Gn1?arguments[1]:void 0,Cn.length)),Pn=String($n);return wn?wn.call(Cn,Pn,_n):Cn.slice(_n,_n+Pn.length)===Pn}});var jn=function($n){return typeof $n=="string"},Mn=function($n){return $n!==null&&kn($n)==="object"},Vn=function(){function $n(){Wt$1(this,$n)}return $t$1($n,null,[{key:"isWindow",value:function(Cn){return Cn===window}},{key:"addEventListener",value:function(Cn,_n,Pn){var In=arguments.length>3&&arguments[3]!==void 0&&arguments[3];Cn&&_n&&Pn&&Cn.addEventListener(_n,Pn,In)}},{key:"removeEventListener",value:function(Cn,_n,Pn){var In=arguments.length>3&&arguments[3]!==void 0&&arguments[3];Cn&&_n&&Pn&&Cn.removeEventListener(_n,Pn,In)}},{key:"triggerDragEvent",value:function(Cn,_n){var Pn=!1,In=function(Rn){var Dn;(Dn=_n.drag)===null||Dn===void 0||Dn.call(_n,Rn)},Nn=function Rn(Dn){var Ln;$n.removeEventListener(document,"mousemove",In),$n.removeEventListener(document,"mouseup",Rn),document.onselectstart=null,document.ondragstart=null,Pn=!1,(Ln=_n.end)===null||Ln===void 0||Ln.call(_n,Dn)};$n.addEventListener(Cn,"mousedown",function(Rn){var Dn;Pn||(document.onselectstart=function(){return!1},document.ondragstart=function(){return!1},$n.addEventListener(document,"mousemove",In),$n.addEventListener(document,"mouseup",Nn),Pn=!0,(Dn=_n.start)===null||Dn===void 0||Dn.call(_n,Rn))})}},{key:"getBoundingClientRect",value:function(Cn){return Cn&&Mn(Cn)&&Cn.nodeType===1?Cn.getBoundingClientRect():null}},{key:"hasClass",value:function(Cn,_n){return!!(Cn&&Mn(Cn)&&jn(_n)&&Cn.nodeType===1)&&Cn.classList.contains(_n.trim())}},{key:"addClass",value:function(Cn,_n){if(Cn&&Mn(Cn)&&jn(_n)&&Cn.nodeType===1&&(_n=_n.trim(),!$n.hasClass(Cn,_n))){var Pn=Cn.className;Cn.className=Pn?Pn+" "+_n:_n}}},{key:"removeClass",value:function(Cn,_n){if(Cn&&Mn(Cn)&&jn(_n)&&Cn.nodeType===1&&typeof Cn.className=="string"){_n=_n.trim();for(var Pn=Cn.className.trim().split(" "),In=Pn.length-1;In>=0;In--)Pn[In]=Pn[In].trim(),Pn[In]&&Pn[In]!==_n||Pn.splice(In,1);Cn.className=Pn.join(" ")}}},{key:"toggleClass",value:function(Cn,_n,Pn){Cn&&Mn(Cn)&&jn(_n)&&Cn.nodeType===1&&Cn.classList.toggle(_n,Pn)}},{key:"replaceClass",value:function(Cn,_n,Pn){Cn&&Mn(Cn)&&jn(_n)&&jn(Pn)&&Cn.nodeType===1&&(_n=_n.trim(),Pn=Pn.trim(),$n.removeClass(Cn,_n),$n.addClass(Cn,Pn))}},{key:"getScrollTop",value:function(Cn){var _n="scrollTop"in Cn?Cn.scrollTop:Cn.pageYOffset;return Math.max(_n,0)}},{key:"setScrollTop",value:function(Cn,_n){"scrollTop"in Cn?Cn.scrollTop=_n:Cn.scrollTo(Cn.scrollX,_n)}},{key:"getRootScrollTop",value:function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0}},{key:"setRootScrollTop",value:function(Cn){$n.setScrollTop(window,Cn),$n.setScrollTop(document.body,Cn)}},{key:"getElementTop",value:function(Cn,_n){if($n.isWindow(Cn))return 0;var Pn=_n?$n.getScrollTop(_n):$n.getRootScrollTop();return Cn.getBoundingClientRect().top+Pn}},{key:"getVisibleHeight",value:function(Cn){return $n.isWindow(Cn)?Cn.innerHeight:Cn.getBoundingClientRect().height}},{key:"isHidden",value:function(Cn){if(!Cn)return!1;var _n=window.getComputedStyle(Cn),Pn=_n.display==="none",In=Cn.offsetParent===null&&_n.position!=="fixed";return Pn||In}},{key:"triggerEvent",value:function(Cn,_n){if("createEvent"in document){var Pn=document.createEvent("HTMLEvents");Pn.initEvent(_n,!1,!0),Cn.dispatchEvent(Pn)}}},{key:"calcAngle",value:function(Cn,_n){var Pn=Cn.getBoundingClientRect(),In=Pn.left+Pn.width/2,Nn=Pn.top+Pn.height/2,Rn=Math.abs(In-_n.clientX),Dn=Math.abs(Nn-_n.clientY),Ln=Dn/Math.sqrt(Math.pow(Rn,2)+Math.pow(Dn,2)),Fn=Math.acos(Ln),Bn=Math.floor(180/(Math.PI/Fn));return _n.clientX>In&&_n.clientY>Nn&&(Bn=180-Bn),_n.clientX==In&&_n.clientY>Nn&&(Bn=180),_n.clientX>In&&_n.clientY==Nn&&(Bn=90),_n.clientXNn&&(Bn=180+Bn),_n.clientX1?Pn-1:0),Nn=1;Nn]*>)/g,Jn=/\$([$&'`]|\d\d?)/g,Zn=function($n,Cn,_n,Pn,In,Nn){var Rn=_n+$n.length,Dn=Pn.length,Ln=Jn;return In!==void 0&&(In=Kt$1(In),Ln=Qn),qn.call(Nn,Ln,function(Fn,Bn){var Hn;switch(Bn.charAt(0)){case"$":return"$";case"&":return $n;case"`":return Cn.slice(0,_n);case"'":return Cn.slice(Rn);case"<":Hn=In[Bn.slice(1,-1)];break;default:var zn=+Bn;if(zn===0)return Fn;if(zn>Dn){var Wn=Kn(zn/10);return Wn===0?Fn:Wn<=Dn?Pn[Wn-1]===void 0?Bn.charAt(1):Pn[Wn-1]+Bn.charAt(1):Fn}Hn=Pn[zn-1]}return Hn===void 0?"":Hn})},tr=Math.max,er=Math.min;Ge$1("replace",2,function($n,Cn,_n,Pn){var In=Pn.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,Nn=Pn.REPLACE_KEEPS_$0,Rn=In?"$":"$0";return[function(Dn,Ln){var Fn=p(this),Bn=Dn==null?void 0:Dn[$n];return Bn!==void 0?Bn.call(Dn,Fn,Ln):Cn.call(String(Fn),Dn,Ln)},function(Dn,Ln){if(!In&&Nn||typeof Ln=="string"&&Ln.indexOf(Rn)===-1){var Fn=_n(Cn,Dn,this,Ln);if(Fn.done)return Fn.value}var Bn=A(Dn),Hn=String(this),zn=typeof Ln=="function";zn||(Ln=String(Ln));var Wn=Bn.global;if(Wn){var Yn=Bn.unicode;Bn.lastIndex=0}for(var Gn=[];;){var Go=tn(Bn,Hn);if(Go===null||(Gn.push(Go),!Wn))break;String(Go[0])===""&&(Bn.lastIndex=Ze(Hn,at$1(Bn.lastIndex),Yn))}for(var Xn,Yo="",qo=0,Jo=0;Jo=qo&&(Yo+=Hn.slice(qo,rr)+ea,qo=rr+Zo.length)}return Yo+Hn.slice(qo)}]});(function(){function $n(){Wt$1(this,$n)}return $t$1($n,null,[{key:"camelize",value:function(Cn){return Cn.replace(/-(\w)/g,function(_n,Pn){return Pn?Pn.toUpperCase():""})}},{key:"capitalize",value:function(Cn){return Cn.charAt(0).toUpperCase()+Cn.slice(1)}}]),$n})();(function(){function $n(){Wt$1(this,$n)}return $t$1($n,null,[{key:"_clone",value:function(){}}]),$n})();var or=ne("isConcatSpreadable"),ir=fe$1>=51||!o(function(){var $n=[];return $n[or]=!1,$n.concat()[0]!==$n}),ur=de("concat"),ar=function($n){if(!h($n))return!1;var Cn=$n[or];return Cn!==void 0?!!Cn:qt$1($n)};It$1({target:"Array",proto:!0,forced:!ir||!ur},{concat:function($n){var Cn,_n,Pn,In,Nn,Rn=Kt$1(this),Dn=oe(Rn,0),Ln=0;for(Cn=-1,Pn=arguments.length;Cn9007199254740991)throw TypeError("Maximum allowed index exceeded");for(_n=0;_n=9007199254740991)throw TypeError("Maximum allowed index exceeded");ie$1(Dn,Ln++,Nn)}return Dn.length=Ln,Dn}});var cr,lr=function($n,Cn,_n){if(Ve$1($n),Cn===void 0)return $n;switch(_n){case 0:return function(){return $n.call(Cn)};case 1:return function(Pn){return $n.call(Cn,Pn)};case 2:return function(Pn,In){return $n.call(Cn,Pn,In)};case 3:return function(Pn,In,Nn){return $n.call(Cn,Pn,In,Nn)}}return function(){return $n.apply(Cn,arguments)}},fr=[].push,sr=function($n){var Cn=$n==1,_n=$n==2,Pn=$n==3,In=$n==4,Nn=$n==6,Rn=$n==7,Dn=$n==5||Nn;return function(Ln,Fn,Bn,Hn){for(var zn,Wn,Yn=Kt$1(Ln),Gn=v(Yn),Go=lr(Fn,Bn,3),Xn=at$1(Gn.length),Yo=0,qo=Hn||oe,Jo=Cn?qo(Ln,Xn):_n||Rn?qo(Ln,0):void 0;Xn>Yo;Yo++)if((Dn||Yo in Gn)&&(Wn=Go(zn=Gn[Yo],Yo,Yn),$n))if(Cn)Jo[Yo]=Wn;else if(Wn)switch($n){case 3:return!0;case 5:return zn;case 6:return Yo;case 2:fr.call(Jo,zn)}else switch($n){case 4:return!1;case 7:fr.call(Jo,zn)}return Nn?-1:Pn||In?In:Jo}},dr={forEach:sr(0),map:sr(1),filter:sr(2),some:sr(3),every:sr(4),find:sr(5),findIndex:sr(6),filterOut:sr(7)},vr=i?Object.defineProperties:function($n,Cn){A($n);for(var _n,Pn=yn(Cn),In=Pn.length,Nn=0;In>Nn;)R.f($n,_n=Pn[Nn++],Cn[_n]);return $n},pr=nt$1("document","documentElement"),gr=Y("IE_PROTO"),hr=function(){},yr=function($n){return" - - - -
    - - diff --git a/hack/swagger/README.md b/docs/swagger/README.md similarity index 100% rename from hack/swagger/README.md rename to docs/swagger/README.md diff --git a/hack/swagger/swagger.json b/docs/swagger/swagger.json similarity index 100% rename from hack/swagger/swagger.json rename to docs/swagger/swagger.json diff --git a/go.mod b/go.mod index 4d300bc63..c8d33c258 100644 --- a/go.mod +++ b/go.mod @@ -15,274 +15,259 @@ module github.com/apache/dubbo-admin -go 1.23.0 +go 1.24.0 + +toolchain go1.24.11 require ( - dubbo.apache.org/dubbo-go/v3 v3.3.0 - github.com/AlecAivazis/survey/v2 v2.3.7 - github.com/Masterminds/semver/v3 v3.2.1 - github.com/Microsoft/go-winio v0.6.2 - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 - github.com/bakito/go-log-logr-adapter v0.0.2 - github.com/buildpacks/pack v0.30.0 - github.com/cheggaaa/pb/v3 v3.1.5 - github.com/containers/image/v5 v5.34.0 - github.com/containers/storage v1.57.1 - github.com/docker/cli v27.5.1+incompatible - github.com/docker/docker v27.5.1+incompatible - github.com/docker/docker-credential-helpers v0.8.2 - github.com/docker/go-connections v0.5.0 - github.com/dubbogo/gost v1.14.0 + dubbo.apache.org/dubbo-go/v3 v3.0.0-20260210015753-35ea886421f9 + github.com/apache/dubbo-go-hessian2 v1.12.5 + github.com/armon/go-radix v1.0.0 + github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 github.com/duke-git/lancet/v2 v2.3.6 - github.com/emicklei/go-restful/v3 v3.11.0 - github.com/envoyproxy/go-control-plane v0.13.4 github.com/envoyproxy/go-control-plane/envoy v1.32.4 - github.com/fatih/color v1.18.0 github.com/fullstorydev/grpcurl v1.9.1 github.com/gin-contrib/sessions v1.0.4 + github.com/gin-contrib/zap v1.1.6 github.com/gin-gonic/gin v1.10.1 - github.com/go-git/go-billy/v5 v5.6.2 - github.com/go-git/go-git/v5 v5.13.1 + github.com/go-co-op/gocron v1.9.0 github.com/go-logr/logr v1.4.2 github.com/go-logr/zapr v1.3.0 - github.com/goburrow/cache v0.1.4 github.com/golang/protobuf v1.5.4 - github.com/google/go-cmp v0.7.0 - github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/hashicorp/go-multierror v1.1.1 - github.com/heroku/color v0.0.6 - github.com/hoisie/mustache v0.0.0-20160804235033-6375acf62c69 github.com/jhump/protoreflect v1.16.0 - github.com/kelseyhightower/envconfig v1.4.0 - github.com/mitchellh/mapstructure v1.5.0 - github.com/moby/term v0.5.0 + github.com/nacos-group/nacos-sdk-go/v2 v2.3.5 github.com/onsi/ginkgo/v2 v2.22.1 github.com/onsi/gomega v1.36.2 - github.com/ory/viper v1.7.5 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.20.5 - github.com/slok/go-http-metrics v0.11.0 github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.37.0 - golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 - golang.org/x/sys v0.32.0 - golang.org/x/term v0.31.0 - golang.org/x/text v0.24.0 + golang.org/x/text v0.31.0 google.golang.org/grpc v1.73.0 google.golang.org/protobuf v1.36.6 gopkg.in/natefinch/lumberjack.v2 v2.2.1 - gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.12.3 - k8s.io/api v0.32.0 - k8s.io/apiextensions-apiserver v0.32.0 - k8s.io/apimachinery v0.32.0 - k8s.io/client-go v0.32.0 - k8s.io/kubectl v0.27.3 + gorm.io/driver/mysql v1.6.0 + gorm.io/driver/postgres v1.6.0 + gorm.io/driver/sqlite v1.5.7 + gorm.io/gorm v1.30.0 + k8s.io/api v0.34.2 + k8s.io/apimachinery v0.34.2 + k8s.io/client-go v0.34.2 + k8s.io/klog/v2 v2.130.1 sigs.k8s.io/controller-runtime v0.19.4 - sigs.k8s.io/controller-tools v0.17.0 - sigs.k8s.io/yaml v1.4.0 + sigs.k8s.io/yaml v1.6.0 +) + +require ( + github.com/Workiva/go-datastructures v1.0.52 // indirect + github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 // indirect + github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect + github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect + github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect + github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect + github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 // indirect + github.com/alibabacloud-go/darabonba-signature-util v0.0.7 // indirect + github.com/alibabacloud-go/darabonba-string v1.0.2 // indirect + github.com/alibabacloud-go/debug v1.0.1 // indirect + github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect + github.com/alibabacloud-go/kms-20160120/v3 v3.2.3 // indirect + github.com/alibabacloud-go/openapi-util v0.1.0 // indirect + github.com/alibabacloud-go/tea v1.2.2 // indirect + github.com/alibabacloud-go/tea-utils v1.4.4 // indirect + github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect + github.com/alibabacloud-go/tea-xml v1.1.3 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 // indirect + github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 // indirect + github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 // indirect + github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 // indirect + github.com/aliyun/credentials-go v1.4.3 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/clbanning/mxj/v2 v2.5.5 // indirect + github.com/deckarep/golang-set v1.7.1 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/natefinch/lumberjack v2.0.0+incompatible // indirect + github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect ) require ( - cel.dev/expr v0.23.0 // indirect - dario.cat/mergo v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.29 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect - github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect - github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/ProtonMail/go-crypto v1.1.3 // indirect - github.com/VividCortex/ewma v1.2.0 // indirect - github.com/agext/levenshtein v1.2.3 // indirect - github.com/apex/log v1.9.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect - github.com/aws/aws-sdk-go-v2/config v1.18.27 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect - github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 // indirect - github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect - github.com/aws/smithy-go v1.13.5 // indirect - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230522190001-adf1bafd791a // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/RoaringBitmap/roaring v1.2.3 // indirect + github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect + github.com/alibaba/sentinel-golang v1.0.4 // indirect + github.com/apache/dubbo-getty v1.4.10 // indirect + github.com/apolloconfig/agollo/v4 v4.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect + github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/bufbuild/protocompile v0.10.0 // indirect - github.com/buildpacks/imgutil v0.0.0-20230626185301-726f02e4225c // indirect - github.com/buildpacks/lifecycle v0.17.0 // indirect github.com/bytedance/sonic v1.13.2 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect - github.com/cespare/xxhash v1.1.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect - github.com/cloudflare/circl v1.3.7 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect - github.com/containerd/containerd v1.7.2 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect - github.com/containerd/typeurl v1.0.2 // indirect - github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/creasty/defaults v1.5.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgraph-io/ristretto v0.0.1 // indirect - github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/go-units v0.5.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 // indirect + github.com/dubbogo/gost v1.14.3 // indirect + github.com/dubbogo/grpc-go v1.42.10 // indirect + github.com/dubbogo/triple v1.2.2-rc4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gdamore/encoding v1.0.0 // indirect - github.com/gdamore/tcell/v2 v2.6.0 // indirect - github.com/gin-contrib/sse v1.0.0 // indirect - github.com/go-errors/errors v1.4.2 // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.26.0 // indirect + github.com/go-resty/resty/v2 v2.7.0 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gobuffalo/flect v1.0.3 // indirect - github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.4.0 // indirect - github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect + github.com/hashicorp/vault/sdk v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/influxdata/tdigest v0.0.1 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.6.0 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/k0kubun/pp v3.0.1+incompatible // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/klauspost/pgzip v1.2.6 // indirect + github.com/knadh/koanf v1.5.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.5 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/buildkit v0.11.6 // indirect - github.com/moby/patternmatcher v0.5.0 // indirect - github.com/moby/sys/capability v0.4.0 // indirect - github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.3.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect - github.com/morikuni/aec v1.0.0 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runc v1.1.7 // indirect - github.com/opencontainers/runtime-spec v1.2.0 // indirect - github.com/opencontainers/selinux v1.11.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/openzipkin/zipkin-go v0.4.2 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/polarismesh/polaris-go v1.3.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/shopspring/decimal v1.3.1 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.52.0 // indirect + github.com/shirou/gopsutil/v3 v3.22.2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skeema/knownhosts v1.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.10.0 // indirect + github.com/spf13/cast v1.3.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/spf13/viper v1.8.1 // indirect github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/tklauser/go-sysconf v0.3.10 // indirect + github.com/tklauser/numcpus v0.4.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/uber/jaeger-client-go v2.29.1+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/ugorji/go/codec v1.2.12 // indirect - github.com/ulikunitz/xz v0.5.12 // indirect - github.com/vbatts/tar-split v0.11.7 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xlab/treeprint v1.2.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zeebo/errs v1.4.0 // indirect + go.etcd.io/etcd/api/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/v3 v3.5.7 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.10.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/mock v0.5.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.16.0 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.38.0 // indirect + golang.org/x/crypto v0.45.0 // indirect + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect golang.org/x/oauth2 v0.28.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.28.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.38.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/cli-runtime v0.32.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/kustomize/api v0.18.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) replace ( + cloud.google.com/go/compute/metadata => cloud.google.com/go/compute/metadata v0.6.0 github.com/docker/cli => github.com/docker/cli v23.0.1+incompatible github.com/docker/distribution => github.com/docker/distribution v2.8.2+incompatible github.com/docker/docker => github.com/docker/docker v23.0.1+incompatible diff --git a/go.sum b/go.sum index 57a3b22a1..414edca8b 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,9 @@ -cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= -cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,6 +14,12 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -33,320 +38,309 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dubbo.apache.org/dubbo-go/v3 v3.3.0 h1:jhwK4nQ1DsKQ6H9p7icZx0jg9ulF1vpAA/c0Ly8Et4w= -dubbo.apache.org/dubbo-go/v3 v3.3.0/go.mod h1:zu2m9tUGaZYfuaMX82pLlwmq7Vl4s5eenZNBGdfAagc= -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= -github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= -github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= -github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= -github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= -github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +dubbo.apache.org/dubbo-go/v3 v3.0.0-20260210015753-35ea886421f9 h1:EJqCaeYde6IjyDsCukn+54x/xOMPh7XGaZZCkoRUZCU= +dubbo.apache.org/dubbo-go/v3 v3.0.0-20260210015753-35ea886421f9/go.mod h1:3ggdIDIW72EmHD2hX9rfCULcKHlaRMSCXWUjAQ9exII= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= -github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= -github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= -github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= -github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY= +github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= +github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= +github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= +github.com/agiledragon/gomonkey/v2 v2.11.0 h1:5oxSgA+tC1xuGsrIorR+sYiziYltmJyEZ9qA25b6l5U= +github.com/agiledragon/gomonkey/v2 v2.11.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alibaba/sentinel-golang v1.0.4 h1:i0wtMvNVdy7vM4DdzYrlC4r/Mpk1OKUUBurKKkWhEo8= +github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk= +github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA= +github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g= +github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY= +github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI= +github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE= +github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8= +github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc= +github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc= +github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.9/go.mod h1:bb+Io8Sn2RuM3/Rpme6ll86jMyFSrD1bxeV/+v61KeU= +github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 h1:GEYkMApgpKEVDn6z12DcH1EGYpDYRB8JxsazM4Rywak= +github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE= +github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg= +github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ= +github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo= +github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= +github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg= +github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q= +github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= +github.com/alibabacloud-go/kms-20160120/v3 v3.2.3 h1:vamGcYQFwXVqR6RWcrVTTqlIXZVsYjaA7pZbx+Xw6zw= +github.com/alibabacloud-go/kms-20160120/v3 v3.2.3/go.mod h1:3rIyughsFDLie1ut9gQJXkWkMg/NfXBCk+OtXnPu3lw= +github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY= +github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= +github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA= +github.com/alibabacloud-go/tea v1.2.2 h1:aTsR6Rl3ANWPfqeQugPglfurloyBJY85eFy7Gc1+8oU= +github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk= +github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= +github.com/alibabacloud-go/tea-utils v1.4.4 h1:lxCDvNCdTo9FaXKKq45+4vGETQUKNOW/qKTcX9Sk53o= +github.com/alibabacloud-go/tea-utils v1.4.4/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= +github.com/alibabacloud-go/tea-utils/v2 v2.0.3/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ= +github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4= +github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= +github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0= +github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= +github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= +github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 h1:ie/8RxBOfKZWcrbYSJi2Z8uX8TcOlSMwPlEJh83OeOw= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= +github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 h1:nJYyoFP+aqGKgPs9JeZgS1rWQ4NndNR0Zfhh161ZltU= +github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1/go.mod h1:WzGOmFFTlUzXM03CJnHWMQ85UN6QGpOXZocCjwkiyOg= +github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 h1:QeUdR7JF7iNCvO/81EhxEr3wDwxk4YBoYZOq6E0AjHI= +github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8/go.mod h1:xP0KIZry6i7oGPF24vhAPr1Q8vLZRcMcxtft5xDKwCU= +github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 h1:8S0mtD101RDYa0LXwdoqgN0RxdMmmJYjq8g2mk7/lQ4= +github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5/go.mod h1:M19fxYz3gpm0ETnoKweYyYtqrtnVtrpKFpwsghbw+cQ= +github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= +github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= +github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM= +github.com/aliyun/credentials-go v1.3.10/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= +github.com/aliyun/credentials-go v1.4.3 h1:N3iHyvHRMyOwY1+0qBLSf3hb5JFiOujVSVuEpgeGttY= +github.com/aliyun/credentials-go v1.4.3/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/dubbo-kubernetes v0.1.4 h1:IL7JVyv4RuGsXC9/aaSkJkf+sRt6k7lHWTYbbdHQ6DU= -github.com/apache/dubbo-kubernetes v0.1.4/go.mod h1:tsb03OXdfHDJrQLcqrvgbMMUMWGw07skKoUjRv+ssHg= -github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0= -github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA= -github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= -github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= -github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= +github.com/apache/dubbo-getty v1.4.10 h1:ZmkpHJa/qgS0evX2tTNqNCz6rClI/9Wwp7ctyMml82w= +github.com/apache/dubbo-getty v1.4.10/go.mod h1:V64WqLIxksEgNu5aBJBOxNIvpOZyfUJ7J/DXBlKSUoA= +github.com/apache/dubbo-go-hessian2 v1.9.1/go.mod h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE= +github.com/apache/dubbo-go-hessian2 v1.9.3/go.mod h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE= +github.com/apache/dubbo-go-hessian2 v1.12.5 h1:19lJz2Md0EYF2bOtEvFqXEQRYvLz04GfsoocsBWlLWQ= +github.com/apache/dubbo-go-hessian2 v1.12.5/go.mod h1:QP9Tc0w/B/mDopjusebo/c7GgEfl6Lz8jeuFg8JA6yw= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apolloconfig/agollo/v4 v4.4.0 h1:bIIRTEN4f7HgLx97/cNpduEvP9qQ7BkCyDOI2j800VM= +github.com/apolloconfig/agollo/v4 v4.4.0/go.mod h1:6WjI68IzqMk/Y6ghMtrj5AX6Uewo20ZnncvRhTceQqg= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo= -github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2/config v1.18.22/go.mod h1:mN7Li1wxaPxSSy4Xkr6stFuinJGf3VZW3ZSNvO0q6sI= -github.com/aws/aws-sdk-go-v2/config v1.18.27 h1:Az9uLwmssTE6OGTpsFqOnaGpLnKDqNYOJzWuC6UAYzA= -github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw= -github.com/aws/aws-sdk-go-v2/credentials v1.13.21/go.mod h1:90Dk1lJoMyspa/EDUrldTxsPns0wn6+KpRKpdAWc0uA= -github.com/aws/aws-sdk-go-v2/credentials v1.13.26 h1:qmU+yhKmOCyujmuPY7tf5MxR/RKyZrOPO3V4DobiTUk= -github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3/go.mod h1:4Q0UFP0YJf0NrsEuEYHpM9fTSEVnD16Z3uyEF7J9JGM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 h1:LxK/bitrAr4lnh9LnIS6i7zWbCOdMsfzKFBI6LUCS0I= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 h1:A5UqQEmPaCFpedKouS4v+dHCTUo2sKqhoKO9U5kxyWo= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 h1:srIVS45eQuewqz6fKKu6ZGXaq6FuFg5NzgQBAM6g8Y4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 h1:LWA+3kDM8ly001vJ1X1waCuLJdtTl48gwkPKWy9sosI= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35/go.mod h1:0Eg1YjxE0Bhn56lx+SHJwCzhW+2JGtizsrx+lCqrfm0= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.10/go.mod h1:Ce1q2jlNm8BVpjLaOnwnm5v2RClAbK6txwPljFzyW6c= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 h1:wlTgmb/sCmVRJrN5De3CiHj4v/bTCgL5+qpdEd0CPtw= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11/go.mod h1:Ce1q2jlNm8BVpjLaOnwnm5v2RClAbK6txwPljFzyW6c= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.1/go.mod h1:uHtRE7aqXNmpeYL+7Ec7LacH5zC9+w2T5MBOeEKDdu0= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 h1:yflJrGmi1pXtP9lOpOeaNZyc0vXnJTuP2sor3nJcGGo= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2/go.mod h1:uHtRE7aqXNmpeYL+7Ec7LacH5zC9+w2T5MBOeEKDdu0= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 h1:bkRyG4a929RCnpVSTvLM2j/T4ls015ZhhYApbmYs15s= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28/go.mod h1:jj7znCIg05jXlaGBlFMGP8+7UN3VtCkRBG2spnmRQkU= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.9/go.mod h1:ouy2P4z6sJN70fR3ka3wD3Ro3KezSxU6eKGQI2+2fjI= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 h1:nneMBM2p79PGWBQovYO/6Xnc2ryRMw3InnDJq1FHkSY= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.9/go.mod h1:AFvkxc8xfBe8XA+5St5XIHHrQQtkxqrRincx4hmMHOk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 h1:2qTR7IFk7/0IN/adSFhYu9Xthr0zVFTgBrmPldILn80= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= -github.com/aws/aws-sdk-go-v2/service/sts v1.18.10/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 h1:XFJ2Z6sNUUcAz9poj+245DMkrHE4h2j5I9/xD50RHfE= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= -github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= -github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230522190001-adf1bafd791a h1:rW+dV12c0WD3+O4Zs8Qt4+oqnr8ecXeyg8g3yB73ZKA= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230522190001-adf1bafd791a/go.mod h1:1mvdZLjy932pV2fhj1jjwUSHaF5Ogq2gk5bvi/6ngEU= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= -github.com/bakito/go-log-logr-adapter v0.0.2 h1:epK+VaMPkK7dK+Vs78xo0BABqN1lIXD3IXX1VUj4PcM= -github.com/bakito/go-log-logr-adapter v0.0.2/go.mod h1:B2tvB31L1Sxpkfhpj13QkJEisDNNKcC9FoYU8KL87AA= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= +github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= +github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= +github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM= github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/buildpacks/imgutil v0.0.0-20230626185301-726f02e4225c h1:HlRuSz+JGAzudNtNCfHIzXe0AEuHX6Vx8uZgmjvX02o= -github.com/buildpacks/imgutil v0.0.0-20230626185301-726f02e4225c/go.mod h1:mBG5M3GJW5nknCEOOqtmMHyPYnSpw/5GEiciuYU/COw= -github.com/buildpacks/lifecycle v0.17.0 h1:vX/kpQfuh4LZvsIhi1wNkx/zahvwiF72bgc46rQ+3z0= -github.com/buildpacks/lifecycle v0.17.0/go.mod h1:WFzcNp1WG4bwgHuXtKxMg4tdU3AguL44ZlP3knANeVs= -github.com/buildpacks/pack v0.30.0 h1:1beK8QAp7By4K40QigYl9JG/Os4nA93dQxYR/GMMbTo= -github.com/buildpacks/pack v0.30.0/go.mod h1:ZtkyUJKcTdWgEDFi0KOmtHQAOkeQeOeJ2wre1+0ipnA= github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= -github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= -github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= -github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo= -github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI= -github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= -github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= -github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= -github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containers/image/v5 v5.34.0 h1:HPqQaDUsox/3mC1pbOyLAIQEp0JhQqiUZ+6JiFIZLDI= -github.com/containers/image/v5 v5.34.0/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo= -github.com/containers/storage v1.57.1 h1:hKPoFsuBcB3qTzBxa4IFpZMRzUuL5Xhv/BE44W0XHx8= -github.com/containers/storage v1.57.1/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= -github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/creasty/defaults v1.5.2 h1:/VfB6uxpyp6h0fr7SPp7n8WJBoV8jfxQXPCnkVSjyls= +github.com/creasty/defaults v1.5.2/go.mod h1:FPZ+Y0WNrbqOVw+c6av63eyHUAl6pMHZwqLPvXUZGfY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/ristretto v0.0.1 h1:cJwdnj42uV8Jg4+KLrYovLiCgIfz9wtWm6E6KA+1tLs= -github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE= +github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= -github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= -github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 h1:O7I1iuzEA7SG+dK8ocOBSlYAA9jBUmCYl/Qa7ey7JAM= +github.com/dop251/goja v0.0.0-20240220182346-e401ed450204/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d h1:W1n4DvpzZGOISgp7wWNtraLcHtnmnTwBlJidqtMIuwQ= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dubbogo/go-zookeeper v1.0.3/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= +github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 h1:XoR8SSVziXe698dt4uZYDfsmHpKLemqAgFyndQsq5Kw= github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= -github.com/dubbogo/gost v1.14.0 h1:yc5YfozvUBAChAox8H7CkmHb6/TvF6cKdqZNJNv2jdE= -github.com/dubbogo/gost v1.14.0/go.mod h1:YP28JweR+hhJdikP3bZ3bVKUWWI313xX1rgLaEE0FvQ= +github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= +github.com/dubbogo/gost v1.11.18/go.mod h1:vIcP9rqz2KsXHPjsAwIUtfJIJjppQLQDcYaZTy/61jI= +github.com/dubbogo/gost v1.13.1/go.mod h1:9HMXBv+WBMRWhF3SklpqDjkS/01AKWm2SrVdz/A0xJI= +github.com/dubbogo/gost v1.14.3 h1:bInkIjdImMo9ENTDdCcs4YlQ/vz5rP/rjcnLakK5x24= +github.com/dubbogo/gost v1.14.3/go.mod h1:WydBuEOkwKEm9mcWLlOnmsVe1ELFgrNPmC5SzXdPv4A= +github.com/dubbogo/grpc-go v1.42.9/go.mod h1:F1T9hnUvYGW4JLK1QNriavpOkhusU677ovPzLkk6zHM= +github.com/dubbogo/grpc-go v1.42.10 h1:CoyCdtqKJEar/3rPa6peZbDqYZ/mVsCqAxB6TfTSkhQ= +github.com/dubbogo/grpc-go v1.42.10/go.mod h1:JMkPt1mIHL96GAFeYsMoMjew6f1ROKycikGzZQH1s5U= +github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWbqL6ynps8jU= +github.com/dubbogo/net v0.0.4/go.mod h1:1CGOnM7X3he+qgGNqjeADuE5vKZQx/eMSeUkpU3ujIc= +github.com/dubbogo/triple v1.0.9/go.mod h1:1t9me4j4CTvNDcsMZy6/OGarbRyAUSY0tFXGXHCp7Iw= +github.com/dubbogo/triple v1.2.2-rc4 h1:zL15Fb6W/yNAFQve5eqpTOEWWD9dpTFq78mdeSKc2pk= +github.com/dubbogo/triple v1.2.2-rc4/go.mod h1:9pgEahtmsY/avYJp3dzUQE8CMMVe1NtGBmUhfICKLJk= github.com/duke-git/lancet/v2 v2.3.6 h1:NKxSSh+dlgp37funvxLCf3xLBeUYa7VW1thYQP6j3Y8= github.com/duke-git/lancet/v2 v2.3.6/go.mod h1:zGa2R4xswg6EG9I6WnyubDbFO/+A/RROxIbXcwryTsc= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ= -github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.10.0/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= -github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= -github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= -github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fullstorydev/grpcurl v1.9.1 h1:YxX1aCcCc4SDBQfj9uoWcTLe8t4NWrZe1y+mk83BQgo= github.com/fullstorydev/grpcurl v1.9.1/go.mod h1:i8gKLIC6s93WdU3LSmkE5vtsCxyRmihUj5FK1cNW5EM= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= -github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1/go.mod h1:Az6Jt+M5idSED2YPGtwnfJV0kXohgdCBPmHGSYc1r04= -github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg= -github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sessions v1.0.4 h1:ha6CNdpYiTOK/hTp05miJLbpTSNfOnFg5Jm2kbcqy8U= github.com/gin-contrib/sessions v1.0.4/go.mod h1:ccmkrb2z6iU2osiAHZG3x3J4suJK+OU27oqzlWOqQgs= -github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= -github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-contrib/zap v1.1.6 h1:TZcXi1UR8QG6OO4rewIMth7SmweyZuCeuUyJohpRcXg= +github.com/gin-contrib/zap v1.1.6/go.mod h1:V/sSE4Rf6ptzsEW4vj1KpUUV8ptJSVdE1nqsX9HQ1II= github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= -github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= -github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= -github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= +github.com/go-co-op/gocron v1.9.0 h1:+V+DDenw3ryB7B+tK1bAIC5p0ruw4oX9IqAsdRnGIf0= +github.com/go-co-op/gocron v1.9.0/go.mod h1:DbJm9kdgr1sEvWpHCA7dFFs/PGHPMil9/97EXCRPr4k= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -354,16 +348,21 @@ github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3 github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= @@ -379,35 +378,37 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= -github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/goburrow/cache v0.1.4 h1:As4KzO3hgmzPlnaMniZU9+VmoNYseUhuELbxy9mRBfw= -github.com/goburrow/cache v0.1.4/go.mod h1:cDFesZDnIlrHoNlMYqqMpCRawuXulgx+y7mXU8HZ+/c= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -415,6 +416,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -432,15 +434,27 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= +github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= +github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y= +github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= +github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= +github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= +github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -448,21 +462,20 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= -github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -470,96 +483,151 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o= github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ= github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/heroku/color v0.0.6 h1:UTFFMrmMLFcL3OweqP1lAdp8i1y/9oHqkeHjQ/b/Ny0= -github.com/heroku/color v0.0.6/go.mod h1:ZBvOcx7cTF2QKOv4LbmoBtNl5uB17qWxGuzZrsi1wLU= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= -github.com/hoisie/mustache v0.0.0-20160804235033-6375acf62c69 h1:umaj0TCQ9lWUUKy2DxAhEzPbwd0jnxiw1EI2z3FiILM= -github.com/hoisie/mustache v0.0.0-20160804235033-6375acf62c69/go.mod h1:zdLK9ilQRSMjSeLKoZ4BqUfBT7jswTGF8zRlKEsiRXA= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= +github.com/hashicorp/vault/sdk v0.7.0/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= +github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/tdigest v0.0.1 h1:XpFptwYmnEKUqmkcDjrzffswZ3nvNeevbUSLPP/ZzIY= +github.com/influxdata/tdigest v0.0.1/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -567,17 +635,15 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40= github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= -github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -587,171 +653,210 @@ github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYW github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= -github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs= +github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= +github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8= +github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e h1:Qa6dnn8DlasdXRnacluu8HzPts0S1I9zvvUPDbBnXFI= -github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e/go.mod h1:waEya8ee1Ro/lgxpVhkJI4BVASzkm3UZqkx/cFJiYHM= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/buildkit v0.11.6 h1:VYNdoKk5TVxN7k4RvZgdeM4GOyRvIi4Z8MXOY7xvyUs= -github.com/moby/buildkit v0.11.6/go.mod h1:GCqKfHhz+pddzfgaR7WmHVEE3nKKZMMDPpK8mh3ZLv4= -github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= -github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= -github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= -github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= -github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= +github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go/v2 v2.2.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g= +github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA= +github.com/nacos-group/nacos-sdk-go/v2 v2.1.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g= +github.com/nacos-group/nacos-sdk-go/v2 v2.3.5 h1:Hux7C4N4rWhwBF5Zm4yyYskrs9VTgrRTA8DZjoEhQTs= +github.com/nacos-group/nacos-sdk-go/v2 v2.3.5/go.mod h1:ygUBdt7eGeYBt6Lz2HO3wx7crKXk25Mp80568emGMWU= +github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= -github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8= -github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE= -github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= +github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= +github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc h1:Ak86L+yDSOzKFa7WM5bf5itSOo1e3Xh8bm5YCMUXIjQ= +github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polarismesh/polaris-go v1.3.0 h1:KZKX//ow4OPPoS5+s7h07ptprg+2AcNVGrN6WakC9QM= +github.com/polarismesh/polaris-go v1.3.0/go.mod h1:HsN0ierETIujHpmnnYJ3qkwQw4QGAECuHvBZTDaw1tI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -762,76 +867,81 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 h1:xe+mmCnDN82KhC010l3NfYlA8ZbOuzbXAzSYBa6wbMc= -github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8/go.mod h1:WIfMkQNY+oq/mWwtsjOYHIZBuwthioY2srOmljJkTnk= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA= +github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= -github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= -github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= -github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.6/go.mod h1:JfVbDpIBLVzT8oKbvMg9P3wEIMDDpVn+LwHTKj0ST88= +github.com/shirou/gopsutil/v3 v3.22.2 h1:wCrArWFkHYIdDxx/FSfF5RB4dpJYW6t7rcp3+zL8uks= github.com/shirou/gopsutil/v3 v3.22.2/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= -github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= -github.com/slok/go-http-metrics v0.11.0 h1:ABJUpekCZSkQT1wQrFvS4kGbhea/w6ndFJaWJeh3zL0= -github.com/slok/go-http-metrics v0.11.0/go.mod h1:ZGKeYG1ET6TEJpQx18BqAJAvxw9jBAZXCHU7bWQqqAc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0= +github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5 h1:GJTW+uNMIV1RKwox+T4aN0/sQlYRg78uHZf2H0aBcDw= github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= @@ -845,74 +955,112 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= -github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= -github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc= -github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= -github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= -github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= +github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= +github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0= +github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= +github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= +github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= +github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/vbatts/tar-split v0.11.7 h1:ixZ93pO/GmvaZw4Vq9OwmfZK/kc2zKdPfu0B+gYqs3U= -github.com/vbatts/tar-split v0.11.7/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= -github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY= +go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg= +go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY= go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= +go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLTs= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4= +go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw= +go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0 h1:3yLUEC0nFCxw/RArImOyRUI4OAFbg4PFpBbAhSNzKNY= go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY= +go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0 h1:DvYJotxV9q1Lkn7pknzAbFO/CLtCVidCr2K9qRLJ8pA= go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w= +go.etcd.io/etcd/server/v3 v3.5.0-alpha.0 h1:fYv7CmmdyuIu27UmKQjS9K/1GtcCa+XnPKqiKBbQkrk= go.etcd.io/etcd/server/v3 v3.5.0-alpha.0/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/propagators/b3 v1.10.0 h1:6AD2VV8edRdEYNaD8cNckpzgdMLU2kbV9OYyxt2kvCg= +go.opentelemetry.io/contrib/propagators/b3 v1.10.0/go.mod h1:oxvamQ/mTDFQVugml/uFS59+aEUnFLhmd1wsG+n5MOE= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= @@ -922,45 +1070,70 @@ go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstF go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U= golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -973,6 +1146,7 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -985,6 +1159,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -993,10 +1169,13 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1005,6 +1184,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1015,6 +1195,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1031,23 +1213,48 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1062,8 +1269,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1071,9 +1279,12 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1081,14 +1292,20 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1099,71 +1316,106 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211106132015-ebca88c72f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1176,6 +1428,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1188,6 +1441,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1200,6 +1454,7 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -1207,17 +1462,34 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201014170642-d1624618ad65/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1234,17 +1506,27 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1270,15 +1552,41 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210106152847-07624b53cd92/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM= google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1287,9 +1595,18 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= @@ -1306,21 +1623,30 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1328,9 +1654,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1343,15 +1668,19 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -helm.sh/helm/v3 v3.12.3 h1:5y1+Sbty12t48T/t/CGNYUIME5BJ0WKfmW/sobYqkFg= -helm.sh/helm/v3 v3.12.3/go.mod h1:KPKQiX9IP5HX7o5YnnhViMnNuKiL/lJBVQ47GHe1R0k= +gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= +gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= +gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= +gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I= +gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= +gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs= +gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1359,40 +1688,33 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= -k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c= -k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ= -k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= -k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= +k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= +k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= +k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= +k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= -k8s.io/kubectl v0.27.3 h1:HyC4o+8rCYheGDWrkcOQHGwDmyLKR5bxXFgpvF82BOw= -k8s.io/kubectl v0.27.3/go.mod h1:g9OQNCC2zxT+LT3FS09ZYqnDhlvsKAfFq76oyarBcq4= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo= sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -sigs.k8s.io/controller-tools v0.17.0 h1:KaEQZbhrdY6J3zLBHplt+0aKUp8PeIttlhtF2UDo6bI= -sigs.k8s.io/controller-tools v0.17.0/go.mod h1:SKoWY8rwGWDzHtfnhmOwljn6fViG0JF7/xmnxpklgjo= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= -sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= -sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= -sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt deleted file mode 100644 index bd96df21d..000000000 --- a/hack/boilerplate.go.txt +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. \ No newline at end of file diff --git a/pkg/common/bizerror/common.go b/pkg/common/bizerror/common.go new file mode 100644 index 000000000..1c25f600e --- /dev/null +++ b/pkg/common/bizerror/common.go @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package bizerror + +import ( + "fmt" +) + +func NewAssertionError(expected, actual interface{}) Error { + return New(UnknownError, fmt.Sprintf("type assertion error, expected:%v, actual:%v", expected, actual)) +} +func NewUnauthorizedError() Error { + return New(Unauthorized, "no access, please login") +} +func MeshNotFoundError(mesh string) Error { + return New(UnknownError, fmt.Sprintf("mesh of name %s is not found", mesh)) +} diff --git a/pkg/common/bizerror/error.go b/pkg/common/bizerror/error.go new file mode 100644 index 000000000..e989d34c8 --- /dev/null +++ b/pkg/common/bizerror/error.go @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package bizerror + +import "fmt" + +type Error interface { + Code() ErrorCode + Message() string + Error() string + String() string +} + +type ErrorCode string + +const ( + InternalError ErrorCode = "InternalError" + UnknownError ErrorCode = "UnknownError" + InvalidArgument ErrorCode = "InvalidArgument" + StoreError ErrorCode = "StoreError" + AppNotFound ErrorCode = "AppNotFound" + Unauthorized ErrorCode = "Unauthorized" + SessionError ErrorCode = "SessionError" + DiscoveryError ErrorCode = "DiscoveryError" + ConfigError ErrorCode = "ConfigError" + NacosError ErrorCode = "NacosError" + ZKError ErrorCode = "ZKError" + EventError ErrorCode = "EventError" + GovernorError ErrorCode = "GovernorError" + JsonError ErrorCode = "JsonError" + YamlError ErrorCode = "YamlError" + NotFoundError ErrorCode = "NotFoundError" + NetWorkError ErrorCode = "NetWorkError" + LockNotHeld ErrorCode = "LockNotHeld" + LockExpired ErrorCode = "LockExpired" +) + +type bizError struct { + code ErrorCode + message string + cause error +} + +var _ Error = &bizError{} + +func New(code ErrorCode, message string) Error { + return &bizError{ + code: code, + message: message, + } +} + +func Wrap(cause error, code ErrorCode, message string) Error { + return &bizError{ + cause: cause, + code: code, + message: message, + } +} + +func (b *bizError) Code() ErrorCode { + return b.code +} + +func (b *bizError) Message() string { + return b.message +} + +func (b *bizError) Error() string { + if b.cause != nil { + return fmt.Sprintf("%s, cause: %s", b.String(), b.cause.Error()) + } + return b.String() +} + +func (b *bizError) String() string { + return "[" + string(b.code) + "], " + b.message +} diff --git a/pkg/core/cmd/helpers.go b/pkg/common/constants/common.go similarity index 69% rename from pkg/core/cmd/helpers.go rename to pkg/common/constants/common.go index 0b710d309..8ae854bc3 100644 --- a/pkg/core/cmd/helpers.go +++ b/pkg/common/constants/common.go @@ -15,17 +15,24 @@ * limitations under the License. */ -package cmd +package constants -import ( - "fmt" - "strings" +const ( + TimeFormatStr = "2006-01-02 15:04:05" ) -func UsageOptions(desc string, options ...interface{}) string { - values := make([]string, 0, len(options)) - for _, option := range options { - values = append(values, fmt.Sprintf("%v", option)) - } - return fmt.Sprintf("%s: one of %s", desc, strings.Join(values, "|")) -} +const ( + PathSeparator = "/" + DotSeparator = "." + ColonSeparator = ":" + CommaSeparator = "," + InterrogationPoint = "?" + IP = "ip" + PlusSigns = "+" + PunctuationPoint = "." + WildcardCharacter = "*" +) + +const ( + DefaultMesh = "default" +) diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go new file mode 100644 index 000000000..a7273c021 --- /dev/null +++ b/pkg/common/constants/constants.go @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package constants + +const ( + DubboPropertyKey = "dubbo.properties" + RegistryAddressKey = "dubbo.registry.address" + MetadataReportAddressKey = "dubbo.metadata-report.address" +) + +const ( + RegistryKey = "registry" + RegistryClusterKey = "REGISTRY_CLUSTER" + RegisterModeKey = "register-mode" + RegistryClusterTypeKey = "registry-cluster-type" + RemoteClientNameKey = "remote-client-name" + DefaultRegisterModeInterface = "interface" + DefaultRegisterModeInstance = "instance" + DefaultRegisterModeAll = "all" + MetadataStorageTypeKey = "dubbo.metadata.storage-type" + TimestampKey = "timestamp" + EndpointsKey = "dubbo.endpoints" + URLParamsKey = "dubbo.metadata-service.url-params" + MetadataRevisionKey = "dubbo.metadata.revision" + AnyValue = "*" + AnyHostValue = "0.0.0.0" + InterfaceKey = "interface" + GroupKey = "group" + VersionKey = "version" + ClassifierKey = "classifier" + CategoryKey = "category" + ProvidersCategory = "providers" + ConsumersCategory = "consumers" + RoutersCategory = "routers" + EnabledKey = "enabled" + CheckKey = "check" + AdminProtocol = "admin" + Side = "side" + ConsumerSide = "consumer" + ProviderSide = "provider" + ConsumerProtocol = "consumer" + EmptyProtocol = "empty" + OverrideProtocol = "override" + DefaultGroup = "dubbo" + DynamicKey = "dynamic" + SerializationKey = "serialization" + PreferSerializationKey = "prefer.serialization" + TimeoutKey = "timeout" + WeightKey = "weight" + BalancingKey = "balancing" + OwnerKey = "owner" + + ConfigFileEnvKey = "conf" // config file path + RegistryAll = "ALL" + RegistryInterface = "INTERFACE" + RegistryInstance = "INSTANCE" + RegistryType = "TYPE" + NamespaceKey = "namespace" +) + +const ( + Application = "application" + Instance = "instance" + Service = "service" + + StatefulSet = "StatefulSet" + Deployment = "Deployment" +) + +const ( + ProtocolKey = "protocol" + DubboVersionKey = "dubbo" + WorkLoadKey = "workLoad" + ReleaseKey = "release" +) + +const ( + Stateful = "有状态" + Stateless = "无状态" +) diff --git a/pkg/common/constants/lock.go b/pkg/common/constants/lock.go new file mode 100644 index 000000000..30a9f4049 --- /dev/null +++ b/pkg/common/constants/lock.go @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package constants + +import "time" + +const ( + // DefaultLockTimeout is the default timeout for distributed lock operations + // This timeout applies to lock acquisition, renewal, and release operations + DefaultLockTimeout = 30 * time.Second + + // DefaultAutoRenewThreshold is the TTL threshold above which auto-renewal is enabled + // Locks with TTL longer than this value will be automatically renewed + DefaultAutoRenewThreshold = 10 * time.Second + + // DefaultUnlockTimeout is the timeout for unlock operations in deferred cleanup + DefaultUnlockTimeout = 5 * time.Second + + // DefaultRenewTimeout is the timeout for lock renewal operations + DefaultRenewTimeout = 5 * time.Second + + // DefaultLockRetryInterval is the interval between lock acquisition retry attempts + DefaultLockRetryInterval = 100 * time.Millisecond + + // DefaultCleanupInterval is the interval for periodic expired lock cleanup + DefaultCleanupInterval = 5 * time.Minute + + // DefaultCleanupTimeout is the timeout for cleanup operations + DefaultCleanupTimeout = 30 * time.Second +) + +// Lock key prefixes for different resource types +const ( + // TagRouteKeyPrefix is the prefix for tag route lock keys + TagRouteKeyPrefix = "tag_route" + + // ConfiguratorRuleKeyPrefix is the prefix for configurator rule lock keys + ConfiguratorRuleKeyPrefix = "configurator_rule" + + // ConditionRuleKeyPrefix is the prefix for condition rule lock keys + ConditionRuleKeyPrefix = "condition_rule" +) diff --git a/pkg/common/constants/nacos.go b/pkg/common/constants/nacos.go new file mode 100644 index 000000000..29b22290b --- /dev/null +++ b/pkg/common/constants/nacos.go @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package constants + +const ( + NacosConfigGroup = "dubbo" + NacosMappingGroup = "mapping" +) + +// ServiceProviderNacosKey blur search service provider metadata +// "*:provider:*" +const ServiceProviderNacosKey = WildcardCharacter + ColonSeparator + ProviderSide + ColonSeparator + WildcardCharacter diff --git a/pkg/common/constants/rule.go b/pkg/common/constants/rule.go new file mode 100644 index 000000000..1749e33ee --- /dev/null +++ b/pkg/common/constants/rule.go @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package constants + +import set "github.com/duke-git/lancet/v2/datastructure/set" + +var RuleSuffixSet = set.New(ConfiguratorsSuffix, ConditionRuleSuffix, TagRuleSuffix, AffinityRuleSuffix) + +const ( + ConfiguratorVersionV3 = `v3.0` + ConfiguratorVersionV3x1 = `v3.1` + ConfigVersionKey = `configVersion` + ScopeApplication = `application` + ScopeService = `service` + SideProvider = `provider` + SideConsumer = `consumer` + + ConfiguratorRuleDotSuffix = ".configurators" + ConfiguratorsSuffix = "configurators" + ConditionRuleDotSuffix = ".condition-router" + ConditionRuleSuffix = "condition-router" + TagRuleDotSuffix = ".tag-router" + TagRuleSuffix = "tag-router" + AffinityRuleDotSuffix = ".affinity-router" + AffinityRuleSuffix = "affinity-router" +) + +const ( + NotEqual = "!=" + Equal = "=" +) + +const ( + ServiceDefaultTimeout int32 = 1000 + DefaultWeight int32 = 100 + ServiceDefaultRetries int32 = 2 +) diff --git a/pkg/common/log/logger.go b/pkg/common/log/logger.go index 8e020d651..167ebeed4 100644 --- a/pkg/common/log/logger.go +++ b/pkg/common/log/logger.go @@ -28,7 +28,6 @@ import ( "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" kubelogzap "sigs.k8s.io/controller-runtime/pkg/log/zap" - ) type LogLevel int diff --git a/pkg/common/util/cache/prometheus_status_counter.go b/pkg/common/util/cache/prometheus_status_counter.go deleted file mode 100644 index 5e9b5f7e6..000000000 --- a/pkg/common/util/cache/prometheus_status_counter.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cache - -import ( - "time" - - "github.com/goburrow/cache" - "github.com/prometheus/client_golang/prometheus" -) - -const ResultLabel = "result" - -func NewMetric(name, help string) *prometheus.CounterVec { - return prometheus.NewCounterVec(prometheus.CounterOpts{ - Name: name, - Help: help, - }, []string{ResultLabel}) -} - -type PrometheusStatsCounter struct { - Metric *prometheus.CounterVec -} - -var _ cache.StatsCounter = &PrometheusStatsCounter{} - -func (p *PrometheusStatsCounter) RecordHits(count uint64) { - p.Metric.WithLabelValues("hit").Add(float64(count)) -} - -func (p *PrometheusStatsCounter) RecordMisses(count uint64) { - p.Metric.WithLabelValues("miss").Add(float64(count)) -} - -func (p *PrometheusStatsCounter) RecordLoadSuccess(loadTime time.Duration) { -} - -func (p *PrometheusStatsCounter) RecordLoadError(loadTime time.Duration) { -} - -func (p *PrometheusStatsCounter) RecordEviction() { -} - -func (p *PrometheusStatsCounter) Snapshot(stats *cache.Stats) { -} diff --git a/pkg/common/util/cache/v3/cache.go b/pkg/common/util/cache/v3/cache.go deleted file mode 100644 index 6156d707c..000000000 --- a/pkg/common/util/cache/v3/cache.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "sort" - - v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - ctl_cache "github.com/envoyproxy/go-control-plane/pkg/cache/v3" - protov1 "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" -) - -func ToDeltaDiscoveryResponse(s ctl_cache.Snapshot) (*v3.DeltaDiscoveryResponse, error) { - resp := &v3.DeltaDiscoveryResponse{} - for _, rs := range s.Resources { - for _, name := range sortedResourceNames(rs) { - r := rs.Items[name] - pbany, err := anypb.New(protov1.MessageV2(r.Resource)) - if err != nil { - return nil, err - } - resp.Resources = append(resp.Resources, &v3.Resource{ - Version: rs.Version, - Name: name, - Resource: pbany, - }) - } - } - return resp, nil -} - -func sortedResourceNames(rs ctl_cache.Resources) []string { - names := make([]string, 0, len(rs.Items)) - for name := range rs.Items { - names = append(names, name) - } - sort.Strings(names) - return names -} diff --git a/pkg/common/util/concurrent/debouncer.go b/pkg/common/util/concurrent/debouncer.go deleted file mode 100644 index 2250822e5..000000000 --- a/pkg/common/util/concurrent/debouncer.go +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package concurrent - -import ( - "time" - - "github.com/apache/dubbo-admin/pkg/common/util/sets" - "github.com/apache/dubbo-admin/pkg/core" -) - -var log = core.Log.WithName("debouncer") - -type Debouncer[T comparable] struct{} - -func (d *Debouncer[T]) Run(ch chan T, stopCh <-chan struct{}, debounceMinInterval, debounceMaxInterval time.Duration, pushFn func(sets.Set[T])) { - var timeChan <-chan time.Time - var startDebounce time.Time - var lastConfigUpdateTime time.Time - - pushCounter := 0 - debouncedEvents := 0 - - // Keeps track of the push requests. If updates are debounce they will be merged. - combinedEvents := sets.New[T]() - - free := true - freeCh := make(chan struct{}, 1) - - push := func(events sets.Set[T], debouncedEvents int, startDebounce time.Time) { - pushFn(events) - freeCh <- struct{}{} - } - - pushWorker := func() { - eventDelay := time.Since(startDebounce) - quietTime := time.Since(lastConfigUpdateTime) - // it has been too long or quiet enough - if eventDelay >= debounceMaxInterval || quietTime >= debounceMinInterval { - if combinedEvents.Len() > 0 { - pushCounter++ - free = false - go push(combinedEvents, debouncedEvents, startDebounce) - combinedEvents = sets.New[T]() - debouncedEvents = 0 - } else { - // For no combined events to process, we can also do nothing here and wait for the config change to trigger - // the next debounce, but I think it's better to set it's to the debounce max interval. - timeChan = time.After(debounceMaxInterval) - } - } else { - timeChan = time.After(debounceMinInterval - quietTime) - } - } - - for { - select { - case <-freeCh: - free = true - pushWorker() - case r := <-ch: - - lastConfigUpdateTime = time.Now() - if debouncedEvents == 0 { - timeChan = time.After(debounceMinInterval) - startDebounce = lastConfigUpdateTime - } - debouncedEvents++ - - combinedEvents = combinedEvents.Insert(r) - case <-timeChan: - if free { - pushWorker() - } - case <-stopCh: - return - } - } -} diff --git a/pkg/common/util/discovery/discovery.go b/pkg/common/util/discovery/discovery.go new file mode 100644 index 000000000..2dd9ea8e9 --- /dev/null +++ b/pkg/common/util/discovery/discovery.go @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package discovery + +import "github.com/apache/dubbo-admin/pkg/config/app" + +func GetOrDefaultRegistryName(cfg app.AdminConfig, mesh string) string { + if discovery := cfg.FindDiscovery(mesh); discovery != nil { + return discovery.Name + } else { + return "default" + } +} diff --git a/pkg/common/util/envoy/raw.go b/pkg/common/util/envoy/raw.go deleted file mode 100644 index 79e79e7da..000000000 --- a/pkg/common/util/envoy/raw.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package envoy - -import ( - "errors" - - envoy_types "github.com/envoyproxy/go-control-plane/pkg/cache/types" - "github.com/golang/protobuf/ptypes/any" - "google.golang.org/protobuf/proto" - "sigs.k8s.io/yaml" - - util_proto "github.com/apache/dubbo-admin/pkg/common/util/proto" -) - -func ResourceFromYaml(resYaml string) (proto.Message, error) { - json, err := yaml.YAMLToJSON([]byte(resYaml)) - if err != nil { - json = []byte(resYaml) - } - - var anything any.Any - if err := util_proto.FromJSON(json, &anything); err != nil { - return nil, err - } - msg, err := anything.UnmarshalNew() - if err != nil { - return nil, err - } - p, ok := msg.(envoy_types.Resource) - if !ok { - return nil, errors.New("xDS resource doesn't implement all required interfaces") - } - if v, ok := p.(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return nil, err - } - } - return p, nil -} diff --git a/pkg/common/util/files/lookup_binary.go b/pkg/common/util/files/lookup_binary.go deleted file mode 100644 index 4b0e00160..000000000 --- a/pkg/common/util/files/lookup_binary.go +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package files - -import ( - "os" - "os/exec" - "path/filepath" - - "github.com/pkg/errors" -) - -type LookupPathFn = func() (string, error) - -// LookupNextToCurrentExecutable looks for the binary next to the current binary -// Example: if this function is executed by /usr/bin/dubbo-dp, this function will lookup for binary 'x' in /usr/bin/x -func LookupNextToCurrentExecutable(binary string) LookupPathFn { - return func() (string, error) { - ex, err := os.Executable() - if err != nil { - return "", err - } - return filepath.Dir(ex) + "/" + binary, nil - } -} - -// LookupInCurrentDirectory looks for the binary in the current directory -// Example: if this function is executed by /usr/bin/dubbo-dp that was run in /home/dubbo-dp, this function will lookup for binary 'x' in /home/dubbo-dp/x -func LookupInCurrentDirectory(binary string) LookupPathFn { - return func() (string, error) { - cwd, err := os.Getwd() - if err != nil { - return "", err - } - return cwd + "/" + binary, nil - } -} - -func LookupInPath(path string) LookupPathFn { - return func() (string, error) { - return path, nil - } -} - -// LookupBinaryPath looks for a binary in order of passed lookup functions. -// It fails only if all lookup function does not contain a binary. -func LookupBinaryPath(pathFns ...LookupPathFn) (string, error) { - var candidatePaths []string - for _, candidatePathFn := range pathFns { - candidatePath, err := candidatePathFn() - if err != nil { - continue - } - candidatePaths = append(candidatePaths, candidatePath) - path, err := exec.LookPath(candidatePath) - if err == nil { - return path, nil - } - } - - return "", errors.Errorf("could not find executable binary in any of the following paths: %v", candidatePaths) -} diff --git a/pkg/common/util/files/project.go b/pkg/common/util/files/project.go deleted file mode 100644 index 04e8f0101..000000000 --- a/pkg/common/util/files/project.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package files - -import ( - "go/build" - "os" - "path" - "strings" -) - -func GetProjectRoot(file string) string { - dir := file - for path.Base(dir) != "pkg" && path.Base(dir) != "app" { - dir = path.Dir(dir) - } - return path.Dir(dir) -} - -func GetProjectRootParent(file string) string { - return path.Dir(GetProjectRoot(file)) -} - -func RelativeToPkgMod(file string) string { - root := path.Dir(path.Dir(path.Dir(GetProjectRoot(file)))) - return strings.TrimPrefix(file, root) -} - -func RelativeToProjectRoot(path string) string { - root := GetProjectRoot(path) - return strings.TrimPrefix(path, root) -} - -func RelativeToProjectRootParent(path string) string { - root := GetProjectRootParent(path) - return strings.TrimPrefix(path, root) -} - -func GetGopath() string { - gopath := os.Getenv("GOPATH") - if gopath == "" { - gopath = build.Default.GOPATH - } - return gopath -} diff --git a/pkg/common/util/grpc/reverse_unary_rpcs.go b/pkg/common/util/grpc/reverse_unary_rpcs.go deleted file mode 100644 index 8728c346e..000000000 --- a/pkg/common/util/grpc/reverse_unary_rpcs.go +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package grpc - -import ( - "sync" - - "github.com/pkg/errors" - "google.golang.org/grpc" - "google.golang.org/protobuf/proto" -) - -type ReverseUnaryMessage interface { - proto.Message - GetRequestId() string -} - -// ReverseUnaryRPCs helps to implement reverse unary rpcs where server sends requests to a client and receives responses from the client. -type ReverseUnaryRPCs interface { - Send(client string, req ReverseUnaryMessage) error - WatchResponse(client string, reqID string, resp chan ReverseUnaryMessage) error - DeleteWatch(client string, reqID string) - - ClientConnected(client string, stream grpc.ServerStream) - ClientDisconnected(client string) - ResponseReceived(client string, resp ReverseUnaryMessage) error -} - -type clientStreams struct { - streamForClient map[string]*clientStream - sync.Mutex // protects streamForClient -} - -func (x *clientStreams) ResponseReceived(client string, resp ReverseUnaryMessage) error { - stream, err := x.clientStream(client) - if err != nil { - return err - } - stream.Lock() - ch, ok := stream.watchForRequestId[resp.GetRequestId()] - stream.Unlock() - if !ok { - return errors.Errorf("callback for request Id %s not found", resp.GetRequestId()) - } - ch <- resp - return nil -} - -func NewReverseUnaryRPCs() ReverseUnaryRPCs { - return &clientStreams{ - streamForClient: map[string]*clientStream{}, - } -} - -func (x *clientStreams) ClientConnected(client string, stream grpc.ServerStream) { - x.Lock() - defer x.Unlock() - x.streamForClient[client] = &clientStream{ - stream: stream, - watchForRequestId: map[string]chan ReverseUnaryMessage{}, - } -} - -func (x *clientStreams) clientStream(client string) (*clientStream, error) { - x.Lock() - defer x.Unlock() - stream, ok := x.streamForClient[client] - if !ok { - return nil, errors.Errorf("client %s is not connected", client) - } - return stream, nil -} - -func (x *clientStreams) ClientDisconnected(client string) { - x.Lock() - defer x.Unlock() - delete(x.streamForClient, client) -} - -type clientStream struct { - stream grpc.ServerStream - watchForRequestId map[string]chan ReverseUnaryMessage - sync.Mutex // protects watchForRequestId -} - -func (x *clientStreams) Send(client string, req ReverseUnaryMessage) error { - stream, err := x.clientStream(client) - if err != nil { - return err - } - return stream.stream.SendMsg(req) -} - -func (x *clientStreams) WatchResponse(client string, reqID string, resp chan ReverseUnaryMessage) error { - stream, err := x.clientStream(client) - if err != nil { - return err - } - stream.Lock() - defer stream.Unlock() - stream.watchForRequestId[reqID] = resp - return nil -} - -func (x *clientStreams) DeleteWatch(client string, reqID string) { - stream, err := x.clientStream(client) - if err != nil { - return // client was already deleted - } - stream.Lock() - defer stream.Unlock() - delete(stream.watchForRequestId, reqID) -} diff --git a/pkg/common/util/http/client_test.go b/pkg/common/util/http/client_test.go deleted file mode 100644 index 87085f764..000000000 --- a/pkg/common/util/http/client_test.go +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package http_test - -import ( - "net/http" - "net/url" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - util_http "github.com/apache/dubbo-admin/pkg/common/util/http" -) - -var _ = Describe("Http Util", func() { - Describe("ClientWithBaseURL(..)", func() { - type testCase struct { - baseURL string - requestURL string - expectedURL string - } - - DescribeTable("should rewrite request URL by combining `baseURL` and `requestURL`", - func(given testCase) { - // setup - baseURL, err := url.Parse(given.baseURL) - Expect(err).ToNot(HaveOccurred()) - - // and - var actualURL *url.URL - delegate := util_http.ClientFunc(func(req *http.Request) (*http.Response, error) { - actualURL = req.URL - return &http.Response{}, nil - }) - - // when - client := util_http.ClientWithBaseURL(delegate, baseURL, nil) - // then - Expect(client).ToNot(BeIdenticalTo(delegate)) - - // when - req, err := http.NewRequest("GET", given.requestURL, nil) - // then - Expect(err).ToNot(HaveOccurred()) - - // when - _, err = client.Do(req) - // then - Expect(err).ToNot(HaveOccurred()) - - // and - Expect(actualURL.String()).To(Equal(given.expectedURL)) - }, - Entry("baseURL without path", testCase{ - baseURL: "https://dubbo-control-plane:5681", - requestURL: "/meshes/default/dataplanes", - expectedURL: "https://dubbo-control-plane:5681/meshes/default/dataplanes", - }), - Entry("baseURL without path and request with a relative path", testCase{ - baseURL: "https://dubbo-control-plane:5681", - requestURL: "meshes/default/dataplanes", - expectedURL: "https://dubbo-control-plane:5681/meshes/default/dataplanes", - }), - Entry("baseURL with path", testCase{ - baseURL: "https://dubbo-control-plane:5681/proxy/foo/bar", - requestURL: "/test", - expectedURL: "https://dubbo-control-plane:5681/proxy/foo/bar/test", - }), - Entry("baseURL that ends with /", testCase{ - baseURL: "https://dubbo-control-plane:5681/", - requestURL: "/meshes/default/dataplanes", - expectedURL: "https://dubbo-control-plane:5681/meshes/default/dataplanes", - }), - Entry("baseURL and/or requestURL with double slashes", testCase{ - baseURL: "https://dubbo-control-plane:5681//proxy/foo/bar", - requestURL: "/test//baz", - expectedURL: "https://dubbo-control-plane:5681/proxy/foo/bar/test/baz", - }), - ) - - It("should tolerate nil URL", func() { - // setup - baseURL, err := url.Parse("https://dubbo-control-plane:5681") - Expect(err).ToNot(HaveOccurred()) - - // and - var actualURL *url.URL - delegate := util_http.ClientFunc(func(req *http.Request) (*http.Response, error) { - actualURL = req.URL - return &http.Response{}, nil - }) - - // when - client := util_http.ClientWithBaseURL(delegate, baseURL, nil) - // then - Expect(client).ToNot(BeIdenticalTo(delegate)) - - // when - req := &http.Request{ - URL: nil, - } - // and - _, err = client.Do(req) - // then - Expect(err).ToNot(HaveOccurred()) - - // and - Expect(actualURL).To(BeNil()) - }) - }) -}) diff --git a/pkg/common/util/http/tls.go b/pkg/common/util/http/tls.go deleted file mode 100644 index 262ef080d..000000000 --- a/pkg/common/util/http/tls.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package http - -import ( - "crypto/tls" - "crypto/x509" - "net/http" - "os" - - "github.com/pkg/errors" -) - -func ConfigureMTLS(httpClient *http.Client, caCert string, clientCert string, clientKey string) error { - transport := &http.Transport{ - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - }, - } - - if caCert == "" { - transport.TLSClientConfig.InsecureSkipVerify = true - } else { - certBytes, err := os.ReadFile(caCert) - if err != nil { - return errors.Wrap(err, "could not read CA cert") - } - certPool := x509.NewCertPool() - if ok := certPool.AppendCertsFromPEM(certBytes); !ok { - return errors.New("could not add certificate") - } - transport.TLSClientConfig.RootCAs = certPool - } - - if clientKey != "" && clientCert != "" { - cert, err := tls.LoadX509KeyPair(clientCert, clientKey) - if err != nil { - return errors.Wrap(err, "could not create key pair from client cert and client key") - } - transport.TLSClientConfig.Certificates = []tls.Certificate{cert} - } - - httpClient.Transport = transport - return nil -} diff --git a/pkg/common/util/maps/sync.go b/pkg/common/util/maps/sync.go deleted file mode 100644 index 38a910cd7..000000000 --- a/pkg/common/util/maps/sync.go +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package maps - -import ( - "sync" -) - -// Sync is a simple wrapper around sync.Map that provides type-safe methods -type Sync[K, V any] struct { - inner sync.Map -} - -func (s *Sync[K, V]) Load(k K) (V, bool) { - v, ok := s.inner.Load(k) - if !ok { - var zero V - return zero, false - } - return v.(V), true -} - -func (s *Sync[K, V]) Store(k K, v V) { - s.inner.Store(k, v) -} - -func (s *Sync[K, V]) LoadOrStore(k K, store V) (V, bool) { - v, ok := s.inner.LoadOrStore(k, store) - return v.(V), ok -} - -func (s *Sync[K, V]) LoadAndDelete(k K) (V, bool) { - v, ok := s.inner.LoadAndDelete(k) - if !ok { - var zero V - return zero, false - } - return v.(V), true -} - -func (s *Sync[K, V]) Delete(k K) { - s.inner.Delete(k) -} - -func (s *Sync[K, V]) Swap(k K, v V) (V, bool) { - prev, ok := s.inner.Swap(k, v) - if !ok { - var zero V - return zero, false - } - return prev.(V), true -} - -func (s *Sync[K, V]) CompareAndSwap(k K, old, new V) bool { - return s.inner.CompareAndSwap(k, old, new) -} - -func (s *Sync[K, V]) CompareAndDelete(k K, old V) bool { - return s.inner.CompareAndDelete(k, old) -} - -func (s *Sync[K, V]) Range(f func(k K, v V) bool) { - s.inner.Range(func(key, value any) bool { - return f(key.(K), value.(V)) - }) -} diff --git a/pkg/common/util/net/ips.go b/pkg/common/util/net/ips.go deleted file mode 100644 index 954468119..000000000 --- a/pkg/common/util/net/ips.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net - -import ( - "fmt" - "net" - "sort" - - "github.com/pkg/errors" -) - -type AddressPredicate = func(address *net.IPNet) bool - -func NonLoopback(address *net.IPNet) bool { - return !address.IP.IsLoopback() -} - -// GetAllIPs returns all IPs (IPv4 and IPv6) from the all network interfaces on the machine -func GetAllIPs(predicates ...AddressPredicate) ([]string, error) { - addrs, err := net.InterfaceAddrs() - if err != nil { - return nil, errors.Wrap(err, "could not list network interfaces") - } - var result []string - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok { - matchedPredicate := true - for _, predicate := range predicates { - if !predicate(ipnet) { - matchedPredicate = false - break - } - } - if matchedPredicate { - result = append(result, ipnet.IP.String()) - } - } - } - sort.Strings(result) // sort so IPv4 are the first elements in the list - return result, nil -} - -// ToV6 return self if ip6 other return the v4 prefixed with ::ffff: -func ToV6(ip string) string { - parsedIp := net.ParseIP(ip) - if parsedIp.To4() != nil { - return fmt.Sprintf("::ffff:%x:%x", uint32(parsedIp[12])<<8+uint32(parsedIp[13]), uint32(parsedIp[14])<<8+uint32(parsedIp[15])) - } - return ip -} - -func IsAddressIPv6(address string) bool { - if address == "" { - return false - } - - ip := net.ParseIP(address) - if ip == nil { - return false - } - - return ip.To4() == nil -} diff --git a/pkg/common/util/net/ips_test.go b/pkg/common/util/net/ips_test.go deleted file mode 100644 index 78a24d5b8..000000000 --- a/pkg/common/util/net/ips_test.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net_test - -import ( - . "github.com/onsi/ginkgo/v2" - - "github.com/apache/dubbo-admin/pkg/common/util/net" - . "github.com/onsi/gomega" -) - -var _ = DescribeTable("ToV6", - func(given string, expected string) { - Expect(net.ToV6(given)).To(Equal(expected)) - }, - Entry("v6 already", "2001:db8::ff00:42:8329", "2001:db8::ff00:42:8329"), - Entry("v6 not compacted", "2001:0db8:0000:0000:0000:ff00:0042:8329", "2001:0db8:0000:0000:0000:ff00:0042:8329"), - Entry("v4 adds prefix", "240.0.0.0", "::ffff:f000:0"), - Entry("v4 adds prefix", "240.0.255.0", "::ffff:f000:ff00"), -) - -var _ = DescribeTable("IsIPv6", - func(given string, expected bool) { - Expect(net.IsAddressIPv6(given)).To(Equal(expected)) - }, - Entry("127.0.0.1 should not be IPv6 ", "127.0.0.1", false), - Entry("should be IPv6", "2001:0db8:0000:0000:0000:ff00:0042:8329", true), - Entry("::6", "::6", true), -) diff --git a/pkg/common/util/net/tcpsock.go b/pkg/common/util/net/tcpsock.go deleted file mode 100644 index 0d23a9889..000000000 --- a/pkg/common/util/net/tcpsock.go +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net - -import ( - "fmt" - "net" -) - -func PickTCPPort(ip string, leftPort, rightPort uint32) (uint32, error) { - lowestPort, highestPort := leftPort, rightPort - if highestPort < lowestPort { - lowestPort, highestPort = highestPort, lowestPort - } - // we prefer a port to remain stable over time, that's why we do sequential availability check - // instead of random selection - for port := lowestPort; port <= highestPort; port++ { - if actualPort, err := ReserveTCPAddr(fmt.Sprintf("%s:%d", ip, port)); err == nil { - return actualPort, nil - } - } - return 0, fmt.Errorf("unable to find port in range %d:%d", lowestPort, highestPort) -} - -func ReserveTCPAddr(address string) (uint32, error) { - addr, err := net.ResolveTCPAddr("tcp", address) - if err != nil { - return 0, err - } - l, err := net.ListenTCP("tcp", addr) - if err != nil { - return 0, err - } - defer l.Close() - return uint32(l.Addr().(*net.TCPAddr).Port), nil -} diff --git a/pkg/common/util/os/limits.go b/pkg/common/util/os/limits.go deleted file mode 100644 index ca86aa0e0..000000000 --- a/pkg/common/util/os/limits.go +++ /dev/null @@ -1,69 +0,0 @@ -//go:build !windows -// +build !windows - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package os - -import ( - "fmt" - "runtime" - - "golang.org/x/sys/unix" -) - -func setFileLimit(n uint64) error { - limit := unix.Rlimit{ - Cur: n, - Max: n, - } - - if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { - return fmt.Errorf("failed to set open file limit to %d: %w", limit.Cur, err) - } - - return nil -} - -// RaiseFileLimit raises the soft open file limit to match the hard limit. -func RaiseFileLimit() error { - limit := unix.Rlimit{} - if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { - return fmt.Errorf("failed to query open file limits: %w", err) - } - - // Darwin sets the max to unlimited, but it is actually limited - // (typically to 24K) by the "kern.maxfilesperproc" systune. - // Since we only run on Darwin for test purposes, just clip this - // to a reasonable value. - if runtime.GOOS == "darwin" && limit.Max > 10240 { - limit.Max = 10240 - } - - return setFileLimit(limit.Max) -} - -// CurrentFileLimit reports the current soft open file limit. -func CurrentFileLimit() (uint64, error) { - limit := unix.Rlimit{} - if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { - return 0, fmt.Errorf("failed to query open file limits: %w", err) - } - - return limit.Cur, nil -} diff --git a/pkg/common/util/os/limits_test.go b/pkg/common/util/os/limits_test.go deleted file mode 100644 index ef687e336..000000000 --- a/pkg/common/util/os/limits_test.go +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package os - -import ( - "runtime" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "golang.org/x/sys/unix" -) - -var _ = Describe("File limits", func() { - It("should query the open file limit", func() { - Expect(CurrentFileLimit()).Should(BeNumerically(">", 0)) - }) - - It("should raise the open file limit", func() { - if runtime.GOOS == "darwin" { - Skip("skipping on darwin because it requires priviledges") - } - initialLimits := unix.Rlimit{} - Expect(unix.Getrlimit(unix.RLIMIT_NOFILE, &initialLimits)).Should(Succeed()) - - Expect(CurrentFileLimit()).Should(BeNumerically("==", initialLimits.Cur)) - - Expect(RaiseFileLimit()).Should(Succeed()) - - Expect(CurrentFileLimit()).Should(BeNumerically("==", initialLimits.Max)) - - // Restore the original limit. - Expect(setFileLimit(initialLimits.Cur)).Should(Succeed()) - Expect(CurrentFileLimit()).Should(BeNumerically("==", initialLimits.Cur)) - }) - - It("should fail to exceed the hard file limit", func() { - Expect(setFileLimit(uint64(1) << 63)).Should(HaveOccurred()) - }) -}) diff --git a/pkg/common/util/prometheus/gorestful_middleware.go b/pkg/common/util/prometheus/gorestful_middleware.go deleted file mode 100644 index 0e7e92c7d..000000000 --- a/pkg/common/util/prometheus/gorestful_middleware.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package prometheus - -import ( - "context" - - gorestful "github.com/emicklei/go-restful/v3" - "github.com/slok/go-http-metrics/middleware" -) - -// MetricsHandler is based on go-restful middleware. -// -// In the original version, URLPath() uses r.req.Request.URL.Path which results in following stats when querying for individual DPs -// api_server_http_response_size_bytes_bucket{code="201",handler="/meshes/default/dataplanes/backend-01",method="PUT",service="",le="100"} 1 -// api_server_http_response_size_bytes_bucket{code="201",handler="/meshes/default/dataplanes/ingress-01",method="PUT",service="",le="100"} 1 -// this is not scalable solution, we would be producing too many metrics. With r.req.SelectedRoutePath() the metrics look like this -// api_server_http_request_duration_seconds_bucket{code="201",handler="/meshes/{mesh}/dataplanes/{name}",method="PUT",service="",le="0.005"} 3 -func MetricsHandler(handlerID string, m middleware.Middleware) gorestful.FilterFunction { - return func(req *gorestful.Request, resp *gorestful.Response, chain *gorestful.FilterChain) { - r := &reporter{req: req, resp: resp} - m.Measure(handlerID, r, func() { - chain.ProcessFilter(req, resp) - }) - } -} - -type reporter struct { - req *gorestful.Request - resp *gorestful.Response -} - -func (r *reporter) Method() string { return r.req.Request.Method } - -func (r *reporter) Context() context.Context { return r.req.Request.Context() } - -func (r *reporter) URLPath() string { - return r.req.SelectedRoutePath() -} - -func (r *reporter) StatusCode() int { return r.resp.StatusCode() } - -func (r *reporter) BytesWritten() int64 { return int64(r.resp.ContentLength()) } diff --git a/pkg/common/util/rmkey/resource_name.go b/pkg/common/util/rmkey/resource_name.go deleted file mode 100644 index a1b7782b9..000000000 --- a/pkg/common/util/rmkey/resource_name.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package rmkey - -import ( - "strings" - - utilk8s "github.com/apache/dubbo-admin/pkg/common/util/k8s" -) - -const ( - firstDelimiter = "-" - secondDelimiter = "." - separator = "/" -) - -func GenerateMetadataResourceKey(app string, revision string, namespace string) string { - res := app - if revision != "" { - res += firstDelimiter + revision - } - if namespace != "" { - res += secondDelimiter + revision - } - return res -} - -func GenerateNamespacedName(name string, namespace string) string { - if namespace == "" { // it's cluster scoped object - return name - } - return utilk8s.K8sNamespacedNameToCoreName(name, namespace) -} - -func GenerateMappingResourceKey(interfaceName string, namespace string) string { - res := strings.ToLower(strings.ReplaceAll(interfaceName, ".", "-")) - if namespace == "" { - return res - } - return utilk8s.K8sNamespacedNameToCoreName(res, namespace) -} diff --git a/pkg/common/util/rsa/pem.go b/pkg/common/util/rsa/pem.go deleted file mode 100644 index c164a73b3..000000000 --- a/pkg/common/util/rsa/pem.go +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package rsa - -import ( - "bytes" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - - "github.com/pkg/errors" -) - -const ( - publicBlockType = "PUBLIC KEY" - rsaPrivateBlockType = "RSA PRIVATE KEY" - rsaPublicBlockType = "RSA PUBLIC KEY" -) - -func FromPrivateKeyToPEMBytes(key *rsa.PrivateKey) ([]byte, error) { - block := pem.Block{ - Type: rsaPrivateBlockType, - Bytes: x509.MarshalPKCS1PrivateKey(key), - } - var keyBuf bytes.Buffer - if err := pem.Encode(&keyBuf, &block); err != nil { - return nil, err - } - return keyBuf.Bytes(), nil -} - -func FromPrivateKeyToPublicKeyPEMBytes(key *rsa.PrivateKey) ([]byte, error) { - block := pem.Block{ - Type: rsaPublicBlockType, - Bytes: x509.MarshalPKCS1PublicKey(&key.PublicKey), - } - var keyBuf bytes.Buffer - if err := pem.Encode(&keyBuf, &block); err != nil { - return nil, err - } - return keyBuf.Bytes(), nil -} - -func FromPrivateKeyPEMBytesToPublicKeyPEMBytes(b []byte) ([]byte, error) { - privateKey, err := FromPEMBytesToPrivateKey(b) - if err != nil { - return nil, err - } - - return FromPrivateKeyToPublicKeyPEMBytes(privateKey) -} - -func FromPEMBytesToPrivateKey(b []byte) (*rsa.PrivateKey, error) { - block, _ := pem.Decode(b) - if block.Type != rsaPrivateBlockType { - return nil, errors.Errorf("invalid key encoding %q", block.Type) - } - return x509.ParsePKCS1PrivateKey(block.Bytes) -} - -func FromPEMBytesToPublicKey(b []byte) (*rsa.PublicKey, error) { - block, _ := pem.Decode(b) - - switch block.Type { - case rsaPublicBlockType: - return x509.ParsePKCS1PublicKey(block.Bytes) - case publicBlockType: - return rsaKeyFromPKIX(block.Bytes) - default: - return nil, errors.Errorf("invalid key encoding %q", block.Type) - } -} - -func IsPrivateKeyPEMBytes(b []byte) bool { - block, _ := pem.Decode(b) - return block != nil && block.Type == rsaPrivateBlockType -} - -func IsPublicKeyPEMBytes(b []byte) bool { - block, _ := pem.Decode(b) - - if block != nil && block.Type == rsaPublicBlockType { - return true - } - - if block != nil && block.Type == publicBlockType { - _, err := rsaKeyFromPKIX(block.Bytes) - return err == nil - } - - return false -} - -func rsaKeyFromPKIX(bytes []byte) (*rsa.PublicKey, error) { - key, err := x509.ParsePKIXPublicKey(bytes) - if err != nil { - return nil, err - } - - rsaKey, ok := key.(*rsa.PublicKey) - if !ok { - return nil, errors.Errorf("encoded key is not a RSA key") - } - - return rsaKey, nil -} diff --git a/pkg/common/util/sets/set.go b/pkg/common/util/sets/set.go deleted file mode 100644 index c1125e8f7..000000000 --- a/pkg/common/util/sets/set.go +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sets - -import ( - "fmt" - - "golang.org/x/exp/constraints" - - "github.com/apache/dubbo-admin/pkg/common/util/slices" -) - -type Set[T comparable] map[T]struct{} - -type String = Set[string] - -// NewWithLength returns an empty Set with the given capacity. -// It's only a hint, not a limitation. -func NewWithLength[T comparable](l int) Set[T] { - return make(Set[T], l) -} - -// New creates a new Set with the given items. -func New[T comparable](items ...T) Set[T] { - s := NewWithLength[T](len(items)) - return s.InsertAll(items...) -} - -// Insert a single item to this Set. -func (s Set[T]) Insert(item T) Set[T] { - s[item] = struct{}{} - return s -} - -// InsertAll adds the items to this Set. -func (s Set[T]) InsertAll(items ...T) Set[T] { - for _, item := range items { - s[item] = struct{}{} - } - return s -} - -// Delete removes an item from the set. -func (s Set[T]) Delete(item T) Set[T] { - delete(s, item) - return s -} - -// DeleteAll removes items from the set. -func (s Set[T]) DeleteAll(items ...T) Set[T] { - for _, item := range items { - delete(s, item) - } - return s -} - -// Merge a set of objects that are in s2 into s -// For example: -// s = {a1, a2, a3} -// s2 = {a3, a4, a5} -// s.Merge(s2) = {a1, a2, a3, a4, a5} -func (s Set[T]) Merge(s2 Set[T]) Set[T] { - for item := range s2 { - s[item] = struct{}{} - } - - return s -} - -// Copy this set. -func (s Set[T]) Copy() Set[T] { - result := NewWithLength[T](s.Len()) - for key := range s { - result.Insert(key) - } - return result -} - -// Union returns a set of objects that are in s or s2 -// For example: -// s = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s.Union(s2) = s2.Union(s) = {a1, a2, a3, a4, a5} -func (s Set[T]) Union(s2 Set[T]) Set[T] { - result := s.Copy() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2 -// For example: -// s = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s.Difference(s2) = {a3} -// s2.Difference(s) = {a4, a5} -func (s Set[T]) Difference(s2 Set[T]) Set[T] { - result := New[T]() - for key := range s { - if !s2.Contains(key) { - result.Insert(key) - } - } - return result -} - -// DifferenceInPlace similar to Difference, but has better performance. -// Note: This function modifies s in place. -func (s Set[T]) DifferenceInPlace(s2 Set[T]) Set[T] { - for key := range s { - if s2.Contains(key) { - delete(s, key) - } - } - return s -} - -// Diff takes a pair of Sets, and returns the elements that occur only on the left and right set. -func (s Set[T]) Diff(other Set[T]) (left []T, right []T) { - for k := range s { - if _, f := other[k]; !f { - left = append(left, k) - } - } - for k := range other { - if _, f := s[k]; !f { - right = append(right, k) - } - } - return -} - -// Intersection returns a set of objects that are common between s and s2 -// For example: -// s = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s.Intersection(s2) = {a1, a2} -func (s Set[T]) Intersection(s2 Set[T]) Set[T] { - result := New[T]() - for key := range s { - if s2.Contains(key) { - result.Insert(key) - } - } - return result -} - -// IntersectInPlace similar to Intersection, but has better performance. -// Note: This function modifies s in place. -func (s Set[T]) IntersectInPlace(s2 Set[T]) Set[T] { - for key := range s { - if !s2.Contains(key) { - delete(s, key) - } - } - return s -} - -// SupersetOf returns true if s contains all elements of s2 -// For example: -// s = {a1, a2, a3} -// s2 = {a1, a2, a3, a4, a5} -// s.SupersetOf(s2) = false -// s2.SupersetOf(s) = true -func (s Set[T]) SupersetOf(s2 Set[T]) bool { - if s2 == nil { - return true - } - if len(s2) > len(s) { - return false - } - for key := range s2 { - if !s.Contains(key) { - return false - } - } - return true -} - -// UnsortedList returns the slice with contents in random order. -func (s Set[T]) UnsortedList() []T { - res := make([]T, 0, s.Len()) - for key := range s { - res = append(res, key) - } - return res -} - -// SortedList returns the slice with contents sorted. -func SortedList[T constraints.Ordered](s Set[T]) []T { - res := s.UnsortedList() - slices.Sort(res) - return res -} - -// InsertContains inserts the item into the set and returns if it was already present. -// Example: -// -// if !set.InsertContains(item) { -// fmt.Println("Added item for the first time", item) -// } -func (s Set[T]) InsertContains(item T) bool { - if s.Contains(item) { - return true - } - s[item] = struct{}{} - return false -} - -// Contains returns whether the given item is in the set. -func (s Set[T]) Contains(item T) bool { - _, ok := s[item] - return ok -} - -// ContainsAll is alias of SupersetOf -// returns true if s contains all elements of s2 -func (s Set[T]) ContainsAll(s2 Set[T]) bool { - return s.SupersetOf(s2) -} - -// Equals checks whether the given set is equal to the current set. -func (s Set[T]) Equals(other Set[T]) bool { - if s.Len() != other.Len() { - return false - } - - for key := range s { - if !other.Contains(key) { - return false - } - } - - return true -} - -// Len returns the number of elements in this Set. -func (s Set[T]) Len() int { - return len(s) -} - -// IsEmpty indicates whether the set is the empty set. -func (s Set[T]) IsEmpty() bool { - return len(s) == 0 -} - -// String returns a string representation of the set. -// Be aware that the order of elements is random so the string representation may vary. -// Use it only for debugging and logging. -func (s Set[T]) String() string { - return fmt.Sprintf("%v", s.UnsortedList()) -} - -// InsertOrNew inserts t into the set if the set exists, or returns a new set with t if not. -// Works well with DeleteCleanupLast. -// Example: -// -// InsertOrNew(m, key, value) -func InsertOrNew[K comparable, T comparable](m map[K]Set[T], k K, v T) { - s, f := m[k] - if !f { - m[k] = New(v) - } else { - s.Insert(v) - } -} - -// DeleteCleanupLast removes an element from a set in a map of sets, deleting the key from the map if there are no keys left. -// Works well with InsertOrNew. -// Example: -// -// sets.DeleteCleanupLast(m, key, value) -func DeleteCleanupLast[K comparable, T comparable](m map[K]Set[T], k K, v T) { - if m[k].Delete(v).IsEmpty() { - delete(m, k) - } -} diff --git a/pkg/common/util/sets/set_test.go b/pkg/common/util/sets/set_test.go deleted file mode 100644 index 78e7f44f4..000000000 --- a/pkg/common/util/sets/set_test.go +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sets - -import ( - "fmt" - "reflect" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - - "k8s.io/apimachinery/pkg/util/rand" -) - -func TestNewSet(t *testing.T) { - elements := []string{"a", "b", "c"} - set := New(elements...) - - if len(set) != len(elements) { - t.Errorf("Expected length %d != %d", len(set), len(elements)) - } - - for _, e := range elements { - if _, exist := set[e]; !exist { - t.Errorf("%s is not in set %v", e, set) - } - } -} - -func TestUnion(t *testing.T) { - elements := []string{"a", "b", "c", "d"} - elements2 := []string{"a", "b", "e"} - want := New("a", "b", "c", "d", "e") - for _, sets := range [][]Set[string]{ - {New(elements...), New(elements2...)}, - {New(elements2...), New(elements...)}, - } { - s1, s2 := sets[0], sets[1] - if got := s1.Union(s2); !got.Equals(want) { - t.Errorf("expected %v; got %v", want, got) - } - } -} - -func TestDifference(t *testing.T) { - s1 := New("a", "b", "c", "d") - s2 := New("a", "b", "e") - want := New("c", "d") - - t.Run("difference", func(t *testing.T) { - d := s1.Difference(s2) - if !want.Equals(d) { - t.Errorf("want %+v, but got %+v", want, d) - } - }) - - t.Run("difference in place", func(t *testing.T) { - s1c := s1.Copy() - r := s1c.DifferenceInPlace(s2) - if !want.Equals(r) { - t.Errorf("want %+v, but got %+v", want, r) - } - // s1c should be updated - if !want.Equals(s1c) { - t.Errorf("want %+v, but got %+v", want, s1c) - } - }) -} - -func TestIntersection(t *testing.T) { - s1 := New("a", "b", "d") - s2 := New("a", "b", "c") - want := New("a", "b") - - t.Run("intersection", func(t *testing.T) { - d := s1.Intersection(s2) - if !d.Equals(want) { - t.Errorf("want %+v, but got %+v", want, d) - } - }) - - t.Run("intersect in replace", func(t *testing.T) { - s1c := s1.Copy() - d := s1c.IntersectInPlace(s2) - if !want.Equals(d) { - t.Errorf("want %+v, but got %+v", want, d) - } - // s1c should be updated - if !want.Equals(s1c) { - t.Errorf("want %+v, but got %+v", want, s1c) - } - }) -} - -func TestSupersetOf(t *testing.T) { - testCases := []struct { - name string - first Set[string] - second Set[string] - want bool - }{ - { - name: "both nil", - first: nil, - second: nil, - want: true, - }, - { - name: "first nil", - first: nil, - second: New("a"), - want: false, - }, - { - name: "second nil", - first: New("a"), - second: nil, - want: true, - }, - { - name: "both empty", - first: New[string](), - second: New[string](), - want: true, - }, - { - name: "first empty", - first: New[string](), - second: New("a"), - want: false, - }, - { - name: "second empty", - first: New("a"), - second: New[string](), - want: true, - }, - { - name: "equal", - first: New("a", "b"), - second: New("a", "b"), - want: true, - }, - { - name: "first contains all second", - first: New("a", "b", "c"), - second: New("a", "b"), - want: true, - }, - { - name: "second contains all first", - first: New("a", "b"), - second: New("a", "b", "c"), - want: false, - }, - } - for _, tt := range testCases { - t.Run(tt.name, func(t *testing.T) { - if got := tt.first.SupersetOf(tt.second); got != tt.want { - t.Errorf("want %v, but got %v", tt.want, got) - } - }) - } -} - -func BenchmarkSupersetOf(b *testing.B) { - set1 := New[string]() - for i := 0; i < 1000; i++ { - set1.Insert(fmt.Sprint(i)) - } - set2 := New[string]() - for i := 0; i < 50; i++ { - set2.Insert(fmt.Sprint(i)) - } - b.ResetTimer() - - b.Run("SupersetOf", func(b *testing.B) { - for n := 0; n < b.N; n++ { - set1.SupersetOf(set2) - } - }) -} - -func TestEquals(t *testing.T) { - tests := []struct { - name string - first Set[string] - second Set[string] - want bool - }{ - { - "both nil", - nil, - nil, - true, - }, - { - "unequal length", - New("test"), - New("test", "test1"), - false, - }, - { - "equal sets", - New("test", "test1"), - New("test", "test1"), - true, - }, - { - "unequal sets", - New("test", "test1"), - New("test", "test2"), - false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := tt.first.Equals(tt.second); got != tt.want { - t.Errorf("Unexpected Equal. got %v, want %v", got, tt.want) - } - }) - } -} - -func TestMerge(t *testing.T) { - cases := []struct { - s1, s2 Set[string] - expected []string - }{ - { - s1: New("a1", "a2"), - s2: New("a1", "a2"), - expected: []string{"a1", "a2"}, - }, - { - s1: New("a1", "a2", "a3"), - s2: New("a1", "a2"), - expected: []string{"a1", "a2", "a3"}, - }, - { - s1: New("a1", "a2"), - s2: New("a3", "a4"), - expected: []string{"a1", "a2", "a3", "a4"}, - }, - } - - for _, tc := range cases { - got := tc.s1.Merge(tc.s2) - assert.Equal(t, tc.expected, SortedList(got)) - } -} - -func TestInsertAll(t *testing.T) { - tests := []struct { - name string - s Set[string] - items []string - want Set[string] - }{ - { - name: "insert new item", - s: New("a1", "a2"), - items: []string{"a3"}, - want: New("a1", "a2", "a3"), - }, - { - name: "inserted item already exists", - s: New("a1", "a2"), - items: []string{"a1"}, - want: New("a1", "a2"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := tt.s.InsertAll(tt.items...); !reflect.DeepEqual(got, tt.want) { - t.Errorf("InsertAll() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestInsertContains(t *testing.T) { - s := New[string]() - assert.Equal(t, s.InsertContains("k1"), false) - assert.Equal(t, s.InsertContains("k1"), true) - assert.Equal(t, s.InsertContains("k2"), false) - assert.Equal(t, s.InsertContains("k2"), true) -} - -func BenchmarkSet(b *testing.B) { - containsTest := New[string]() - for i := 0; i < 1000; i++ { - containsTest.Insert(fmt.Sprint(i)) - } - sortOrder := []string{} - for i := 0; i < 1000; i++ { - sortOrder = append(sortOrder, fmt.Sprint(rand.Intn(1000))) - } - b.ResetTimer() - var s Set[string] // ensure no inlining - b.Run("insert", func(b *testing.B) { - for n := 0; n < b.N; n++ { - s = New[string]() - for i := 0; i < 1000; i++ { - s.Insert("item") - } - } - }) - b.Run("contains", func(b *testing.B) { - for n := 0; n < b.N; n++ { - containsTest.Contains("100") - } - }) - b.Run("sorted", func(b *testing.B) { - for n := 0; n < b.N; n++ { - b.StopTimer() - s := New(sortOrder...) - b.StartTimer() - SortedList(s) - } - }) -} - -func TestMapOfSet(t *testing.T) { - m := map[int]String{} - InsertOrNew(m, 1, "a") - InsertOrNew(m, 1, "b") - InsertOrNew(m, 2, "c") - assert.Equal(t, m, map[int]String{1: New("a", "b"), 2: New("c")}) - - DeleteCleanupLast(m, 1, "a") - assert.Equal(t, m, map[int]String{1: New("b"), 2: New("c")}) - DeleteCleanupLast(m, 1, "b") - DeleteCleanupLast(m, 1, "not found") - assert.Equal(t, m, map[int]String{2: New("c")}) -} - -func TestSetString(t *testing.T) { - elements := []string{"a"} - set := New(elements...) - assert.Equal(t, "[a]", set.String()) -} - -func BenchmarkOperateInPlace(b *testing.B) { - s1 := New[int]() - for i := 0; i < 100; i++ { - s1.Insert(i) - } - s2 := New[int]() - for i := 0; i < 100; i += 2 { - s2.Insert(i) - } - b.ResetTimer() - - b.Run("Difference", func(b *testing.B) { - for i := 0; i < b.N; i++ { - s1.Difference(s2) - } - }) - b.Run("DifferenceInPlace", func(b *testing.B) { - for i := 0; i < b.N; i++ { - s1.DifferenceInPlace(s2) - } - }) - b.Run("Intersection", func(b *testing.B) { - for i := 0; i < b.N; i++ { - s1.Intersection(s2) - } - }) - b.Run("IntersectInPlace", func(b *testing.B) { - for i := 0; i < b.N; i++ { - s1.IntersectInPlace(s2) - } - }) -} diff --git a/pkg/common/util/slices/slices.go b/pkg/common/util/slices/slices.go deleted file mode 100644 index 6165c4405..000000000 --- a/pkg/common/util/slices/slices.go +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package slices - -import ( - "cmp" - "slices" - "strings" - - "golang.org/x/exp/constraints" -) - -// Equal reports whether two slices are equal: the same length and all -// elements equal. If the lengths are different, Equal returns false. -// Otherwise, the elements are compared in increasing index order, and the -// comparison stops at the first unequal pair. -// Floating point NaNs are not considered equal. -func Equal[E comparable](s1, s2 []E) bool { - return slices.Equal(s1, s2) -} - -// EqualUnordered reports whether two slices are equal, ignoring order -func EqualUnordered[E comparable](s1, s2 []E) bool { - if len(s1) != len(s2) { - return false - } - first := make(map[E]struct{}, len(s1)) - for _, c := range s1 { - first[c] = struct{}{} - } - for _, c := range s2 { - if _, f := first[c]; !f { - return false - } - } - return true -} - -// EqualFunc reports whether two slices are equal using a comparison -// function on each pair of elements. If the lengths are different, -// EqualFunc returns false. Otherwise, the elements are compared in -// increasing index order, and the comparison stops at the first index -// for which eq returns false. -func EqualFunc[E1, E2 comparable](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool { - return slices.EqualFunc(s1, s2, eq) -} - -// SortFunc sorts the slice x in ascending order as determined by the less function. -// This sort is not guaranteed to be stable. -// The slice is modified in place but returned. -func SortFunc[E any](x []E, less func(a, b E) int) []E { - if len(x) <= 1 { - return x - } - slices.SortFunc(x, less) - return x -} - -// SortStableFunc sorts the slice x while keeping the original order of equal element. -// The slice is modified in place but returned. -// Please refer to SortFunc for usage instructions. -func SortStableFunc[E any](x []E, less func(a, b E) int) []E { - if len(x) <= 1 { - return x - } - slices.SortStableFunc(x, less) - return x -} - -// SortBy is a helper to sort a slice by some value. Typically, this would be sorting a struct -// by a single field. If you need to have multiple fields, see the ExampleSort. -func SortBy[E any, A constraints.Ordered](x []E, extract func(a E) A) []E { - if len(x) <= 1 { - return x - } - SortFunc(x, func(a, b E) int { - return cmp.Compare(extract(a), extract(b)) - }) - return x -} - -// Sort sorts a slice of any ordered type in ascending order. -// The slice is modified in place but returned. -func Sort[E constraints.Ordered](x []E) []E { - if len(x) <= 1 { - return x - } - slices.Sort(x) - return x -} - -// Clone returns a copy of the slice. -// The elements are copied using assignment, so this is a shallow clone. -func Clone[S ~[]E, E any](s S) S { - return slices.Clone(s) -} - -// Delete removes the element i from s, returning the modified slice. -func Delete[S ~[]E, E any](s S, i int) S { - // Since Go 1.22, "slices.Delete zeroes the elements s[len(s)-(j-i):len(s)]" - // (no memory leak) - return slices.Delete(s, i, i+1) -} - -// Contains reports whether v is present in s. -func Contains[E comparable](s []E, v E) bool { - return slices.Contains(s, v) -} - -// FindFunc finds the first element matching the function, or nil if none do -func FindFunc[E any](s []E, f func(E) bool) *E { - idx := slices.IndexFunc(s, f) - if idx == -1 { - return nil - } - return &s[idx] -} - -// First returns the first item in the slice, if there is one -func First[E any](s []E) *E { - if len(s) == 0 { - return nil - } - return &s[0] -} - -// Reverse returns its argument array reversed -func Reverse[E any](r []E) []E { - for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { - r[i], r[j] = r[j], r[i] - } - return r -} - -func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) { - return slices.BinarySearch(x, target) -} - -// FilterInPlace retains all elements in []E that f(E) returns true for. -// The array is *mutated in place* and returned. -// Use Filter to avoid mutation -func FilterInPlace[E any](s []E, f func(E) bool) []E { - n := 0 - for _, val := range s { - if f(val) { - s[n] = val - n++ - } - } - - // If those elements contain pointers you might consider zeroing those elements - // so that objects they reference can be garbage collected." - var empty E - for i := n; i < len(s); i++ { - s[i] = empty - } - - s = s[:n] - return s -} - -// FilterDuplicatesPresorted retains all unique elements in []E. -// The slices MUST be pre-sorted. -func FilterDuplicatesPresorted[E comparable](s []E) []E { - if len(s) <= 1 { - return s - } - n := 1 - for i := 1; i < len(s); i++ { - val := s[i] - if val != s[i-1] { - s[n] = val - n++ - } - } - - // If those elements contain pointers you might consider zeroing those elements - // so that objects they reference can be garbage collected." - var empty E - for i := n; i < len(s); i++ { - s[i] = empty - } - - s = s[:n] - return s -} - -// Filter retains all elements in []E that f(E) returns true for. -// A new slice is created and returned. Use FilterInPlace to perform in-place -func Filter[E any](s []E, f func(E) bool) []E { - matched := []E{} - for _, v := range s { - if f(v) { - matched = append(matched, v) - } - } - return matched -} - -// Map runs f() over all elements in s and returns the result -func Map[E any, O any](s []E, f func(E) O) []O { - n := make([]O, 0, len(s)) - for _, e := range s { - n = append(n, f(e)) - } - return n -} - -// MapErr runs f() over all elements in s and returns the result, short circuiting if there is an error. -func MapErr[E any, O any](s []E, f func(E) (O, error)) ([]O, error) { - n := make([]O, 0, len(s)) - for _, e := range s { - res, err := f(e) - if err != nil { - return nil, err - } - n = append(n, res) - } - return n, nil -} - -// MapFilter runs f() over all elements in s and returns any non-nil results -func MapFilter[E any, O any](s []E, f func(E) *O) []O { - n := make([]O, 0, len(s)) - for _, e := range s { - if res := f(e); res != nil { - n = append(n, *res) - } - } - return n -} - -// Reference takes a pointer to all elements in the slice -func Reference[E any](s []E) []*E { - res := make([]*E, 0, len(s)) - for _, v := range s { - v := v - res = append(res, &v) - } - return res -} - -// Dereference returns all non-nil references, dereferenced -func Dereference[E any](s []*E) []E { - res := make([]E, 0, len(s)) - for _, v := range s { - if v != nil { - res = append(res, *v) - } - } - return res -} - -// Flatten merges a slice of slices into a single slice. -func Flatten[E any](s [][]E) []E { - if s == nil { - return nil - } - res := make([]E, 0) - for _, v := range s { - res = append(res, v...) - } - return res -} - -// Group groups a slice by a key. -func Group[T any, K comparable](data []T, f func(T) K) map[K][]T { - res := make(map[K][]T, len(data)) - for _, e := range data { - k := f(e) - res[k] = append(res[k], e) - } - return res -} - -// GroupUnique groups a slice by a key. Each key must be unique or data will be lost. To allow multiple use Group. -func GroupUnique[T any, K comparable](data []T, f func(T) K) map[K]T { - res := make(map[K]T, len(data)) - for _, e := range data { - res[f(e)] = e - } - return res -} - -func Join(sep string, fields ...string) string { - return strings.Join(fields, sep) -} - -// Insert inserts the values v... into s at index i, -// returning the modified slice. -// The elements at s[i:] are shifted up to make room. -// In the returned slice r, r[i] == v[0], -// and r[i+len(v)] == value originally at r[i]. -// Insert panics if i is out of range. -// This function is O(len(s) + len(v)). -func Insert[S ~[]E, E any](s S, i int, v ...E) S { - return slices.Insert(s, i, v...) -} diff --git a/pkg/common/util/slices/slices_test.go b/pkg/common/util/slices/slices_test.go deleted file mode 100644 index facb08ebb..000000000 --- a/pkg/common/util/slices/slices_test.go +++ /dev/null @@ -1,916 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package slices - -import ( - "cmp" - "fmt" - "math/rand" - "reflect" - "strconv" - "testing" -) - -import ( - cmp2 "github.com/google/go-cmp/cmp" - - "github.com/stretchr/testify/assert" -) - -type s struct { - Junk string -} - -func TestEqual(t *testing.T) { - tests := []struct { - name string - s1 []int - s2 []int - want bool - }{ - {"Empty Slices", []int{}, []int{}, true}, - {"Equal Slices", []int{1, 2, 3}, []int{1, 2, 3}, true}, - {"Unequal Slices", []int{1, 2, 3}, []int{3, 2, 1}, false}, - {"One Empty Slice", []int{}, []int{1, 2, 3}, false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := Equal(tt.s1, tt.s2) - if got != tt.want { - t.Errorf("Equal() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestEqualFunc(t *testing.T) { - tests := []struct { - name string - s1 []int - s2 []int - eq func(int, int) bool - want bool - }{ - { - name: "Equal slices", - s1: []int{1, 2, 3}, - s2: []int{1, 2, 3}, - eq: func(a, b int) bool { - return a == b - }, - want: true, - }, - { - name: "Unequal slices", - s1: []int{1, 2, 3}, - s2: []int{4, 5, 6}, - eq: func(a, b int) bool { - return a == b - }, - want: false, - }, - { - name: "Empty slices", - s1: []int{}, - s2: []int{}, - eq: func(a, b int) bool { - return a == b - }, - want: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := EqualFunc(tt.s1, tt.s2, tt.eq) - if diff := cmp2.Diff(tt.want, got); diff != "" { - t.Errorf("Unexpected result (-want +got):\n%s", diff) - } - }) - } -} - -func TestSortBy(t *testing.T) { - testCases := []struct { - name string - input []int - extract func(a int) int - expected []int - }{ - { - name: "Normal Case", - input: []int{4, 2, 3, 1}, - extract: func(a int) int { return a }, - expected: []int{1, 2, 3, 4}, - }, - { - name: "Reverse Case", - input: []int{1, 2, 3, 4}, - extract: func(a int) int { return -a }, - expected: []int{4, 3, 2, 1}, - }, - { - name: "Same Elements Case", - input: []int{2, 2, 2, 2}, - extract: func(a int) int { return a }, - expected: []int{2, 2, 2, 2}, - }, - { - name: "Empty Slice Case", - input: []int{}, - extract: func(a int) int { return a }, - expected: []int{}, - }, - { - name: "One Element Case", - input: []int{1}, - extract: func(a int) int { return a }, - expected: []int{1}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - result := SortBy(tc.input, tc.extract) - if !reflect.DeepEqual(result, tc.expected) { - t.Fatalf("Expected: %+v, but got: %+v", tc.expected, result) - } - }) - } -} - -func TestSort(t *testing.T) { - testCases := []struct { - name string - input []int - expected []int - }{ - { - name: "Single_Element", - input: []int{1}, - expected: []int{1}, - }, - { - name: "Already_Sorted", - input: []int{1, 2, 3, 4}, - expected: []int{1, 2, 3, 4}, - }, - { - name: "Reverse_Order", - input: []int{4, 3, 2, 1}, - expected: []int{1, 2, 3, 4}, - }, - { - name: "Unique_Elements", - input: []int{12, 3, 5, 1, 27}, - expected: []int{1, 3, 5, 12, 27}, - }, - { - name: "Empty_Slice", - input: []int{}, - expected: []int{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - result := Sort(tc.input) - if !reflect.DeepEqual(result, tc.expected) { - t.Fatalf("Expected %v, got %v", tc.expected, result) - } - }) - } -} - -func TestReverse(t *testing.T) { - tests := []struct { - name string - input []int - expected []int - }{ - { - name: "empty slice", - input: []int{}, - expected: []int{}, - }, - { - name: "single element", - input: []int{1}, - expected: []int{1}, - }, - { - name: "two elements", - input: []int{1, 2}, - expected: []int{2, 1}, - }, - { - name: "multiple elements", - input: []int{1, 2, 3, 4, 5}, - expected: []int{5, 4, 3, 2, 1}, - }, - { - name: "odd number of elements", - input: []int{1, 2, 3}, - expected: []int{3, 2, 1}, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - result := Reverse(tc.input) - if diff := cmp2.Diff(tc.expected, result); diff != "" { - t.Errorf("Reverse() mismatch (-want +got):\n%s", diff) - } - }) - } -} - -func TestClone(t *testing.T) { - tests := []struct { - name string - slice []interface{} - }{ - { - name: "Empty", - slice: []interface{}{}, - }, - { - name: "Single Element", - slice: []interface{}{1}, - }, - { - name: "Multiple Elements", - slice: []interface{}{1, "a", 3.14159}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - clone := Clone(tt.slice) - if !reflect.DeepEqual(clone, tt.slice) { - t.Errorf("Clone() got = %v, want = %v", clone, tt.slice) - } - }) - } -} - -func TestDelete(t *testing.T) { - type s struct { - Junk string - } - var input []*s - var output []*s - t.Run("inner", func(t *testing.T) { - a := &s{"a"} - b := &s{"b"} - input = []*s{a, b} - output = Delete(input, 1) - }) - assert.Equal(t, output, []*s{{"a"}}) -} - -func TestContains(t *testing.T) { - testCases := []struct { - name string - slice []int - v int - want bool - }{ - { - name: "ContainsElement", - slice: []int{1, 2, 3, 4, 5}, - v: 3, - want: true, - }, - { - name: "DoesNotContainElement", - slice: []int{1, 2, 3, 4, 5}, - v: 6, - want: false, - }, - { - name: "EmptySlice", - slice: []int{}, - v: 1, - want: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if got := Contains(tc.slice, tc.v); got != tc.want { - t.Errorf("Contains(%v, %v) = %v; want %v", tc.slice, tc.v, got, tc.want) - } - }) - } -} - -func TestFindFunc(t *testing.T) { - emptyElement := []string{} - elements := []string{"a", "b", "c"} - tests := []struct { - name string - elements []string - fn func(string) bool - want *string - }{ - { - elements: emptyElement, - fn: func(s string) bool { - return s == "b" - }, - want: nil, - }, - { - elements: elements, - fn: func(s string) bool { - return s == "bb" - }, - want: nil, - }, - { - elements: elements, - fn: func(s string) bool { - return s == "b" - }, - want: &elements[1], - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := FindFunc(tt.elements, tt.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindFunc got %v, want %v", got, tt.want) - } - }) - } -} - -func TestFilter(t *testing.T) { - tests := []struct { - name string - elements []string - fn func(string) bool - want []string - }{ - { - name: "empty element", - elements: []string{}, - fn: func(s string) bool { - return len(s) > 1 - }, - want: []string{}, - }, - { - name: "element length equals 0", - elements: []string{"", "", ""}, - fn: func(s string) bool { - return len(s) > 1 - }, - want: []string{}, - }, - { - name: "filter elements with length greater than 1", - elements: []string{"a", "bbb", "ccc", ""}, - fn: func(s string) bool { - return len(s) > 1 - }, - want: []string{"bbb", "ccc"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - filter := Filter(tt.elements, tt.fn) - if !reflect.DeepEqual(filter, tt.want) { - t.Errorf("Filter got %v, want %v", filter, tt.want) - } - filterInPlace := FilterInPlace(tt.elements, tt.fn) - if !reflect.DeepEqual(filterInPlace, tt.want) { - t.Errorf("FilterInPlace got %v, want %v", filterInPlace, tt.want) - } - if !reflect.DeepEqual(filter, filterInPlace) { - t.Errorf("Filter got %v, FilterInPlace got %v", filter, filterInPlace) - } - }) - } -} - -func TestFilterInPlace(t *testing.T) { - var input []*s - var output []*s - a := &s{"a"} - b := &s{"b"} - c := &s{"c"} - input = []*s{a, b, c} - - t.Run("delete first element a", func(t *testing.T) { - output = FilterInPlace(input, func(s *s) bool { - return s != nil && s.Junk != "a" - }) - }) - assert.Equal(t, output, []*s{{"b"}, {"c"}}) - assert.Equal(t, input, []*s{{"b"}, {"c"}, nil}) - - t.Run("delete end element c", func(t *testing.T) { - output = FilterInPlace(input, func(s *s) bool { - return s != nil && s.Junk != "c" - }) - }) - assert.Equal(t, output, []*s{{"b"}}) - assert.Equal(t, input, []*s{{"b"}, nil, nil}) -} - -func TestMap(t *testing.T) { - tests := []struct { - name string - elements []int - fn func(int) int - want []int - }{ - { - name: "empty element", - elements: []int{}, - fn: func(s int) int { - return s + 10 - }, - want: []int{}, - }, - { - name: "add ten to each element", - elements: []int{0, 1, 2, 3}, - fn: func(s int) int { - return s + 10 - }, - want: []int{10, 11, 12, 13}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Map(tt.elements, tt.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Map got %v, want %v", got, tt.want) - } - }) - } -} - -func TestGroup(t *testing.T) { - tests := []struct { - name string - elements []string - fn func(string) int - want map[int][]string - }{ - { - name: "empty element", - elements: []string{}, - fn: func(s string) int { - return len(s) - }, - want: map[int][]string{}, - }, - { - name: "group by the length of each element", - elements: []string{"", "a", "b", "cc"}, - fn: func(s string) int { - return len(s) - }, - want: map[int][]string{0: {""}, 1: {"a", "b"}, 2: {"cc"}}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Group(tt.elements, tt.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("GroupUnique got %v, want %v", got, tt.want) - } - }) - } -} - -func TestGroupUnique(t *testing.T) { - tests := []struct { - name string - elements []string - fn func(string) int - want map[int]string - }{ - { - name: "empty element", - elements: []string{}, - fn: func(s string) int { - return len(s) - }, - want: map[int]string{}, - }, - { - name: "group by the length of each element", - elements: []string{"", "a", "bb", "ccc"}, - fn: func(s string) int { - return len(s) - }, - want: map[int]string{0: "", 1: "a", 2: "bb", 3: "ccc"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := GroupUnique(tt.elements, tt.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("GroupUnique got %v, want %v", got, tt.want) - } - }) - } -} - -var ( - i1, i2, i3 = 1, 2, 3 - s1, s2, s3 = "a", "b", "c" -) - -func TestMapFilter(t *testing.T) { - tests := []struct { - name string - input []int - function func(int) *int - want []int - }{ - { - name: "RegularMapping", - input: []int{1, 2, 3, 4, 5}, - function: func(num int) *int { - if num%2 == 0 { - return &num - } - return nil - }, - want: []int{2, 4}, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - got := MapFilter(tc.input, tc.function) - - if len(got) != len(tc.want) { - t.Errorf("got %d, want %d", got, tc.want) - } - - for i := range got { - if got[i] != tc.want[i] { - t.Errorf("got %d, want %d", got[i], tc.want[i]) - } - } - }) - } -} - -func TestReference(t *testing.T) { - type args[E any] struct { - s []E - } - type testCase[E any] struct { - name string - args args[E] - want []*E - } - stringTests := []testCase[string]{ - { - name: "empty slice", - args: args[string]{ - []string{}, - }, - want: []*string{}, - }, - { - name: "slice with 1 element", - args: args[string]{ - []string{s1}, - }, - want: []*string{&s1}, - }, - { - name: "slice with many elements", - args: args[string]{ - []string{s1, s2, s3}, - }, - want: []*string{&s1, &s2, &s3}, - }, - } - intTests := []testCase[int]{ - { - name: "empty slice", - args: args[int]{ - []int{}, - }, - want: []*int{}, - }, - { - name: "slice with 1 element", - args: args[int]{ - []int{i1}, - }, - want: []*int{&i1}, - }, - { - name: "slice with many elements", - args: args[int]{ - []int{i1, i2, i3}, - }, - want: []*int{&i1, &i2, &i3}, - }, - } - for _, tt := range stringTests { - t.Run(tt.name, func(t *testing.T) { - if got := Reference(tt.args.s); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Reference() = %v, want %v", got, tt.want) - } - }) - } - for _, tt := range intTests { - t.Run(tt.name, func(t *testing.T) { - if got := Reference(tt.args.s); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Reference() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestDereference(t *testing.T) { - type args[E any] struct { - s []*E - } - type testCase[E any] struct { - name string - args args[E] - want []E - } - stringTests := []testCase[string]{ - { - name: "empty slice", - args: args[string]{ - []*string{}, - }, - want: []string{}, - }, - { - name: "slice with 1 element", - args: args[string]{ - []*string{&s1}, - }, - want: []string{s1}, - }, - { - name: "slice with many elements", - args: args[string]{ - []*string{&s1, &s2, &s3}, - }, - want: []string{s1, s2, s3}, - }, - } - intTests := []testCase[int]{ - { - name: "empty slice", - args: args[int]{ - []*int{}, - }, - want: []int{}, - }, - { - name: "slice with 1 element", - args: args[int]{ - []*int{&i1}, - }, - want: []int{i1}, - }, - { - name: "slice with many elements", - args: args[int]{ - []*int{&i1, &i2, &i3}, - }, - want: []int{i1, i2, i3}, - }, - } - for _, tt := range stringTests { - t.Run(tt.name, func(t *testing.T) { - if got := Dereference(tt.args.s); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Dereference() = %v, want %v", got, tt.want) - } - }) - } - for _, tt := range intTests { - t.Run(tt.name, func(t *testing.T) { - if got := Dereference(tt.args.s); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Dereference() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestFlatten(t *testing.T) { - testCases := []struct { - name string - input [][]int - want []int - }{ - { - name: "simple case", - input: [][]int{{1, 2}, {3, 4}, {5, 6}}, - want: []int{1, 2, 3, 4, 5, 6}, - }, - { - name: "empty inner slices", - input: [][]int{{}, {}, {}}, - want: []int{}, - }, - { - name: "nil slice", - input: nil, - want: nil, - }, - { - name: "empty slice", - input: [][]int{}, - want: []int{}, - }, - { - name: "single element slices", - input: [][]int{{1}, {2}, {3}}, - want: []int{1, 2, 3}, - }, - { - name: "mixed empty and non-empty slices", - input: [][]int{{1, 2}, {}, {3, 4}}, - want: []int{1, 2, 3, 4}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := Flatten(tc.input) - if !reflect.DeepEqual(got, tc.want) { - t.Errorf("Flatten(%v) = %v; want %v", tc.input, got, tc.want) - } - }) - } -} - -// nolint: unused -type myStruct struct { - a, b, c, d string - n int -} - -func makeRandomStructs(n int) []*myStruct { - rand.Seed(42) // nolint: staticcheck - structs := make([]*myStruct, n) - for i := 0; i < n; i++ { - structs[i] = &myStruct{n: rand.Intn(n)} // nolint: gosec - } - return structs -} - -const N = 100_000 - -func BenchmarkSort(b *testing.B) { - b.Run("SortFunc", func(b *testing.B) { - cmpFunc := func(a, b *myStruct) int { return a.n - b.n } - for i := 0; i < b.N; i++ { - b.StopTimer() - ss := makeRandomStructs(N) - b.StartTimer() - SortFunc(ss, cmpFunc) - } - }) - b.Run("SortStableFunc", func(b *testing.B) { - cmpFunc := func(a, b *myStruct) int { return a.n - b.n } - for i := 0; i < b.N; i++ { - b.StopTimer() - ss := makeRandomStructs(N) - b.StartTimer() - SortStableFunc(ss, cmpFunc) - } - }) - b.Run("SortBy", func(b *testing.B) { - cmpFunc := func(a *myStruct) int { return a.n } - for i := 0; i < b.N; i++ { - b.StopTimer() - ss := makeRandomStructs(N) - b.StartTimer() - SortBy(ss, cmpFunc) - } - }) -} - -func ExampleSort() { - // ExampleSort shows the best practices in sorting by multiple keys. - // If you just have one key, use SortBy - - // Test has 3 values; we will sort by them in Rank < First < Last order - type Test struct { - Rank int - First string - Last string - } - l := []Test{ - {0, "b", "b"}, - {0, "b", "a"}, - {1, "a", "a"}, - {0, "c", "a"}, - {1, "c", "a"}, - {0, "a", "a"}, - {2, "z", "a"}, - } - SortFunc(l, func(a, b Test) int { - if r := cmp.Compare(a.Rank, b.Rank); r != 0 { - return r - } - if r := cmp.Compare(a.First, b.First); r != 0 { - return r - } - return cmp.Compare(a.Last, b.Last) - }) - fmt.Println(l) - - // Output: - // [{0 a a} {0 b a} {0 b b} {0 c a} {1 a a} {1 c a} {2 z a}] -} - -func BenchmarkEqualUnordered(b *testing.B) { - size := 100 - var l []string - for i := 0; i < size; i++ { - l = append(l, strconv.Itoa(i)) - } - var equal []string - for i := 0; i < size; i++ { - equal = append(equal, strconv.Itoa(i)) - } - var notEqual []string - for i := 0; i < size; i++ { - notEqual = append(notEqual, strconv.Itoa(i)) - } - notEqual[size-1] = "z" - - for n := 0; n < b.N; n++ { - EqualUnordered(l, equal) - EqualUnordered(l, notEqual) - } -} - -func TestFilterDuplicates(t *testing.T) { - tests := []struct { - name string - in []string - out []string - }{ - { - name: "empty", - in: nil, - out: nil, - }, - { - name: "one", - in: []string{"a"}, - out: []string{"a"}, - }, - { - name: "no dupes", - in: []string{"a", "b", "c", "d"}, - out: []string{"a", "b", "c", "d"}, - }, - { - name: "dupes first", - in: []string{"a", "a", "c", "d"}, - out: []string{"a", "c", "d"}, - }, - { - name: "dupes last", - in: []string{"a", "b", "c", "c"}, - out: []string{"a", "b", "c"}, - }, - { - name: "dupes middle", - in: []string{"a", "b", "b", "c"}, - out: []string{"a", "b", "c"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := FilterDuplicatesPresorted(tt.in) - assert.Equal(t, tt.out, got) - assert.Equal(t, tt.out, tt.in[:len(tt.out)]) - }) - } -} diff --git a/pkg/common/util/watchdog/watchdog.go b/pkg/common/util/watchdog/watchdog.go deleted file mode 100644 index a14405c5f..000000000 --- a/pkg/common/util/watchdog/watchdog.go +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package watchdog - -import ( - "context" - "time" - - "github.com/pkg/errors" -) - -type Watchdog interface { - Start(stop <-chan struct{}) -} - -type SimpleWatchdog struct { - NewTicker func() *time.Ticker - OnTick func(context.Context) error - OnError func(error) - OnStop func() -} - -func (w *SimpleWatchdog) Start(stop <-chan struct{}) { - ticker := w.NewTicker() - defer ticker.Stop() - - for { - ctx, cancel := context.WithCancel(context.Background()) - // cancel is called at the end of the loop - go func() { - select { - case <-stop: - cancel() - case <-ctx.Done(): - } - }() - select { - case <-ticker.C: - select { - case <-stop: - default: - if err := w.onTick(ctx); err != nil && !errors.Is(err, context.Canceled) { - w.OnError(err) - } - } - case <-stop: - if w.OnStop != nil { - w.OnStop() - } - // cancel will be called by the above goroutine - return - } - cancel() - } -} - -func (w *SimpleWatchdog) onTick(ctx context.Context) error { - defer func() { - if cause := recover(); cause != nil { - if w.OnError != nil { - var err error - switch typ := cause.(type) { - case error: - err = errors.WithStack(typ) - default: - err = errors.Errorf("%v", cause) - } - w.OnError(err) - } - } - }() - return w.OnTick(ctx) -} diff --git a/pkg/common/util/xds/callbacks.go b/pkg/common/util/xds/callbacks.go deleted file mode 100644 index bd586ebec..000000000 --- a/pkg/common/util/xds/callbacks.go +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xds - -import ( - "context" - - discoveryv3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/structpb" -) - -// DiscoveryRequest defines interface over real Envoy's DiscoveryRequest. -type DiscoveryRequest interface { - NodeId() string - // Node returns either a v2 or v3 Node - Node() interface{} - Metadata() *structpb.Struct - VersionInfo() string - GetTypeUrl() string - GetResponseNonce() string - GetResourceNames() []string - HasErrors() bool - ErrorMsg() string -} - -// DiscoveryResponse defines interface over real Envoy's DiscoveryResponse. -type DiscoveryResponse interface { - GetTypeUrl() string - VersionInfo() string - GetResources() []*anypb.Any - GetNonce() string -} - -type DeltaDiscoveryRequest interface { - NodeId() string - // Node returns either a v2 or v3 Node - Node() interface{} - Metadata() *structpb.Struct - GetTypeUrl() string - GetResponseNonce() string - GetResourceNamesSubscribe() []string - GetInitialResourceVersions() map[string]string - HasErrors() bool - ErrorMsg() string -} - -// DeltaDiscoveryResponse defines interface over real Envoy's DeltaDiscoveryResponse. -type DeltaDiscoveryResponse interface { - GetTypeUrl() string - GetResources() []*discoveryv3.Resource - GetRemovedResources() []string - GetNonce() string -} - -// Callbacks defines Callbacks for xDS streaming requests. The difference over real go-control-plane Callbacks is that it takes an DiscoveryRequest / DiscoveryResponse interface. -// It helps us to implement Callbacks once for many different versions of Envoy API. -type Callbacks interface { - // OnStreamOpen is called once an xDS stream is opened with a stream ID and the type URL (or "" for ADS). - // Returning an error will end processing and close the stream. OnStreamClosed will still be called. - OnStreamOpen(context.Context, int64, string) error - // OnStreamClosed is called immediately prior to closing an xDS stream with a stream ID. - OnStreamClosed(int64) - // OnStreamRequest is called once a request is received on a stream. - // Returning an error will end processing and close the stream. OnStreamClosed will still be called. - OnStreamRequest(int64, DiscoveryRequest) error - // OnStreamResponse is called immediately prior to sending a response on a stream. - OnStreamResponse(int64, DiscoveryRequest, DiscoveryResponse) -} - -type DeltaCallbacks interface { - // OnDeltaStreamOpen is called once an xDS stream is opened with a stream ID and the type URL (or "" for ADS). - // Returning an error will end processing and close the stream. OnDeltaStreamClosed will still be called. - OnDeltaStreamOpen(context.Context, int64, string) error - // OnDeltaStreamClosed is called immediately prior to closing an xDS stream with a stream ID. - OnDeltaStreamClosed(int64) - // OnStreamDeltaRequest is called once a request is received on a stream. - // Returning an error will end processing and close the stream. OnDeltaStreamClosed will still be called. - OnStreamDeltaRequest(int64, DeltaDiscoveryRequest) error - // OnStreamDeltaResponse is called immediately prior to sending a response on a stream. - OnStreamDeltaResponse(int64, DeltaDiscoveryRequest, DeltaDiscoveryResponse) -} - -// RestCallbacks defines rest.Callbacks for xDS fetch requests. The difference over real go-control-plane -// Callbacks is that it takes an DiscoveryRequest / DiscoveryResponse interface. -// It helps us to implement Callbacks once for many different versions of Envoy API. -type RestCallbacks interface { - // OnFetchRequest is called when a new rest request comes in. - // Returning an error will end processing. OnFetchResponse will not be called. - OnFetchRequest(ctx context.Context, request DiscoveryRequest) error - // OnFetchResponse is called immediately prior to sending a rest response. - OnFetchResponse(request DiscoveryRequest, response DiscoveryResponse) -} - -// MultiCallbacks implements callbacks for both rest and streaming xDS requests. -type MultiCallbacks interface { - Callbacks - RestCallbacks -} diff --git a/pkg/common/util/xds/logging_callbacks.go b/pkg/common/util/xds/logging_callbacks.go deleted file mode 100644 index 5d0deaa98..000000000 --- a/pkg/common/util/xds/logging_callbacks.go +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xds - -import ( - "context" - - "github.com/go-logr/logr" -) - -type LoggingCallbacks struct { - Log logr.Logger -} - -var _ Callbacks = LoggingCallbacks{} - -// OnStreamOpen is called once an xDS stream is open with a stream ID and the type URL (or "" for ADS). -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (cb LoggingCallbacks) OnStreamOpen(ctx context.Context, streamID int64, typ string) error { - cb.Log.V(1).Info("OnStreamOpen", "context", ctx, "streamid", streamID, "type", typ) - return nil -} - -// OnStreamClosed is called immediately prior to closing an xDS stream with a stream ID. -func (cb LoggingCallbacks) OnStreamClosed(streamID int64) { - cb.Log.V(1).Info("OnStreamClosed", "streamid", streamID) -} - -// OnStreamRequest is called once a request is received on a stream. -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (cb LoggingCallbacks) OnStreamRequest(streamID int64, req DiscoveryRequest) error { - cb.Log.V(1).Info("OnStreamRequest", "streamid", streamID, "req", req) - return nil -} - -// OnStreamResponse is called immediately prior to sending a response on a stream. -func (cb LoggingCallbacks) OnStreamResponse(streamID int64, req DiscoveryRequest, resp DiscoveryResponse) { - cb.Log.V(1).Info("OnStreamResponse", "streamid", streamID, "req", req, "resp", resp) -} - -// OnDeltaStreamOpen is called once an xDS stream is open with a stream ID and the type URL (or "" for ADS). -// Returning an error will end processing and close the stream. OnDeltaStreamOpen will still be called. -func (cb LoggingCallbacks) OnDeltaStreamOpen(ctx context.Context, streamID int64, typ string) error { - cb.Log.V(1).Info("OnDeltaStreamOpen", "context", ctx, "streamid", streamID, "type", typ) - return nil -} - -// OnDeltaStreamClosed is called immediately prior to closing an xDS stream with a stream ID. -func (cb LoggingCallbacks) OnDeltaStreamClosed(streamID int64) { - cb.Log.V(1).Info("OnDeltaStreamClosed", "streamid", streamID) -} - -// OnStreamDeltaRequest is called once a request is received on a stream. -// Returning an error will end processing and close the stream. OnStreamDeltaRequest will still be called. -func (cb LoggingCallbacks) OnStreamDeltaRequest(streamID int64, req DeltaDiscoveryRequest) error { - cb.Log.V(1).Info("OnStreamDeltaRequest", "streamid", streamID, "req", req) - return nil -} - -// OnStreamDeltaResponse is called immediately prior to sending a response on a stream. -func (cb LoggingCallbacks) OnStreamDeltaResponse(streamID int64, req DeltaDiscoveryRequest, resp DeltaDiscoveryResponse) { - cb.Log.V(1).Info("OnStreamDeltaResponse", "streamid", streamID, "req", req, "resp", resp) -} - -// OnFetchRequest is called for each Fetch request. Returning an error will end processing of the -// request and respond with an error. -func (cb LoggingCallbacks) OnFetchRequest(ctx context.Context, req DiscoveryRequest) error { - cb.Log.V(1).Info("OnFetchRequest", "context", ctx, "req", req) - return nil -} - -// OnFetchRequest is called for each Fetch request. Returning an error will end processing of the -// request and respond with an error. -// OnFetchResponse is called immediately prior to sending a response. -func (cb LoggingCallbacks) OnFetchResponse(req DiscoveryRequest, resp DiscoveryResponse) { - cb.Log.V(1).Info("OnFetchResponse", "req", req, "resp", resp) -} diff --git a/pkg/common/util/xds/noop_callbacks.go b/pkg/common/util/xds/noop_callbacks.go deleted file mode 100644 index 2ceb7d115..000000000 --- a/pkg/common/util/xds/noop_callbacks.go +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xds - -import ( - "context" -) - -type NoopCallbacks struct{} - -func (n *NoopCallbacks) OnStreamOpen(context.Context, int64, string) error { - return nil -} - -func (n *NoopCallbacks) OnStreamClosed(int64) { -} - -func (n *NoopCallbacks) OnStreamRequest(int64, DiscoveryRequest) error { - return nil -} - -func (n *NoopCallbacks) OnStreamResponse(int64, DiscoveryRequest, DiscoveryResponse) { -} - -func (n *NoopCallbacks) OnDeltaStreamOpen(context.Context, int64, string) error { - return nil -} - -func (n *NoopCallbacks) OnDeltaStreamClosed(int64) { -} - -func (n *NoopCallbacks) OnStreamDeltaRequest(int64, DeltaDiscoveryRequest) error { - return nil -} - -func (n *NoopCallbacks) OnStreamDeltaResponse(int64, DeltaDiscoveryRequest, DeltaDiscoveryResponse) { -} - -var _ Callbacks = &NoopCallbacks{} diff --git a/pkg/common/util/xds/stats_callbacks.go b/pkg/common/util/xds/stats_callbacks.go deleted file mode 100644 index e703afd53..000000000 --- a/pkg/common/util/xds/stats_callbacks.go +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xds - -import ( - "context" - "sync" - "time" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/apache/dubbo-admin/pkg/core" -) - -var statsLogger = core.Log.WithName("stats-callbacks") - -const ConfigInFlightThreshold = 100_000 - -type StatsCallbacks interface { - // ConfigReadyForDelivery marks a configuration as a ready to be delivered. - // This means that any config (EDS/CDS/DDS policies etc.) with specified version was set to a Snapshot - // and it's scheduled to be delivered. - ConfigReadyForDelivery(configVersion string) - // DiscardConfig removes a configuration from being delivered. - // This should be called when the client of xDS/DDS server disconnects. - DiscardConfig(configVersion string) - Callbacks - DeltaCallbacks -} - -type statsCallbacks struct { - NoopCallbacks - responsesSentMetric *prometheus.CounterVec - requestsReceivedMetric *prometheus.CounterVec - deliveryMetric prometheus.Summary - deliveryMetricName string - streamsActive int - configsQueue map[string]time.Time - sync.RWMutex -} - -func (s *statsCallbacks) ConfigReadyForDelivery(configVersion string) { - s.Lock() - if len(s.configsQueue) > ConfigInFlightThreshold { - // We clean up times of ready for delivery configs when config is delivered or client is disconnected. - // However, there is always a potential case that may have missed. - // When we get to the point of ConfigInFlightThreshold elements in the map we want to wipe the map - // instead of grow it to the point that CP runs out of memory. - // The statistic is not critical for CP to work, and we will still get data points of configs that are constantly being delivered. - statsLogger.Info("cleaning up config ready for delivery times to avoid potential memory leak. This operation may cause problems with metric for a short period of time", "metric", s.deliveryMetricName) - s.configsQueue = map[string]time.Time{} - } - s.configsQueue[configVersion] = core.Now() - s.Unlock() -} - -func (s *statsCallbacks) DiscardConfig(configVersion string) { - s.Lock() - delete(s.configsQueue, configVersion) - s.Unlock() -} - -var _ StatsCallbacks = &statsCallbacks{} - -func NewStatsCallbacks(metrics prometheus.Registerer, dsType string) (StatsCallbacks, error) { - stats := &statsCallbacks{ - configsQueue: map[string]time.Time{}, - } - - return stats, nil -} - -func (s *statsCallbacks) OnStreamOpen(context.Context, int64, string) error { - s.Lock() - defer s.Unlock() - s.streamsActive++ - return nil -} - -func (s *statsCallbacks) OnStreamClosed(int64) { - s.Lock() - defer s.Unlock() - s.streamsActive-- -} - -func (s *statsCallbacks) OnStreamRequest(_ int64, request DiscoveryRequest) error { - if request.VersionInfo() == "" { - return nil // It's initial DiscoveryRequest to ask for resources. It's neither ACK nor NACK. - } - - if request.HasErrors() { - s.requestsReceivedMetric.WithLabelValues(request.GetTypeUrl(), "NACK").Inc() - } else { - s.requestsReceivedMetric.WithLabelValues(request.GetTypeUrl(), "ACK").Inc() - } - - if configTime, exists := s.takeConfigTimeFromQueue(request.VersionInfo()); exists { - s.deliveryMetric.Observe(float64(core.Now().Sub(configTime).Milliseconds())) - } - return nil -} - -func (s *statsCallbacks) takeConfigTimeFromQueue(configVersion string) (time.Time, bool) { - s.Lock() - generatedTime, ok := s.configsQueue[configVersion] - delete(s.configsQueue, configVersion) - s.Unlock() - return generatedTime, ok -} - -func (s *statsCallbacks) OnStreamResponse(_ int64, _ DiscoveryRequest, response DiscoveryResponse) { - s.responsesSentMetric.WithLabelValues(response.GetTypeUrl()).Inc() -} - -func (s *statsCallbacks) OnDeltaStreamOpen(context.Context, int64, string) error { - s.Lock() - defer s.Unlock() - s.streamsActive++ - return nil -} - -func (s *statsCallbacks) OnDeltaStreamClosed(int64) { - s.Lock() - defer s.Unlock() - s.streamsActive-- -} - -func (s *statsCallbacks) OnStreamDeltaRequest(_ int64, request DeltaDiscoveryRequest) error { - if request.GetResponseNonce() == "" { - return nil // It's initial DiscoveryRequest to ask for resources. It's neither ACK nor NACK. - } - - if request.HasErrors() { - s.requestsReceivedMetric.WithLabelValues(request.GetTypeUrl(), "NACK").Inc() - } else { - s.requestsReceivedMetric.WithLabelValues(request.GetTypeUrl(), "ACK").Inc() - } - - // Delta only has an initial version, therefore we need to change the key to nodeID and typeURL. - if configTime, exists := s.takeConfigTimeFromQueue(request.NodeId() + request.GetTypeUrl()); exists { - s.deliveryMetric.Observe(float64(core.Now().Sub(configTime).Milliseconds())) - } - return nil -} - -func (s *statsCallbacks) OnStreamDeltaResponse(_ int64, _ DeltaDiscoveryRequest, response DeltaDiscoveryResponse) { - s.responsesSentMetric.WithLabelValues(response.GetTypeUrl()).Inc() -} diff --git a/pkg/common/util/xds/v3/cache.go b/pkg/common/util/xds/v3/cache.go deleted file mode 100644 index 3ba272735..000000000 --- a/pkg/common/util/xds/v3/cache.go +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Copyright 2018 Envoyproxy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v3 - -import ( - "context" - "fmt" - "sync" - "sync/atomic" - "time" - - envoyconfigcorev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - "github.com/envoyproxy/go-control-plane/pkg/cache/types" - envoycache "github.com/envoyproxy/go-control-plane/pkg/cache/v3" - "github.com/envoyproxy/go-control-plane/pkg/log" - "github.com/envoyproxy/go-control-plane/pkg/server/stream/v3" -) - -type Snapshot interface { - // GetSupportedTypes returns a list of xDS types supported by this snapshot. - GetSupportedTypes() []string - - // Consistent check verifies that the dependent resources are exactly listed in the - // snapshot: - // - all EDS resources are listed by name in CDS resources - // - all RDS resources are listed by name in LDS resources - // - // Note that clusters and listeners are requested without name references, so - // Envoy will accept the snapshot list of clusters as-is even if it does not match - // all references found in xDS. - Consistent() error - - // GetResources selects snapshot resources by type. - GetResources(typ string) map[string]types.Resource - - // GetVersion returns the version for a resource type. - GetVersion(typ string) string - - // WithVersion creates a new snapshot with a different version for a given resource type. - WithVersion(typ string, version string) Snapshot -} - -// SnapshotCache is a snapshot-based envoy_cache that maintains a single versioned -// snapshot of responses per node. SnapshotCache consistently replies with the -// latest snapshot. For the protocol to work correctly in ADS mode, EDS/RDS -// requests are responded only when all resources in the snapshot xDS response -// are named as part of the request. It is expected that the CDS response names -// all EDS clusters, and the LDS response names all RDS routes in a snapshot, -// to ensure that Envoy makes the request for all EDS clusters or RDS routes -// eventually. -// -// SnapshotCache can operate as a REST or regular xDS backend. The snapshot -// can be partial, e.g. only include RDS or EDS resources. -type SnapshotCache interface { - envoycache.Cache - - // SetSnapshot sets a response snapshot for a node. For ADS, the snapshots - // should have distinct versions and be internally consistent (e.g. all - // referenced resources must be included in the snapshot). - // - // This method will cause the server to respond to all open watches, for which - // the version differs from the snapshot version. - SetSnapshot(node string, snapshot Snapshot) error - - // GetSnapshot gets the snapshot for a node. - GetSnapshot(node string) (Snapshot, error) - - // HasSnapshot checks whether there is a snapshot present for a node. - HasSnapshot(node string) bool - - // ClearSnapshot removes all status and snapshot information associated with a node. Return the removed snapshot or nil - ClearSnapshot(node string) Snapshot - - // GetStatusInfo retrieves status information for a node ID. - GetStatusInfo(string) StatusInfo - - // GetStatusKeys retrieves node IDs for all statuses. - GetStatusKeys() []string -} - -// Generates a snapshot of xDS resources for a given node. -type SnapshotGenerator interface { - GenerateSnapshot(context.Context, *envoyconfigcorev3.Node) (Snapshot, error) -} - -type snapshotCache struct { - // watchCount is an atomic counter incremented for each watch. This needs to - // be the first field in the struct to guarantee that it is 64-bit aligned, - // which is a requirement for atomic operations on 64-bit operands to work on - // 32-bit machines. - watchCount int64 - - log log.Logger - - // ads flag to hold responses until all resources are named - ads bool - - // snapshots are cached resources indexed by node IDs - snapshots map[string]Snapshot - - // status information for all nodes indexed by node IDs - status map[string]*statusInfo - - // hash is the hashing function for Envoy nodes - hash NodeHash - - mu sync.RWMutex -} - -// NewSnapshotCache initializes a simple envoy_cache. -// -// ADS flag forces a delay in responding to streaming requests until all -// resources are explicitly named in the request. This avoids the problem of a -// partial request over a single stream for a subset of resources which would -// require generating a fresh version for acknowledgement. ADS flag requires -// snapshot consistency. For non-ADS case (and fetch), multiple partial -// requests are sent across multiple streams and re-using the snapshot version -// is OK. -// -// Logger is optional. -func NewSnapshotCache(ads bool, hash NodeHash, logger log.Logger) SnapshotCache { - return &snapshotCache{ - log: logger, - ads: ads, - snapshots: make(map[string]Snapshot), - status: make(map[string]*statusInfo), - hash: hash, - } -} - -// SetSnapshotCache updates a snapshot for a node. -func (cache *snapshotCache) SetSnapshot(node string, snapshot Snapshot) error { - cache.mu.Lock() - defer cache.mu.Unlock() - - // update the existing entry - cache.snapshots[node] = snapshot - - // trigger existing watches for which version changed - if info, ok := cache.status[node]; ok { - info.mu.Lock() - for id, watch := range info.watches { - version := snapshot.GetVersion(watch.Request.TypeUrl) - if version != watch.Request.VersionInfo { - if cache.log != nil { - cache.log.Debugf("respond open watch %d%v with new version %q", id, watch.Request.ResourceNames, version) - } - cache.respond(watch.Request, watch.Response, snapshot.GetResources(watch.Request.TypeUrl), version) - - // discard the watch - delete(info.watches, id) - } - } - info.mu.Unlock() - } - - return nil -} - -// GetSnapshots gets the snapshot for a node, and returns an error if not found. -func (cache *snapshotCache) GetSnapshot(node string) (Snapshot, error) { - cache.mu.RLock() - defer cache.mu.RUnlock() - - snap, ok := cache.snapshots[node] - if !ok { - return nil, fmt.Errorf("no snapshot found for node %s", node) - } - return snap, nil -} - -func (cache *snapshotCache) HasSnapshot(node string) bool { - cache.mu.RLock() - defer cache.mu.RUnlock() - - _, ok := cache.snapshots[node] - return ok -} - -// ClearSnapshot clears snapshot and info for a node. -func (cache *snapshotCache) ClearSnapshot(node string) Snapshot { - cache.mu.Lock() - defer cache.mu.Unlock() - - snapshot := cache.snapshots[node] - delete(cache.snapshots, node) - delete(cache.status, node) - return snapshot -} - -// nameSet creates a map from a string slice to value true. -func nameSet(names []string) map[string]bool { - set := make(map[string]bool) - for _, name := range names { - set[name] = true - } - return set -} - -// superset checks that all resources are listed in the names set. -func superset(names map[string]bool, resources map[string]types.Resource) error { - for resourceName := range resources { - if _, exists := names[resourceName]; !exists { - return fmt.Errorf("%q not listed", resourceName) - } - } - return nil -} - -func (cache *snapshotCache) CreateDeltaWatch(*envoycache.DeltaRequest, stream.StreamState, chan envoycache.DeltaResponse) func() { - return nil -} - -// CreateWatch returns a watch for an xDS request. -func (cache *snapshotCache) CreateWatch(request *envoycache.Request, _ stream.StreamState, responseChan chan envoycache.Response) func() { - nodeID := cache.hash.ID(request.Node) - - cache.mu.Lock() - defer cache.mu.Unlock() - info, ok := cache.status[nodeID] - if !ok { - info = newStatusInfo(request.Node) - cache.status[nodeID] = info - } - - // update last watch request time - info.mu.Lock() - info.lastWatchRequestTime = time.Now() - info.mu.Unlock() - - snapshot, exists := cache.snapshots[nodeID] - version := "" - if exists { - version = snapshot.GetVersion(request.TypeUrl) - } - - // if the requested version is up-to-date or missing a response, leave an open watch - if !exists || request.VersionInfo == version { - watchID := cache.nextWatchID() - if cache.log != nil { - cache.log.Debugf("open watch %d for %s%v from nodeID %q, version %q", watchID, - request.TypeUrl, request.ResourceNames, nodeID, request.VersionInfo) - } - info.mu.Lock() - info.watches[watchID] = ResponseWatch{Request: request, Response: responseChan} - info.mu.Unlock() - return cache.cancelWatch(nodeID, watchID) - } - - // otherwise, the watch may be responded immediately - cache.respond(request, responseChan, snapshot.GetResources(request.TypeUrl), version) - - return nil -} - -func (cache *snapshotCache) nextWatchID() int64 { - return atomic.AddInt64(&cache.watchCount, 1) -} - -// cancellation function for cleaning stale watches -func (cache *snapshotCache) cancelWatch(nodeID string, watchID int64) func() { - return func() { - // uses the envoy_cache mutex - cache.mu.Lock() - defer cache.mu.Unlock() - if info, ok := cache.status[nodeID]; ok { - info.mu.Lock() - delete(info.watches, watchID) - info.mu.Unlock() - } - } -} - -// Respond to a watch with the snapshot value. The value channel should have capacity not to block. -// TODO(kuat) do not respond always, see issue https://github.com/envoyproxy/go-control-plane/issues/46 -func (cache *snapshotCache) respond(request *envoycache.Request, value chan envoycache.Response, resources map[string]types.Resource, version string) { - // for ADS, the request names must match the snapshot names - // if they do not, then the watch is never responded, and it is expected that envoy makes another request - if len(request.ResourceNames) != 0 && cache.ads { - if err := superset(nameSet(request.ResourceNames), resources); err != nil { - if cache.log != nil { - cache.log.Debugf("ADS mode: not responding to request: %v", err) - } - return - } - } - if cache.log != nil { - cache.log.Debugf("respond %s%v version %q with version %q", - request.TypeUrl, request.ResourceNames, request.VersionInfo, version) - } - - value <- createResponse(request, resources, version) -} - -func createResponse(request *envoycache.Request, resources map[string]types.Resource, version string) envoycache.Response { - filtered := make([]types.ResourceWithTTL, 0, len(resources)) - - // Reply only with the requested resources. Envoy may ask each resource - // individually in a separate stream. It is ok to reply with the same version - // on separate streams since requests do not share their response versions. - if len(request.ResourceNames) != 0 { - set := nameSet(request.ResourceNames) - for name, resource := range resources { - if set[name] { - filtered = append(filtered, types.ResourceWithTTL{Resource: resource}) - } - } - } else { - for _, resource := range resources { - filtered = append(filtered, types.ResourceWithTTL{Resource: resource}) - } - } - - return &envoycache.RawResponse{ - Request: request, - Version: version, - Resources: filtered, - } -} - -// Fetch implements the envoy_cache fetch function. -// Fetch is called on multiple streams, so responding to individual names with the same version works. -// If there is a Deadline set on the context, the call will block until either the context is terminated -// or there is a new update. -func (cache *snapshotCache) Fetch(ctx context.Context, request *envoycache.Request) (envoycache.Response, error) { - if _, hasDeadline := ctx.Deadline(); hasDeadline { - return cache.blockingFetch(ctx, request) - } - - nodeID := cache.hash.ID(request.Node) - - cache.mu.RLock() - defer cache.mu.RUnlock() - - if snapshot, exists := cache.snapshots[nodeID]; exists { - // Respond only if the request version is distinct from the current snapshot state. - // It might be beneficial to hold the request since Envoy will re-attempt the refresh. - version := snapshot.GetVersion(request.TypeUrl) - if request.VersionInfo == version { - if cache.log != nil { - cache.log.Warnf("skip fetch: version up to date") - } - return nil, &types.SkipFetchError{} - } - - resources := snapshot.GetResources(request.TypeUrl) - out := createResponse(request, resources, version) - return out, nil - } - - return nil, fmt.Errorf("missing snapshot for %q", nodeID) -} - -// blockingFetch will wait until either the context is terminated or new resources become available -func (cache *snapshotCache) blockingFetch(ctx context.Context, request *envoycache.Request) (envoycache.Response, error) { - responseChan := make(chan envoycache.Response, 1) - cancelFunc := cache.CreateWatch(request, stream.StreamState{}, responseChan) - if cancelFunc != nil { - defer cancelFunc() - } - - select { - case <-ctx.Done(): - // finished without an update - return nil, &types.SkipFetchError{} - case resp := <-responseChan: - return resp, nil - } -} - -// GetStatusInfo retrieves the status info for the node. -func (cache *snapshotCache) GetStatusInfo(node string) StatusInfo { - cache.mu.RLock() - defer cache.mu.RUnlock() - - info, exists := cache.status[node] - if !exists { - if cache.log != nil { - cache.log.Warnf("node does not exist") - } - return nil - } - - return info -} - -// GetStatusKeys retrieves all node IDs in the status map. -func (cache *snapshotCache) GetStatusKeys() []string { - cache.mu.RLock() - defer cache.mu.RUnlock() - - out := make([]string, 0, len(cache.status)) - for id := range cache.status { - out = append(out, id) - } - - return out -} - -// NodeHash computes string identifiers for Envoy nodes. -type NodeHash interface { - // ID function defines a unique string identifier for the remote Envoy node. - ID(node *envoyconfigcorev3.Node) string -} - -// IDHash uses ID field as the node hash. -type IDHash struct{} - -// ID uses the node ID field -func (IDHash) ID(node *envoyconfigcorev3.Node) string { - if node == nil { - return "" - } - return node.Id -} - -var _ NodeHash = IDHash{} - -// StatusInfo tracks the server state for the remote Envoy node. -// Not all fields are used by all envoy_cache implementations. -type StatusInfo interface { - // GetNode returns the node metadata. - GetNode() *envoyconfigcorev3.Node - - // GetNumWatches returns the number of open watches. - GetNumWatches() int - - // GetLastWatchRequestTime returns the timestamp of the last discoveryengine watch request. - GetLastWatchRequestTime() time.Time -} - -type statusInfo struct { - // node is the constant Envoy node metadata. - node *envoyconfigcorev3.Node - - // watches are indexed channels for the response watches and the original requests. - watches map[int64]ResponseWatch - - // the timestamp of the last watch request - lastWatchRequestTime time.Time - - // mutex to protect the status fields. - // should not acquire mutex of the parent envoy_cache after acquiring this mutex. - mu sync.RWMutex -} - -// ResponseWatch is a watch record keeping both the request and an open channel for the response. -type ResponseWatch struct { - // Request is the original request for the watch. - Request *envoycache.Request - - // Response is the channel to push responses to. - Response chan envoycache.Response -} - -// newStatusInfo initializes a status info data structure. -func newStatusInfo(node *envoyconfigcorev3.Node) *statusInfo { - out := statusInfo{ - node: node, - watches: make(map[int64]ResponseWatch), - } - return &out -} - -func (info *statusInfo) GetNode() *envoyconfigcorev3.Node { - info.mu.RLock() - defer info.mu.RUnlock() - return info.node -} - -func (info *statusInfo) GetNumWatches() int { - info.mu.RLock() - defer info.mu.RUnlock() - return len(info.watches) -} - -func (info *statusInfo) GetLastWatchRequestTime() time.Time { - info.mu.RLock() - defer info.mu.RUnlock() - return info.lastWatchRequestTime -} diff --git a/pkg/common/util/xds/v3/callbacks.go b/pkg/common/util/xds/v3/callbacks.go deleted file mode 100644 index 9e1ad8282..000000000 --- a/pkg/common/util/xds/v3/callbacks.go +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "context" - - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_sd "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" - "google.golang.org/protobuf/types/known/structpb" - - "github.com/apache/dubbo-admin/pkg/common/util/xds" -) - -// stream callbacks -type adapterCallbacks struct { - NoopCallbacks - callbacks xds.Callbacks -} - -// AdaptCallbacks translate dubbo callbacks to real go-control-plane Callbacks -func AdaptCallbacks(callbacks xds.Callbacks) envoy_xds.Callbacks { - return &adapterCallbacks{ - callbacks: callbacks, - } -} - -var _ envoy_xds.Callbacks = &adapterCallbacks{} - -func (a *adapterCallbacks) OnStreamOpen(ctx context.Context, streamID int64, typeURL string) error { - return a.callbacks.OnStreamOpen(ctx, streamID, typeURL) -} - -func (a *adapterCallbacks) OnStreamClosed(streamID int64, _ *envoy_core.Node) { - a.callbacks.OnStreamClosed(streamID) -} - -func (a *adapterCallbacks) OnStreamRequest(streamID int64, request *envoy_sd.DiscoveryRequest) error { - return a.callbacks.OnStreamRequest(streamID, &discoveryRequest{request}) -} - -func (a *adapterCallbacks) OnStreamResponse(ctx context.Context, streamID int64, request *envoy_sd.DiscoveryRequest, response *envoy_sd.DiscoveryResponse) { - a.callbacks.OnStreamResponse(streamID, &discoveryRequest{request}, &discoveryResponse{response}) -} - -// delta callbacks - -type adapterDeltaCallbacks struct { - NoopCallbacks - callbacks xds.DeltaCallbacks -} - -// AdaptDeltaCallbacks translate dubbo callbacks to real go-control-plane Callbacks -func AdaptDeltaCallbacks(callbacks xds.DeltaCallbacks) envoy_xds.Callbacks { - return &adapterDeltaCallbacks{ - callbacks: callbacks, - } -} - -var _ envoy_xds.Callbacks = &adapterDeltaCallbacks{} - -func (a *adapterDeltaCallbacks) OnDeltaStreamOpen(ctx context.Context, streamID int64, typeURL string) error { - return a.callbacks.OnDeltaStreamOpen(ctx, streamID, typeURL) -} - -func (a *adapterDeltaCallbacks) OnDeltaStreamClosed(streamID int64, _ *envoy_core.Node) { - a.callbacks.OnDeltaStreamClosed(streamID) -} - -func (a *adapterDeltaCallbacks) OnStreamDeltaRequest(streamID int64, request *envoy_sd.DeltaDiscoveryRequest) error { - return a.callbacks.OnStreamDeltaRequest(streamID, &deltaDiscoveryRequest{request}) -} - -func (a *adapterDeltaCallbacks) OnStreamDeltaResponse(streamID int64, request *envoy_sd.DeltaDiscoveryRequest, response *envoy_sd.DeltaDiscoveryResponse) { - a.callbacks.OnStreamDeltaResponse(streamID, &deltaDiscoveryRequest{request}, &deltaDiscoveryResponse{response}) -} - -// rest callbacks - -type adapterRestCallbacks struct { - NoopCallbacks - callbacks xds.RestCallbacks -} - -// AdaptRestCallbacks translate dubbo callbacks to real go-control-plane Callbacks -func AdaptRestCallbacks(callbacks xds.RestCallbacks) envoy_xds.Callbacks { - return &adapterRestCallbacks{ - callbacks: callbacks, - } -} - -func (a *adapterRestCallbacks) OnFetchRequest(ctx context.Context, request *envoy_sd.DiscoveryRequest) error { - return a.callbacks.OnFetchRequest(ctx, &discoveryRequest{request}) -} - -func (a *adapterRestCallbacks) OnFetchResponse(request *envoy_sd.DiscoveryRequest, response *envoy_sd.DiscoveryResponse) { - a.callbacks.OnFetchResponse(&discoveryRequest{request}, &discoveryResponse{response}) -} - -// Both rest and stream - -type adapterMultiCallbacks struct { - NoopCallbacks - callbacks xds.MultiCallbacks -} - -// AdaptMultiCallbacks translate dubbo callbacks to real go-control-plane Callbacks -func AdaptMultiCallbacks(callbacks xds.MultiCallbacks) envoy_xds.Callbacks { - return &adapterMultiCallbacks{ - callbacks: callbacks, - } -} - -func (a *adapterMultiCallbacks) OnFetchRequest(ctx context.Context, request *envoy_sd.DiscoveryRequest) error { - return a.callbacks.OnFetchRequest(ctx, &discoveryRequest{request}) -} - -func (a *adapterMultiCallbacks) OnFetchResponse(request *envoy_sd.DiscoveryRequest, response *envoy_sd.DiscoveryResponse) { - a.callbacks.OnFetchResponse(&discoveryRequest{request}, &discoveryResponse{response}) -} - -func (a *adapterMultiCallbacks) OnStreamOpen(ctx context.Context, streamID int64, typeURL string) error { - return a.callbacks.OnStreamOpen(ctx, streamID, typeURL) -} - -func (a *adapterMultiCallbacks) OnStreamClosed(streamID int64, _ *envoy_core.Node) { - a.callbacks.OnStreamClosed(streamID) -} - -func (a *adapterMultiCallbacks) OnStreamRequest(streamID int64, request *envoy_sd.DiscoveryRequest) error { - return a.callbacks.OnStreamRequest(streamID, &discoveryRequest{request}) -} - -func (a *adapterMultiCallbacks) OnStreamResponse(ctx context.Context, streamID int64, request *envoy_sd.DiscoveryRequest, response *envoy_sd.DiscoveryResponse) { - a.callbacks.OnStreamResponse(streamID, &discoveryRequest{request}, &discoveryResponse{response}) -} - -// DiscoveryRequest facade - -type discoveryRequest struct { - *envoy_sd.DiscoveryRequest -} - -func (d *discoveryRequest) Metadata() *structpb.Struct { - return d.GetNode().GetMetadata() -} - -func (d *discoveryRequest) VersionInfo() string { - return d.GetVersionInfo() -} - -func (d *discoveryRequest) NodeId() string { - return d.GetNode().GetId() -} - -func (d *discoveryRequest) Node() interface{} { - return d.GetNode() -} - -func (d *discoveryRequest) HasErrors() bool { - return d.ErrorDetail != nil -} - -func (d *discoveryRequest) ErrorMsg() string { - return d.GetErrorDetail().GetMessage() -} - -func (d *discoveryRequest) ResourceNames() []string { - return d.GetResourceNames() -} - -var _ xds.DiscoveryRequest = &discoveryRequest{} - -type discoveryResponse struct { - *envoy_sd.DiscoveryResponse -} - -func (d *discoveryResponse) VersionInfo() string { - return d.GetVersionInfo() -} - -type deltaDiscoveryRequest struct { - *envoy_sd.DeltaDiscoveryRequest -} - -func (d *deltaDiscoveryRequest) Metadata() *structpb.Struct { - return d.GetNode().GetMetadata() -} - -func (d *deltaDiscoveryRequest) NodeId() string { - return d.GetNode().GetId() -} - -func (d *deltaDiscoveryRequest) Node() interface{} { - return d.GetNode() -} - -func (d *deltaDiscoveryRequest) HasErrors() bool { - return d.ErrorDetail != nil -} - -func (d *deltaDiscoveryRequest) ErrorMsg() string { - return d.GetErrorDetail().GetMessage() -} - -func (d *deltaDiscoveryRequest) ResourceNames() []string { - return d.GetResourceNamesSubscribe() -} - -func (d *deltaDiscoveryRequest) GetInitialResourceVersions() map[string]string { - return d.InitialResourceVersions -} - -var _ xds.DeltaDiscoveryRequest = &deltaDiscoveryRequest{} - -type deltaDiscoveryResponse struct { - *envoy_sd.DeltaDiscoveryResponse -} - -var _ xds.DeltaDiscoveryResponse = &deltaDiscoveryResponse{} - -func (d *deltaDiscoveryResponse) GetTypeUrl() string { - return d.TypeUrl -} diff --git a/pkg/common/util/xds/v3/callbacks_chain.go b/pkg/common/util/xds/v3/callbacks_chain.go deleted file mode 100644 index e95160c35..000000000 --- a/pkg/common/util/xds/v3/callbacks_chain.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "context" - - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_sd "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" -) - -type CallbacksChain []envoy_xds.Callbacks - -var _ envoy_xds.Callbacks = CallbacksChain{} - -// OnStreamOpen is called once an xDS stream is open with a stream ID and the type URL (or "" for ADS). -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (chain CallbacksChain) OnStreamOpen(ctx context.Context, streamID int64, typ string) error { - for _, cb := range chain { - if err := cb.OnStreamOpen(ctx, streamID, typ); err != nil { - return err - } - } - return nil -} - -// OnStreamClosed is called immediately prior to closing an xDS stream with a stream ID. -func (chain CallbacksChain) OnStreamClosed(streamID int64, node *envoy_core.Node) { - for i := len(chain) - 1; i >= 0; i-- { - cb := chain[i] - cb.OnStreamClosed(streamID, node) - } -} - -// OnStreamRequest is called once a request is received on a stream. -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (chain CallbacksChain) OnStreamRequest(streamID int64, req *envoy_sd.DiscoveryRequest) error { - for _, cb := range chain { - if err := cb.OnStreamRequest(streamID, req); err != nil { - return err - } - } - return nil -} - -// OnStreamResponse is called immediately prior to sending a response on a stream. -func (chain CallbacksChain) OnStreamResponse(ctx context.Context, streamID int64, req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - for i := len(chain) - 1; i >= 0; i-- { - cb := chain[i] - cb.OnStreamResponse(ctx, streamID, req, resp) - } -} - -// OnFetchRequest is called for each Fetch request. Returning an error will end processing of the -// request and respond with an error. -func (chain CallbacksChain) OnFetchRequest(ctx context.Context, req *envoy_sd.DiscoveryRequest) error { - for _, cb := range chain { - if err := cb.OnFetchRequest(ctx, req); err != nil { - return err - } - } - return nil -} - -// OnFetchRequest is called for each Fetch request. Returning an error will end processing of the -// request and respond with an error. -// OnFetchResponse is called immediately prior to sending a response. -func (chain CallbacksChain) OnFetchResponse(req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - for i := len(chain) - 1; i >= 0; i-- { - cb := chain[i] - cb.OnFetchResponse(req, resp) - } -} - -func (chain CallbacksChain) OnDeltaStreamOpen(ctx context.Context, streamID int64, typeURL string) error { - for _, cb := range chain { - if err := cb.OnDeltaStreamOpen(ctx, streamID, typeURL); err != nil { - return err - } - } - - return nil -} - -func (chain CallbacksChain) OnDeltaStreamClosed(streamID int64, node *envoy_core.Node) { - for i := len(chain) - 1; i >= 0; i-- { - cb := chain[i] - cb.OnDeltaStreamClosed(streamID, node) - } -} - -func (chain CallbacksChain) OnStreamDeltaRequest(streamID int64, request *envoy_sd.DeltaDiscoveryRequest) error { - for _, cb := range chain { - if err := cb.OnStreamDeltaRequest(streamID, request); err != nil { - return err - } - } - - return nil -} - -func (chain CallbacksChain) OnStreamDeltaResponse(streamID int64, request *envoy_sd.DeltaDiscoveryRequest, response *envoy_sd.DeltaDiscoveryResponse) { - for i := len(chain) - 1; i >= 0; i-- { - cb := chain[i] - cb.OnStreamDeltaResponse(streamID, request, response) - } -} diff --git a/pkg/common/util/xds/v3/callbacks_chain_test.go b/pkg/common/util/xds/v3/callbacks_chain_test.go deleted file mode 100644 index 9f1c90681..000000000 --- a/pkg/common/util/xds/v3/callbacks_chain_test.go +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3_test - -import ( - "context" - "fmt" - - util_xds_v3 "github.com/apache/dubbo-admin/pkg/common/util/xds/v3" - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_sd "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("CallbacksChain", func() { - var first, second CallbacksFuncs - - type methodCall struct { - obj string - method string - args []interface{} - } - var calls []methodCall - - BeforeEach(func() { - calls = make([]methodCall, 0) - first = CallbacksFuncs{ - OnStreamOpenFunc: func(ctx context.Context, streamID int64, typ string) error { - calls = append(calls, methodCall{"1st", "OnStreamOpen()", []interface{}{ctx, streamID, typ}}) - return fmt.Errorf("1st: OnStreamOpen()") - }, - OnStreamClosedFunc: func(streamID int64, n *envoy_core.Node) { - calls = append(calls, methodCall{"1st", "OnStreamClosed()", []interface{}{streamID, n}}) - }, - OnStreamRequestFunc: func(streamID int64, req *envoy_sd.DiscoveryRequest) error { - calls = append(calls, methodCall{"1st", "OnStreamRequest()", []interface{}{streamID, req}}) - return fmt.Errorf("1st: OnStreamRequest()") - }, - OnStreamResponseFunc: func(ctx context.Context, streamID int64, req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - calls = append(calls, methodCall{"1st", "OnStreamResponse()", []interface{}{ctx, streamID, req, resp}}) - }, - } - second = CallbacksFuncs{ - OnStreamOpenFunc: func(ctx context.Context, streamID int64, typ string) error { - calls = append(calls, methodCall{"2nd", "OnStreamOpen()", []interface{}{ctx, streamID, typ}}) - return fmt.Errorf("2nd: OnStreamOpen()") - }, - OnStreamClosedFunc: func(streamID int64, n *envoy_core.Node) { - calls = append(calls, methodCall{"2nd", "OnStreamClosed()", []interface{}{streamID, n}}) - }, - OnStreamRequestFunc: func(streamID int64, req *envoy_sd.DiscoveryRequest) error { - calls = append(calls, methodCall{"2nd", "OnStreamRequest()", []interface{}{streamID, req}}) - return fmt.Errorf("2nd: OnStreamRequest()") - }, - OnStreamResponseFunc: func(ctx context.Context, streamID int64, req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - calls = append(calls, methodCall{"2nd", "OnStreamResponse()", []interface{}{ctx, streamID, req, resp}}) - }, - } - }) - - Describe("OnStreamOpen", func() { - It("should be called sequentially and return after first error", func() { - // given - ctx := context.Background() - streamID := int64(1) - typ := "xDS" - // setup - chain := util_xds_v3.CallbacksChain{first, second} - - // when - err := chain.OnStreamOpen(ctx, streamID, typ) - - // then - Expect(calls).To(Equal([]methodCall{ - {"1st", "OnStreamOpen()", []interface{}{ctx, streamID, typ}}, - })) - // and - Expect(err).To(MatchError("1st: OnStreamOpen()")) - }) - }) - Describe("OnStreamClose", func() { - It("should be called in reverse order", func() { - // given - streamID := int64(1) - n := &envoy_core.Node{Id: "my-node"} - // setup - chain := util_xds_v3.CallbacksChain{first, second} - - // when - chain.OnStreamClosed(streamID, n) - - // then - Expect(calls).To(Equal([]methodCall{ - {"2nd", "OnStreamClosed()", []interface{}{streamID, n}}, - {"1st", "OnStreamClosed()", []interface{}{streamID, n}}, - })) - }) - }) - Describe("OnStreamRequest", func() { - It("should be called sequentially and return after first error", func() { - // given - streamID := int64(1) - req := &envoy_sd.DiscoveryRequest{} - - // setup - chain := util_xds_v3.CallbacksChain{first, second} - - // when - err := chain.OnStreamRequest(streamID, req) - - // then - Expect(calls).To(Equal([]methodCall{ - {"1st", "OnStreamRequest()", []interface{}{streamID, req}}, - })) - // and - Expect(err).To(MatchError("1st: OnStreamRequest()")) - }) - }) - Describe("OnStreamResponse", func() { - It("should be called in reverse order", func() { - // given - chain := util_xds_v3.CallbacksChain{first, second} - streamID := int64(1) - req := &envoy_sd.DiscoveryRequest{} - resp := &envoy_sd.DiscoveryResponse{} - ctx := context.TODO() - - // when - chain.OnStreamResponse(ctx, streamID, req, resp) - - // then - Expect(calls).To(Equal([]methodCall{ - {"2nd", "OnStreamResponse()", []interface{}{ctx, streamID, req, resp}}, - {"1st", "OnStreamResponse()", []interface{}{ctx, streamID, req, resp}}, - })) - }) - }) -}) - -var _ envoy_xds.Callbacks = CallbacksFuncs{} - -type CallbacksFuncs struct { - OnStreamOpenFunc func(context.Context, int64, string) error - OnStreamClosedFunc func(int64, *envoy_core.Node) - - OnStreamRequestFunc func(int64, *envoy_sd.DiscoveryRequest) error - OnStreamResponseFunc func(context.Context, int64, *envoy_sd.DiscoveryRequest, *envoy_sd.DiscoveryResponse) - - OnFetchRequestFunc func(context.Context, *envoy_sd.DiscoveryRequest) error - OnFetchResponseFunc func(*envoy_sd.DiscoveryRequest, *envoy_sd.DiscoveryResponse) -} - -func (f CallbacksFuncs) OnStreamOpen(ctx context.Context, streamID int64, typ string) error { - if f.OnStreamOpenFunc != nil { - return f.OnStreamOpenFunc(ctx, streamID, typ) - } - return nil -} - -func (f CallbacksFuncs) OnStreamClosed(streamID int64, n *envoy_core.Node) { - if f.OnStreamClosedFunc != nil { - f.OnStreamClosedFunc(streamID, n) - } -} - -func (f CallbacksFuncs) OnStreamRequest(streamID int64, req *envoy_sd.DiscoveryRequest) error { - if f.OnStreamRequestFunc != nil { - return f.OnStreamRequestFunc(streamID, req) - } - return nil -} - -func (f CallbacksFuncs) OnStreamResponse(ctx context.Context, streamID int64, req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - if f.OnStreamResponseFunc != nil { - f.OnStreamResponseFunc(ctx, streamID, req, resp) - } -} - -func (f CallbacksFuncs) OnFetchRequest(ctx context.Context, req *envoy_sd.DiscoveryRequest) error { - if f.OnFetchRequestFunc != nil { - return f.OnFetchRequestFunc(ctx, req) - } - return nil -} - -func (f CallbacksFuncs) OnFetchResponse(req *envoy_sd.DiscoveryRequest, resp *envoy_sd.DiscoveryResponse) { - if f.OnFetchResponseFunc != nil { - f.OnFetchResponseFunc(req, resp) - } -} - -func (f CallbacksFuncs) OnDeltaStreamOpen(ctx context.Context, i int64, s string) error { - return nil -} - -func (f CallbacksFuncs) OnDeltaStreamClosed(i int64, n *envoy_core.Node) { -} - -func (f CallbacksFuncs) OnStreamDeltaRequest(i int64, request *envoy_sd.DeltaDiscoveryRequest) error { - return nil -} - -func (f CallbacksFuncs) OnStreamDeltaResponse(i int64, request *envoy_sd.DeltaDiscoveryRequest, response *envoy_sd.DeltaDiscoveryResponse) { -} diff --git a/pkg/common/util/xds/v3/control_plane_id_callbacks.go b/pkg/common/util/xds/v3/control_plane_id_callbacks.go deleted file mode 100644 index a8a6e2273..000000000 --- a/pkg/common/util/xds/v3/control_plane_id_callbacks.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "context" - - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" -) - -// controlPlaneIdCallbacks adds Control Plane ID to the DiscoveryResponse -type controlPlaneIdCallbacks struct { - NoopCallbacks - id string -} - -var _ envoy_xds.Callbacks = &controlPlaneIdCallbacks{} - -func NewControlPlaneIdCallbacks(id string) envoy_xds.Callbacks { - return &controlPlaneIdCallbacks{ - id: id, - } -} - -func (c *controlPlaneIdCallbacks) OnStreamResponse(ctx context.Context, streamID int64, request *envoy_discovery.DiscoveryRequest, response *envoy_discovery.DiscoveryResponse) { - if c.id != "" { - response.ControlPlane = &envoy_core.ControlPlane{ - Identifier: c.id, - } - } -} - -func (c *controlPlaneIdCallbacks) OnStreamDeltaResponse(streamID int64, request *envoy_discovery.DeltaDiscoveryRequest, response *envoy_discovery.DeltaDiscoveryResponse) { - if c.id != "" { - response.ControlPlane = &envoy_core.ControlPlane{ - Identifier: c.id, - } - } -} diff --git a/pkg/common/util/xds/v3/noop_callbacks.go b/pkg/common/util/xds/v3/noop_callbacks.go deleted file mode 100644 index 8e8d30bf4..000000000 --- a/pkg/common/util/xds/v3/noop_callbacks.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "context" - - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_sd "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" -) - -type NoopCallbacks struct{} - -func (c *NoopCallbacks) OnFetchRequest(context.Context, *envoy_sd.DiscoveryRequest) error { - return nil -} - -func (c *NoopCallbacks) OnFetchResponse(*envoy_sd.DiscoveryRequest, *envoy_sd.DiscoveryResponse) { -} - -func (c *NoopCallbacks) OnStreamOpen(context.Context, int64, string) error { - return nil -} - -func (c *NoopCallbacks) OnStreamClosed(int64, *envoy_core.Node) { -} - -func (c *NoopCallbacks) OnStreamRequest(int64, *envoy_sd.DiscoveryRequest) error { - return nil -} - -func (c *NoopCallbacks) OnStreamResponse(context.Context, int64, *envoy_sd.DiscoveryRequest, *envoy_sd.DiscoveryResponse) { -} - -func (c *NoopCallbacks) OnDeltaStreamOpen(ctx context.Context, i int64, s string) error { - return nil -} - -func (c *NoopCallbacks) OnDeltaStreamClosed(int64, *envoy_core.Node) { -} - -func (c *NoopCallbacks) OnStreamDeltaRequest(i int64, request *envoy_sd.DeltaDiscoveryRequest) error { - return nil -} - -func (c *NoopCallbacks) OnStreamDeltaResponse(i int64, request *envoy_sd.DeltaDiscoveryRequest, response *envoy_sd.DeltaDiscoveryResponse) { -} - -var _ envoy_xds.Callbacks = &NoopCallbacks{} diff --git a/pkg/common/util/xds/v3/versioner.go b/pkg/common/util/xds/v3/versioner.go deleted file mode 100644 index 4aa23d849..000000000 --- a/pkg/common/util/xds/v3/versioner.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - envoy_types "github.com/envoyproxy/go-control-plane/pkg/cache/types" - - "google.golang.org/protobuf/proto" -) - -// SnapshotVersioner assigns versions to xDS resources in a new Snapshot. -type SnapshotVersioner interface { - Version(new, old Snapshot) Snapshot -} - -// SnapshotAutoVersioner assigns versions to xDS resources in a new Snapshot -// by reusing if possible a version from the old snapshot and -// generating a new version (UUID) otherwise. -type SnapshotAutoVersioner struct { - UUID func() string -} - -func (v SnapshotAutoVersioner) Version(new, old Snapshot) Snapshot { - if new == nil { - return nil - } - for _, typ := range new.GetSupportedTypes() { - version := new.GetVersion(typ) - if version != "" { - // favor a version assigned by resource generator - continue - } - if old != nil && v.equal(new.GetResources(typ), old.GetResources(typ)) { - version = old.GetVersion(typ) - } - if version == "" { - version = v.UUID() - } - new = new.WithVersion(typ, version) - } - return new -} - -func (_ SnapshotAutoVersioner) equal(new, old map[string]envoy_types.Resource) bool { - if len(new) != len(old) { - return false - } - for key, newValue := range new { - if oldValue, hasOldValue := old[key]; !hasOldValue || !proto.Equal(newValue, oldValue) { - return false - } - } - return true -} diff --git a/pkg/common/util/xds/v3/watchdog_callbacks.go b/pkg/common/util/xds/v3/watchdog_callbacks.go deleted file mode 100644 index 37c3a4655..000000000 --- a/pkg/common/util/xds/v3/watchdog_callbacks.go +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package v3 - -import ( - "context" - "sync" - - envoy_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - envoy_xds "github.com/envoyproxy/go-control-plane/pkg/server/v3" - - util_watchdog "github.com/apache/dubbo-admin/pkg/common/util/watchdog" -) - -type NewNodeWatchdogFunc func(ctx context.Context, node *envoy_core.Node, streamId int64) (util_watchdog.Watchdog, error) - -func NewWatchdogCallbacks(newNodeWatchdog NewNodeWatchdogFunc) envoy_xds.Callbacks { - return &watchdogCallbacks{ - newNodeWatchdog: newNodeWatchdog, - streams: make(map[int64]watchdogStreamState), - } -} - -type watchdogCallbacks struct { - NoopCallbacks - newNodeWatchdog NewNodeWatchdogFunc - - mu sync.RWMutex // protects access to the fields below - streams map[int64]watchdogStreamState -} - -type watchdogStreamState struct { - context context.Context - cancel context.CancelFunc -} - -var _ envoy_xds.Callbacks = &watchdogCallbacks{} - -// RestStreamID is used in the non-streaming REST context -const RestStreamID = int64(-1) - -func (cb *watchdogCallbacks) hasStream(streamID int64) bool { - cb.mu.RLock() // read access to the map of all ADS streams - defer cb.mu.RUnlock() - _, ok := cb.streams[streamID] - return ok -} - -func (cb *watchdogCallbacks) OnFetchRequest(ctx context.Context, req *envoy_discovery.DiscoveryRequest) error { - // Open up a new "stream" state, which all REST requests use, if one doesn't already exist - if cb.hasStream(RestStreamID) { - return nil - } - - if err := cb.OnStreamOpen(ctx, RestStreamID, req.TypeUrl); err != nil { - return err - } - // TODO: could also register a TTL on the REST stream to clean it up if there is no activity over a certain period, - // since it will currently never be closed once opened - return cb.OnStreamRequest(RestStreamID, req) -} - -// OnStreamOpen is called once an xDS stream is open with a stream ID and the type URL (or "" for ADS). -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (cb *watchdogCallbacks) OnStreamOpen(ctx context.Context, streamID int64, typ string) error { - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - cb.streams[streamID] = watchdogStreamState{ - context: ctx, - } - - return nil -} - -// OnStreamClosed is called immediately prior to closing an xDS stream with a stream ID. -func (cb *watchdogCallbacks) OnStreamClosed(streamID int64, node *envoy_core.Node) { - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - defer delete(cb.streams, streamID) - - if watchdog := cb.streams[streamID]; watchdog.cancel != nil { - watchdog.cancel() - } -} - -// OnStreamRequest is called once a request is received on a stream. -// Returning an error will end processing and close the stream. OnStreamClosed will still be called. -func (cb *watchdogCallbacks) OnStreamRequest(streamID int64, req *envoy_discovery.DiscoveryRequest) error { - cb.mu.RLock() // read access to the map of all ADS streams - watchdog := cb.streams[streamID] - cb.mu.RUnlock() - - if watchdog.cancel != nil { - return nil - } - - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - // create a stop channel even if there won't be an actual watchdog - stopCh := make(chan struct{}) - watchdog.cancel = func() { - close(stopCh) - } - cb.streams[streamID] = watchdog - - runnable, err := cb.newNodeWatchdog(watchdog.context, req.Node, streamID) - if err != nil { - return err - } - - if runnable != nil { - // kick off watchdog for that stream - go runnable.Start(stopCh) - } - return nil -} - -// OnDeltaStreamOpen is called once an xDS stream is open with a stream ID and the type URL (or "" for ADS). -// Returning an error will end processing and close the stream. OnDeltaStreamClosed will still be called. -func (cb *watchdogCallbacks) OnDeltaStreamOpen(ctx context.Context, streamID int64, typ string) error { - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - cb.streams[streamID] = watchdogStreamState{ - context: ctx, - } - - return nil -} - -// OnDeltaStreamClosed is called immediately prior to closing an xDS stream with a stream ID. -func (cb *watchdogCallbacks) OnDeltaStreamClosed(streamID int64, node *envoy_core.Node) { - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - defer delete(cb.streams, streamID) - - if watchdog := cb.streams[streamID]; watchdog.cancel != nil { - watchdog.cancel() - } -} - -// OnStreamDeltaRequest is called once a request is received on a stream. -// Returning an error will end processing and close the stream. OnDeltaStreamClosed will still be called. -func (cb *watchdogCallbacks) OnStreamDeltaRequest(streamID int64, req *envoy_discovery.DeltaDiscoveryRequest) error { - cb.mu.RLock() // read access to the map of all ADS streams - watchdog := cb.streams[streamID] - cb.mu.RUnlock() - - if watchdog.cancel != nil { - return nil - } - - cb.mu.Lock() // write access to the map of all ADS streams - defer cb.mu.Unlock() - - // create a stop channel even if there won't be an actual watchdog - stopCh := make(chan struct{}) - watchdog.cancel = func() { - close(stopCh) - } - cb.streams[streamID] = watchdog - - runnable, err := cb.newNodeWatchdog(watchdog.context, req.Node, streamID) - if err != nil { - return err - } - - if runnable != nil { - // kick off watchdog for that stream - go runnable.Start(stopCh) - } - return nil -} diff --git a/pkg/common/util/yaml/split.go b/pkg/common/util/yaml/split.go deleted file mode 100644 index ed5f76b7c..000000000 --- a/pkg/common/util/yaml/split.go +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package yaml - -import ( - "regexp" - "strings" -) - -var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*") - -// SplitYAML takes YAMLs separated by `---` line and splits it into multiple YAMLs. Empty entries are ignored -func SplitYAML(yamls string) []string { - var result []string - // Making sure that any extra whitespace in YAML stream doesn't interfere in splitting documents correctly. - trimYAMLs := strings.TrimSpace(yamls) - docs := sep.Split(trimYAMLs, -1) - for _, doc := range docs { - if doc == "" { - continue - } - doc = strings.TrimSpace(doc) - result = append(result, doc) - } - return result -} diff --git a/pkg/common/validators/common_validators.go b/pkg/common/validators/common_validators.go deleted file mode 100644 index 1f55ad0c7..000000000 --- a/pkg/common/validators/common_validators.go +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package validators - -import ( - "fmt" - "math" - "regexp" - "time" - - "github.com/asaskevich/govalidator" - k8s "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func ValidateDurationNotNegative(path PathBuilder, duration *k8s.Duration) ValidationError { - var err ValidationError - if duration == nil { - err.AddViolationAt(path, MustBeDefined) - return err - } - if duration.Duration < 0 { - err.AddViolationAt(path, WhenDefinedHasToBeNonNegative) - } - return err -} - -func ValidateDurationNotNegativeOrNil(path PathBuilder, duration *k8s.Duration) ValidationError { - var err ValidationError - if duration == nil { - return err - } - - if duration.Duration < 0 { - err.AddViolationAt(path, WhenDefinedHasToBeNonNegative) - } - - return err -} - -func ValidateDurationGreaterThanZero(path PathBuilder, duration k8s.Duration) ValidationError { - var err ValidationError - if duration.Duration <= 0 { - err.AddViolationAt(path, MustBeDefinedAndGreaterThanZero) - } - return err -} - -func ValidateDurationGreaterThanZeroOrNil(path PathBuilder, duration *k8s.Duration) ValidationError { - var err ValidationError - if duration == nil { - return err - } - - if duration.Duration <= 0 { - err.AddViolationAt(path, WhenDefinedHasToBeGreaterThanZero) - } - - return err -} - -func ValidateValueGreaterThanZero(path PathBuilder, value int32) ValidationError { - var err ValidationError - if value <= 0 { - err.AddViolationAt(path, MustBeDefinedAndGreaterThanZero) - } - return err -} - -func ValidateValueGreaterThanZeroOrNil(path PathBuilder, value *int32) ValidationError { - var err ValidationError - if value == nil { - return err - } - if *value <= 0 { - err.AddViolationAt(path, WhenDefinedHasToBeGreaterThanZero) - } - return err -} - -func ValidateIntPercentageOrNil(path PathBuilder, percentage *int32) ValidationError { - var err ValidationError - if percentage == nil { - return err - } - - if *percentage < 0 || *percentage > 100 { - err.AddViolationAt(path, HasToBeInUintPercentageRange) - } - - return err -} - -func ValidateUInt32PercentageOrNil(path PathBuilder, percentage *uint32) ValidationError { - var err ValidationError - if percentage == nil { - return err - } - - if *percentage > 100 { - err.AddViolationAt(path, HasToBeInUintPercentageRange) - } - - return err -} - -func ValidateStringDefined(path PathBuilder, value string) ValidationError { - var err ValidationError - if value == "" { - err.AddViolationAt(path, MustBeDefined) - } - - return err -} - -func ValidatePathOrNil(path PathBuilder, filePath *string) ValidationError { - var err ValidationError - if filePath == nil { - return err - } - - isFilePath, _ := govalidator.IsFilePath(*filePath) - if !isFilePath { - err.AddViolationAt(path, WhenDefinedHasToBeValidPath) - } - - return err -} - -func ValidateStatusCode(path PathBuilder, status int32) ValidationError { - var err ValidationError - if status < 100 || status >= 600 { - err.AddViolationAt(path, fmt.Sprintf(HasToBeInRangeFormat, 100, 599)) - } - - return err -} - -func ValidateDurationGreaterThan(path PathBuilder, duration *k8s.Duration, minDuration time.Duration) ValidationError { - var err ValidationError - if duration == nil { - err.AddViolationAt(path, MustBeDefined) - return err - } - - if duration.Duration <= minDuration { - err.AddViolationAt(path, fmt.Sprintf("%s: %s", HasToBeGreaterThan, minDuration)) - } - - return err -} - -func ValidateIntegerGreaterThanZeroOrNil(path PathBuilder, value *uint32) ValidationError { - var err ValidationError - if value == nil { - return err - } - - return ValidateIntegerGreaterThan(path, *value, 0) -} - -func ValidateIntegerGreaterThan(path PathBuilder, value uint32, minValue uint32) ValidationError { - var err ValidationError - if value <= minValue { - err.AddViolationAt(path, fmt.Sprintf("%s %d", HasToBeGreaterThan, minValue)) - } - - return err -} - -var BandwidthRegex = regexp.MustCompile(`(\d*)\s?([GMk]?bps)`) - -func ValidateBandwidth(path PathBuilder, value string) ValidationError { - var err ValidationError - if value == "" { - err.AddViolationAt(path, MustBeDefined) - return err - } - if matched := BandwidthRegex.MatchString(value); !matched { - err.AddViolationAt(path, MustHaveBPSUnit) - } - return err -} - -func ValidateNil[T any](path PathBuilder, t *T, msg string) ValidationError { - var err ValidationError - if t != nil { - err.AddViolationAt(path, msg) - } - return err -} - -func ValidatePort(path PathBuilder, value uint32) ValidationError { - var err ValidationError - if value == 0 || value > math.MaxUint16 { - err.AddViolationAt(path, "port must be a valid (1-65535)") - } - return err -} diff --git a/pkg/common/validators/messages.go b/pkg/common/validators/messages.go deleted file mode 100644 index e8c96d9a6..000000000 --- a/pkg/common/validators/messages.go +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package validators - -import ( - "fmt" - "strings" -) - -const ( - HasToBeGreaterThan = "must be greater than" - HasToBeLessThan = "must be less than" - HasToBeGreaterOrEqualThen = "must be greater or equal then" - HasToBeGreaterThanZero = "must be greater than 0" - MustNotBeEmpty = "must not be empty" - MustBeDefined = "must be defined" - MustBeSet = "must be set" - MustNotBeSet = "must not be set" - MustNotBeDefined = "must not be defined" - MustBeDefinedAndGreaterThanZero = "must be defined and greater than zero" - WhenDefinedHasToBeNonNegative = "must not be negative when defined" - WhenDefinedHasToBeGreaterThanZero = "must be greater than zero when defined" - HasToBeInRangeFormat = "must be in inclusive range [%v, %v]" - WhenDefinedHasToBeValidPath = "must be a valid path when defined" - StringHasToBeValidNumber = "string must be a valid number" - MustHaveBPSUnit = "must be in kbps/Mbps/Gbps units" -) - -var ( - HasToBeInPercentageRange = fmt.Sprintf(HasToBeInRangeFormat, "0.0", "100.0") - HasToBeInUintPercentageRange = fmt.Sprintf(HasToBeInRangeFormat, 0, 100) -) - -func MustHaveOnlyOne(entity string, allowedValues ...string) string { - return fmt.Sprintf(`%s must have only one type defined: %s`, entity, strings.Join(allowedValues, ", ")) -} - -func MustHaveExactlyOneOf(entity string, allowedValues ...string) string { - return fmt.Sprintf(`%s must have exactly one defined: %s`, entity, strings.Join(allowedValues, ", ")) -} - -func MustHaveAtLeastOne(allowedValues ...string) string { - return fmt.Sprintf(`must have at least one defined: %s`, strings.Join(allowedValues, ", ")) -} diff --git a/pkg/common/validators/types.go b/pkg/common/validators/types.go deleted file mode 100644 index 6ca9c729d..000000000 --- a/pkg/common/validators/types.go +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package validators - -import ( - "fmt" - "strings" -) - -type ValidationError struct { - Violations []Violation `json:"violations"` -} - -type Violation struct { - Field string `json:"field"` - Message string `json:"message"` -} - -// OK returns and empty validation error (i.e. success). -func OK() ValidationError { - return ValidationError{} -} - -func (v *ValidationError) Error() string { - msg := "" - for _, violation := range v.Violations { - if msg != "" { - msg = fmt.Sprintf("%s; %s: %s", msg, violation.Field, violation.Message) - } else { - msg += fmt.Sprintf("%s: %s", violation.Field, violation.Message) - } - } - return msg -} - -func (v *ValidationError) HasViolations() bool { - return len(v.Violations) > 0 -} - -func (v *ValidationError) OrNil() error { - if v.HasViolations() { - return v - } - return nil -} - -func (v *ValidationError) AddViolationAt(path PathBuilder, message string) { - v.AddViolation(path.String(), message) -} - -func (v *ValidationError) AddViolation(field string, message string) { - violation := Violation{ - Field: field, - Message: message, - } - v.Violations = append(v.Violations, violation) -} - -func (v *ValidationError) AddErrorAt(path PathBuilder, validationErr ValidationError) { - for _, violation := range validationErr.Violations { - field := Root() - if violation.Field != "" { - field = RootedAt(violation.Field) - } - newViolation := Violation{ - Field: path.concat(field).String(), - Message: violation.Message, - } - v.Violations = append(v.Violations, newViolation) - } -} - -func (v *ValidationError) Add(err ValidationError) { - v.AddErrorAt(Root(), err) -} - -func (v *ValidationError) AddError(rootField string, validationErr ValidationError) { - root := Root() - if rootField != "" { - root = RootedAt(rootField) - } - v.AddErrorAt(root, validationErr) -} - -// Transform returns a new ValidationError with every violation -// transformed by a given transformFunc. -func (v *ValidationError) Transform(transformFunc func(Violation) Violation) *ValidationError { - if v == nil { - return nil - } - if transformFunc == nil || len(v.Violations) == 0 { - rv := *v - return &rv - } - result := ValidationError{ - Violations: make([]Violation, len(v.Violations)), - } - for i := range v.Violations { - result.Violations[i] = transformFunc(v.Violations[i]) - } - return &result -} - -func MakeUnimplementedFieldErr(path PathBuilder) ValidationError { - var err ValidationError - err.AddViolationAt(path, "field is not implemented") - return err -} - -func MakeRequiredFieldErr(path PathBuilder) ValidationError { - var err ValidationError - err.AddViolationAt(path, "cannot be empty") - return err -} - -func MakeOneOfErr(fieldA, fieldB, msg string, oneOf []string) ValidationError { - var err ValidationError - var quoted []string - - for _, value := range oneOf { - quoted = append(quoted, fmt.Sprintf("%q", value)) - } - - message := fmt.Sprintf( - "%q %s one of [%s]", - fieldA, - msg, - strings.Join(quoted, ", "), - ) - - if fieldB != "" { - message = fmt.Sprintf( - "%q %s when %q is one of [%s]", - fieldA, - msg, - fieldB, - strings.Join(quoted, ", "), - ) - } - - err.AddViolationAt(Root(), message) - - return err -} - -func MakeFieldMustBeOneOfErr(field string, allowed ...string) ValidationError { - return MakeOneOfErr(field, "", "must be", allowed) -} - -func IsValidationError(err error) bool { - _, ok := err.(*ValidationError) - return ok -} - -type PathBuilder []string - -func RootedAt(name string) PathBuilder { - return PathBuilder{name} -} - -func Root() PathBuilder { - return PathBuilder{} -} - -func (p PathBuilder) Field(name string) PathBuilder { - element := name - if len(p) > 0 { - element = fmt.Sprintf(".%s", element) - } - return append(p, element) -} - -func (p PathBuilder) Index(index int) PathBuilder { - return append(p, fmt.Sprintf("[%d]", index)) -} - -func (p PathBuilder) Key(key string) PathBuilder { - return append(p, fmt.Sprintf("[%q]", key)) -} - -func (p PathBuilder) String() string { - return strings.Join(p, "") -} - -func (p PathBuilder) concat(other PathBuilder) PathBuilder { - if len(other) == 0 { - return p - } - if len(p) == 0 { - return other - } - - firstOther := other[0] - if !strings.HasPrefix(firstOther, "[") { - firstOther = "." + firstOther - } - - return append(append(p, firstOther), other[1:]...) -} diff --git a/pkg/config/app/admin.go b/pkg/config/app/admin.go index 3d4722ed2..61e3fb196 100644 --- a/pkg/config/app/admin.go +++ b/pkg/config/app/admin.go @@ -18,82 +18,187 @@ package app import ( - "github.com/pkg/errors" + "github.com/duke-git/lancet/v2/slice" "go.uber.org/multierr" + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/config" "github.com/apache/dubbo-admin/pkg/config/console" "github.com/apache/dubbo-admin/pkg/config/diagnostics" "github.com/apache/dubbo-admin/pkg/config/discovery" "github.com/apache/dubbo-admin/pkg/config/engine" - "github.com/apache/dubbo-admin/pkg/config/mode" + "github.com/apache/dubbo-admin/pkg/config/eventbus" + "github.com/apache/dubbo-admin/pkg/config/log" + "github.com/apache/dubbo-admin/pkg/config/observability" "github.com/apache/dubbo-admin/pkg/config/store" ) type AdminConfig struct { config.BaseConfig - // Mode in which dubbo admin is running. Available values are: "test", "global", "zone" - Mode mode.Mode `json:"mode" envconfig:"DUBBO_MODE"` + // Log configuration + Log *log.Config `json:"log" yaml:"log"` // Diagnostics configuration - Diagnostics *diagnostics.Config `json:"diagnostics,omitempty"` + Diagnostics *diagnostics.Config `json:"diagnostics,omitempty" yaml:"diagnostics"` + // Observability configuration + Observability *observability.Config `json:"observability" yaml:"observability"` // Console configuration - Console *console.Config `json:"admin"` + Console *console.Config `json:"console" yaml:"console"` // Store configuration - Store *store.Config `json:"store"` + Store *store.Config `json:"store" yaml:"store"` // Discovery configuration - Discovery *discovery.Config `json:"discovery"` + Discovery []*discovery.Config `json:"discovery" yaml:"discovery"` // Engine configuration - Engine *engine.Config `json:"engine"` + Engine *engine.Config `json:"engine" yaml:"engine"` + // EventBus configuration + EventBus *eventbus.Config `json:"eventBus,omitempty" yaml:"eventBus,omitempty"` + // MCP configuration + MCP *MCPConfig `json:"mcp,omitempty" yaml:"mcp"` +} + +// MCPConfig MCP配置 +type MCPConfig struct { + // Enabled 是否启用MCP端点 + Enabled bool `json:"enabled" yaml:"enabled"` + // Path MCP端点路径,默认 /api/mcp + Path string `json:"path,omitempty" yaml:"path"` + // APIKey MCP API密钥,用于认证。如果为空则不需要认证 + APIKey string `json:"apiKey,omitempty" yaml:"apiKey"` } var _ = &AdminConfig{} -func (c *AdminConfig) Sanitize() { +var DefaultAdminConfig = func() AdminConfig { + eventBusCfg := eventbus.Default() + return AdminConfig{ + Log: log.DefaultLogConfig(), + Store: store.DefaultStoreConfig(), + Engine: engine.DefaultResourceEngineConfig(), + Observability: observability.DefaultObservabilityConfig(), + Diagnostics: diagnostics.DefaultDiagnosticsConfig(), + Console: console.DefaultConsoleConfig(), + EventBus: &eventBusCfg, + } +} + +func (c AdminConfig) Sanitize() { c.Engine.Sanitize() - c.Discovery.Sanitize() + for _, d := range c.Discovery { + d.Sanitize() + } c.Store.Sanitize() c.Console.Sanitize() + c.Observability.Sanitize() c.Diagnostics.Sanitize() + c.Log.Sanitize() } -func (c *AdminConfig) PostProcess() error { +func (c AdminConfig) PreProcess() error { + discoveryPreProcess := func() error { + for _, d := range c.Discovery { + if err := d.PreProcess(); err != nil { + return err + } + } + return nil + } + return multierr.Combine( + c.Engine.PreProcess(), + discoveryPreProcess(), + c.Store.PreProcess(), + c.Console.PreProcess(), + c.Observability.PreProcess(), + c.Diagnostics.PreProcess(), + c.Log.PreProcess(), + ) +} + +func (c AdminConfig) PostProcess() error { + discoveryPostProcess := func() error { + for _, d := range c.Discovery { + if err := d.PostProcess(); err != nil { + return err + } + } + return nil + } return multierr.Combine( c.Engine.PostProcess(), - c.Discovery.PostProcess(), + discoveryPostProcess(), c.Store.PostProcess(), c.Console.PostProcess(), + c.Observability.PostProcess(), c.Diagnostics.PostProcess(), + c.Log.PostProcess(), ) } -var DefaultAdminConfig = func() AdminConfig { - return AdminConfig{ - Mode: mode.Zone, - Store: store.DefaultStoreConfig(), - Engine: engine.DefaultResourceEngineConfig(), - Diagnostics: diagnostics.DefaultDiagnosticsConfig(), - Console: console.DefaultConsoleConfig(), - } -} - -func (c *AdminConfig) Validate() error { - if err := mode.ValidateMode(c.Mode); err != nil { - return errors.Wrap(err, "Mode Config validation failed") +func (c AdminConfig) Validate() error { + if c.Log == nil { + c.Log = log.DefaultLogConfig() + } else if err := c.Log.Validate(); err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, "log config validation failed") } if c.Store == nil { c.Store = store.DefaultStoreConfig() } else if err := c.Store.Validate(); err != nil { - return errors.Wrap(err, "Store Config validation failed") + return bizerror.Wrap(err, bizerror.ConfigError, "store config validation failed") } if c.Diagnostics == nil { c.Diagnostics = diagnostics.DefaultDiagnosticsConfig() } else if err := c.Diagnostics.Validate(); err != nil { - return errors.Wrap(err, "Diagnostics Config validation failed") + return bizerror.Wrap(err, bizerror.ConfigError, "diagnostics config validation failed") } if c.Console == nil { c.Console = console.DefaultConsoleConfig() } else if err := c.Console.Validate(); err != nil { - return errors.Wrap(err, "Admin validation failed") + return bizerror.Wrap(err, bizerror.ConfigError, "console config validation failed") + } + if c.Observability == nil { + c.Observability = observability.DefaultObservabilityConfig() + } else if err := c.Observability.Validate(); err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, "observability config validation failed") + } + if c.Discovery == nil || len(c.Discovery) == 0 { + return bizerror.New(bizerror.ConfigError, "discover config is needed") + } + for _, d := range c.Discovery { + if err := d.Validate(); err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, "discovery config validation failed") + } + } + discoveryIDList := slice.Map(c.Discovery, func(index int, item *discovery.Config) string { + return item.ID + }) + if len(discoveryIDList) != len(slice.Unique(discoveryIDList)) { + return bizerror.New(bizerror.ConfigError, "discovery id must be unique") + } + if c.Engine == nil { + c.Engine = engine.DefaultResourceEngineConfig() + } else if err := c.Engine.Validate(); err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, "engine config validation failed") + } + if c.EventBus == nil { + cfg := eventbus.Default() + c.EventBus = &cfg + } else if err := c.EventBus.Validate(); err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, "event bus config validation failed") } return nil } + +// FindDiscovery finds the DiscoveryConfig by id, returns nil if not found +func (c AdminConfig) FindDiscovery(id string) *discovery.Config { + for _, d := range c.Discovery { + if d.ID == id { + return d + } + } + return nil +} + +// Meshes return the mesh id list of discoveries +func (c AdminConfig) Meshes() []string { + return slice.Map(c.Discovery, func(index int, item *discovery.Config) string { + return item.ID + }) +} diff --git a/pkg/config/config.go b/pkg/config/base.go similarity index 100% rename from pkg/config/config.go rename to pkg/config/base.go diff --git a/pkg/config/console/config.go b/pkg/config/console/config.go index e9141aec8..d3d526856 100644 --- a/pkg/config/console/config.go +++ b/pkg/config/console/config.go @@ -18,54 +18,113 @@ package console import ( - "errors" + "fmt" + "net/url" - "go.uber.org/multierr" + set "github.com/duke-git/lancet/v2/datastructure/set" + "github.com/duke-git/lancet/v2/strutil" + "github.com/gin-gonic/gin" + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/config" "github.com/apache/dubbo-admin/pkg/config/console/auth" - . "github.com/apache/dubbo-admin/pkg/config/console/observability" +) + +type GinRunningMode string + +var supportedGinRunningMode = set.New(DebugMode, ReleaseMode, TestMode) + +const ( + DebugMode GinRunningMode = gin.DebugMode + ReleaseMode GinRunningMode = gin.ReleaseMode + TestMode GinRunningMode = gin.TestMode ) type Config struct { config.BaseConfig - Port int `json:"port" envconfig:"DUBBO_ADMIN_PORT"` - MetricDashboards *MetricDashboardConfig `json:"metricDashboards"` - TraceDashboards *TraceDashboardConfig `json:"traceDashboards"` - Prometheus string `json:"prometheus"` - Grafana string `json:"grafana"` - Auth *auth.Config `json:"auth"` -} - -func (s *Config) PostProcess() error { - return multierr.Combine( - s.MetricDashboards.PostProcess(), - s.TraceDashboards.PostProcess(), - ) + GinMode GinRunningMode `json:"ginMode" yaml:"ginMode"` + Port int `json:"port" yaml:"port"` + MetricDashboards *GrafanaDashboardConfig `json:"metricDashboards" yaml:"metricDashboards"` + TraceDashboards *GrafanaDashboardConfig `json:"traceDashboards" yaml:"traceDashboards"` + Auth *auth.Config `json:"auth" yaml:"auth"` } -func (s *Config) Validate() error { - if s.MetricDashboards != nil { - if err := s.MetricDashboards.Validate(); err != nil { +func (c *Config) Validate() error { + if !supportedGinRunningMode.Contain(c.GinMode) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("invalid gin mode: %s", c.GinMode)) + } + if c.Port < 1 || c.Port > 65535 { + return bizerror.New(bizerror.ConfigError, "port of console must between 1 to 65535") + } + if c.Auth == nil { + return bizerror.New(bizerror.ConfigError, "auth config is needed, but found empty") + } + if c.MetricDashboards != nil { + if err := c.MetricDashboards.Validate(); err != nil { return err } } - if s.TraceDashboards != nil { - if err := s.TraceDashboards.Validate(); err != nil { + if c.TraceDashboards != nil { + if err := c.TraceDashboards.Validate(); err != nil { return err } } - if s.Auth == nil { - return errors.New("auth config is needed, but found empty") - } - if err := s.Auth.Validate(); err != nil { + if err := c.Auth.Validate(); err != nil { return err } return nil } +type GrafanaDashboardConfig struct { + config.BaseConfig + // application level metrics panel + Application string `json:"application" yaml:"application"` + // instance level metrics panel + Instance string `json:"instance" yaml:"instance"` + // service level metrics panel + Service string `json:"service" yaml:"service"` + + AppDashboardURL *url.URL `json:"-" yaml:"-"` + InstanceDashboardURL *url.URL `json:"-" yaml:"-"` + ServiceDashboardURL *url.URL `json:"-" yaml:"-"` +} + +func (g *GrafanaDashboardConfig) Validate() error { + if strutil.IsNotBlank(g.Application) { + dashboardURL, err := url.Parse(g.Application) + if err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, + fmt.Sprintf("invalid application dashboard url: %s", g.Application)) + } + g.AppDashboardURL = dashboardURL + } + if strutil.IsNotBlank(g.Instance) { + dashboardURL, err := url.Parse(g.Instance) + if err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, + fmt.Sprintf("invalid instance dashboard url: %s", g.Instance)) + } + g.InstanceDashboardURL = dashboardURL + } + if strutil.IsNotBlank(g.Service) { + dashboardURL, err := url.Parse(g.Service) + if err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, + fmt.Sprintf("invalid service dashboard url: %s", g.Service)) + } + g.ServiceDashboardURL = dashboardURL + } + return nil +} + func DefaultConsoleConfig() *Config { return &Config{ - Port: 8888, + GinMode: ReleaseMode, + Port: 8888, + Auth: &auth.Config{ + User: "admin", + Password: "admin", + ExpirationTime: 3600, + }, } } diff --git a/pkg/config/console/observability/config.go b/pkg/config/console/observability/config.go deleted file mode 100644 index 2a926fda9..000000000 --- a/pkg/config/console/observability/config.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package observability - -import ( - "net/url" - "strings" - - "github.com/pkg/errors" - "go.uber.org/multierr" - - "github.com/apache/dubbo-admin/pkg/config" -) - -// MetricDashboardConfig are grafana dashboards for metrics display -type MetricDashboardConfig struct { - config.BaseConfig - // application level metrics panel - Application DashboardConfig `json:"application"` - // instance level metrics panel - Instance DashboardConfig `json:"instance"` - // service level metrics panel - Service DashboardConfig `json:"service"` -} - -func (c *MetricDashboardConfig) PostProcess() error { - return multierr.Combine( - c.Application.PostProcess(), - c.Instance.PostProcess(), - c.Service.PostProcess(), - ) -} - -func (c *MetricDashboardConfig) Validate() error { - return multierr.Combine( - c.Application.Validate(), - c.Instance.Validate(), - c.Service.Validate(), - ) -} - -// TraceDashboardConfig are grafana dashboards for traces display -type TraceDashboardConfig struct { - config.BaseConfig - // application level traces panel - Application DashboardConfig `json:"application"` - // instance level traces panel - Instance DashboardConfig `json:"instance"` - // service level traces panel - Service DashboardConfig `json:"service"` -} - -func (c *TraceDashboardConfig) PostProcess() error { - return multierr.Combine( - c.Application.PostProcess(), - c.Instance.PostProcess(), - c.Service.PostProcess(), - ) -} - -func (c *TraceDashboardConfig) Validate() error { - return multierr.Combine( - c.Application.Validate(), - c.Instance.Validate(), - c.Service.Validate(), - ) -} - -// DashboardConfig grafana dashboard config TODO add dynamic variables -type DashboardConfig struct { - config.BaseConfig - BaseURL string `json:"baseURL"` -} - -func (c *DashboardConfig) PostProcess() error { - // trim suffix "/" of dashboard url - c.BaseURL = strings.TrimSuffix(c.BaseURL, "/") - return nil -} - -func (c *DashboardConfig) Validate() error { - _, err := url.Parse(c.BaseURL) - if err != nil { - return errors.Wrap(err, "invalid url"+c.BaseURL) - } - return nil -} - -// PrometheusConfig is used to query metrics data for frontend -type PrometheusConfig string diff --git a/pkg/config/diagnostics/config.go b/pkg/config/diagnostics/config.go index 9972d4739..b5fe1ac21 100644 --- a/pkg/config/diagnostics/config.go +++ b/pkg/config/diagnostics/config.go @@ -18,6 +18,7 @@ package diagnostics import ( + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/config" ) @@ -25,12 +26,15 @@ type Config struct { config.BaseConfig // Port of Diagnostic Server for checking health and readiness of the Control Plane - ServerPort uint32 `json:"serverPort" envconfig:"DUBBO_DIAGNOSTICS_SERVER_PORT"` + ServerPort uint32 `json:"serverPort"` } var _ = &Config{} -func (d *Config) Validate() error { +func (c *Config) Validate() error { + if c.ServerPort < 1 || c.ServerPort > 65535 { + return bizerror.New(bizerror.ConfigError, "server port for diagnotics must between 1 to 65535") + } return nil } diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index b65d54d26..d1df84013 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -1,37 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package discovery -import "github.com/apache/dubbo-admin/pkg/config" +import ( + "github.com/duke-git/lancet/v2/strutil" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config" +) type Type string const ( - zookeeper Type = "zookeeper" - nacos Type = "nacos" + Zookeeper Type = "zookeeper" + Nacos2 Type = "nacos2" + // Mock is only for develop and test + Mock Type = "mock" +) + +const ( + defaultConfigWatchPeriod = 30 + defaultServiceWatchPeriod = 30 ) -// Config defines Discovery Engine configuration +// Config defines Discovery configuration type Config struct { config.BaseConfig - Name string `json:"name"` - Type Type `json:"type"` - Address AddressConfig + ID string `json:"id" yaml:"id"` + Name string `json:"name" yaml:"name"` + Type Type `json:"type" yaml:"type"` + Address AddressConfig `json:"address" yaml:"address"` + Properties Properties `json:"properties" yaml:"properties"` } // AddressConfig defines Discovery Engine address type AddressConfig struct { - Registry string `json:"registry"` - ConfigCenter string `json:"configCenter"` - MetadataReport string `json:"metadataReport"` + Registry string `json:"registry" yaml:"registry"` + ConfigCenter string `json:"configCenter" yaml:"configCenter"` + MetadataReport string `json:"metadataReport" yaml:"metadataReport"` +} + +type Properties struct { + ConfigWatchPeriod int `json:"configWatchPeriod" yaml:"configWatchPeriod"` + ServiceWatchPeriod int `json:"serviceWatchPeriod" yaml:"serviceWatchPeriod"` } -func DefaultDiscoveryEnginConfig() *Config { - return &Config{ - Name: "localhost", - Type: nacos, - Address: AddressConfig{ - Registry: "nacos://127.0.0.1:8848?username=nacos&password=nacos", - ConfigCenter: "nacos://127.0.0.1:8848?username=nacos&password=nacos", - MetadataReport: "nacos://127.0.0.1:8848?username=nacos&password=nacos", - }, +func (c *Config) PreProcess() error { + // if config center or metadata report is not set, use registry address + if strutil.IsBlank(c.Address.ConfigCenter) { + c.Address.ConfigCenter = c.Address.Registry + } + if strutil.IsBlank(c.Address.MetadataReport) { + c.Address.MetadataReport = c.Address.Registry + } + if c.Properties.ServiceWatchPeriod <= 0 { + c.Properties.ServiceWatchPeriod = defaultServiceWatchPeriod + c.Properties.ConfigWatchPeriod = defaultConfigWatchPeriod + } + return nil +} + +func (c *Config) Validate() error { + if strutil.IsBlank(c.ID) { + return bizerror.New(bizerror.InvalidArgument, "discovery id is needed") + } + if strutil.IsBlank(c.Name) { + return bizerror.New(bizerror.InvalidArgument, "discovery name is needed") + } + if strutil.IsBlank(string(c.Type)) { + return bizerror.New(bizerror.InvalidArgument, "discovery type is needed") + } + if strutil.IsBlank(c.Address.Registry) && c.Type != Mock { + return bizerror.New(bizerror.InvalidArgument, "discovery address is needed") } + return nil } diff --git a/pkg/config/engine/config.go b/pkg/config/engine/config.go index f68f76b0d..cde1afbce 100644 --- a/pkg/config/engine/config.go +++ b/pkg/config/engine/config.go @@ -1,30 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package engine -import "github.com/apache/dubbo-admin/pkg/config" +import ( + "fmt" + + set "github.com/duke-git/lancet/v2/datastructure/set" + "github.com/duke-git/lancet/v2/strutil" + "github.com/google/uuid" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config" +) type Type string +var supportedEngineTypes = set.New(Kubernetes, Mock) + const ( - VM Type = "vm" Kubernetes Type = "kubernetes" + Mock Type = "mock" ) type Config struct { config.BaseConfig - Name string `json:"name"` - Type Type `json:"type"` + ID string `json:"id" yaml:"id"` + Name string `json:"name" yaml:"name"` + Type Type `json:"type" yaml:"type"` + Properties Properties `json:"properties" yaml:"properties"` +} + +func (c *Config) Validate() error { + if strutil.IsBlank(c.ID) { + return bizerror.New(bizerror.ConfigError, "engine id can not be empty") + } + if !supportedEngineTypes.Contain(c.Type) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("engine type %s is not supported", c.Type)) + } + return c.Properties.Validate() +} + +type Properties struct { + config.BaseConfig + KubeConfigPath string `json:"kubeConfigPath" yaml:"kubeConfigPath"` + PodWatchSelector string `json:"podWatchSelector" yaml:"podWatchSelector"` + DubboAppIdentifier *KubernetesIdentifier `json:"dubboAppIdentifier" yaml:"dubboAppIdentifier"` + DubboRPCPortIdentifier *KubernetesIdentifier `json:"dubboRPCPortIdentifier" yaml:"dubboRPCPortIdentifier"` + DubboDiscoveryIdentifier *KubernetesIdentifier `json:"dubboDiscoveryIdentifier" yaml:"dubboDiscoveryIdentifier"` + MainContainerChooseStrategy *MainContainerChooseStrategy `json:"mainContainerChooseStrategy" yaml:"mainContainerChooseStrategy"` +} + +func (p *Properties) Validate() error { + if p.DubboAppIdentifier != nil { + if err := p.DubboAppIdentifier.Validate(); err != nil { + return err + } + } + if p.DubboRPCPortIdentifier != nil { + if err := p.DubboRPCPortIdentifier.Validate(); err != nil { + return err + } + } + if p.DubboDiscoveryIdentifier != nil { + if err := p.DubboDiscoveryIdentifier.Validate(); err != nil { + return err + } + } + if p.MainContainerChooseStrategy != nil { + if err := p.MainContainerChooseStrategy.Validate(); err != nil { + return err + } + } + return nil +} + +type MainContainerChooseStrategyType string + +var mainContainerChooseStrategyTypes = set.New(ChooseByLast, ChooseByIndex, ChooseByName, ChooseByAnnotation) + +const ( + ChooseByLast MainContainerChooseStrategyType = "ByLast" + ChooseByIndex MainContainerChooseStrategyType = "ByIndex" + ChooseByName MainContainerChooseStrategyType = "ByName" + ChooseByAnnotation MainContainerChooseStrategyType = "ByAnnotation" +) + +type MainContainerChooseStrategy struct { + config.BaseConfig + Type MainContainerChooseStrategyType `json:"type"` + Index int `json:"index"` + Name string `json:"name"` + AnnotationKey string `json:"annotationKey"` +} + +func (m *MainContainerChooseStrategy) Validate() error { + if !mainContainerChooseStrategyTypes.Contain(m.Type) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("unsupported main container choose strategy type: %s", m.Type)) + } + return nil } -// AddressConfig defines Discovery Engine address -type AddressConfig struct { - Registry string `json:"registry"` - ConfigCenter string `json:"configCenter"` - MetadataReport string `json:"metadataReport"` +type IdentifierType string + +var identifierTypes = set.New(IdentifyByLabel, IdentifyByAnnotation) + +const ( + IdentifyByLabel IdentifierType = "ByLabel" + IdentifyByAnnotation IdentifierType = "ByAnnotation" +) + +type KubernetesIdentifier struct { + config.BaseConfig + Type IdentifierType `json:"type"` + LabelKey string `json:"labelKey"` + AnnotationKey string `json:"annotationKey"` +} + +func (k *KubernetesIdentifier) Validate() error { + if !identifierTypes.Contain(k.Type) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("unsupported identifier type: %s", k.Type)) + } + return nil } func DefaultResourceEngineConfig() *Config { return &Config{ + ID: uuid.New().String(), Name: "default", - Type: VM, + Type: Mock, + Properties: Properties{ + MainContainerChooseStrategy: &MainContainerChooseStrategy{ + Type: ChooseByIndex, + Index: 0, + }, + }, } } diff --git a/pkg/config/eventbus/config.go b/pkg/config/eventbus/config.go index 4cb84b319..4c912ed35 100644 --- a/pkg/config/eventbus/config.go +++ b/pkg/config/eventbus/config.go @@ -29,6 +29,6 @@ func (c Config) Validate() error { func Default() Config { return Config{ - BufferSize: 100, + BufferSize: 1024, } } diff --git a/pkg/config/loader.go b/pkg/config/loader.go index 8dae68124..8c0d3bdbb 100644 --- a/pkg/config/loader.go +++ b/pkg/config/loader.go @@ -18,39 +18,38 @@ package config import ( + "fmt" "os" - "github.com/kelseyhightower/envconfig" "github.com/pkg/errors" "sigs.k8s.io/yaml" - "github.com/apache/dubbo-admin/pkg/core" + "github.com/apache/dubbo-admin/pkg/common/bizerror" ) func Load(file string, cfg Config) error { - return LoadWithOption(file, cfg, false, true, true) + return LoadWithOption(file, cfg, false, true) } -func LoadWithOption(file string, cfg Config, strict bool, includeEnv bool, validate bool) error { +func LoadWithOption(file string, cfg Config, strict bool, validate bool) error { if file == "" { - core.Log.WithName("config").Info("skipping reading config from file") - } else if err := loadFromFile(file, cfg, strict); err != nil { - return err + return bizerror.New(bizerror.ConfigError, "config file is needed") + } + if err := loadFromFile(file, cfg, strict); err != nil { + return fmt.Errorf("configuration loading failed, %w", err) } - if includeEnv { - if err := envconfig.Process("", cfg); err != nil { - return err - } + if err := cfg.PreProcess(); err != nil { + return fmt.Errorf("configuration pre processing failed, %w", err) } if err := cfg.PostProcess(); err != nil { - return errors.Wrap(err, "configuration post processing failed") + return fmt.Errorf("configuration post processing failed, %w", err) } if validate { if err := cfg.Validate(); err != nil { - return errors.Wrapf(err, "Invalid configuration") + return fmt.Errorf("configuration validation failed, %w", err) } } return nil diff --git a/pkg/config/log/config.go b/pkg/config/log/config.go new file mode 100644 index 000000000..591a0ea40 --- /dev/null +++ b/pkg/config/log/config.go @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package log + +import ( + "fmt" + + "github.com/duke-git/lancet/v2/slice" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config" +) + +type Level string + +var supportLevels = []Level{LevelDebug, LevelInfo, LevelWarn, LevelError} + +const ( + LevelDebug Level = "debug" + LevelInfo Level = "info" + LevelWarn Level = "warn" + LevelError Level = "error" +) + +const ( + defaultLogLevel = LevelDebug + defaultOutputPath = "logs/dubbo-admin.log" + defaultMaxSize = 100 + defaultMaxBackups = 5 + defaultMaxAge = 3 +) + +type Config struct { + config.BaseConfig + Level Level `json:"level" yaml:"level"` + OutputPath string `json:"outputPath" yaml:"outputPath"` + MaxSize int `json:"maxSize" yaml:"maxSize"` + MaxBackups int `json:"maxBackups" yaml:"maxBackups"` + MaxAge int `json:"maxAge" yaml:"maxAge"` +} + +func (c *Config) Validate() error { + if !slice.Contain(supportLevels, c.Level) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("unsupported log level: %s", c.Level)) + } + return nil +} + +func DefaultLogConfig() *Config { + return &Config{ + Level: defaultLogLevel, + OutputPath: defaultOutputPath, + MaxSize: defaultMaxSize, + MaxBackups: defaultMaxBackups, + MaxAge: defaultMaxAge, + } +} diff --git a/pkg/config/mode/config.go b/pkg/config/mode/config.go index b89e83eb9..ba9612605 100644 --- a/pkg/config/mode/config.go +++ b/pkg/config/mode/config.go @@ -21,18 +21,6 @@ import ( "github.com/pkg/errors" ) -// DeployMode 部署模型 -// 1. 纯Kubernetes -// 2. 半托管, 使用Kubernetes做平台, 服务注册的模型仍然使用zookeeper -// 3. vm, 使用vm机器传统服务注册模型 -type DeployMode = string - -const ( - KubernetesMode DeployMode = "k8s" // 全托管 - HalfHostMode DeployMode = "half" // 半托管 - UniversalMode DeployMode = "universal" // vm传统 -) - // Mode Control Plane mode type Mode = string diff --git a/pkg/config/observability/config.go b/pkg/config/observability/config.go new file mode 100644 index 000000000..879e22998 --- /dev/null +++ b/pkg/config/observability/config.go @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package observability + +import ( + "fmt" + "net/url" + + "github.com/duke-git/lancet/v2/strutil" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config" +) + +type Config struct { + config.BaseConfig + // Grafana is the url of grafana + Grafana string `json:"grafana" yaml:"grafana"` + // Prometheus is the url of prometheus + Prometheus string `json:"prometheus" yaml:"prometheus"` + + GrafanaBaseURL *url.URL `json:"-" yaml:"-"` + PrometheusBaseURL *url.URL `json:"-" yaml:"-"` +} + +func (c *Config) Validate() error { + if strutil.IsNotBlank(c.Prometheus) { + prometheusBaseURL, err := url.Parse(c.Prometheus) + if err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, + fmt.Sprintf("invalid prometheus url: %s", c.Prometheus)) + } + c.PrometheusBaseURL = prometheusBaseURL + } + if strutil.IsNotBlank(c.Grafana) { + grafanaBaseURL, err := url.Parse(c.Grafana) + if err != nil { + return bizerror.Wrap(err, bizerror.ConfigError, + fmt.Sprintf("invalid grafana url: %s", c.Grafana)) + } + c.GrafanaBaseURL = grafanaBaseURL + } + return nil +} + +func DefaultObservabilityConfig() *Config { + return &Config{} +} diff --git a/pkg/config/schema/gvk/resources.gen.go b/pkg/config/schema/gvk/resources.gen.go deleted file mode 100644 index c7027edd7..000000000 --- a/pkg/config/schema/gvk/resources.gen.go +++ /dev/null @@ -1,86 +0,0 @@ -package gvk - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/apache/dubbo-admin/operator/pkg/config" - "github.com/apache/dubbo-admin/pkg/config/schema/gvr" -) - -var ( - Namespace = config.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"} - CustomResourceDefinition = config.GroupVersionKind{Group: "apiextensions.k8s.io", Version: "v1", Kind: "CustomResourceDefinition"} - MutatingWebhookConfiguration = config.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfiguration"} - ValidatingWebhookConfiguration = config.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "ValidatingWebhookConfiguration"} - Deployment = config.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"} - StatefulSet = config.GroupVersionKind{Group: "apps", Version: "v1", Kind: "StatefulSet"} - DaemonSet = config.GroupVersionKind{Group: "apps", Version: "v1", Kind: "DaemonSet"} - Job = config.GroupVersionKind{Group: "batch", Version: "v1", Kind: "Job"} - ConfigMap = config.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} - Secret = config.GroupVersionKind{Group: "", Version: "v1", Kind: "Secret"} - Service = config.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"} - ServiceAccount = config.GroupVersionKind{Group: "", Version: "v1", Kind: "ServiceAccount"} -) - -func ToGVR(g config.GroupVersionKind) (schema.GroupVersionResource, bool) { - switch g { - case CustomResourceDefinition: - return gvr.CustomResourceDefinition, true - case MutatingWebhookConfiguration: - return gvr.MutatingWebhookConfiguration, true - case ValidatingWebhookConfiguration: - return gvr.ValidatingWebhookConfiguration, true - case Deployment: - return gvr.Deployment, true - case StatefulSet: - return gvr.StatefulSet, true - case DaemonSet: - return gvr.DaemonSet, true - case ConfigMap: - return gvr.ConfigMap, true - case Secret: - return gvr.Secret, true - case Service: - return gvr.Service, true - case ServiceAccount: - return gvr.ServiceAccount, true - case Namespace: - return gvr.Namespace, true - case Job: - return gvr.Job, true - } - return schema.GroupVersionResource{}, false -} -func MustToGVR(g config.GroupVersionKind) schema.GroupVersionResource { - r, ok := ToGVR(g) - if !ok { - panic("unknown kind: " + g.String()) - } - return r -} - -func FromGVR(g schema.GroupVersionResource) (config.GroupVersionKind, bool) { - switch g { - case gvr.CustomResourceDefinition: - return CustomResourceDefinition, true - case gvr.Namespace: - return Namespace, true - case gvr.Deployment: - return Deployment, true - case gvr.StatefulSet: - return StatefulSet, true - case gvr.DaemonSet: - return DaemonSet, true - case gvr.Job: - return Job, true - } - return config.GroupVersionKind{}, false -} - -func MustFromGVR(g schema.GroupVersionResource) config.GroupVersionKind { - r, ok := FromGVR(g) - if !ok { - panic("unknown kind: " + g.String()) - } - return r -} diff --git a/pkg/config/schema/gvr/resource.gen.go b/pkg/config/schema/gvr/resource.gen.go deleted file mode 100644 index f5f1bbaf2..000000000 --- a/pkg/config/schema/gvr/resource.gen.go +++ /dev/null @@ -1,20 +0,0 @@ -package gvr - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" -) - -var ( - CustomResourceDefinition = schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"} - MutatingWebhookConfiguration = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "MutatingWebhookConfiguration"} - ValidatingWebhookConfiguration = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "ValidatingWebhookConfiguration"} - Deployment = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"} - StatefulSet = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"} - DaemonSet = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"} - Job = schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"} - Namespace = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"} - ConfigMap = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"} - Secret = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"} - Service = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"} - ServiceAccount = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"} -) diff --git a/pkg/config/store/config.go b/pkg/config/store/config.go index 6797e83d7..174f62ad6 100644 --- a/pkg/config/store/config.go +++ b/pkg/config/store/config.go @@ -18,6 +18,11 @@ package store import ( + "fmt" + + set "github.com/duke-git/lancet/v2/datastructure/set" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/config" ) @@ -26,15 +31,26 @@ var _ config.Config = &Config{} type Type = string const ( - Memory Type = "memory" + Memory Type = "memory" + MySQL Type = "mysql" + Postgres Type = "postgres" ) +var supportTypes = set.New(Memory, MySQL, Postgres) + // Config defines the ResourceStore configuration type Config struct { config.BaseConfig // Type of Store used in Admin - Type Type `json:"type"` - Address string `json:"address"` + Type Type `json:"type" yaml:"type"` + Address string `json:"address" yaml:"address"` +} + +func (c *Config) Validate() error { + if !supportTypes.Contain(c.Type) { + return bizerror.New(bizerror.ConfigError, fmt.Sprintf("unsupported store type: %s", c.Type)) + } + return nil } func DefaultStoreConfig() *Config { diff --git a/pkg/console/component.go b/pkg/console/component.go index cd9769d9f..631fcaeed 100644 --- a/pkg/console/component.go +++ b/pkg/console/component.go @@ -24,18 +24,25 @@ import ( "net/http" "strconv" "strings" + "time" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" + ginzap "github.com/gin-contrib/zap" "github.com/gin-gonic/gin" ui "github.com/apache/dubbo-admin/app/dubbo-ui" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config/app" "github.com/apache/dubbo-admin/pkg/config/console" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/router" "github.com/apache/dubbo-admin/pkg/core/logger" "github.com/apache/dubbo-admin/pkg/core/runtime" + mcpcore "github.com/apache/dubbo-admin/pkg/mcp/core" + mcphttp "github.com/apache/dubbo-admin/pkg/mcp/transport/http" + mcp_tools "github.com/apache/dubbo-admin/pkg/mcp/tools" ) func init() { @@ -43,25 +50,41 @@ func init() { } type consoleWebServer struct { - Engine *gin.Engine - cfg *console.Config - cs consolectx.Context + Engine *gin.Engine + cfg *console.Config + cs consolectx.Context + mcpPath string // MCP端点路径,用于auth中间件跳过认证 + mcpAPIKey string // MCP API密钥,用于认证 } -func (c *consoleWebServer) Type() runtime.ComponentType { - return runtime.Console +func (c *consoleWebServer) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.ResourceManager, // Console needs Manager for resource operations + // Note: No need to list ResourceStore explicitly as Manager already depends on it + } } -func (c *consoleWebServer) SubType() runtime.ComponentSubType { - return runtime.DefaultComponentSubType +func (c *consoleWebServer) Type() runtime.ComponentType { + return runtime.Console } func (c *consoleWebServer) Order() int { - return math.MaxInt + return math.MaxInt - 5 } func (c *consoleWebServer) Init(ctx runtime.BuilderContext) error { - r := gin.Default() + c.cfg = ctx.Config().Console + + // 提前读取 MCP 配置,供 auth 中间件使用 + cfg := ctx.Config() + if cfg.MCP != nil { + if cfg.MCP.Path != "" { + c.mcpPath = cfg.MCP.Path + } + c.mcpAPIKey = cfg.MCP.APIKey + } + + r := gin.New() // Admin UI r.StaticFS("/admin", http.FS(ui.FS())) r.NoRoute(func(c *gin.Context) { @@ -79,15 +102,28 @@ func (c *consoleWebServer) Init(ctx runtime.BuilderContext) error { store := cookie.NewStore([]byte("secret")) r.Use(sessions.Sessions("session", store)) r.Use(c.authMiddleware()) + r.Use(ginzap.Ginzap(logger.Logger(), time.RFC3339, true)) + r.Use(ginzap.RecoveryWithZap(logger.Logger(), true)) c.Engine = r - c.cfg = ctx.Config().Console + gin.SetMode(string(c.cfg.GinMode)) return nil } func (c *consoleWebServer) Start(coreRt runtime.Runtime, stop <-chan struct{}) error { + // If console config is nil, skip starting (e.g., MCP mode) + if c.cfg == nil { + logger.Sugar().Info("Console config is nil, skipping console start") + // Wait for stop signal since we need to keep the component "running" + <-stop + return nil + } errChan := make(chan error) c.cs = consolectx.NewConsoleContext(coreRt) router.InitRouter(c.Engine, c.cs) + + // 注册MCP端点(如果启用) + c.registerMCPEndpoints(coreRt, c.Engine) + httpServer := c.startHttpServer(errChan) select { case <-stop: @@ -123,21 +159,101 @@ func (c *consoleWebServer) startHttpServer(errChan chan error) *http.Server { return server } +func (c *consoleWebServer) registerMCPEndpoints(coreRt runtime.Runtime, engine *gin.Engine) { + // 从runtime获取完整配置 + var cfg app.AdminConfig = coreRt.Config() + + // 检查MCP是否启用 + if cfg.MCP == nil || !cfg.MCP.Enabled { + return + } + + // 确定端点路径 + path := cfg.MCP.Path + if path == "" { + path = "/api/mcp" + } + + // 存储MCP路径和API Key供auth中间件使用 + c.mcpPath = path + c.mcpAPIKey = cfg.MCP.APIKey + + // 直接创建MCP服务器 + consoleCtx := consolectx.NewConsoleContext(coreRt) + server := mcpcore.NewServer("dubbo-admin", "1.0.0") + server.SetConsoleContext(consoleCtx) + + // 注册所有工具 + reg := server.GetRegistry() + reg.RegisterRegistrar(&mcp_tools.MetricsRegistrar{}) + reg.RegisterRegistrar(&mcp_tools.ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&mcp_tools.ServiceRegistrar{}) + reg.RegisterRegistrar(&mcp_tools.DetailRegistrar{}) + reg.RegisterAll() + + // 创建HTTP处理器 + handler := mcphttp.NewHandler(server) + + // 注册路由 + engine.POST(path, func(ctx *gin.Context) { + handler.ServeHTTP(ctx.Writer, ctx.Request) + }) + + authStatus := "no-auth" + if c.mcpAPIKey != "" { + authStatus = "with-auth" + } + logger.Sugar().Infof("MCP endpoint registered at %s with %d tools (%s)", path, len(reg.List()), authStatus) +} + func (c *consoleWebServer) authMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { + return func(ctx *gin.Context) { + requestPath := ctx.Request.URL.Path + // skip login api - requestPath := c.Request.URL.Path if strings.HasSuffix(requestPath, "/login") { - c.Next() + ctx.Next() + return + } + + // check MCP endpoint authentication + isMCPRequest := requestPath == "/api/mcp" || (c.mcpPath != "" && requestPath == c.mcpPath) + if isMCPRequest { + // 如果配置了 API Key,验证 Bearer Token + if c.mcpAPIKey != "" { + authHeader := ctx.GetHeader("Authorization") + if authHeader == "" { + ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Missing Authorization header"}) + ctx.Abort() + return + } + // 检查 Bearer Token 格式 + if len(authHeader) < 7 || authHeader[:7] != "Bearer " { + ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid Authorization header format. Use: Bearer "}) + ctx.Abort() + return + } + token := authHeader[7:] + if token != c.mcpAPIKey { + ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid API key"}) + ctx.Abort() + return + } + } + // API Key 验证通过或未配置 API Key,继续处理 + ctx.Next() return } - session := sessions.Default(c) + + // 其他 API 需要会话认证 + session := sessions.Default(ctx) user := session.Get("user") if user == nil { - c.JSON(http.StatusUnauthorized, model.NewUnauthorizedResp()) - c.Abort() + authErr := bizerror.New(bizerror.Unauthorized, "no access, please login") + ctx.JSON(http.StatusUnauthorized, model.NewBizErrorResp(authErr)) + ctx.Abort() return } - c.Next() + ctx.Next() } } diff --git a/pkg/console/constants/constants.go b/pkg/console/constants/constants.go deleted file mode 100644 index a6000fe05..000000000 --- a/pkg/console/constants/constants.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package constants - -// Registry Constants -const ( - RegistryKey = "registry" - RegistryClusterKey = "REGISTRY_CLUSTER" - RegisterModeKey = "register-mode" - RegistryClusterTypeKey = "registry-cluster-type" - RemoteClientNameKey = "remote-client-name" - DefaultRegisterModeInterface = "interface" - DefaultRegisterModeInstance = "instance" - DefaultRegisterModeAll = "all" -) - -const ( - SerializationKey = "prefer.serialization" -) - -const ( - DubboVersionKey = "dubbo" - WorkLoadKey = "workLoad" - ReleaseKey = "release" -) - -const ( - ServiceInfoSide = "side" - ProviderSide = "provider" - ConsumerSide = "consumer" -) - -const ( - RetriesKey = "retries" - TimeoutKey = "timeout" -) - -const ( - Application = "application" - Instance = "instance" - Service = "service" -) - -const ( - Stateful = "有状态" - Stateless = "无状态" -) diff --git a/pkg/console/context/context.go b/pkg/console/context/context.go index e4a5f3c0b..f4c64ce5b 100644 --- a/pkg/console/context/context.go +++ b/pkg/console/context/context.go @@ -1,22 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package context import ( ctx "context" + "github.com/apache/dubbo-admin/pkg/core/lock" "github.com/apache/dubbo-admin/pkg/config/app" + "github.com/apache/dubbo-admin/pkg/console/counter" "github.com/apache/dubbo-admin/pkg/core/manager" "github.com/apache/dubbo-admin/pkg/core/runtime" - "github.com/apache/dubbo-admin/pkg/core/store" ) type Context interface { ResourceManager() manager.ResourceManager - - ResourceStore() store.ResourceStore + CounterManager() counter.CounterManager Config() app.AdminConfig AppContext() ctx.Context + LockManager() lock.Lock } var _ Context = &context{} @@ -44,7 +62,22 @@ func (c *context) ResourceManager() manager.ResourceManager { return rmc.(manager.ResourceManagerComponent).ResourceManager() } -func (c *context) ResourceStore() store.ResourceStore { - rsc, _ := c.coreRt.GetComponent(runtime.ResourceStore) - return rsc.(store.BaseResourceStoreComponent).ResourceStore() +func (c *context) CounterManager() counter.CounterManager { + comp, err := c.coreRt.GetComponent(counter.ComponentType) + if err != nil { + return nil + } + managerComp, ok := comp.(counter.ManagerComponent) + if !ok { + return nil + } + return managerComp.CounterManager() +} + +func (c *context) LockManager() lock.Lock { + distributedLock, err := lock.GetLockFromRuntime(c.coreRt) + if err != nil { + return nil + } + return distributedLock } diff --git a/pkg/console/counter/component.go b/pkg/console/counter/component.go new file mode 100644 index 000000000..710518c14 --- /dev/null +++ b/pkg/console/counter/component.go @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package counter + +import ( + "context" + "fmt" + "math" + "sync/atomic" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/leader" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + resmodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +const ComponentType runtime.ComponentType = "counter manager" + +func init() { + runtime.RegisterComponent(&managerComponent{}) +} + +type ManagerComponent interface { + runtime.Component + CounterManager() CounterManager +} + +var _ ManagerComponent = &managerComponent{} + +func (c *managerComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.ResourceStore, + runtime.EventBus, + } +} + +type managerComponent struct { + manager CounterManager + leaderElection *leader.LeaderElection + needsLeaderElection bool + isLeader atomic.Bool + bound atomic.Bool + storeRouter store.Router + bus events.EventBus +} + +func (c *managerComponent) Type() runtime.ComponentType { + return ComponentType +} + +func (c *managerComponent) Order() int { + return math.MaxInt - 1 +} + +func (c *managerComponent) Init(ctx runtime.BuilderContext) error { + mgr := NewCounterManager() + c.manager = mgr + + // Memory store runs single-replica; leader election is not needed. + if ctx.Config().Store.Type == storecfg.Memory { + return nil + } + + storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) + if err != nil { + logger.Warnf("counter: failed to get ResourceStore component, skipping leader election: %v", err) + return nil + } + dbSrc, ok := storeComponent.(leader.DBSource) + if !ok { + return nil + } + db, hasDB := dbSrc.GetDB() + if !hasDB { + return nil + } + holderID, err := leader.GenerateHolderID() + if err != nil { + logger.Warnf("counter: failed to generate holder ID, skipping leader election: %v", err) + return nil + } + le := leader.NewLeaderElection(db, string(ComponentType), holderID) + if err := le.EnsureTable(); err != nil { + logger.Warnf("counter: failed to ensure leader lease table: %v", err) + return nil + } + c.leaderElection = le + c.needsLeaderElection = true + logger.Infof("counter: leader election initialized (holder: %s)", holderID) + return nil +} + +func (c *managerComponent) Start(rt runtime.Runtime, ch <-chan struct{}) error { + storeComponent, err := rt.GetComponent(runtime.ResourceStore) + if err != nil { + return err + } + storeRouter, ok := storeComponent.(store.Router) + if !ok { + return fmt.Errorf("component %s does not implement store.Router", runtime.ResourceStore) + } + c.storeRouter = storeRouter + + component, err := rt.GetComponent(runtime.EventBus) + if err != nil { + return err + } + bus, ok := component.(events.EventBus) + if !ok { + return fmt.Errorf("component %s does not implement events.EventBus", runtime.EventBus) + } + c.bus = bus + + if !c.needsLeaderElection { + return c.startBusinessLogic() + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + <-ch + cancel() + }() + + c.leaderElection.RunLeaderElection(ctx, ch, + func() { // onStartLeading + logger.Infof("counter: became leader, starting business logic") + c.isLeader.Store(true) + if err := c.startBusinessLogic(); err != nil { + logger.Errorf("counter: failed to start business logic: %v", err) + } + }, + func() { // onStopLeading + logger.Warnf("counter: lost leadership, resetting counters") + c.isLeader.Store(false) + c.manager.Reset() + }, + ) + + return nil +} + +// startBusinessLogic initializes counts from store and binds to EventBus. +// When re-elected, it resets and re-initializes counts; Bind is called only once. +func (c *managerComponent) startBusinessLogic() error { + c.manager.Reset() + // Wire up leader guard so event handler skips processing when not leader. + if c.needsLeaderElection { + cm := c.manager.(*counterManager) + cm.isLeader = &c.isLeader + } + if err := c.initializeCountsFromStore(c.storeRouter); err != nil { + logger.Warnf("Failed to initialize counter manager from store: %v", err) + } + if !c.bound.Load() { + if err := c.manager.Bind(c.bus); err != nil { + return err + } + c.bound.Store(true) + } + return nil +} + +func (c *managerComponent) initializeCountsFromStore(storeRouter store.Router) error { + if err := c.initializeResourceCount(storeRouter, meshresource.InstanceKind); err != nil { + return fmt.Errorf("failed to initialize instance count: %w", err) + } + + if err := c.initializeResourceCount(storeRouter, meshresource.ApplicationKind); err != nil { + return fmt.Errorf("failed to initialize application count: %w", err) + } + + if err := c.initializeResourceCount(storeRouter, meshresource.ServiceProviderMetadataKind); err != nil { + return fmt.Errorf("failed to initialize service provider metadata count: %w", err) + } + + return nil +} + +func (c *managerComponent) initializeResourceCount(storeRouter store.Router, kind resmodel.ResourceKind) error { + resourceStore, err := storeRouter.ResourceKindRoute(kind) + if err != nil { + return err + } + + allResources := resourceStore.List() + cm := c.manager.(*counterManager) + + for _, obj := range allResources { + resource, ok := obj.(resmodel.Resource) + if !ok { + continue + } + + mesh := resource.ResourceMesh() + if mesh == "" { + mesh = "default" + } + + if counter, exists := cm.simpleCounters[kind]; exists { + counter.Increment(mesh) + } + + if kind == meshresource.InstanceKind { + instance, ok := resource.(*meshresource.InstanceResource) + if ok && instance.Spec != nil { + protocol := instance.Spec.GetProtocol() + if protocol != "" { + if cfg := cm.getDistributionConfig(kind, ProtocolCounter); cfg != nil { + cfg.counter.Increment(mesh, protocol) + } + } + + releaseVersion := instance.Spec.GetReleaseVersion() + if releaseVersion != "" { + if cfg := cm.getDistributionConfig(kind, ReleaseCounter); cfg != nil { + cfg.counter.Increment(mesh, releaseVersion) + } + } + + if cfg := cm.getDistributionConfig(kind, DiscoveryCounter); cfg != nil { + cfg.counter.Increment(mesh, mesh) + } + } + } + } + + return nil +} + +func (c *managerComponent) CounterManager() CounterManager { + return c.manager +} diff --git a/pkg/console/counter/counter.go b/pkg/console/counter/counter.go new file mode 100644 index 000000000..6d5e2a1ad --- /dev/null +++ b/pkg/console/counter/counter.go @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package counter + +import ( + "sync" +) + +type Counter struct { + name string + data map[string]int64 + mu sync.RWMutex +} + +func NewCounter(name string) *Counter { + return &Counter{ + name: name, + data: make(map[string]int64), + } +} + +func (c *Counter) Get() int64 { + c.mu.RLock() + defer c.mu.RUnlock() + var sum int64 + for _, v := range c.data { + sum += v + } + return sum +} + +func (c *Counter) GetByGroup(group string) int64 { + if group == "" { + group = "default" + } + c.mu.RLock() + defer c.mu.RUnlock() + return c.data[group] +} + +func (c *Counter) Increment(group string) { + if group == "" { + group = "default" + } + c.mu.Lock() + defer c.mu.Unlock() + c.data[group]++ +} + +func (c *Counter) Decrement(group string) { + if group == "" { + group = "default" + } + c.mu.Lock() + defer c.mu.Unlock() + if value, ok := c.data[group]; ok { + value-- + if value <= 0 { + delete(c.data, group) + } else { + c.data[group] = value + } + } +} + +func (c *Counter) Reset() { + c.mu.Lock() + defer c.mu.Unlock() + c.data = make(map[string]int64) +} + +type DistributionCounter struct { + name string + data map[string]map[string]int64 + mu sync.RWMutex +} + +func NewDistributionCounter(name string) *DistributionCounter { + return &DistributionCounter{ + name: name, + data: make(map[string]map[string]int64), + } +} + +func (c *DistributionCounter) Increment(group, key string) { + if group == "" { + group = "default" + } + if key == "" { + key = "unknown" + } + c.mu.Lock() + defer c.mu.Unlock() + if c.data[group] == nil { + c.data[group] = make(map[string]int64) + } + c.data[group][key]++ +} + +func (c *DistributionCounter) Decrement(group, key string) { + if group == "" { + group = "default" + } + if key == "" { + key = "unknown" + } + c.mu.Lock() + defer c.mu.Unlock() + groupData, exists := c.data[group] + if !exists { + return + } + if value, ok := groupData[key]; ok { + value-- + if value <= 0 { + delete(groupData, key) + if len(groupData) == 0 { + delete(c.data, group) + } + } else { + groupData[key] = value + } + } +} + +func (c *DistributionCounter) GetAll() map[string]int64 { + c.mu.RLock() + defer c.mu.RUnlock() + result := make(map[string]int64) + for _, groupData := range c.data { + for k, v := range groupData { + result[k] += v + } + } + return result +} + +func (c *DistributionCounter) GetByGroup(group string) map[string]int64 { + if group == "" { + group = "default" + } + c.mu.RLock() + defer c.mu.RUnlock() + groupData, exists := c.data[group] + if !exists { + return map[string]int64{} + } + result := make(map[string]int64, len(groupData)) + for k, v := range groupData { + result[k] = v + } + return result +} + +func (c *DistributionCounter) Reset() { + c.mu.Lock() + defer c.mu.Unlock() + c.data = make(map[string]map[string]int64) +} diff --git a/pkg/console/counter/manager.go b/pkg/console/counter/manager.go new file mode 100644 index 000000000..0cef62e8c --- /dev/null +++ b/pkg/console/counter/manager.go @@ -0,0 +1,367 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package counter + +import ( + "fmt" + "sync/atomic" + + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + resmodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +type CounterType string + +type FieldExtractor func(resmodel.Resource) string + +const ( + ProtocolCounter CounterType = "protocol" + ReleaseCounter CounterType = "release" + DiscoveryCounter CounterType = "discovery" +) + +type CounterManager interface { + RegisterSimpleCounter(kind resmodel.ResourceKind) + RegisterDistributionCounter(kind resmodel.ResourceKind, metric CounterType, extractor FieldExtractor) + Count(kind resmodel.ResourceKind) int64 + Distribution(metric CounterType) map[string]int64 + CountByMesh(kind resmodel.ResourceKind, mesh string) int64 + DistributionByMesh(metric CounterType, mesh string) map[string]int64 + Reset() + Bind(bus events.EventBus) error +} + +type distributionCounterConfig struct { + counterType CounterType + counter *DistributionCounter + extractor func(resmodel.Resource) string +} + +type counterManager struct { + simpleCounters map[resmodel.ResourceKind]*Counter + distributionConfigs map[resmodel.ResourceKind][]*distributionCounterConfig + distributionByType map[CounterType]*DistributionCounter + isLeader *atomic.Bool +} + +func NewCounterManager() CounterManager { + return newCounterManager() +} + +func newCounterManager() *counterManager { + cm := &counterManager{ + simpleCounters: make(map[resmodel.ResourceKind]*Counter), + distributionConfigs: make(map[resmodel.ResourceKind][]*distributionCounterConfig), + distributionByType: make(map[CounterType]*DistributionCounter), + } + + cm.RegisterSimpleCounter(meshresource.ApplicationKind) + cm.RegisterSimpleCounter(meshresource.ServiceProviderMetadataKind) + cm.RegisterSimpleCounter(meshresource.InstanceKind) + + cm.RegisterDistributionCounter(meshresource.InstanceKind, ProtocolCounter, instanceProtocolKey) + cm.RegisterDistributionCounter(meshresource.InstanceKind, ReleaseCounter, instanceReleaseKey) + cm.RegisterDistributionCounter(meshresource.InstanceKind, DiscoveryCounter, instanceMeshKey) + + return cm +} + +func (cm *counterManager) RegisterSimpleCounter(kind resmodel.ResourceKind) { + if kind == "" { + return + } + if _, exists := cm.simpleCounters[kind]; exists { + return + } + cm.simpleCounters[kind] = NewCounter(string(kind)) +} + +func (cm *counterManager) RegisterDistributionCounter(kind resmodel.ResourceKind, metric CounterType, extractor FieldExtractor) { + if kind == "" || metric == "" { + return + } + counter := cm.distributionByType[metric] + if counter == nil { + counter = NewDistributionCounter(string(metric)) + cm.distributionByType[metric] = counter + } + + configs := cm.distributionConfigs[kind] + for _, cfg := range configs { + if cfg.counterType == metric { + cfg.counter = counter + cfg.extractor = extractor + return + } + } + + cm.distributionConfigs[kind] = append(configs, &distributionCounterConfig{ + counterType: metric, + counter: counter, + extractor: extractor, + }) +} + +func (cm *counterManager) Reset() { + for _, counter := range cm.simpleCounters { + counter.Reset() + } + for _, counter := range cm.distributionByType { + counter.Reset() + } +} + +func (cm *counterManager) Count(kind resmodel.ResourceKind) int64 { + if counter, exists := cm.simpleCounters[kind]; exists { + return counter.Get() + } + return 0 +} + +func (cm *counterManager) Distribution(metric CounterType) map[string]int64 { + counter, exists := cm.distributionByType[metric] + if !exists { + return map[string]int64{} + } + return counter.GetAll() +} + +func (cm *counterManager) CountByMesh(kind resmodel.ResourceKind, mesh string) int64 { + if mesh == "" { + mesh = "default" + } + if counter, exists := cm.simpleCounters[kind]; exists { + return counter.GetByGroup(mesh) + } + return 0 +} + +func (cm *counterManager) DistributionByMesh(metric CounterType, mesh string) map[string]int64 { + if mesh == "" { + mesh = "default" + } + counter, exists := cm.distributionByType[metric] + if !exists { + return map[string]int64{} + } + return counter.GetByGroup(mesh) +} + +func (cm *counterManager) Bind(bus events.EventBus) error { + handledKinds := make(map[resmodel.ResourceKind]struct{}) + for kind := range cm.simpleCounters { + handledKinds[kind] = struct{}{} + } + for kind := range cm.distributionConfigs { + handledKinds[kind] = struct{}{} + } + + for kind := range handledKinds { + resourceKind := kind + name := fmt.Sprintf("counter-manager/%s", resourceKind) + subscriber := &counterEventSubscriber{ + kind: resourceKind, + name: name, + handler: func(event events.Event) error { + return cm.handleEvent(resourceKind, event) + }, + } + if err := bus.Subscribe(subscriber); err != nil { + return err + } + logger.Infof("CounterManager subscribed to %s events", resourceKind) + } + logger.Infof("CounterManager bound to EventBus successfully") + return nil +} + +func (cm *counterManager) handleEvent(kind resmodel.ResourceKind, event events.Event) error { + if cm.isLeader != nil && !cm.isLeader.Load() { + return nil + } + logger.Debugf("CounterManager handling %s event, type: %s", kind, event.Type()) + if counter := cm.simpleCounters[kind]; counter != nil { + processSimpleCounter(counter, event) + } + if configs := cm.distributionConfigs[kind]; len(configs) > 0 { + for _, cfg := range configs { + processDistributionCounter(cfg, event) + } + } + return nil +} + +func (cm *counterManager) getDistributionConfig(kind resmodel.ResourceKind, metric CounterType) *distributionCounterConfig { + configs := cm.distributionConfigs[kind] + for _, cfg := range configs { + if cfg.counterType == metric { + return cfg + } + } + return nil +} + +func extractMeshName(res resmodel.Resource) string { + if res == nil { + return "default" + } + mesh := res.ResourceMesh() + if mesh == "" { + return "default" + } + return mesh +} + +func processSimpleCounter(counter *Counter, event events.Event) { + mesh := extractMeshName(event.NewObj()) + if event.NewObj() == nil { + mesh = extractMeshName(event.OldObj()) + } + + switch event.Type() { + case cache.Added: + counter.Increment(mesh) + logger.Debugf("CounterManager: Increment %s for mesh=%s, current count=%d", counter.name, mesh, counter.GetByGroup(mesh)) + case cache.Sync, cache.Replaced: + if isNewResourceEvent(event) { + counter.Increment(mesh) + logger.Debugf("CounterManager: Increment %s for mesh=%s (Sync/Replaced), current count=%d", counter.name, mesh, counter.GetByGroup(mesh)) + } + case cache.Deleted: + counter.Decrement(mesh) + logger.Debugf("CounterManager: Decrement %s for mesh=%s, current count=%d", counter.name, mesh, counter.GetByGroup(mesh)) + case cache.Updated: + default: + } +} + +func processDistributionCounter(cfg *distributionCounterConfig, event events.Event) { + mesh := extractMeshName(event.NewObj()) + if event.NewObj() == nil { + mesh = extractMeshName(event.OldObj()) + } + + switch event.Type() { + case cache.Added: + key := cfg.extractFrom(event.NewObj()) + cfg.counter.Increment(mesh, normalizeDistributionKey(key)) + case cache.Sync, cache.Replaced: + if isNewResourceEvent(event) { + key := cfg.extractFrom(event.NewObj()) + cfg.counter.Increment(mesh, normalizeDistributionKey(key)) + } else { + cfg.update(event.OldObj(), event.NewObj()) + } + case cache.Updated: + cfg.update(event.OldObj(), event.NewObj()) + case cache.Deleted: + key := cfg.extractFrom(event.OldObj()) + cfg.counter.Decrement(mesh, normalizeDistributionKey(key)) + default: + } +} + +func (cfg *distributionCounterConfig) extractFrom(res resmodel.Resource) string { + if cfg.extractor == nil || res == nil { + return "" + } + return cfg.extractor(res) +} + +func (cfg *distributionCounterConfig) update(oldObj, newObj resmodel.Resource) { + oldKey := normalizeDistributionKey(cfg.extractFrom(oldObj)) + newKey := normalizeDistributionKey(cfg.extractFrom(newObj)) + oldMesh := extractMeshName(oldObj) + newMesh := extractMeshName(newObj) + if oldKey == newKey && oldMesh == newMesh { + return + } + if oldObj != nil { + cfg.counter.Decrement(oldMesh, oldKey) + } + if newObj != nil { + cfg.counter.Increment(newMesh, newKey) + } +} + +func instanceProtocolKey(res resmodel.Resource) string { + instance, ok := res.(*meshresource.InstanceResource) + if !ok || instance == nil || instance.Spec == nil { + return "" + } + return instance.Spec.GetProtocol() +} + +func instanceReleaseKey(res resmodel.Resource) string { + instance, ok := res.(*meshresource.InstanceResource) + if !ok || instance == nil || instance.Spec == nil { + return "" + } + return instance.Spec.GetReleaseVersion() +} + +func instanceMeshKey(res resmodel.Resource) string { + instance, ok := res.(*meshresource.InstanceResource) + if !ok || instance == nil { + return "" + } + return instance.Mesh +} + +func normalizeDistributionKey(key string) string { + if key == "" { + return "unknown" + } + return key +} + +func isNewResourceEvent(event events.Event) bool { + if event == nil { + return false + } + return event.OldObj() == nil +} + +type counterEventSubscriber struct { + kind resmodel.ResourceKind + name string + handler func(events.Event) error +} + +func (s *counterEventSubscriber) ResourceKind() resmodel.ResourceKind { + return s.kind +} + +func (s *counterEventSubscriber) Name() string { + return s.name +} + +func (s *counterEventSubscriber) AsyncEnabled() bool { + return false +} + +func (s *counterEventSubscriber) ProcessEvent(event events.Event) error { + if s.handler == nil { + return nil + } + return s.handler(event) +} diff --git a/pkg/console/handler/application.go b/pkg/console/handler/application.go index af6b49fdc..1b33212f3 100644 --- a/pkg/console/handler/application.go +++ b/pkg/console/handler/application.go @@ -18,31 +18,29 @@ package handler import ( + "errors" "net/http" "strconv" + "github.com/duke-git/lancet/v2/strutil" "github.com/gin-gonic/gin" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" - "github.com/apache/dubbo-admin/pkg/core/logger" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - corestore "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" ) func GetApplicationDetail(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := &model.ApplicationDetailReq{} if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } resp, err := service.GetApplicationDetail(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) @@ -53,13 +51,13 @@ func GetApplicationTabInstanceInfo(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := model.NewApplicationTabInstanceInfoReq() if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - resp, err := service.GetApplicationTabInstanceInfo(ctx, req) + resp, err := service.GetAppInstanceInfo(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } @@ -71,12 +69,12 @@ func GetApplicationServiceForm(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := model.NewApplicationServiceFormReq() if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - resp, err := service.GetApplicationServiceFormInfo(ctx, req) + resp, err := service.GetAppServiceInfo(ctx, req) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) @@ -87,432 +85,176 @@ func ApplicationSearch(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := model.NewApplicationSearchReq() if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - resp, err := service.GetApplicationSearchInfo(ctx, req) + resp, err := service.SearchApplications(ctx, req) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func isAppOperatorLogOpened(conf *meshproto.OverrideConfig, appName string) bool { - if conf.Side != consts.SideProvider || - conf.Parameters == nil || - conf.Match == nil || - conf.Match.Application == nil || - conf.Match.Application.Oneof == nil || - len(conf.Match.Application.Oneof) != 1 || - conf.Match.Application.Oneof[0].Exact != appName { - return false - } else if val, ok := conf.Parameters[`accesslog`]; !ok || val != `true` { - return false - } - return true -} +func GetApplicationGraph(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + req := model.NewApplicationGraphReq() + if err := c.ShouldBindQuery(req); err != nil { + util.HandleArgumentError(c, err) + return + } -func generateDefaultConfigurator(name string, scope string, version string, enabled bool) *coremodel.DynamicConfigResource { - return &coremodel.DynamicConfigResource{ - Meta: nil, - Spec: &meshproto.DynamicConfig{ - Key: name, - Scope: scope, - ConfigVersion: version, - Enabled: enabled, - Configs: make([]*meshproto.OverrideConfig, 0), - }, + resp, err := service.GraphApplications(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func ApplicationConfigOperatorLogPut(ctx consolectx.Context) gin.HandlerFunc { +func ApplicationConfigAccessLogPut(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var ( - ApplicationName string - OperatorLog bool - isNotExist = false - ) - ApplicationName = c.Query("appName") - OperatorLog, err := strconv.ParseBool(c.Query("operatorLog")) - if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + appName := c.Query("appName") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) return } - res, err := service.GetConfigurator(ctx, ApplicationName) - if err != nil { - if corestore.IsResourceNotFound(err) { - // for check app exist - data, err := service.GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: ApplicationName}) - if err != nil || data == nil { - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) - return - } - res = generateDefaultConfigurator(ApplicationName, consts.ScopeApplication, consts.ConfiguratorVersionV3, true) - isNotExist = true - } else { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + mesh := c.Query("mesh") + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) + return } - // append or remove - if OperatorLog { - // check is already exist - alreadyExist := false - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - alreadyExist = isAppOperatorLogOpened(conf, ApplicationName) - return alreadyExist - }) - if alreadyExist { - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - return - } - if res.Spec.Configs == nil { - res.Spec.Configs = make([]*meshproto.OverrideConfig, 0) - } - res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ - Side: consts.SideProvider, - Parameters: map[string]string{`accesslog`: `true`}, - Enabled: true, - Match: &meshproto.ConditionMatch{Application: &meshproto.ListStringMatch{Oneof: []*meshproto.StringMatch{{Exact: ApplicationName}}}}, - XGenerateByCp: true, - }) - } else { - res.Spec.RangeConfigsToRemove(func(conf *meshproto.OverrideConfig) (IsRemove bool) { - if conf == nil { - return true - } - return isAppOperatorLogOpened(conf, ApplicationName) - }) + operatorLogOpen, err := strconv.ParseBool(c.Query("operatorLog")) + if err != nil { + util.HandleArgumentError(c, err) + return } - // restore - if isNotExist { - err = service.CreateConfigurator(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateConfigurator(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + if err := service.UpInsertAppAccessLog(ctx, appName, operatorLogOpen, mesh); err != nil { + util.HandleServiceError(c, err) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + c.JSON(http.StatusOK, model.NewSuccessResp(true)) } } -func ApplicationConfigOperatorLogGet(ctx consolectx.Context) gin.HandlerFunc { +func ApplicationConfigAccessLogGet(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - ApplicationName := c.Query("appName") - if ApplicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("appName is required")) + appName := c.Query("appName") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) + return + } + mesh := c.Query("mesh") + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) return } - res, err := service.GetConfigurator(ctx, ApplicationName) + resp, err := service.GetAppAccessLog(ctx, appName, mesh) if err != nil { - if corestore.IsResourceNotFound(err) { - c.JSON(http.StatusOK, model.NewSuccessResp(map[string]interface{}{"operatorLog": false})) - return - } - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } - isExist := false - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - if isExist = isAppOperatorLogOpened(conf, ApplicationName); isExist { - return true - } - return false - }) - c.JSON(http.StatusOK, model.NewSuccessResp(map[string]interface{}{"operatorLog": isExist})) + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } func ApplicationConfigFlowWeightGET(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var ( - ApplicationName string - resp = struct { - FlowWeightSets []model.FlowWeightSet `json:"flowWeightSets"` - }{} - ) - ApplicationName = c.Query("appName") - if ApplicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("appName is required")) + appName := c.Query("appName") + mesh := c.Query("mesh") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) return } - - resp.FlowWeightSets = make([]model.FlowWeightSet, 0) - - res, err := service.GetConfigurator(ctx, ApplicationName) - if err != nil { - if corestore.IsResourceNotFound(err) { - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - return - } - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) return } - - weight := 0 - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - if isFlowWeight(conf) { - weight, err = strconv.Atoi(conf.Parameters[`weight`]) - if err != nil { - logger.Error("parse weight failed", err) - return true - } - scope := make([]model.ParamMatch, 0, len(conf.Match.Param)) - for _, param := range conf.Match.Param { - scope = append(scope, model.ParamMatch{ - Key: ¶m.Key, - Value: model.StringMatchToModelStringMatch(param.Value), - }) - } - - resp.FlowWeightSets = append(resp.FlowWeightSets, model.FlowWeightSet{ - Weight: int32(weight), - Scope: scope, - }) - } - return false - }) + resp, err := service.GetAppFlowWeight(ctx, appName, mesh) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func isFlowWeight(conf *meshproto.OverrideConfig) bool { - if conf.Side != consts.SideProvider || - conf.Parameters == nil || - conf.Match == nil || - conf.Match.Param == nil { - return false - } else if _, ok := conf.Parameters[`weight`]; !ok { - return false - } - return true -} - func ApplicationConfigFlowWeightPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var ( - ApplicationName = "" - body = struct { - FlowWeightSets []model.FlowWeightSet `json:"flowWeightSets"` - }{} - ) - ApplicationName = c.Query("appName") - if ApplicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is required")) + body := struct { + FlowWeightSets []model.FlowWeightSet `json:"flowWeightSets"` + }{} + appName := c.Query("appName") + mesh := c.Query("mesh") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) + return + } + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) + return } if err := c.Bind(&body); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - // get from store, or generate default resource - isNotExist := false - res, err := service.GetConfigurator(ctx, ApplicationName) + err := service.UpInsertAppFlowWeightConfig(ctx, appName, mesh, body.FlowWeightSets) if err != nil { - if corestore.IsResourceNotFound(err) { - // for check app exist - data, err := service.GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: ApplicationName}) - if err != nil { - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) - return - } else if data == nil { - c.JSON(http.StatusNotFound, model.NewErrorResp("application not found")) - return - } - res = generateDefaultConfigurator(ApplicationName, consts.ScopeApplication, consts.ConfiguratorVersionV3, true) - isNotExist = true - } else { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } - - // remove old - res.Spec.RangeConfigsToRemove(func(conf *meshproto.OverrideConfig) (IsRemove bool) { - return isFlowWeight(conf) - }) - // append new - for _, set := range body.FlowWeightSets { - paramMatch := make([]*meshproto.ParamMatch, 0, len(set.Scope)) - for _, match := range set.Scope { - paramMatch = append(paramMatch, &meshproto.ParamMatch{ - Key: *match.Key, - Value: model.ModelStringMatchToStringMatch(match.Value), - }) - } - res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ - Side: consts.SideProvider, - Parameters: map[string]string{`weight`: strconv.Itoa(int(set.Weight))}, - Match: &meshproto.ConditionMatch{ - Param: paramMatch, - }, - XGenerateByCp: true, - }) - } - // restore - if isNotExist { - err = service.CreateConfigurator(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateConfigurator(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + util.HandleServiceError(c, err) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + c.JSON(http.StatusOK, model.NewSuccessResp(true)) } } func ApplicationConfigGrayGET(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var ( - ApplicationName = "" - resp = struct { - GraySets []model.GraySet `json:"graySets"` - }{} - ) - ApplicationName = c.Query("appName") - if ApplicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("appName is required")) + appName := c.Query("appName") + mesh := c.Query("mesh") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) return } - - res, err := service.GetTagRule(ctx, ApplicationName) + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) + return + } + resp, err := service.GetGrayConfig(ctx, appName, mesh) if err != nil { - if corestore.IsResourceNotFound(err) { - resp.GraySets = make([]model.GraySet, 0) - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - return - } - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } - resp.GraySets = make([]model.GraySet, 0, len(res.Spec.Tags)) - - res.Spec.RangeTags(func(tag *meshproto.Tag) (isStop bool) { - if isGrayTag(tag) { - scope := make([]model.ParamMatch, 0, len(tag.Match)) - for _, paramMatch := range tag.Match { - scope = append(scope, model.ParamMatch{ - Key: ¶mMatch.Key, - Value: model.StringMatchToModelStringMatch(paramMatch.Value), - }) - } - resp.GraySets = append(resp.GraySets, model.GraySet{ - EnvName: tag.Name, - Scope: scope, - }) - } - return false - }) - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } func ApplicationConfigGrayPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var ( - ApplicationName = "" - body = struct { - GraySets []model.GraySet `json:"graySets"` - }{} - ) - ApplicationName = c.Query("appName") - if ApplicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is required")) + body := struct { + GraySets []model.GraySet `json:"graySets"` + }{} + appName := c.Query("appName") + mesh := c.Query("mesh") + if strutil.IsBlank(appName) { + util.HandleArgumentError(c, errors.New("appName is required")) return } - if err := c.Bind(&body); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - } - - isNotExist := false - res, err := service.GetTagRule(ctx, ApplicationName) - if corestore.IsResourceNotFound(err) { - data, err := service.GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: ApplicationName}) - if err != nil { - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) - return - } else if data == nil { - c.JSON(http.StatusNotFound, model.NewErrorResp("application not found")) - return - } - res = generateDefaultTagRule(ApplicationName, consts.ConfiguratorVersionV3, true, false) - isNotExist = true + if strutil.IsBlank(mesh) { + util.HandleArgumentError(c, errors.New("mesh is required")) + return } - - // remove old config, generate config from admin, append - res.Spec.RangeTagsToRemove(func(tag *meshproto.Tag) (IsRemove bool) { - return isGrayTag(tag) - }) - newTags := make([]*meshproto.Tag, 0) - for _, set := range body.GraySets { - paramMatches := make([]*meshproto.ParamMatch, 0, len(set.Scope)) - for _, match := range set.Scope { - paramMatches = append(paramMatches, &meshproto.ParamMatch{ - Key: *match.Key, - Value: model.ModelStringMatchToStringMatch(match.Value), - }) - } - newTags = append(newTags, &meshproto.Tag{ - Name: set.EnvName, - Match: paramMatches, - XGenerateByCp: true, - }) + if err := c.Bind(&body); err != nil { + util.HandleArgumentError(c, err) + return } - res.Spec.Tags = append(res.Spec.Tags, newTags...) - - // restore - if isNotExist { - err = service.CreateTagRule(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateTagRule(ctx, ApplicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + err := service.UpInsertAppGrayConfig(ctx, appName, mesh, body.GraySets) + if err != nil { + util.HandleServiceError(c, err) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - } -} - -func isGrayTag(tag *meshproto.Tag) bool { - if tag.Name == "" || tag.Addresses != nil || len(tag.Addresses) != 0 { - return false - } - return true -} - -func generateDefaultTagRule(name string, version string, enable, force bool) *coremodel.TagRouteResource { - return &coremodel.TagRouteResource{ - Meta: nil, - Spec: &meshproto.TagRoute{ - Enabled: enable, - Key: name, - ConfigVersion: version, - Force: force, - Tags: make([]*meshproto.Tag, 0), - }, + c.JSON(http.StatusOK, model.NewSuccessResp(true)) } } diff --git a/pkg/console/handler/auth.go b/pkg/console/handler/auth.go index dc1777e4c..1d2b7c1ab 100644 --- a/pkg/console/handler/auth.go +++ b/pkg/console/handler/auth.go @@ -23,6 +23,7 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" + "github.com/apache/dubbo-admin/pkg/common/bizerror" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" ) @@ -33,21 +34,24 @@ func Login(ctx consolectx.Context) gin.HandlerFunc { password := c.PostForm("password") // verify username and password authCfg := ctx.Config().Console.Auth - if user == authCfg.User && password == authCfg.Password { - session := sessions.Default(c) - session.Set("user", user) - session.Options(sessions.Options{ - MaxAge: authCfg.ExpirationTime, - Path: "/", - }) - err := session.Save() - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - } else { - c.JSON(http.StatusUnauthorized, model.NewUnauthorizedResp()) + if user != authCfg.User || password != authCfg.Password { + authErr := bizerror.New(bizerror.Unauthorized, "username or password is not correct!") + c.JSON(http.StatusUnauthorized, model.NewBizErrorResp(authErr)) + return } + session := sessions.Default(c) + session.Set("user", user) + session.Options(sessions.Options{ + MaxAge: authCfg.ExpirationTime, + Path: "/", + }) + err := session.Save() + if err != nil { + sessionErr := bizerror.New(bizerror.SessionError, err.Error()) + c.JSON(http.StatusOK, model.NewBizErrorResp(sessionErr)) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(true)) } } @@ -57,8 +61,10 @@ func Logout(_ consolectx.Context) gin.HandlerFunc { session.Clear() err := session.Save() if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + sessionErr := bizerror.New(bizerror.SessionError, err.Error()) + c.JSON(http.StatusOK, model.NewBizErrorResp(sessionErr)) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + c.JSON(http.StatusOK, model.NewSuccessResp(true)) } } diff --git a/pkg/console/handler/condition_rule.go b/pkg/console/handler/condition_rule.go index d39bfca6b..653c12e71 100644 --- a/pkg/console/handler/condition_rule.go +++ b/pkg/console/handler/condition_rule.go @@ -18,20 +18,19 @@ package handler import ( - "encoding/json" "fmt" - "io" "net/http" "strings" "github.com/gin-gonic/gin" - "github.com/mitchellh/mapstructure" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/console/util" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" ) func ConditionRuleSearch(cs consolectx.Context) gin.HandlerFunc { @@ -43,7 +42,7 @@ func ConditionRuleSearch(cs consolectx.Context) gin.HandlerFunc { } resp, err := service.SearchConditionRules(cs, req) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) @@ -52,94 +51,52 @@ func ConditionRuleSearch(cs consolectx.Context) gin.HandlerFunc { func GetConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConditionRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConditionRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConditionRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConditionRuleDotSuffix) { + c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", constants.ConditionRuleDotSuffix))) return } - if res, err := service.GetConditionRule(cs, name); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + res, err := service.GetConditionRule(cs, ruleName, mesh) + if err != nil { + util.HandleServiceError(c, err) return - } else { - if v3x1 := res.Spec.ToConditionRouteV3x1(); v3x1 != nil { - res.Spec = v3x1.ToConditionRoute() - } - c.JSON(http.StatusOK, model.GenConditionRuleToResp(res.Spec)) } + if res == nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.NotFoundError, fmt.Sprintf("%s not found", ruleName)))) + return + } + c.JSON(http.StatusOK, model.GenConditionRuleToResp(res.Spec)) } } -func bodyToMap(reader io.ReadCloser) (map[string]interface{}, error) { - defer reader.Close() - res := map[string]interface{}{} - err := json.NewDecoder(reader).Decode(&res) - return res, err -} - -func mapToStructure(m map[string]interface{}, s interface{}) error { - decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - Result: s, - TagName: "json", - }) - if err != nil { - return err - } - err = decoder.Decode(m) - return err -} - func PutConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConditionRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConditionRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConditionRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConditionRuleDotSuffix) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("ruleName must end with %s", constants.ConditionRuleDotSuffix)))) return } - _map, err := bodyToMap(c.Request.Body) + conditionRuleRes, err := service.GetConditionRule(cs, ruleName, mesh) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } - - res := &mesh.ConditionRouteResource{} - if version := _map[consts.ConfigVersionKey]; version == consts.ConfiguratorVersionV3 { - v3 := new(meshproto.ConditionRouteV3) - err = mapToStructure(_map, &v3) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - err = res.SetSpec(v3.ToConditionRoute()) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else if version == consts.ConfiguratorVersionV3x1 { - v3x1 := new(meshproto.ConditionRouteV3X1) - err = mapToStructure(_map, &v3x1) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - - err = res.SetSpec(v3x1.ToConditionRoute()) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp("invalid request body")) + if conditionRuleRes == nil { + util.HandleNotFoundError(c, ruleName) + return + } + res := meshresource.NewConditionRouteResourceWithAttributes(ruleName, mesh) + if err := c.ShouldBindJSON(res.Spec); err != nil { + util.HandleArgumentError(c, err) return } - if err := service.UpdateConditionRule(cs, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := service.UpdateConditionRule(cs, res); err != nil { + util.HandleServiceError(c, err) return } else { c.JSON(http.StatusOK, model.GenConditionRuleToResp(res.Spec)) @@ -149,52 +106,21 @@ func PutConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { func PostConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConditionRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConditionRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConditionRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConditionRuleDotSuffix) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("ruleName must end with %s", constants.ConditionRuleDotSuffix)))) return } - _map, err := bodyToMap(c.Request.Body) - if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + res := meshresource.NewConditionRouteResourceWithAttributes(ruleName, mesh) + if err := c.ShouldBindJSON(res.Spec); err != nil { + util.HandleArgumentError(c, err) return } - res := &mesh.ConditionRouteResource{} - if version := _map[consts.ConfigVersionKey]; version == consts.ConfiguratorVersionV3 { - v3 := new(meshproto.ConditionRouteV3) - err = mapToStructure(_map, &v3) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - err = res.SetSpec(v3.ToConditionRoute()) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else if version == consts.ConfiguratorVersionV3x1 { - v3x1 := new(meshproto.ConditionRouteV3X1) - err = mapToStructure(_map, &v3x1) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - err = res.SetSpec(v3x1.ToConditionRoute()) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp("invalid request body")) - return - } - - if err := service.CreateConditionRule(cs, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := service.CreateConditionRule(cs, res); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } else { c.JSON(http.StatusOK, model.GenConditionRuleToResp(res.Spec)) @@ -204,17 +130,15 @@ func PostConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { func DeleteConditionRuleWithRuleName(cs consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - res := &mesh.ConditionRouteResource{Spec: &meshproto.ConditionRoute{}} - if strings.HasSuffix(ruleName, consts.ConditionRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConditionRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConditionRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConditionRuleDotSuffix) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("ruleName must end with %s", constants.ConditionRuleDotSuffix)))) return } - if err := service.DeleteConditionRule(cs, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := service.DeleteConditionRule(cs, ruleName, mesh); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } c.JSON(http.StatusOK, model.NewSuccessResp("")) diff --git a/pkg/console/handler/configurator_rule.go b/pkg/console/handler/configurator_rule.go index 1851a9da9..0b806715b 100644 --- a/pkg/console/handler/configurator_rule.go +++ b/pkg/console/handler/configurator_rule.go @@ -20,142 +20,134 @@ package handler import ( "fmt" "net/http" - "strconv" "strings" + "github.com/duke-git/lancet/v2/strutil" "github.com/gin-gonic/gin" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" ) func ConfiguratorSearch(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - req := model.NewSearchConfiguratorReq() + req := model.NewSearchReq() if err := c.ShouldBindQuery(req); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - ruleList := &mesh.DynamicConfigResourceList{} - var respList []model.ConfiguratorSearchResp - if req.Keywords == "" { - if err := ctx.ResourceManager().List(ctx.AppContext(), ruleList, store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } + var searchResult *model.SearchPaginationResult + var err error + if strutil.IsBlank(req.Keywords) { + searchResult, err = service.PageListConfiguratorRule(ctx, req) } else { - if err := ctx.ResourceManager().List(ctx.AppContext(), ruleList, store.ListByNameContains(req.Keywords), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } - } - for _, item := range ruleList.Items { - respList = append(respList, model.ConfiguratorSearchResp{ - RuleName: item.Meta.GetName(), - Scope: item.Spec.GetScope(), - CreateTime: item.Meta.GetCreationTime().String(), - Enabled: item.Spec.GetEnabled(), - }) - } - result := model.NewSearchPaginationResult() - result.List = respList - result.PageInfo = &ruleList.Pagination - c.JSON(http.StatusOK, model.NewSuccessResp(result)) + searchResult, err = service.SearchConfiguratorRuleByKeywords(ctx, req) + } + if err != nil { + util.HandleServiceError(c, err) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(searchResult)) } } func GetConfiguratorWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConfiguratorRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConfiguratorRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConfiguratorRuleSuffix))) + mesh := c.Query("mesh") + if strutil.IsBlank(ruleName) { + c.JSON(http.StatusBadRequest, model.NewErrorResp("ruleName cannot be empty")) + return + } + if strutil.IsBlank(mesh) { + c.JSON(http.StatusBadRequest, model.NewErrorResp("mesh cannot be empty")) return } - res, err := service.GetConfigurator(ctx, name) + res, err := service.GetConfigurator(ctx, ruleName, mesh) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } + if res == nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.NotFoundError, fmt.Sprintf("%s not found", ruleName)))) + } c.JSON(http.StatusOK, model.GenDynamicConfigToResp(res.Spec)) } } func PutConfiguratorWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConfiguratorRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConfiguratorRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConfiguratorRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConfiguratorRuleDotSuffix) { + c.JSON(http.StatusOK, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("dynamic config name must end with %s", constants.ConfiguratorRuleDotSuffix)))) return } - res := &mesh.DynamicConfigResource{ - Meta: nil, - Spec: &meshproto.DynamicConfig{}, - } + res := meshresource.NewDynamicConfigResourceWithAttributes(ruleName, mesh) err := c.Bind(res.Spec) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - if err = service.UpdateConfigurator(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + configurator, err := service.GetConfigurator(ctx, ruleName, mesh) + if err != nil { + util.HandleServiceError(c, err) + return + } + if configurator == nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.NotFoundError, fmt.Sprintf("%s not found", ruleName)))) + } + if err = service.UpdateConfigurator(ctx, res); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return - } else { - c.JSON(http.StatusOK, model.GenDynamicConfigToResp(res.Spec)) } + c.JSON(http.StatusOK, model.GenDynamicConfigToResp(res.Spec)) } } func PostConfiguratorWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.ConfiguratorRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConfiguratorRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConfiguratorRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConfiguratorRuleDotSuffix) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("dynamic config name must end with %s", constants.ConfiguratorRuleDotSuffix)))) return } - res := &mesh.DynamicConfigResource{ - Meta: nil, - Spec: &meshproto.DynamicConfig{}, - } + res := meshresource.NewDynamicConfigResourceWithAttributes(ruleName, mesh) err := c.Bind(res.Spec) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - if err = service.CreateConfigurator(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err = service.CreateConfigurator(ctx, res); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return - } else { - c.JSON(http.StatusOK, model.GenDynamicConfigToResp(res.Spec)) } + c.JSON(http.StatusOK, model.GenDynamicConfigToResp(res.Spec)) + } } func DeleteConfiguratorWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - res := &mesh.DynamicConfigResource{Spec: &meshproto.DynamicConfig{}} - if strings.HasSuffix(ruleName, consts.ConfiguratorRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.ConfiguratorRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.ConfiguratorRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.ConfiguratorRuleDotSuffix) { + c.JSON(http.StatusOK, model.NewBizErrorResp(bizerror.New(bizerror.InvalidArgument, + fmt.Sprintf("dynamic config name must end with %s", constants.ConfiguratorRuleDotSuffix)))) return } - if err := service.DeleteConfigurator(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := service.DeleteConfigurator(ctx, ruleName, mesh); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } c.JSON(http.StatusOK, model.NewSuccessResp("")) diff --git a/pkg/console/handler/instance.go b/pkg/console/handler/instance.go index 91aead806..48d4966e4 100644 --- a/pkg/console/handler/instance.go +++ b/pkg/console/handler/instance.go @@ -22,15 +22,14 @@ import ( "strconv" "strings" + "github.com/duke-git/lancet/v2/strutil" "github.com/gin-gonic/gin" - "github.com/pkg/errors" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" - corestore "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" ) func GetInstanceDetail(ctx consolectx.Context) gin.HandlerFunc { @@ -43,15 +42,15 @@ func GetInstanceDetail(ctx consolectx.Context) gin.HandlerFunc { resp, err := service.GetInstanceDetail(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } - if len(resp) == 0 { - c.JSON(http.StatusNotFound, model.NewErrorResp("instance not exist")) + if resp == nil { + util.HandleNotFoundError(c, req.InstanceName) return } - c.JSON(http.StatusOK, model.NewSuccessResp(resp[0])) + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } @@ -59,13 +58,14 @@ func SearchInstances(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := model.NewSearchInstanceReq() if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.New(bizerror.InvalidArgument, "appName is empty"))) return } instances, err := service.SearchInstances(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } @@ -79,205 +79,55 @@ func InstanceConfigTrafficDisableGET(ctx consolectx.Context) gin.HandlerFunc { TrafficDisable bool `json:"trafficDisable"` }{false} applicationName := c.Query("appName") - if applicationName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is empty")) + mesh := c.Query("mesh") + if strutil.IsBlank(applicationName) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.New(bizerror.InvalidArgument, "appName is empty"))) return } instanceIP := strings.TrimSpace(c.Query("instanceIP")) - if instanceIP == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("instanceIP is empty")) + if strutil.IsBlank(instanceIP) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.New(bizerror.InvalidArgument, "instanceIP is empty"))) return } - - res, err := service.GetConditionRule(ctx, applicationName) + trafficStatus, err := service.GetInstanceTrafficStatus(ctx, mesh, applicationName, instanceIP) if err != nil { - if corestore.IsResourceNotFound(err) { - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - return - } - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - - if res.Spec.GetVersion() != consts.ConfiguratorVersionV3 { - c.JSON(http.StatusServiceUnavailable, model.NewErrorResp("this config only serve condition-route.configVersion == v3, got v3.1 config ")) + util.HandleServiceError(c, err) return } - - cr := res.Spec.ToConditionRouteV3() - cr.RangeConditions(func(condition string) (isStop bool) { - _, resp.TrafficDisable = isTrafficDisabledV3(condition, instanceIP) - return resp.TrafficDisable - }) - + resp.TrafficDisable = trafficStatus c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func isTrafficDisabledV3X1(r *meshproto.ConditionRule, targetIP string) bool { - if len(r.To) != 0 { - return false - } - // rule must match `host=x1{,x2,x3}` - if r.From.Match != "" && !strings.Contains(r.From.Match, "&") && strings.Index(r.From.Match, "!=") == -1 { - idx := strings.Index(r.From.Match, "=") - if idx == -1 { - return false - } - then := r.From.Match[idx+1:] - Ips := strings.Split(then, ",") - for _, ip := range Ips { - if strings.TrimSpace(ip) == targetIP { - return true - } - } - } - return false -} - -/* -* -isTrafficDisabledV3 judge if a condition is disabled or not. -A condition include fromCondition and toCondition which is seperated by `=>`. -The first return parameter `exist` indicates if a condition of specific targetIP exists. -The second return parameter `disabled` indicates if the traffic of targetIP is disabled. -*/ -func isTrafficDisabledV3(condition string, targetIP string) (exist bool, disabled bool) { - if len(condition) == 0 { - return false, false - } - condition = strings.ReplaceAll(condition, " ", "") - // only accept string start with `=>` - if !strings.HasPrefix(condition, "=>") { - return false, false - } - toCondition := strings.TrimPrefix(condition, "=>") - // TODO more specific judge - if !strings.Contains(toCondition, targetIP) { - return false, false - } - targetExpression := "host!=" + targetIP - if targetExpression != toCondition { - return true, false - } - return true, true -} - func InstanceConfigTrafficDisablePUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { appName := strings.TrimSpace(c.Query("appName")) - if appName == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is empty")) + mesh := c.Query("mesh") + if strutil.IsBlank(appName) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.New(bizerror.InvalidArgument, "appName is empty"))) return } instanceIP := strings.TrimSpace(c.Query("instanceIP")) - if instanceIP == "" { - c.JSON(http.StatusBadRequest, model.NewErrorResp("instanceIP is empty")) + if strutil.IsBlank(instanceIP) { + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.New(bizerror.InvalidArgument, "instanceIP is empty"))) return } - newDisabled, err := strconv.ParseBool(c.Query(`trafficDisable`)) + disableTraffic, err := strconv.ParseBool(c.Query(`trafficDisable`)) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(errors.Wrap(err, "parse trafficDisable fail").Error())) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp( + bizerror.Wrap(err, bizerror.InvalidArgument, "parse trafficDisable failed"))) return } - - existRule := true - rawRes, err := service.GetConditionRule(ctx, appName) - var res *meshproto.ConditionRouteV3 + err = service.UpdateInstanceTrafficStatus(ctx, mesh, appName, instanceIP, disableTraffic) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } else if !newDisabled { // not found && cancel traffic-disable - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - return - } - existRule = false - res = generateDefaultConditionV3(true, true, true, appName, consts.ScopeApplication) - rawRes = &mesh.ConditionRouteResource{Spec: res.ToConditionRoute()} - } else if res = rawRes.Spec.ToConditionRouteV3(); res == nil { - c.JSON(http.StatusServiceUnavailable, model.NewErrorResp("this config only serve condition-route.configVersion == v3.1, got v3.0 config ")) + util.HandleServiceError(c, err) return } - - // enable traffic - if !newDisabled { - for i, condition := range res.Conditions { - existCondition, oldDisabled := isTrafficDisabledV3(condition, instanceIP) - if existCondition { - if oldDisabled != newDisabled { - res.Conditions = append(res.Conditions[:i], res.Conditions[i+1:]...) - rawRes.Spec = res.ToConditionRoute() - if err = updateORCreateConditionRule(ctx, existRule, appName, rawRes); err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - return - } - } - } - } else { // disable traffic - // check if condition exists - for _, condition := range res.Conditions { - existCondition, oldDisabled := isTrafficDisabledV3(condition, instanceIP) - if existCondition && oldDisabled { - c.JSON(http.StatusBadRequest, model.NewErrorResp("The instance has been disabled!")) - return - } - } - res.Conditions = append(res.Conditions, disableExpression(instanceIP)) - if err = updateORCreateConditionRule(ctx, existRule, appName, rawRes); err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - } - } -} - -func disableExpression(instanceIP string) string { - return "=>host!=" + instanceIP -} -func updateORCreateConditionRule(ctx consolectx.Context, existRule bool, appName string, rawRes *mesh.ConditionRouteResource) error { - if !existRule { - return service.CreateConditionRule(ctx, appName, rawRes) - } else { - return service.UpdateConditionRule(ctx, appName, rawRes) - } -} - -func newDisableConditionV3x1(ip string) *meshproto.ConditionRule { - return &meshproto.ConditionRule{ - From: &meshproto.ConditionRuleFrom{Match: "host=" + ip}, - To: nil, - } -} - -func newDisableConditionV3(ip string) string { - return "=>host!=" + ip -} - -func generateDefaultConditionV3x1(Enabled, Force, Runtime bool, Key, Scope string) *meshproto.ConditionRouteV3X1 { - return &meshproto.ConditionRouteV3X1{ - ConfigVersion: consts.ConfiguratorVersionV3x1, - Enabled: Enabled, - Force: Force, - Runtime: Runtime, - Key: Key, - Scope: Scope, - Conditions: make([]*meshproto.ConditionRule, 0), - } -} - -func generateDefaultConditionV3(Enabled, Force, Runtime bool, Key, Scope string) *meshproto.ConditionRouteV3 { - return &meshproto.ConditionRouteV3{ - ConfigVersion: consts.ConfiguratorVersionV3, - Priority: 0, - Enabled: true, - Force: Force, - Runtime: Runtime, - Key: Key, - Scope: Scope, - Conditions: make([]string, 0), + c.JSON(http.StatusOK, model.NewSuccessResp(nil)) } } @@ -287,113 +137,56 @@ func InstanceConfigOperatorLogGET(ctx consolectx.Context) gin.HandlerFunc { OperatorLog bool `json:"operatorLog"` }{false} applicationName := c.Query(`appName`) - if applicationName == "" { + if strutil.IsBlank(applicationName) { c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is empty")) return } instanceIP := c.Query(`instanceIP`) - if instanceIP == "" { + if strutil.IsBlank(instanceIP) { c.JSON(http.StatusBadRequest, model.NewErrorResp("instanceIP is empty")) return } - - res, err := service.GetConfigurator(ctx, applicationName) - if err != nil { - if corestore.IsResourceNotFound(err) { - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - return - } - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) + mesh := c.Query(`mesh`) + if strutil.IsBlank(mesh) { + c.JSON(http.StatusBadRequest, model.NewErrorResp("mesh is empty")) return } - - if res.Spec.Enabled { - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - resp.OperatorLog = isInstanceOperatorLogOpen(conf, instanceIP) - return resp.OperatorLog - }) + accessLogOpenStatus, err := service.GetInstanceAccessLogOpenStatus(ctx, mesh, applicationName, instanceIP) + if err != nil { + util.HandleServiceError(c, err) + return } - + resp.OperatorLog = accessLogOpenStatus c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func isInstanceOperatorLogOpen(conf *meshproto.OverrideConfig, IP string) bool { - if conf != nil && - conf.Match != nil && - conf.Match.Address != nil && - conf.Match.Address.Wildcard == IP+`:*` && - conf.Side == consts.SideProvider && - conf.Parameters != nil && - conf.Parameters[`accesslog`] == `true` { - return true - } - return false -} - func InstanceConfigOperatorLogPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { applicationName := c.Query(`appName`) - if applicationName == "" { + if strutil.IsBlank(applicationName) { c.JSON(http.StatusBadRequest, model.NewErrorResp("application name is empty")) return } instanceIP := c.Query(`instanceIP`) - if instanceIP == "" { + if strutil.IsBlank(instanceIP) { c.JSON(http.StatusBadRequest, model.NewErrorResp("instanceIP is empty")) return } - adminOperatorLog, err := strconv.ParseBool(c.Query(`operatorLog`)) + openAccessLog, err := strconv.ParseBool(c.Query(`operatorLog`)) if err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - - res, err := service.GetConfigurator(ctx, applicationName) - notExist := false - if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusNotFound, model.NewErrorResp(err.Error())) - return - } - res = generateDefaultConfigurator(applicationName, consts.ScopeApplication, consts.ConfiguratorVersionV3, true) - notExist = true - } - - if !adminOperatorLog { - res.Spec.RangeConfigsToRemove(func(conf *meshproto.OverrideConfig) (IsRemove bool) { - return isInstanceOperatorLogOpen(conf, instanceIP) - }) - } else { - var isExist bool - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - isExist = isInstanceOperatorLogOpen(conf, instanceIP) - return isExist - }) - if !isExist { - res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ - Side: consts.SideProvider, - Match: &meshproto.ConditionMatch{Address: &meshproto.AddressMatch{Wildcard: instanceIP + `:*`}}, - Parameters: map[string]string{`accesslog`: `true`}, - XGenerateByCp: true, - }) - } + mesh := c.Query("mesh") + if strutil.IsBlank(mesh) { + c.JSON(http.StatusBadRequest, model.NewErrorResp("mesh is empty")) + return } - - if notExist { - err = service.CreateConfigurator(ctx, applicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateConfigurator(ctx, applicationName, res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + if err = service.UpdateInstanceAccessLogOpenStatus(ctx, mesh, applicationName, instanceIP, openAccessLog); err != nil { + util.HandleServiceError(c, err) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) } } diff --git a/pkg/console/handler/grafana.go b/pkg/console/handler/mesh.go similarity index 63% rename from pkg/console/handler/grafana.go rename to pkg/console/handler/mesh.go index d8043fcb7..227c3427d 100644 --- a/pkg/console/handler/grafana.go +++ b/pkg/console/handler/mesh.go @@ -17,29 +17,28 @@ package handler -// reverse proxy for grafana import ( "net/http" - "net/http/httputil" - "net/url" + "github.com/duke-git/lancet/v2/slice" "github.com/gin-gonic/gin" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" ) -func Grafana(ctx consolectx.Context) gin.HandlerFunc { +// ListMeshes list all meshes(discoveries) defined in config +func ListMeshes(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - baseUrl := ctx.Config().Console.Grafana - grafanaURL := baseUrl + "grafana" + c.Param("any") - proxyUrl, _ := url.Parse(grafanaURL) - director := func(req *http.Request) { - req.URL.Scheme = proxyUrl.Scheme - req.URL.Host = proxyUrl.Host - req.Host = proxyUrl.Host - req.URL.Path = proxyUrl.Path - } - proxy := &httputil.ReverseProxy{Director: director} - proxy.ServeHTTP(c.Writer, c.Request) + discoveries := ctx.Config().Discovery + meshes := slice.Map(discoveries, func(index int, item *discoverycfg.Config) model.MeshResp { + return model.MeshResp{ + ID: item.ID, + Name: item.Name, + Type: string(item.Type), + } + }) + c.JSON(http.StatusOK, model.NewSuccessResp(meshes)) } } diff --git a/pkg/console/handler/observability.go b/pkg/console/handler/observability.go index 6a59e3e24..77044a928 100644 --- a/pkg/console/handler/observability.go +++ b/pkg/console/handler/observability.go @@ -18,14 +18,25 @@ package handler import ( + "fmt" "net/http" "github.com/gin-gonic/gin" - "github.com/apache/dubbo-admin/pkg/console/constants" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + consolecfg "github.com/apache/dubbo-admin/pkg/config/console" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" + "github.com/apache/dubbo-admin/pkg/console/util" +) + +type DashboardType string + +const ( + MetricDashboard DashboardType = "metric" + TraceDashboard DashboardType = "trace" ) type Dimension string @@ -36,63 +47,62 @@ const ( ServiceDimension Dimension = constants.Service ) -func GetMetricDashBoard(ctx consolectx.Context, dim Dimension) gin.HandlerFunc { +func GetGrafanaDashboard(ctx consolectx.Context, dim Dimension, dashboardType DashboardType) gin.HandlerFunc { return func(c *gin.Context) { - var req model.DashboardReq - var url string - switch dim { - case AppDimension: - req = &model.AppDashboardReq{} - url = ctx.Config().Console.MetricDashboards.Application.BaseURL - case InstanceDimension: - req = &model.InstanceDashboardReq{} - url = ctx.Config().Console.MetricDashboards.Instance.BaseURL - case ServiceDimension: - req = &model.ServiceDashboardReq{} - url = ctx.Config().Console.MetricDashboards.Service.BaseURL - } - if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return + var grafanaDashboards *consolecfg.GrafanaDashboardConfig + switch dashboardType { + case MetricDashboard: + grafanaDashboards = ctx.Config().Console.MetricDashboards + case TraceDashboard: + grafanaDashboards = ctx.Config().Console.TraceDashboards } - resp := model.DashboardResp{ - BaseURL: url + req.GetKeyVariable(), + if grafanaDashboards == nil { + c.JSON(http.StatusOK, model.NewBizErrorResp(bizerror.New(bizerror.NotFoundError, + fmt.Sprintf("please configure grafana dashboard for %s %s in config yaml", dim, dashboardType)))) } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - } -} - -func GetTraceDashBoard(ctx consolectx.Context, dim Dimension) gin.HandlerFunc { - return func(c *gin.Context) { - var req model.DashboardReq - var url string + var fullURL string + var err error switch dim { case AppDimension: - req = &model.AppDashboardReq{} - url = ctx.Config().Console.TraceDashboards.Application.BaseURL + "?var-application=" + var req model.AppDashboardReq + if err = c.ShouldBindQuery(&req); err != nil { + break + } + fullURL, err = service.GetAppDashboard(grafanaDashboards.AppDashboardURL, &req) case InstanceDimension: - req = &model.InstanceDashboardReq{} - url = ctx.Config().Console.TraceDashboards.Instance.BaseURL + "?var-instance=" + var req model.InstanceDashboardReq + if err = c.ShouldBindQuery(&req); err != nil { + break + } + fullURL, err = service.GetInstanceDashboard(ctx, grafanaDashboards.InstanceDashboardURL, &req) case ServiceDimension: - req = &model.ServiceDashboardReq{} - url = ctx.Config().Console.TraceDashboards.Service.BaseURL + "?var-service=" + var req model.ServiceDashboardReq + if err = c.ShouldBindQuery(&req); err != nil { + break + } + fullURL, err = service.GetServiceDashboard(grafanaDashboards.ServiceDashboardURL, &req) } - if err := c.ShouldBindQuery(req); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + + if err != nil { + util.HandleServiceError(c, err) return } - resp := model.DashboardResp{ - BaseURL: url + req.GetKeyVariable(), - } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + c.JSON(http.StatusOK, model.NewSuccessResp(model.DashboardResp{ + FullURL: fullURL, + })) } } func GetPrometheus(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - resp := ctx.Config().Console.Prometheus + if ctx.Config().Observability.PrometheusBaseURL == nil { + c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + return + } + resp := ctx.Config().Observability.PrometheusBaseURL.String() c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + return } } @@ -100,10 +110,12 @@ func GetMetricsList(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := &model.MetricsReq{} if err := c.ShouldBindQuery(req); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) + return } resp, err := service.GetInstanceMetrics(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } c.JSON(http.StatusOK, model.NewSuccessResp(resp)) diff --git a/pkg/console/handler/overview.go b/pkg/console/handler/overview.go index 28ebd64d0..1d9dc9715 100644 --- a/pkg/console/handler/overview.go +++ b/pkg/console/handler/overview.go @@ -20,182 +20,74 @@ package handler import ( "net/http" - gxset "github.com/dubbogo/gost/container/set" "github.com/gin-gonic/gin" - "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/counter" "github.com/apache/dubbo-admin/pkg/console/model" - coremanager "github.com/apache/dubbo-admin/pkg/core/manager" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" ) -func GetInstances(ctx consolectx.Context) gin.HandlerFunc { +func AdminMetadata(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - if err := manager.List(ctx.AppContext(), dataplaneList); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - }) + mesh, exists := c.GetQuery("mesh") + if !exists { + util.HandleServiceError(c, bizerror.New(bizerror.InvalidArgument, "mesh is required")) return } - c.JSON(http.StatusOK, model.NewSuccessResp(dataplaneList)) - } -} - -func GetMetas(ctx consolectx.Context) gin.HandlerFunc { - return func(c *gin.Context) { - manager := ctx.ResourceManager() - metadataList := &mesh.MetaDataResourceList{} - if err := manager.List(ctx.AppContext(), metadataList); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - }) - return + var registryAddr string + var metadataAddr string + var configAddr string + if d := ctx.Config().FindDiscovery(mesh); d != nil { + registryAddr = d.Address.Registry + metadataAddr = d.Address.MetadataReport + configAddr = d.Address.ConfigCenter } - c.JSON(http.StatusOK, model.NewSuccessResp(metadataList)) - } -} - -func GetMappings(ctx consolectx.Context) gin.HandlerFunc { - return func(c *gin.Context) { - manager := ctx.ResourceManager() - mappingList := &mesh.MappingResourceList{} - if err := manager.List(ctx.AppContext(), mappingList); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - }) - return + var prometheusURL string + var grafanaURL string + if ctx.Config().Observability.PrometheusBaseURL != nil { + prometheusURL = ctx.Config().Observability.PrometheusBaseURL.String() } - c.JSON(http.StatusOK, model.NewSuccessResp(mappingList)) - } -} - -func AdminMetadata(ctx consolectx.Context) gin.HandlerFunc { - return func(c *gin.Context) { - res := model.NewAdminMetadata() - // TODO - c.JSON(http.StatusOK, model.NewSuccessResp(res)) - } -} - -func ClusterOverview(ctx consolectx.Context) gin.HandlerFunc { - return func(c *gin.Context) { - res := model.NewOverviewResp() - - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - if err := manager.List(ctx.AppContext(), dataplaneList); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - }) - return + if ctx.Config().Observability.GrafanaBaseURL != nil { + grafanaURL = ctx.Config().Observability.GrafanaBaseURL.String() } - - calAppCount(res, dataplaneList) - err := calServiceInfo(res, dataplaneList, ctx, manager) - if err != nil { - return + metadata := model.AdminMetadata{ + Registry: registryAddr, + Metadata: metadataAddr, + Config: configAddr, + Prometheus: prometheusURL, + Grafana: grafanaURL, + Tracing: "", } - res.InsCount = len(dataplaneList.Items) - - c.JSON(http.StatusOK, model.NewSuccessResp(res)) - } -} - -func calAppCount(res *model.OverviewResp, list *mesh.DataplaneResourceList) { - set := gxset.NewSet() - for _, ins := range list.Items { - set.Add(ins.Spec.GetExtensions()[v1alpha1.Application]) + c.JSON(http.StatusOK, model.NewSuccessResp(metadata)) } - - res.AppCount = set.Size() } -func calServiceInfo(res *model.OverviewResp, list *mesh.DataplaneResourceList, ctx consolectx.Context, manager coremanager.ResourceManager) error { - revisions := make(map[string]*mesh.MetaDataResource, 0) - protocols := make(map[string]*gxset.HashSet) - releases := make(map[string]string) - services := make(map[string]string) - discoveries := make(map[string]*gxset.HashSet) - - for _, ins := range list.Items { - app := ins.Spec.GetExtensions()[v1alpha1.Application] - - t := ins.Spec.GetExtensions()["registry-type"] - if t == "" { - t = "instance" - } - if set, ok := discoveries[t]; ok { - set.Add(app) - } else { - newSet := gxset.NewSet() - newSet.Add(app) - discoveries[t] = newSet - } - - rev, exists := ins.Spec.GetExtensions()[v1alpha1.RevisionLabel] - if exists { - metadata, cached := revisions[rev] - if !cached { - metadata = &mesh.MetaDataResource{ - Spec: &v1alpha1.MetaData{}, - } - if err := manager.Get(ctx.AppContext(), metadata, store.GetByRevision(rev), store.GetByType(ins.Spec.GetExtensions()["registry-type"])); err != nil { - return err - } - revisions[rev] = metadata - - for _, serviceInfo := range metadata.Spec.Services { - // proKey := serviceInfo.Protocol + strconv.Itoa(int(serviceInfo.Port)) - proKey := serviceInfo.Protocol - if extProtocols, ok := serviceInfo.GetParams()["ext.protocol"]; ok { - proKey = proKey + extProtocols - } - if set, ok := protocols[proKey]; ok { - set.Add(serviceInfo.Name) - } else { - newSet := gxset.NewSet() - protocols[proKey] = newSet - newSet.Add(serviceInfo.Name) - } - - if _, ok := releases[app]; !ok { - releases[app] = serviceInfo.Params["release"] - } - - if _, ok := services[serviceInfo.Name]; !ok { - services[serviceInfo.Name] = serviceInfo.Name - } - } +// ClusterOverview get cluster overview +func ClusterOverview(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + resp := model.NewOverviewResp() + if counterMgr := ctx.CounterManager(); counterMgr != nil { + mesh := c.Query("mesh") + + if mesh != "" { + resp.AppCount = counterMgr.CountByMesh(meshresource.ApplicationKind, mesh) + resp.ServiceCount = counterMgr.CountByMesh(meshresource.ServiceProviderMetadataKind, mesh) + resp.InsCount = counterMgr.CountByMesh(meshresource.InstanceKind, mesh) + resp.Protocols = counterMgr.DistributionByMesh(counter.ProtocolCounter, mesh) + resp.Releases = counterMgr.DistributionByMesh(counter.ReleaseCounter, mesh) + resp.Discoveries = counterMgr.DistributionByMesh(counter.DiscoveryCounter, mesh) + } else { + resp.AppCount = counterMgr.Count(meshresource.ApplicationKind) + resp.ServiceCount = counterMgr.Count(meshresource.ServiceProviderMetadataKind) + resp.InsCount = counterMgr.Count(meshresource.InstanceKind) + resp.Protocols = counterMgr.Distribution(counter.ProtocolCounter) + resp.Releases = counterMgr.Distribution(counter.ReleaseCounter) + resp.Discoveries = counterMgr.Distribution(counter.DiscoveryCounter) } } + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } - - releaseCount := make(map[string]int) - for _, ver := range releases { - if n, ok := releaseCount[ver]; ok { - releaseCount[ver] = n + 1 - } else { - releaseCount[ver] = 1 - } - } - - protocolCount := make(map[string]int) - for p, set := range protocols { - protocolCount[p] = set.Size() - } - - discoveryCount := make(map[string]int) - for d, set := range discoveries { - discoveryCount[d] = set.Size() - } - - res.ServiceCount = len(services) - res.Releases = releaseCount - res.Protocols = protocolCount - res.Discoveries = discoveryCount - - return nil } diff --git a/pkg/console/handler/prometheus.go b/pkg/console/handler/prometheus.go index fdf92b4bb..f02625285 100644 --- a/pkg/console/handler/prometheus.go +++ b/pkg/console/handler/prometheus.go @@ -17,30 +17,44 @@ package handler -// proxy for prometheus - import ( + "io" "net/http" - "net/http/httputil" - "net/url" "github.com/gin-gonic/gin" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" ) func PromQL(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - query := c.Request.URL.Query().Get("query") - values := url.Values{} - values.Add("query", query) - promUrl := ctx.Config().Console.Prometheus + "/api/v1/query?" + values.Encode() - proxyUrl, _ := url.Parse(promUrl) - director := func(req *http.Request) { - req.URL.Scheme = proxyUrl.Scheme - req.URL.Host = proxyUrl.Host - req.Host = proxyUrl.Host - req.URL.Path = proxyUrl.Path + promBaseUrl := ctx.Config().Observability.PrometheusBaseURL + if promBaseUrl == nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.ConfigError, "Please configure prometheus url to retrieve metrics"))) + return + } + + u := *promBaseUrl + u.RawQuery = c.Request.URL.RawQuery + u.Path = "/api/v1/query" + s := u.String() + resp, err := http.Get(s) + if err != nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.NetWorkError, err.Error()))) + return + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + c.JSON(http.StatusOK, model.NewBizErrorResp( + bizerror.New(bizerror.NetWorkError, err.Error()))) + return } - proxy := &httputil.ReverseProxy{Director: director} - proxy.ServeHTTP(c.Writer, c.Request) + c.Data(http.StatusOK, resp.Header.Get("Content-Type"), body) } } diff --git a/pkg/console/handler/search.go b/pkg/console/handler/search.go index ad62cc81b..d888b7116 100644 --- a/pkg/console/handler/search.go +++ b/pkg/console/handler/search.go @@ -25,29 +25,27 @@ import ( consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) func BannerGlobalSearch(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - // 参考 API 定义 request 参数 req := model.NewSearchReq() if err := c.ShouldBindQuery(req); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - // 根据 request 分流调用,如服务未实现继续实现 - var res *model.SearchRes switch req.SearchType { case "ip": - instances, _ := service.BannerSearchIp(ctx, req) + instances, _ := service.SearchInstanceByIp(ctx, req) res = convertInstancesToSearchRes(instances) case "instanceName": - instances, _ := service.BannerSearchInstances(ctx, req) + instances, _ := service.SearchInstanceByName(ctx, req) res = convertInstancesToSearchRes(instances) case "appName": - applications, _ := service.BannerSearchApplications(ctx, req) + applications, _ := service.SearchApplicationsByKeywords(ctx, req) res = convertApplicationsToSearchRes(applications) case "serviceName": sreq := &model.ServiceSearchReq{ @@ -55,14 +53,14 @@ func BannerGlobalSearch(ctx consolectx.Context) gin.HandlerFunc { Keywords: req.Keywords, PageReq: req.PageReq, } - services, _ := service.BannerSearchServices(ctx, sreq) + services, _ := service.SearchServicesByKeywords(ctx, sreq) res = convertServicesToSearchRes(services) default: c.JSON(http.StatusBadRequest, model.NewErrorResp("invalid search type")) return } - - c.JSON(http.StatusOK, model.NewSuccessResp(model.NewPageData().WithData(res).WithTotal(len(res.Candidates)).WithPageSize(req.PageSize).WithCurPage(req.PageOffset))) + pageResult := coremodel.NewPageData[string](len(res.Candidates), req.PageOffset, req.PageSize, res.Candidates) + c.JSON(http.StatusOK, model.NewSuccessResp(pageResult)) } } diff --git a/pkg/console/handler/service.go b/pkg/console/handler/service.go index 7ff37e2ec..d78ff5264 100644 --- a/pkg/console/handler/service.go +++ b/pkg/console/handler/service.go @@ -18,18 +18,14 @@ package handler import ( - "errors" "net/http" - "strconv" "github.com/gin-gonic/gin" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" - corestore "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" ) const ( @@ -45,9 +41,9 @@ func SearchServices(ctx consolectx.Context) gin.HandlerFunc { return } - resp, err := service.GetSearchServices(ctx, req) + resp, err := service.SearchServices(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } @@ -55,7 +51,6 @@ func SearchServices(ctx consolectx.Context) gin.HandlerFunc { } } -// service distribution func GetServiceTabDistribution(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { req := &model.ServiceTabDistributionReq{} @@ -66,7 +61,7 @@ func GetServiceTabDistribution(ctx consolectx.Context) gin.HandlerFunc { resp, err := service.GetServiceTabDistribution(ctx, req) if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) + util.HandleServiceError(c, err) return } @@ -74,144 +69,119 @@ func GetServiceTabDistribution(ctx consolectx.Context) gin.HandlerFunc { } } -func ListServices(ctx consolectx.Context) gin.HandlerFunc { +func GetServiceProviderInstances(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - // req := &model.SearchInstanceReq{} + req := model.BaseServiceReq{} + if err := req.Query(c); err != nil { + util.HandleArgumentError(c, err) + return + } - c.JSON(http.StatusOK, model.NewSuccessResp("")) + resp, err := service.GetServiceProviderInstances(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } + + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func GetServiceDetail(ctx consolectx.Context) gin.HandlerFunc { +func GetServiceMethodNames(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - // req := &model.SearchInstanceReq{} + req := model.BaseServiceReq{} + if err := req.Query(c); err != nil { + util.HandleArgumentError(c, err) + return + } + + methodNames, err := service.GetServiceMethodNames(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } - c.JSON(http.StatusOK, model.NewSuccessResp("")) + c.JSON(http.StatusOK, model.NewSuccessResp(methodNames)) } } -func GetServiceInterfaces(ctx consolectx.Context) gin.HandlerFunc { +func GetServiceMethodDetail(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - // req := &model.SearchInstanceReq{} + req := model.ServiceMethodDetailReq{} + if err := req.Query(c); err != nil { + util.HandleArgumentError(c, err) + return + } - c.JSON(http.StatusOK, model.NewSuccessResp("")) + resp, err := service.GetServiceMethodDetail(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } + + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -type baseService struct { - Service string `json:"serviceName"` - Group string `json:"group"` - Version string `json:"version"` -} +func ServiceGenericInvoke(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + req := model.ServiceGenericInvokeReq{} + if err := c.ShouldBindJSON(&req); err != nil { + util.HandleArgumentError(c, err) + return + } -func (s *baseService) serviceName() string { - return s.Service -} + if err := req.Validate(); err != nil { + util.HandleArgumentError(c, err) + return + } -func (s *baseService) query(c *gin.Context) error { - s.Service = c.Query("serviceName") - if s.Service == "" { - return errors.New("service name is empty") - } - s.Group = c.Query("group") - s.Version = c.Query("version") - return nil -} + resp, err := service.InvokeServiceGeneric(ctx, req) + if err != nil { + util.HandleServiceError(c, err) + return + } -func (s *baseService) toInterface() string { - return s.Service + consts.Colon + s.Group + consts.Colon + s.Version + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + } } func ServiceConfigTimeoutGET(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - param := baseService{} + req := model.BaseServiceReq{} resp := struct { Timeout int32 `json:"timeout"` }{DefaultTimeout} - if err := param.query(c); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := req.Query(c); err != nil { + util.HandleArgumentError(c, err) return } - res, err := service.GetConfigurator(ctx, param.toInterface()) + timeout, err := service.GetServiceTimeoutConfig(ctx, req) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + util.HandleServiceError(c, err) return } - - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - resp.Timeout, isStop = getServiceTimeout(conf) - return isStop - }) - + resp.Timeout = timeout c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func getServiceTimeout(conf *meshproto.OverrideConfig) (int32, bool) { - if conf.Side == consts.SideProvider && conf.Parameters != nil && conf.Parameters[`timeout`] != "" { - timeout, err := strconv.Atoi(conf.Parameters[`timeout`]) - if err == nil { - return int32(timeout), true - } - } - return DefaultTimeout, false -} - func ServiceConfigTimeoutPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { param := struct { - baseService + model.BaseServiceReq Timeout int32 `json:"timeout"` }{} + Mesh := c.Query("mesh") + param.Mesh = Mesh if err := c.Bind(¶m); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - - isExist := true - res, err := service.GetConfigurator(ctx, param.toInterface()) + err := service.UpInsertServiceConfigTimeoutConfig(ctx, param.BaseServiceReq, param.Timeout) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - res = generateDefaultConfigurator(param.serviceName(), consts.ScopeService, consts.ConfiguratorVersionV3, true) - isExist = false - } else { - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - _, ok := getServiceTimeout(conf) - if ok { - conf.Parameters[`timeout`] = strconv.Itoa(int(param.Timeout)) - } - return ok - }) - } - - if !isExist { - res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ - Side: consts.SideProvider, - Parameters: map[string]string{`timeout`: strconv.Itoa(int(param.Timeout))}, - XGenerateByCp: true, - }) - err = service.CreateConfigurator(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateConfigurator(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + util.HandleServiceError(c, err) + return } c.JSON(http.StatusOK, model.NewSuccessResp(nil)) } @@ -219,92 +189,39 @@ func ServiceConfigTimeoutPUT(ctx consolectx.Context) gin.HandlerFunc { func ServiceConfigRetryGET(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - param := baseService{} + param := model.BaseServiceReq{} resp := struct { RetryTimes int32 `json:"retryTimes"` }{DefaultRetries} - if err := param.query(c); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := param.Query(c); err != nil { + util.HandleArgumentError(c, err) return } - res, err := service.GetConfigurator(ctx, param.toInterface()) + retries, err := service.GetServiceRetryConfig(ctx, param) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + util.HandleServiceError(c, err) return } - - res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { - resp.RetryTimes, isStop = getServiceRetryTimes(conf) - return isStop - }) - + resp.RetryTimes = retries c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func getServiceRetryTimes(conf *meshproto.OverrideConfig) (int32, bool) { - if conf.Side == consts.SideConsumer && conf.Parameters != nil && conf.Parameters[`retries`] != "" { - retries, err := strconv.Atoi(conf.Parameters[`retries`]) - if err == nil { - return int32(retries), true - } - } - return DefaultRetries, false -} - func ServiceConfigRetryPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { param := struct { - baseService + model.BaseServiceReq RetryTimes int32 `json:"retryTimes"` }{} + Mesh := c.Query("mesh") + param.Mesh = Mesh if err := c.Bind(¶m); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + util.HandleArgumentError(c, err) return } - - isExist := true - res, err := service.GetConfigurator(ctx, param.toInterface()) - if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - res = generateDefaultConfigurator(param.serviceName(), consts.ScopeService, consts.ConfiguratorVersionV3, true) - isExist = false - } - - res.Spec.RangeConfigsToRemove(func(conf *meshproto.OverrideConfig) (isRemove bool) { - _, ok := getServiceRetryTimes(conf) - return ok - }) - - res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ - Side: consts.SideConsumer, - Parameters: map[string]string{`retries`: strconv.Itoa(int(param.RetryTimes))}, - XGenerateByCp: true, - }) - - if !isExist { - err = service.CreateConfigurator(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.UpdateConfigurator(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + if err := service.UpInsertServiceRetryConfig(ctx, param.BaseServiceReq, param.RetryTimes); err != nil { + util.HandleServiceError(c, err) + return } c.JSON(http.StatusOK, model.NewSuccessResp(nil)) } @@ -312,200 +229,138 @@ func ServiceConfigRetryPUT(ctx consolectx.Context) gin.HandlerFunc { func ServiceConfigRegionPriorityGET(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - param := baseService{} + req := model.BaseServiceReq{} resp := struct { - Enabled bool `json:"enabled"` - Key string `json:"key"` - Ratio int `json:"ratio"` - }{false, "", 0} - if err := param.query(c); err != nil { + Enabled bool `json:"enabled"` + }{false} + if err := req.Query(c); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - - res, err := getAffinityRule(ctx, param.toInterface()) + openSameRegionPrior, err := service.GetServiceRegionPriorityConfig(ctx, req) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) - return - } else { - resp.Enabled = res.Spec.GetEnabled() - resp.Key = res.Spec.GetAffinity().GetKey() - resp.Ratio = int(res.Spec.GetAffinity().GetRatio()) - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + util.HandleServiceError(c, err) return } + resp.Enabled = openSameRegionPrior + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } func ServiceConfigRegionPriorityPUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { param := struct { - baseService - Enabled bool `json:"enabled"` - Key string `json:"key"` - Ratio int `json:"ratio"` + model.BaseServiceReq + Enabled bool `json:"enabled"` }{} + Mesh := c.Query("mesh") + param.Mesh = Mesh if err := c.Bind(¶m); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - - isExist := true - res, err := getAffinityRule(ctx, param.toInterface()) - if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } else { - res = new(mesh.AffinityRouteResource) - res.Spec = generateDefaultAffinityRule( - "service", - param.serviceName(), - param.Key, - false, - true, - param.Ratio, - ) - isExist = false - } - } else { - res.Spec.Enabled = param.Enabled - res.Spec.Affinity.Key = param.Key - res.Spec.Affinity.Ratio = int32(param.Ratio) - } - - if !isExist { - err = createAffinityRule(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = updateAffinityRule(ctx, param.toInterface(), res) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + if err := service.UpInsertServiceRegionPriorityConfig(ctx, param.BaseServiceReq, param.Enabled); err != nil { + util.HandleServiceError(c, err) + return } c.JSON(http.StatusOK, model.NewSuccessResp(nil)) - return } } -func generateDefaultAffinityRule(scope, key, focusKey string, runtime, enabled bool, ratio int) *meshproto.AffinityRoute { - return &meshproto.AffinityRoute{ - ConfigVersion: "v3.1", - Scope: scope, - Key: key, - Runtime: runtime, - Enabled: enabled, - Affinity: &meshproto.AffinityAware{ - Key: focusKey, - Ratio: int32(ratio), - }, +func ServiceConfigArgumentRouteGET(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + req := struct { + model.BaseServiceReq + }{} + if err := req.Query(c); err != nil { + util.HandleArgumentError(c, err) + return + } + resp, err := service.GetServiceArgumentRouteConfig(ctx, req.BaseServiceReq) + if err != nil { + util.HandleServiceError(c, err) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func ServiceConfigArgumentRouteGET(ctx consolectx.Context) gin.HandlerFunc { +func ServiceConfigArgumentRoutePUT(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { param := struct { - baseService + model.BaseServiceReq + model.ServiceArgumentRoute }{} - resp := model.ServiceArgumentRoute{Routes: make([]model.ServiceArgument, 0)} - if err := param.query(c); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + Mesh := c.Query("mesh") + param.Mesh = Mesh + if err := c.Bind(¶m); err != nil { + util.HandleArgumentError(c, err) return } - rawRes, err := service.GetConditionRule(ctx, param.toInterface()) + err := service.UpInsertServiceArgumentRouteConfig(ctx, param.BaseServiceReq, param.ServiceArgumentRoute) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + util.HandleServiceError(c, err) return + } + c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + } +} - } else if rawRes.Spec.ToConditionRouteV3() != nil { - c.JSON(http.StatusServiceUnavailable, model.NewErrorResp("this config only serve condition-route.configVersion == v3.1, got v3.0 config ")) +// GetServiceGraph returns the service graph as graph data (nodes and edges) for visualization +func GetServiceGraph(ctx consolectx.Context) gin.HandlerFunc { + return func(c *gin.Context) { + req := &model.ServiceGraphReq{} + if err := c.ShouldBindQuery(req); err != nil { + c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return + } - } else { - res := rawRes.Spec.ToConditionRouteV3x1() - res.RangeConditionsToRemove(func(r *meshproto.ConditionRule) (isRemove bool) { // 去除非方法匹配项 - _, ok := r.IsMatchMethod() - return !ok - }) - c.JSON(http.StatusOK, model.NewSuccessResp(model.ConditionV3x1ToServiceArgumentRoute(res.Conditions))) + resp, err := service.GraphServices(ctx, req) + if err != nil { + util.HandleServiceError(c, err) return } + + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } -func ServiceConfigArgumentRoutePUT(ctx consolectx.Context) gin.HandlerFunc { +// GetServiceDetail returns service detail information +func GetServiceDetail(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - param := struct { - baseService - model.ServiceArgumentRoute - }{} - if err := c.Bind(¶m); err != nil { + req := &model.ServiceDetailReq{} + if err := c.ShouldBindQuery(req); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - isExist := true - rawRes, err := service.GetConditionRule(ctx, param.toInterface()) + resp, err := service.GetServiceDetail(ctx, req) if err != nil { - if !corestore.IsResourceNotFound(err) { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } else if false { - // TODO(YarBor) : to check service exist or not - } - rawRes = new(mesh.ConditionRouteResource) - rawRes.Spec = generateDefaultConditionV3x1(true, false, true, param.serviceName(), consts.ScopeService).ToConditionRoute() - isExist = false - } - - res := rawRes.Spec.ToConditionRouteV3x1() - if res == nil { - c.JSON(http.StatusServiceUnavailable, model.NewErrorResp("this config only serve condition-route.configVersion == v3.1, got v3.0 config ")) - return - } - - if res.Conditions == nil { - res.Conditions = make([]*meshproto.ConditionRule, 0) - } - res.RangeConditionsToRemove(func(r *meshproto.ConditionRule) (isRemove bool) { - _, ok := r.IsMatchMethod() - return ok - }) - res.Conditions = append(res.Conditions, param.ToConditionV3x1Condition()...) - rawRes.Spec = res.ToConditionRoute() - - if isExist { - err = service.UpdateConditionRule(ctx, param.toInterface(), rawRes) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } - } else { - err = service.CreateConditionRule(ctx, param.toInterface(), rawRes) - if err != nil { - c.JSON(http.StatusInternalServerError, model.NewErrorResp(err.Error())) - return - } + util.HandleServiceError(c, err) + return } - c.JSON(http.StatusOK, model.NewSuccessResp(nil)) + + c.JSON(http.StatusOK, model.NewSuccessResp(resp)) } } + +// GetServiceInterfaces returns service interfaces information +func GetServiceInterfaces(ctx consolectx.Context) gin.HandlerFunc { + // return func(c *gin.Context) { + // req := &model.ServiceInterfacesReq{} + // if err := c.ShouldBindQuery(req); err != nil { + // c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + // return + // } + + // resp, err := service.GetServiceInterfaces(ctx, req) + // if err != nil { + // util.HandleServiceError(c, err) + // return + // } + + // c.JSON(http.StatusOK, model.NewSuccessResp(resp)) + // } + return nil +} diff --git a/pkg/console/handler/tag_rule.go b/pkg/console/handler/tag_rule.go index 03a3b0e1f..a6fe3637c 100644 --- a/pkg/console/handler/tag_rule.go +++ b/pkg/console/handler/tag_rule.go @@ -20,95 +20,91 @@ package handler import ( "fmt" "net/http" - "strconv" "strings" + "github.com/duke-git/lancet/v2/strutil" "github.com/gin-gonic/gin" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/console/service" - "github.com/apache/dubbo-admin/pkg/core/consts" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/console/util" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" ) func TagRuleSearch(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { + req := model.NewSearchReq() if err := c.ShouldBindQuery(req); err != nil { c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) return } - resList := &mesh.TagRouteResourceList{} - if req.Keywords == "" { - if err := ctx.ResourceManager().List(ctx.AppContext(), resList, store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } + var searchResult *model.SearchPaginationResult + var err error + if strutil.IsBlank(req.Keywords) { + searchResult, err = service.PageListTagRule(ctx, req) } else { - if err := ctx.ResourceManager().List(ctx.AppContext(), resList, store.ListByNameContains(req.Keywords), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) - return - } - } - var respList []model.TagRuleSearchResp - for _, item := range resList.Items { - time := item.Meta.GetCreationTime().String() - name := item.Meta.GetName() - respList = append(respList, model.TagRuleSearchResp{ - CreateTime: &time, - Enabled: &item.Spec.Enabled, - RuleName: &name, - }) - } - result := model.NewSearchPaginationResult() - result.List = respList - result.PageInfo = &resList.Pagination - c.JSON(http.StatusOK, model.NewSuccessResp(result)) + searchResult, err = service.SearchTagRuleByKeywords(ctx, req) + } + if err != nil { + util.HandleServiceError(c, err) + return + } + c.JSON(http.StatusOK, model.NewSuccessResp(searchResult)) } } func GetTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.TagRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.TagRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.TagRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.TagRuleDotSuffix) { + err := bizerror.New(bizerror.InvalidArgument, fmt.Sprintf("ruleName must end with %s", constants.TagRuleDotSuffix)) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(err)) return } - if res, err := service.GetTagRule(ctx, name); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + res, err := service.GetTagRule(ctx, ruleName, mesh) + if err != nil { + util.HandleServiceError(c, err) return - } else { - c.JSON(http.StatusOK, model.GenTagRouteResp(res.Spec)) } + if res == nil { + util.HandleNotFoundError(c, ruleName) + return + } + c.JSON(http.StatusOK, model.GenTagRouteResp(res.Spec)) } } func PutTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.TagRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.TagRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.TagRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.TagRuleDotSuffix) { + err := bizerror.New(bizerror.InvalidArgument, fmt.Sprintf("ruleName must end with %s", constants.TagRuleDotSuffix)) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(err)) return } - res := &mesh.TagRouteResource{ - Meta: nil, - Spec: &meshproto.TagRoute{}, + tagRuleRes, err := service.GetTagRule(ctx, ruleName, mesh) + if err != nil { + util.HandleServiceError(c, err) + return } - err := c.Bind(res.Spec) + if tagRuleRes == nil { + util.HandleNotFoundError(c, ruleName) + return + } + res := meshresource.NewTagRouteResourceWithAttributes(ruleName, mesh) + err = c.Bind(res.Spec) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } - if err = service.UpdateTagRule(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err = service.UpdateTagRule(ctx, res); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } else { c.JSON(http.StatusOK, model.GenTagRouteResp(res.Spec)) @@ -118,25 +114,21 @@ func PutTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { func PostTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.TagRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.TagRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.TagRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.TagRuleDotSuffix) { + err := bizerror.New(bizerror.InvalidArgument, fmt.Sprintf("ruleName must end with %s", constants.TagRuleDotSuffix)) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(err)) return } - res := &mesh.TagRouteResource{ - Meta: nil, - Spec: &meshproto.TagRoute{}, - } + res := meshresource.NewTagRouteResourceWithAttributes(ruleName, mesh) err := c.Bind(res.Spec) if err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } - if err = service.CreateTagRule(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err = service.CreateTagRule(ctx, res); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } else { c.JSON(http.StatusOK, model.GenTagRouteResp(res.Spec)) @@ -146,17 +138,15 @@ func PostTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { func DeleteTagRuleWithRuleName(ctx consolectx.Context) gin.HandlerFunc { return func(c *gin.Context) { - var name string ruleName := c.Param("ruleName") - if strings.HasSuffix(ruleName, consts.TagRuleSuffix) { - name = ruleName[:len(ruleName)-len(consts.TagRuleSuffix)] - } else { - c.JSON(http.StatusBadRequest, model.NewErrorResp(fmt.Sprintf("ruleName must end with %s", consts.TagRuleSuffix))) + mesh := c.Query("mesh") + if !strings.HasSuffix(ruleName, constants.TagRuleDotSuffix) { + err := bizerror.New(bizerror.InvalidArgument, fmt.Sprintf("ruleName must end with %s", constants.TagRuleDotSuffix)) + c.JSON(http.StatusBadRequest, model.NewBizErrorResp(err)) return } - res := &mesh.TagRouteResource{Spec: &meshproto.TagRoute{}} - if err := service.DeleteTagRule(ctx, name, res); err != nil { - c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error())) + if err := service.DeleteTagRule(ctx, ruleName, mesh); err != nil { + c.JSON(http.StatusOK, model.NewErrorResp(err.Error())) return } c.JSON(http.StatusOK, model.NewSuccessResp("")) diff --git a/pkg/console/handler/traffic_affinity_rule.go b/pkg/console/handler/traffic_affinity_rule.go deleted file mode 100644 index 8fbf4511d..000000000 --- a/pkg/console/handler/traffic_affinity_rule.go +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package handler - -import ( - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - consolectx "github.com/apache/dubbo-admin/pkg/console/context" - "github.com/apache/dubbo-admin/pkg/core/consts" - "github.com/apache/dubbo-admin/pkg/core/logger" - "github.com/apache/dubbo-admin/pkg/core/store" -) - -func getAffinityRule(ctx consolectx.Context, name string) (*mesh.AffinityRouteResource, error) { - res := &mesh.AffinityRouteResource{Spec: &meshproto.AffinityRoute{}} - err := ctx.ResourceManager().Get(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.GetByApplication(name), store.GetByKey(name+consts.AffinityRuleSuffix, resmodel.DefaultMesh)) - if err != nil { - logger.Warnf("get tag rule %s error: %v", name, err) - return nil, err - } - return res, nil -} - -func updateAffinityRule(ctx consolectx.Context, name string, res *mesh.AffinityRouteResource) error { - err := ctx.ResourceManager().Update(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.UpdateByApplication(name), store.UpdateByKey(name+consts.AffinityRuleSuffix, resmodel.DefaultMesh)) - if err != nil { - logger.Warnf("update tag rule %s error: %v", name, err) - return err - } - return nil -} - -func createAffinityRule(ctx consolectx.Context, name string, res *mesh.AffinityRouteResource) error { - err := ctx.ResourceManager().Create(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.CreateByApplication(name), store.CreateByKey(name+consts.AffinityRuleSuffix, resmodel.DefaultMesh)) - if err != nil { - logger.Warnf("create tag rule %s error: %v", name, err) - return err - } - return nil -} - -func deleteAffinityRule(ctx consolectx.Context, name string, res *mesh.AffinityRouteResource) error { - err := ctx.ResourceManager().Delete(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.DeleteByApplication(name), store.DeleteByKey(name+consts.AffinityRuleSuffix, resmodel.DefaultMesh)) - if err != nil { - logger.Warnf("delete tag rule %s error: %v", name, err) - return err - } - return nil -} diff --git a/pkg/console/model/application.go b/pkg/console/model/application.go index d7e503751..35b3e4636 100644 --- a/pkg/console/model/application.go +++ b/pkg/console/model/application.go @@ -18,19 +18,19 @@ package model import ( - "encoding/json" - "fmt" - "regexp" "strconv" - "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - "github.com/apache/dubbo-admin/pkg/console/constants" - consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/duke-git/lancet/v2/strutil" + + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/config/app" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type ApplicationDetailReq struct { AppName string `form:"appName"` + Mesh string `form:"mesh"` } type ApplicationDetailResp struct { @@ -88,127 +88,63 @@ func NewApplicationDetail() *ApplicationDetail { Workloads: NewSet(), } } - -func (a *ApplicationDetail) MergeMetaData(metadata *mesh.MetaDataResource) { - a.mergeServiceInfo(metadata) -} - -func (a *ApplicationDetail) mergeServiceInfo(metadata *mesh.MetaDataResource) { - for _, serviceInfo := range metadata.Spec.Services { - a.DubboVersions.Add(fmt.Sprintf("dubbo %s", serviceInfo.Params[constants.ReleaseKey])) - a.RPCProtocols.Add(serviceInfo.Protocol) - a.SerialProtocols.Add(serviceInfo.Params[constants.SerializationKey]) - - } -} - -func (a *ApplicationDetail) MergeDataplane(dataplane *mesh.DataplaneResource) { - if work, ok := dataplane.Spec.Extensions[constants.WorkLoadKey]; ok && - regexp.MustCompile(`^.*-\d+$`).MatchString(work) { +func (a *ApplicationDetail) MergeInstance(instanceRes *meshresource.InstanceResource, cfg app.AdminConfig) { + instance := instanceRes.Spec + if instance.WorkloadType == constants.StatefulSet { a.AppTypes.Add(constants.Stateful) } else { a.AppTypes.Add(constants.Stateless) } - - inbounds := dataplane.Spec.Networking.Inbound - for _, inbound := range inbounds { - a.mergeInbound(inbound) + a.DubboPorts.Add(strconv.FormatInt(instance.RpcPort, 10)) + a.DubboVersions.Add(instance.ReleaseVersion) + a.Images.Add(instance.Image) + if d := cfg.FindDiscovery(instanceRes.Mesh); d != nil { + a.RegisterClusters.Add(instanceRes.Mesh) } - extensions := dataplane.Spec.Extensions - a.mergeExtensions(extensions) -} - -func (a *ApplicationDetail) mergeInbound(inbound *legacy.Dataplane_Networking_Inbound) { - a.DubboPorts.Add(strconv.Itoa(int(inbound.Port))) - a.DeployClusters.Add(inbound.Tags[legacy.ZoneTag]) -} - -func (a *ApplicationDetail) mergeExtensions(extensions map[string]string) { - a.Images.Add(extensions[coremodel.ExtensionsImageKey]) - a.Workloads.Add(extensions[coremodel.ExtensionsWorkLoadKey]) -} - -func (a *ApplicationDetail) GetRegistry(ctx consolectx.Context) { - // TODO - + if cfg.Engine != nil && cfg.Engine.ID == instance.SourceEngine { + a.DeployClusters.Add(cfg.Engine.Name) + } + a.RegisterModes.Add(constants.Application) + a.RPCProtocols.Add(instance.Protocol) + if strutil.IsNotBlank(instance.Serialization) { + a.SerialProtocols.Add(instance.Serialization) + } else if strutil.IsNotBlank(instance.PreferSerialization) { + a.SerialProtocols.Add(instance.PreferSerialization) + } + a.Workloads.Add(instance.WorkloadName) } -// todo Application instance info - type ApplicationTabInstanceInfoReq struct { + coremodel.PageReq + AppName string `form:"appName"` - PageReq + Mesh string `form:"mesh"` } func NewApplicationTabInstanceInfoReq() *ApplicationTabInstanceInfoReq { return &ApplicationTabInstanceInfoReq{ - PageReq: PageReq{ + PageReq: coremodel.PageReq{ PageOffset: 0, PageSize: 15, }, } } -type ApplicationTabInstanceInfoResp struct { - AppName string `json:"appName"` - CreateTime string `json:"createTime"` - DeployState string `json:"deployState"` - DeployClusters string `json:"deployClusters"` - IP string `json:"ip"` - Labels map[string]string `json:"labels"` - Name string `json:"name"` - RegisterCluster string `json:"registerCluster"` - RegisterState string `json:"registerState"` - RegisterTime string `json:"registerTime"` - WorkloadName string `json:"workloadName"` -} - -type ByApplicationInstanceName []*ApplicationTabInstanceInfoResp - -func (a ByApplicationInstanceName) Len() int { return len(a) } - -func (a ByApplicationInstanceName) Less(i, j int) bool { - return a[i].Name < a[j].Name -} - -func (a ByApplicationInstanceName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -func (a *ApplicationTabInstanceInfoResp) FromDataplaneResource(dataplane *mesh.DataplaneResource) *ApplicationTabInstanceInfoResp { - // TODO: support more fields - extensions := dataplane.Spec.Extensions - a.mergeExtension(extensions) - a.mergeMainDataplane(dataplane) - return a -} - -// nolint -func (a *ApplicationTabInstanceInfoResp) mergeMainDataplane(dataplane *mesh.DataplaneResource) { - a.AppName = dataplane.GetMeta().GetLabels()[v1alpha1.Application] - a.CreateTime = dataplane.Meta.GetCreationTime().String() - a.IP = dataplane.Spec.Networking.Address - a.DeployClusters = dataplane.Spec.Networking.Inbound[0].Tags[legacy.ZoneTag] - a.Labels = dataplane.GetMeta().GetLabels() - a.Name = dataplane.Meta.GetName() - a.RegisterTime = a.CreateTime - if a.RegisterTime != "" { - a.RegisterState = "Registed" - } else { - a.RegisterState = "UnRegisted" - } -} - -func (a *ApplicationTabInstanceInfoResp) mergeExtension(extensions map[string]string) { - a.WorkloadName = extensions[coremodel.ExtensionsWorkLoadKey] - a.DeployState = extensions[coremodel.ExtensionsPodPhaseKey] -} - -func (a *ApplicationTabInstanceInfoResp) GetRegistry(ctx consolectx.Context) { - // TODO - +type AppInstanceInfoResp struct { + AppName string `json:"appName"` + CreateTime string `json:"createTime"` + LifecycleState InstanceLifecycleState `json:"lifecycleState"` + DeployState InstanceDeployState `json:"deployState"` + DeployClusters string `json:"deployClusters"` + IP string `json:"ip"` + Labels map[string]string `json:"labels"` + Name string `json:"name"` + RegisterCluster string `json:"registerCluster"` + RegisterState InstanceRegisterState `json:"registerState"` + RegisterTime string `json:"registerTime"` + WorkloadName string `json:"workloadName"` } -// Todo Application Service - type ApplicationServiceReq struct { AppName string `json:"appName"` } @@ -219,95 +155,51 @@ type ApplicationServiceResp struct { } type ApplicationServiceFormReq struct { - AppName string `form:"appName"` - Side string `form:"side"` - PageReq + coremodel.PageReq + + AppName string `form:"appName"` + ServiceName string `form:"serviceName"` + Side string `form:"side"` + Mesh string `form:"mesh"` } func NewApplicationServiceFormReq() *ApplicationServiceFormReq { return &ApplicationServiceFormReq{ - PageReq: PageReq{ + PageReq: coremodel.PageReq{ PageOffset: 0, PageSize: 15, }, } } -type ApplicationServiceFormResp struct { - ServiceName string `json:"serviceName"` - VersionGroups []versionGroup `json:"versionGroups"` -} - -type ByAppServiceFormName []*ApplicationServiceFormResp - -func (a ByAppServiceFormName) Len() int { return len(a) } - -func (a ByAppServiceFormName) Less(i, j int) bool { - return a[i].ServiceName < a[j].ServiceName -} - -func (a ByAppServiceFormName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -type versionGroup struct { - Group string `json:"group"` - Version string `json:"version"` -} - -func NewApplicationServiceFormResp() *ApplicationServiceFormResp { - return &ApplicationServiceFormResp{ - ServiceName: "", - VersionGroups: nil, - } -} - -func (a *ApplicationServiceFormResp) FromApplicationServiceForm(form *ApplicationServiceForm) error { - a.ServiceName = form.ServiceName - versionGroupList := make([]versionGroup, 0) - for _, gv := range form.VersionGroups.Values() { - var versionGroupInfo versionGroup - if err := json.Unmarshal([]byte(gv), &versionGroupInfo); err != nil { - return err - } - versionGroupList = append(versionGroupList, versionGroupInfo) - } - a.VersionGroups = versionGroupList - return nil -} +type ApplicationSearchReq struct { + coremodel.PageReq -type ApplicationServiceForm struct { - ServiceName string - VersionGroups Set + AppName string `form:"appName" json:"appName"` + Keywords string `form:"keywords" json:"keywords"` + Mesh string `form:"mesh" json:"mesh"` } -func NewApplicationServiceForm(serviceName string) *ApplicationServiceForm { - return &ApplicationServiceForm{ - ServiceName: serviceName, - VersionGroups: NewSet(), +func NewApplicationSearchReq() *ApplicationSearchReq { + return &ApplicationSearchReq{ + PageReq: coremodel.PageReq{ + PageOffset: 0, + PageSize: 15, + }, } } -func (a *ApplicationServiceForm) FromServiceInfo(serviceInfo *v1alpha1.ServiceInfo) error { - versionGroupInfo := versionGroup{ - Group: serviceInfo.Group, - Version: serviceInfo.Version, - } - bytes, err := json.Marshal(versionGroupInfo) - if err != nil { - return err - } - a.VersionGroups.Add(string(bytes)) - return nil -} +type ApplicationGraphReq struct { + coremodel.PageReq -type ApplicationSearchReq struct { AppName string `form:"appName" json:"appName"` Keywords string `form:"keywords" json:"keywords"` - PageReq + Mesh string `form:"mesh" json:"mesh"` } -func NewApplicationSearchReq() *ApplicationSearchReq { - return &ApplicationSearchReq{ - PageReq: PageReq{ +func NewApplicationGraphReq() *ApplicationGraphReq { + return &ApplicationGraphReq{ + PageReq: coremodel.PageReq{ PageOffset: 0, PageSize: 15, }, @@ -321,56 +213,6 @@ type ApplicationSearchResp struct { RegistryClusters []string `json:"registryClusters"` } -func (a *ApplicationSearchResp) FromApplicationSearch(applicationSearch *ApplicationSearch) *ApplicationSearchResp { - a.RegistryClusters = applicationSearch.RegistryClusters.Values() - a.InstanceCount = applicationSearch.InstanceCount - a.DeployClusters = applicationSearch.DeployClusters.Values() - return a -} - -type ByAppName []*ApplicationSearchResp - -func (a ByAppName) Len() int { return len(a) } - -func (a ByAppName) Less(i, j int) bool { - return a[i].AppName < a[j].AppName -} - -func (a ByAppName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// Todo Application Search - -type ApplicationSearch struct { - AppName string - DeployClusters Set - InstanceCount int64 - RegistryClusters Set -} - -func NewApplicationSearch(appName string) *ApplicationSearch { - return &ApplicationSearch{ - AppName: appName, - DeployClusters: NewSet(), - InstanceCount: 0, - RegistryClusters: NewSet(), - } -} - -func (a *ApplicationSearch) MergeDataplane(dataplane *mesh.DataplaneResource) { - a.InstanceCount++ - - // merge inbounds - inbounds := dataplane.Spec.Networking.Inbound - for _, inbound := range inbounds { - a.DeployClusters.Add(inbound.Tags[legacy.ZoneTag]) - } -} - -func (a *ApplicationSearch) GetRegistry(ctx consolectx.Context) { - - // TODO -} - type FlowWeightSet struct { Weight int32 `json:"weight"` Scope []ParamMatch `json:"scope,omitempty"` @@ -380,3 +222,15 @@ type GraySet struct { EnvName string `json:"name,omitempty"` Scope []ParamMatch `json:"scope,omitempty"` } + +type AppAccessLogConfigResp struct { + AccessLog bool `json:"operatorLog"` +} + +type AppFlowWeightConfigResp struct { + FlowWeightSets []FlowWeightSet `json:"flowWeightSets"` +} + +type AppGrayConfigResp struct { + GraySets []GraySet `json:"graySets"` +} diff --git a/pkg/console/model/common.go b/pkg/console/model/common.go index aacf6e706..1931a297f 100644 --- a/pkg/console/model/common.go +++ b/pkg/console/model/common.go @@ -17,25 +17,24 @@ package model -const ( - successCode = 200 - unauthorizedCode = 401 - errorCode = 500 +import ( + "github.com/apache/dubbo-admin/pkg/common/bizerror" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type CommonResp struct { - Code int `json:"code"` - Msg string `json:"msg"` - Data any `json:"data"` + Code string `json:"code"` + Message string `json:"message"` + Data any `json:"data"` } -func (r *CommonResp) WithCode(code int) *CommonResp { +func (r *CommonResp) WithCode(code string) *CommonResp { r.Code = code return r } func (r *CommonResp) WithMsg(msg string) *CommonResp { - r.Msg = msg + r.Message = msg return r } @@ -46,73 +45,40 @@ func (r *CommonResp) WithData(data any) *CommonResp { func NewSuccessResp(data any) *CommonResp { return &CommonResp{ - Code: successCode, - Msg: "success", - Data: data, + Code: "Success", + Message: "success", + Data: data, } } -func NewUnauthorizedResp() *CommonResp { +// NewErrorResp TODO replace with NewBizErrorResp +func NewErrorResp(msg string) *CommonResp { return &CommonResp{ - Code: unauthorizedCode, - Msg: "UnAuthorized, please login", - Data: nil, + Code: string(bizerror.UnknownError), + Message: msg, + Data: nil, } } -func NewErrorResp(msg string) *CommonResp { +func NewBizErrorResp(err bizerror.Error) *CommonResp { return &CommonResp{ - Code: errorCode, - Msg: msg, - Data: nil, + Code: string(err.Code()), + Message: err.Message(), + Data: nil, } } -type PageData struct { - Total int `json:"total"` - CurPage int `json:"curPage"` - PageSize int `json:"pageSize"` - Data any `json:"data"` -} - -func NewPageData() *PageData { - return &PageData{} -} - -func (pd *PageData) WithTotal(total int) *PageData { - pd.Total = total - return pd -} - -func (pd *PageData) WithCurPage(curPage int) *PageData { - pd.CurPage = curPage - return pd -} - -func (pd *PageData) WithPageSize(pageSize int) *PageData { - pd.PageSize = pageSize - return pd -} - -func (pd *PageData) WithData(data any) *PageData { - pd.Data = data - return pd -} - -type PageReq struct { - PageOffset int `form:"pageOffset" json:"pageOffset"` - PageSize int `form:"pageSize" json:"pageSize"` -} - type SearchReq struct { + coremodel.PageReq + SearchType string `form:"searchType"` Keywords string `form:"keywords"` - PageReq + Mesh string `form:"mesh"` } func NewSearchReq() *SearchReq { return &SearchReq{ - PageReq: PageReq{PageSize: 15}, + PageReq: coremodel.PageReq{PageSize: 15}, } } diff --git a/pkg/console/model/condition_rule.go b/pkg/console/model/condition_rule.go index 912d6a114..11b92fe11 100644 --- a/pkg/console/model/condition_rule.go +++ b/pkg/console/model/condition_rule.go @@ -18,21 +18,26 @@ package model import ( - "net/http" "strings" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/common/constants" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type SearchConditionRuleReq struct { - Keywords string `json:"keywords"` - PageReq + coremodel.PageReq + Mesh string `form:"mesh"` + Keywords string `form:"keywords"` +} + +func (s *SearchConditionRuleReq) PageRequest() coremodel.PageReq { + return s.PageReq } func NewSearchConditionRuleReq() *SearchConditionRuleReq { return &SearchConditionRuleReq{ - PageReq: PageReq{PageSize: 15}, + PageReq: coremodel.PageReq{PageSize: 15}, } } @@ -62,11 +67,43 @@ type ServiceArgument struct { Method string `json:"method"` } -func (s *ServiceArgument) toFrom() *meshproto.ConditionRuleFrom { - res := "method=" + s.Method - if len(s.Conditions) != 0 { - for i := 0; len(s.Conditions) > i; i++ { - res += " & " + s.Conditions[i].string() +// ToExpression Convert ServiceArgument to expression string +func (sa *ServiceArgument) ToExpression() string { + expression := "method=" + sa.Method + + // Add route conditions + for _, condition := range sa.Conditions { + expression += " & " + condition.string() + } + + // Add destinations if any + if len(sa.Destinations) > 0 { + expression += " => " + + // Process each destination + for destIdx, destination := range sa.Destinations { + for condIdx, condition := range destination.Conditions { + if destIdx > 0 || condIdx > 0 { + expression += " & " + } + expression += condition.string() + } + + // If there are multiple destinations, separate them (using comma as separator) + if destIdx < len(sa.Destinations)-1 { + expression += ", " + } + } + } + + return expression +} + +func (sa *ServiceArgument) toFrom() *meshproto.ConditionRuleFrom { + res := "method=" + sa.Method + if len(sa.Conditions) != 0 { + for i := 0; len(sa.Conditions) > i; i++ { + res += " & " + sa.Conditions[i].string() } } return &meshproto.ConditionRuleFrom{ @@ -74,9 +111,9 @@ func (s *ServiceArgument) toFrom() *meshproto.ConditionRuleFrom { } } -func (s *ServiceArgument) toTo() []*meshproto.ConditionRuleTo { - res := make([]*meshproto.ConditionRuleTo, 0, len(s.Destinations)) - for _, destination := range s.Destinations { +func (sa *ServiceArgument) toTo() []*meshproto.ConditionRuleTo { + res := make([]*meshproto.ConditionRuleTo, 0, len(sa.Destinations)) + for _, destination := range sa.Destinations { match := "" for _, condition := range destination.Conditions { if match == "" { @@ -100,10 +137,10 @@ type RouteCondition struct { } func (r *RouteCondition) string() string { - if r.Relation == consts.Equal { - return "arguments[" + r.Index + "]" + consts.Equal + r.Value + if r.Relation == constants.Equal { + return "arguments[" + r.Index + "]" + constants.Equal + r.Value } else { - return "arguments[" + r.Index + "]" + consts.NotEqual + r.Value + return "arguments[" + r.Index + "]" + constants.NotEqual + r.Value } } @@ -119,10 +156,10 @@ type DestinationCondition struct { } func (d *DestinationCondition) string() string { - if d.Relation == consts.Equal { - return d.Tag + consts.Equal + d.Value + if d.Relation == constants.Equal { + return d.Tag + constants.Equal + d.Value } else { - return d.Tag + consts.NotEqual + d.Value + return d.Tag + constants.NotEqual + d.Value } } @@ -163,17 +200,17 @@ func matchValueToRouteCondition(val string) []RouteCondition { subsets := strings.Split(val, "&") res := make([]RouteCondition, 0, len(subsets)) for _, subset := range subsets { - if index := strings.Index(subset, consts.NotEqual); index != -1 { + if index := strings.Index(subset, constants.NotEqual); index != -1 { res = append(res, RouteCondition{ Index: strings.Trim(subset[:index], " "), - Relation: consts.NotEqual, - Value: strings.Trim(subset[index+len(consts.NotEqual):], " "), + Relation: constants.NotEqual, + Value: strings.Trim(subset[index+len(constants.NotEqual):], " "), }) - } else if index := strings.Index(subset, consts.Equal); index != -1 { + } else if index := strings.Index(subset, constants.Equal); index != -1 { res = append(res, RouteCondition{ Index: strings.Trim(subset[:index], " "), - Relation: consts.Equal, - Value: strings.Trim(subset[index+len(consts.Equal):], " "), + Relation: constants.Equal, + Value: strings.Trim(subset[index+len(constants.Equal):], " "), }) } } @@ -184,17 +221,17 @@ func matchValueToDestinationCondition(val string) []DestinationCondition { subsets := strings.Split(val, "&") res := make([]DestinationCondition, 0, len(subsets)) for _, subset := range subsets { - if index := strings.Index(subset, consts.NotEqual); index != -1 { + if index := strings.Index(subset, constants.NotEqual); index != -1 { res = append(res, DestinationCondition{ Tag: strings.Trim(subset[:index], " "), - Relation: consts.NotEqual, - Value: strings.Trim(subset[index+len(consts.NotEqual):], " "), + Relation: constants.NotEqual, + Value: strings.Trim(subset[index+len(constants.NotEqual):], " "), }) - } else if index := strings.Index(subset, consts.Equal); index != -1 { + } else if index := strings.Index(subset, constants.Equal); index != -1 { res = append(res, DestinationCondition{ Tag: strings.Trim(subset[:index], " "), - Relation: consts.Equal, - Value: strings.Trim(subset[index+len(consts.Equal):], " "), + Relation: constants.Equal, + Value: strings.Trim(subset[index+len(constants.Equal):], " "), }) } } @@ -203,52 +240,16 @@ func matchValueToDestinationCondition(val string) []DestinationCondition { func GenConditionRuleToResp(data *meshproto.ConditionRoute) *CommonResp { if data == nil { - return &CommonResp{ - Code: http.StatusNotFound, - Msg: "not found", - Data: map[string]string{}, - } - } - if pb := data.ToConditionRouteV3(); pb != nil { - return NewSuccessResp(ConditionRuleResp{ - Conditions: pb.Conditions, - ConfigVersion: pb.ConfigVersion, - Enabled: pb.Enabled, - Key: pb.Key, - Runtime: pb.Runtime, - Scope: pb.Scope, - }) - } else if pb := data.ToConditionRouteV3x1(); pb != nil { - res := ConditionRuleV3X1{ - Conditions: make([]Condition, 0, len(pb.Conditions)), - ConfigVersion: "v3.1", - Enabled: pb.Enabled, - Force: pb.Force, - Key: pb.Key, - Runtime: pb.Runtime, - Scope: pb.Scope, - } - for _, condition := range pb.Conditions { - resCondition := Condition{ - From: ConditionFrom{Match: condition.From.Match}, - To: make([]ConditionTo, 0, len(condition.To)), - } - for _, to := range condition.To { - resCondition.To = append(resCondition.To, ConditionTo{ - Match: to.Match, - Weight: to.Weight, - }) - } - res.Conditions = append(res.Conditions, resCondition) - } - return NewSuccessResp(res) - } else { - return &CommonResp{ - Code: http.StatusInternalServerError, - Msg: "invalid condition rule", - Data: data, - } + return NewSuccessResp(nil) } + return NewSuccessResp(ConditionRuleResp{ + Conditions: data.Conditions, + ConfigVersion: data.ConfigVersion, + Enabled: data.Enabled, + Key: data.Key, + Runtime: data.Runtime, + Scope: data.Scope, + }) } type ConditionRuleV3X1 struct { @@ -279,3 +280,147 @@ type ConditionTo struct { Match string `json:"match"` Weight int32 `json:"weight"` } + +// ParseConditionExpression converts an expression string to a ServiceArgument struct +// Expression format: "method=methodName & condition1 => destination1" +func ParseConditionExpression(expression string) ServiceArgument { + // Split into from and to parts (separated by "=>") + parts := strings.Split(expression, "=>") + fromPart := strings.TrimSpace(parts[0]) + toPart := "" + if len(parts) > 1 { + toPart = strings.TrimSpace(parts[1]) + } + + // Parse from part to get method and conditions + method, conditions := parseFromPart(fromPart) + + // Parse to part to get destinations + destinations := parseToPart(toPart) + + return ServiceArgument{ + Method: method, + Conditions: conditions, + Destinations: destinations, + } +} + +// parseFromPart parses the from part containing method and arguments conditions +func parseFromPart(fromPart string) (string, []RouteCondition) { + conditions := []RouteCondition{} + method := "" + + // Split conditions by "&" + subConditions := strings.Split(fromPart, "&") + + for _, condition := range subConditions { + condition = strings.TrimSpace(condition) + + // Check if it's a method condition + if strings.HasPrefix(condition, "method=") { + method = strings.TrimPrefix(condition, "method=") + method = strings.TrimSpace(method) + } else { + // Parse arguments condition + routeCond := parseRouteCondition(condition) + if routeCond.Index != "" { + conditions = append(conditions, routeCond) + } + } + } + + return method, conditions +} + +// parseRouteCondition parses a single route condition +func parseRouteCondition(condition string) RouteCondition { + var relation string + var relationOp string + + // Check if it's "=" or "!=" + if index := strings.Index(condition, constants.NotEqual); index != -1 { + relation = constants.NotEqual + relationOp = constants.NotEqual + } else if index := strings.Index(condition, constants.Equal); index != -1 { + relation = constants.Equal + relationOp = constants.Equal + } else { + return RouteCondition{} // Invalid condition + } + + // Find the position of the relation + index := strings.Index(condition, relationOp) + leftPart := strings.TrimSpace(condition[:index]) + rightPart := strings.TrimSpace(condition[index+len(relationOp):]) + + // Parse arguments[index] format + if strings.HasPrefix(leftPart, "arguments[") && strings.HasSuffix(leftPart, "]") { + argIndex := leftPart[10 : len(leftPart)-1] // Extract index within brackets + return RouteCondition{ + Index: argIndex, + Relation: relation, + Value: rightPart, + } + } + + // If not arguments format, return generic condition + return RouteCondition{ + Index: leftPart, + Relation: relation, + Value: rightPart, + } +} + +// parseToPart parses the to part (destination conditions) +func parseToPart(toPart string) []Destination { + if toPart == "" { + return []Destination{} + } + + // Split multiple conditions by "&" + conditions := strings.Split(toPart, "&") + destinationConditions := []DestinationCondition{} + + for _, condition := range conditions { + condition = strings.TrimSpace(condition) + destCond := parseDestinationCondition(condition) + if destCond.Tag != "" { + destinationConditions = append(destinationConditions, destCond) + } + } + + return []Destination{ + { + Conditions: destinationConditions, + Weight: 0, // Default weight is 0, can be adjusted as needed + }, + } +} + +// parseDestinationCondition parses destination condition +func parseDestinationCondition(condition string) DestinationCondition { + var relation string + var relationOp string + + // Check if it's "=" or "!=" + if index := strings.Index(condition, constants.NotEqual); index != -1 { + relation = constants.NotEqual + relationOp = constants.NotEqual + } else if index := strings.Index(condition, constants.Equal); index != -1 { + relation = constants.Equal + relationOp = constants.Equal + } else { + return DestinationCondition{} // Invalid condition + } + + // Find the position of the relation + index := strings.Index(condition, relationOp) + leftPart := strings.TrimSpace(condition[:index]) + rightPart := strings.TrimSpace(condition[index+len(relationOp):]) + + return DestinationCondition{ + Tag: leftPart, + Relation: relation, + Value: rightPart, + } +} diff --git a/pkg/console/model/configurator_rule.go b/pkg/console/model/configurator_rule.go index 897a34999..677f742eb 100644 --- a/pkg/console/model/configurator_rule.go +++ b/pkg/console/model/configurator_rule.go @@ -18,19 +18,20 @@ package model import ( - "net/http" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type SearchConfiguratorReq struct { + coremodel.PageReq + Keywords string `json:"keywords"` - PageReq + Mesh string `json:"mesh"` } func NewSearchConfiguratorReq() *SearchConfiguratorReq { return &SearchConfiguratorReq{ - PageReq: PageReq{ + PageReq: coremodel.PageReq{ PageSize: 15, PageOffset: 0, }, @@ -98,7 +99,7 @@ type RespAddressMatch struct { } func GenDynamicConfigToResp(pb *meshproto.DynamicConfig) (res *CommonResp) { - cfg := RespConfigurator{} + cfg := &RespConfigurator{} if pb != nil { cfg.ConfigVersion = pb.ConfigVersion cfg.Key = pb.Key @@ -107,10 +108,7 @@ func GenDynamicConfigToResp(pb *meshproto.DynamicConfig) (res *CommonResp) { cfg.Configs = overrideConfigToRespConfigItem(pb.Configs) return NewSuccessResp(cfg) } - return &CommonResp{ - Code: http.StatusNotFound, - Msg: "configurator not found", - } + return NewSuccessResp(nil) } func overrideConfigToRespConfigItem(OverrideConfigs []*meshproto.OverrideConfig) []ConfigItem { diff --git a/pkg/console/model/graph.go b/pkg/console/model/graph.go new file mode 100644 index 000000000..333b9a07b --- /dev/null +++ b/pkg/console/model/graph.go @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package model + +import ( + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + + "github.com/apache/dubbo-admin/pkg/common/constants" +) + +// GraphNode represents a node in the graph for AntV G6 +type GraphNode struct { + ID string `json:"id"` + Label string `json:"label"` + Type string `json:"type"` // "application" or "service" + Rule string `json:"rule"` // "provider", "consumer", or "" + Data interface{} `json:"data,omitempty"` +} + +// GraphEdge represents an edge in the graph for AntV G6 +type GraphEdge struct { + Source string `json:"source"` + Target string `json:"target"` + Data map[string]interface{} `json:"data,omitempty"` // Additional data for the edge +} + +// GraphData represents the complete graph structure for AntV G6 +type GraphData struct { + Nodes []GraphNode `json:"nodes"` + Edges []GraphEdge `json:"edges"` +} + +// CrossNode represents a node in the cross-linked list structure +type CrossNode struct { + Instance *meshresource.InstanceResource + Next *CrossNode // pointer to next node in the same row + Down *CrossNode // pointer to next node in the same column +} + +// CrossLinkedListGraph represents the cross-linked list structure as a directed graph +type CrossLinkedListGraph struct { + Head *CrossNode + Rows int // number of rows + Cols int // number of columns +} + +// ServiceGraphReq represents the request parameters for fetching the service graph +type ServiceGraphReq struct { + Mesh string `json:"mesh" form:"mesh" binding:"required"` + ServiceName string `json:"serviceName" form:"serviceName" binding:"required"` + Version string `json:"version" form:"version"` + Group string `json:"group" form:"group"` +} + +// ServiceKey returns the unique service identifier +func (s *ServiceGraphReq) ServiceKey() string { + return s.ServiceName + constants.ColonSeparator + s.Version + constants.ColonSeparator + s.Group +} diff --git a/pkg/console/model/instance.go b/pkg/console/model/instance.go index 8c0a6c95f..907fea272 100644 --- a/pkg/console/model/instance.go +++ b/pkg/console/model/instance.go @@ -18,31 +18,36 @@ package model import ( - gxset "github.com/dubbogo/gost/container/set" + "github.com/duke-git/lancet/v2/strutil" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/config/app" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type SearchInstanceReq struct { + coremodel.PageReq + AppName string `form:"appName"` Keywords string `form:"keywords"` - PageReq + Mesh string `form:"mesh"` } func NewSearchInstanceReq() *SearchInstanceReq { return &SearchInstanceReq{ - PageReq: PageReq{PageSize: 15}, + PageReq: coremodel.PageReq{PageSize: 15}, } } type InstanceDetailReq struct { InstanceName string `form:"instanceName"` + Mesh string `form:"mesh"` } type SearchPaginationResult struct { - List any `json:"list"` - PageInfo *coremodel.Pagination `json:"pageInfo"` + List any `json:"list"` + PageInfo coremodel.Pagination `json:"pageInfo"` } func NewSearchPaginationResult() *SearchPaginationResult { @@ -50,67 +55,44 @@ func NewSearchPaginationResult() *SearchPaginationResult { } type SearchInstanceResp struct { - Ip string `json:"ip"` - Name string `json:"name"` - WorkloadName string `json:"workloadName"` - AppName string `json:"appName"` - DeployState string `json:"deployState"` - DeployCluster string `json:"deployCluster"` - RegisterState string `json:"registerState"` - RegisterClustersSet *gxset.HashSet `json:"-"` - RegisterClusters []string `json:"registerClusters"` - CreateTime string `json:"createTime"` - RegisterTime string `json:"registerTime"` // TODO: not converted - Labels map[string]string `json:"labels"` + Ip string `json:"ip"` + Name string `json:"name"` + WorkloadName string `json:"workloadName"` + AppName string `json:"appName"` + LifecycleState InstanceLifecycleState `json:"lifecycleState"` + DeployState InstanceDeployState `json:"deployState"` + DeployCluster string `json:"deployCluster"` + RegisterState InstanceRegisterState `json:"registerState"` + RegisterClusters []string `json:"registerClusters"` + CreateTime string `json:"createTime"` + RegisterTime string `json:"registerTime"` + Labels map[string]string `json:"labels"` } func NewSearchInstanceResp() *SearchInstanceResp { return &SearchInstanceResp{ - RegisterClustersSet: gxset.NewSet(), - RegisterClusters: make([]string, 0), + RegisterClusters: make([]string, 0), } } -func (r *SearchInstanceResp) FromDataplaneResource(dr *mesh.DataplaneResource) *SearchInstanceResp { - // TODO: support more fields - r.Ip = dr.GetIP() - meta := dr.GetMeta() - r.Name = meta.GetName() - r.CreateTime = meta.GetCreationTime().String() - r.RegisterTime = r.CreateTime // TODO: separate createTime and RegisterTime - cluster := dr.Spec.Networking.Inbound[0].Tags[legacy.ZoneTag] - r.RegisterClustersSet.Add(cluster) - for _, c := range r.RegisterClustersSet.Values() { - r.RegisterClusters = append(r.RegisterClusters, c.(string)) - } - r.DeployCluster = cluster - if r.RegisterTime != "" { - r.RegisterState = "Registed" - } else { - r.RegisterState = "UnRegisted" +func (r *SearchInstanceResp) FromInstanceResource(instanceResource *meshresource.InstanceResource, cfg app.AdminConfig) *SearchInstanceResp { + instance := instanceResource.Spec + r.Ip = instance.Ip + r.Name = instance.Name + r.CreateTime = instance.CreateTime + r.RegisterTime = instance.RegisterTime + if d := cfg.FindDiscovery(instanceResource.Mesh); d != nil { + r.RegisterClusters = []string{d.Name} } - // label conversion - r.Labels = meta.GetLabels() - // spec conversion - spec := dr.Spec - { - statusValue := spec.Extensions[coremodel.ExtensionsPodPhaseKey] - if v, ok := spec.Extensions[coremodel.ExtensionsPodStatusKey]; ok { - statusValue = v - } - if v, ok := spec.Extensions[coremodel.ExtensionsContainerStatusReasonKey]; ok { - statusValue = v - } - r.DeployState = statusValue - r.WorkloadName = spec.Extensions[coremodel.ExtensionsWorkLoadKey] - // name field source is different between universal and k8s mode - r.AppName = spec.Extensions[meshproto.Application] - if r.AppName == "" { - for _, inbound := range spec.Networking.Inbound { - r.AppName = inbound.Tags[legacy.AppTag] - } - } + if cfg.Engine != nil && cfg.Engine.ID == instance.SourceEngine { + r.DeployCluster = cfg.Engine.Name } + r.RegisterState = DeriveInstanceRegisterState(instance) + r.Labels = instance.Tags + r.DeployState = DeriveInstanceDeployState(instance) + r.LifecycleState = DeriveInstanceLifecycleState(instance, r.DeployState, r.RegisterState) + r.WorkloadName = instance.WorkloadName + r.AppName = instance.AppName return r } @@ -121,179 +103,205 @@ type State struct { Value string `json:"value"` } +// InstanceDeployState describes the runtime deployment state reported by the platform. +type InstanceDeployState string + +const ( + // InstanceDeployStateUnknown indicates the deployment state cannot be derived from runtime metadata. + InstanceDeployStateUnknown InstanceDeployState = "Unknown" + // InstanceDeployStatePending indicates the workload has been accepted but is not running yet. + InstanceDeployStatePending InstanceDeployState = "Pending" + // InstanceDeployStateStarting indicates the workload is running but not ready to serve. + InstanceDeployStateStarting InstanceDeployState = "Starting" + // InstanceDeployStateRunning indicates the workload is running and ready. + InstanceDeployStateRunning InstanceDeployState = "Running" + // InstanceDeployStateTerminating indicates the workload is shutting down. + InstanceDeployStateTerminating InstanceDeployState = "Terminating" + // InstanceDeployStateFailed indicates the workload has failed. + InstanceDeployStateFailed InstanceDeployState = "Failed" + // InstanceDeployStateSucceeded indicates the workload has completed successfully and exited. + InstanceDeployStateSucceeded InstanceDeployState = "Succeeded" + // InstanceDeployStateCrashing indicates the workload is repeatedly crashing or restarting. + InstanceDeployStateCrashing InstanceDeployState = "Crashing" +) + +// InstanceRegisterState describes whether the instance is visible to the registry. +type InstanceRegisterState string + +const ( + // InstanceRegisterStateRegistered indicates the instance has been registered to the registry. + InstanceRegisterStateRegistered InstanceRegisterState = "Registered" + // InstanceRegisterStateUnregistered indicates the instance has not registered yet or has been removed. + InstanceRegisterStateUnregistered InstanceRegisterState = "UnRegistered" +) + +// InstanceLifecycleState describes the user-facing lifecycle synthesized from deploy/register signals. +type InstanceLifecycleState string + +const ( + // InstanceLifecycleStateStarting indicates the instance is still warming up. + InstanceLifecycleStateStarting InstanceLifecycleState = "Starting" + // InstanceLifecycleStateServing indicates the instance is both running and registered. + InstanceLifecycleStateServing InstanceLifecycleState = "Serving" + // InstanceLifecycleStateDraining indicates the instance is running but has started unregistering. + InstanceLifecycleStateDraining InstanceLifecycleState = "Draining" + // InstanceLifecycleStateTerminating indicates the instance is shutting down. + InstanceLifecycleStateTerminating InstanceLifecycleState = "Terminating" + // InstanceLifecycleStateError indicates the instance is in an unexpected or failed state. + InstanceLifecycleStateError InstanceLifecycleState = "Error" + // InstanceLifecycleStateUnknown indicates the lifecycle cannot be inferred from current signals. + InstanceLifecycleStateUnknown InstanceLifecycleState = "Unknown" +) + type InstanceDetailResp struct { - RpcPort int `json:"rpcPort"` - Ip string `json:"ip"` - AppName string `json:"appName"` - WorkloadName string `json:"workloadName"` - Labels map[string]string `json:"labels"` - CreateTime string `json:"createTime"` - ReadyTime string `json:"readyTime"` - RegisterTime string `json:"registerTime"` - RegisterClusters []string `json:"registerClusters"` - DeployCluster string `json:"deployCluster"` - DeployState string `json:"deployState"` - RegisterState string `json:"registerState"` - Node string `json:"node"` - Image string `json:"image"` - Probes ProbeStruct `json:"probes"` - Tags map[string]string `json:"tags"` + RpcPort int64 `json:"rpcPort"` + Ip string `json:"ip"` + AppName string `json:"appName"` + WorkloadName string `json:"workloadName"` + Labels map[string]string `json:"labels"` + CreateTime string `json:"createTime"` + ReadyTime string `json:"readyTime"` + RegisterTime string `json:"registerTime"` + RegisterClusters []string `json:"registerClusters"` + DeployCluster string `json:"deployCluster"` + LifecycleState InstanceLifecycleState `json:"lifecycleState"` + DeployState InstanceDeployState `json:"deployState"` + RegisterState InstanceRegisterState `json:"registerState"` + Node string `json:"node"` + Image string `json:"image"` + Probes ProbeStruct `json:"probes"` + Tags map[string]string `json:"tags"` } +const ( + StartupProbeType = "startup" + ReadinessProbeType = "readiness" + LivenessProbeType = "liveness" +) + type ProbeStruct struct { - StartupProbe StartupProbe `json:"startupProbe"` - ReadinessProbe ReadinessProbe `json:"readinessProbe"` - LivenessProbe LivenessProbe `json:"livenessProbe"` + StartupProbe Probe `json:"startupProbe"` + ReadinessProbe Probe `json:"readinessProbe"` + LivenessProbe Probe `json:"livenessProbe"` } -type StartupProbe struct { - Type string `json:"type"` - Port int `json:"port"` - Open bool `json:"open"` -} -type ReadinessProbe struct { - Type string `json:"type"` - Port int `json:"port"` - Open bool `json:"open"` -} -type LivenessProbe struct { +type Probe struct { Type string `json:"type"` - Port int `json:"port"` + Port int32 `json:"port"` Open bool `json:"open"` } -func (r *InstanceDetailResp) FromInstanceDetail(id *InstanceDetail) *InstanceDetailResp { - r.AppName = id.AppName - r.RpcPort = id.RpcPort - r.Ip = id.Ip - r.WorkloadName = id.WorkloadName - r.Labels = id.Labels - r.CreateTime = id.CreateTime - r.ReadyTime = id.ReadyTime - r.RegisterTime = id.RegisterTime - r.RegisterClusters = id.RegisterClusters.Values() - r.DeployCluster = id.DeployCluster - r.DeployCluster = id.DeployCluster - r.DeployState = id.DeployState - r.Node = id.Node - r.Image = id.Image - r.Tags = id.Tags - r.RegisterState = id.RegisterState - r.Probes = id.Probes - return r -} +func FromInstanceResource(res *meshresource.InstanceResource, cfg app.AdminConfig) *InstanceDetailResp { + r := &InstanceDetailResp{} + instance := res.Spec + r.RpcPort = instance.RpcPort + r.Ip = instance.Ip + r.AppName = instance.AppName + r.WorkloadName = instance.WorkloadName + r.Labels = instance.Tags + r.CreateTime = instance.CreateTime + r.ReadyTime = instance.ReadyTime + r.RegisterTime = instance.RegisterTime + if d := cfg.FindDiscovery(res.Mesh); d != nil { + r.RegisterClusters = []string{d.Name} + } + if cfg.Engine.ID == res.Spec.SourceEngine { + r.DeployCluster = cfg.Engine.Name + } + r.DeployState = DeriveInstanceDeployState(instance) + r.RegisterState = DeriveInstanceRegisterState(instance) + r.LifecycleState = DeriveInstanceLifecycleState(instance, r.DeployState, r.RegisterState) + r.Node = instance.Node + r.Image = instance.Image + r.Probes = ProbeStruct{} + for _, p := range instance.Probes { + switch p.Type { + case StartupProbeType: + r.Probes.StartupProbe = Probe{ + Type: StartupProbeType, + Port: p.Port, + Open: true, + } + case ReadinessProbeType: + r.Probes.ReadinessProbe = Probe{ + Type: ReadinessProbeType, + Port: p.Port, + Open: true, + } + case LivenessProbeType: + r.Probes.LivenessProbe = Probe{ + Type: LivenessProbeType, + Port: p.Port, + Open: true, + } + } -type InstanceDetail struct { - RpcPort int - Ip string - AppName string - WorkloadName string - Labels map[string]string - CreateTime string - ReadyTime string - RegisterTime string - RegisterState string - RegisterClusters Set - DeployCluster string - DeployState string - Node string - Image string - Tags map[string]string - Probes ProbeStruct + } + return r } -func NewInstanceDetail() *InstanceDetail { - return &InstanceDetail{ - RpcPort: -1, - Ip: "", - AppName: "", - WorkloadName: "", - Labels: nil, - CreateTime: "", - ReadyTime: "", - RegisterTime: "", - RegisterClusters: NewSet(), - DeployCluster: "", - Node: "", - Image: "", +func DeriveInstanceDeployState(instance *meshproto.Instance) InstanceDeployState { + if instance == nil || strutil.IsBlank(instance.DeployState) { + return InstanceDeployStateUnknown + } + deployState := InstanceDeployState(instance.DeployState) + switch deployState { + case InstanceDeployStateRunning: + if !isPodReady(instance) { + return InstanceDeployStateStarting + } + return InstanceDeployStateRunning + default: + return deployState } } -func (a *InstanceDetail) Merge(dataplane *mesh.DataplaneResource) { - // TODO: support more fields - inbounds := dataplane.Spec.Networking.Inbound - for _, inbound := range inbounds { - a.mergeInbound(inbound) - } - meta := dataplane.Meta - a.mergeMeta(meta) - extensions := dataplane.Spec.Extensions - a.mergeExtensions(extensions) - probes := dataplane.Spec.Probes - a.mergeProbes(probes) - - a.Ip = dataplane.GetIP() - if a.RegisterTime != "" { - a.RegisterState = "Registed" - } else { - a.RegisterState = "UnRegisted" +func DeriveInstanceRegisterState(instance *meshproto.Instance) InstanceRegisterState { + if instance == nil || strutil.IsBlank(instance.RegisterTime) { + return InstanceRegisterStateUnregistered } + return InstanceRegisterStateRegistered } -func (a *InstanceDetail) mergeInbound(inbound *legacy.Dataplane_Networking_Inbound) { - a.RpcPort = int(inbound.Port) - a.RegisterClusters.Add(inbound.Tags[legacy.ZoneTag]) - for _, deployCluster := range a.RegisterClusters.Values() { - a.DeployCluster = deployCluster // TODO: separate deployCluster and registerCluster +func DeriveInstanceLifecycleState( + instance *meshproto.Instance, + deployState InstanceDeployState, + registerState InstanceRegisterState, +) InstanceLifecycleState { + switch deployState { + case InstanceDeployStateCrashing, InstanceDeployStateFailed, InstanceDeployStateUnknown, InstanceDeployStateSucceeded: + return InstanceLifecycleStateError + case InstanceDeployStateTerminating: + return InstanceLifecycleStateTerminating } - a.Tags = inbound.Tags - if a.AppName == "" { - a.AppName = inbound.Tags[legacy.AppTag] + + if registerState == InstanceRegisterStateRegistered { + if deployState == InstanceDeployStateRunning { + return InstanceLifecycleStateServing + } + return InstanceLifecycleStateError } -} -func (a *InstanceDetail) mergeExtensions(extensions map[string]string) { - image := extensions[coremodel.ExtensionsImageKey] - a.Image = image - if a.AppName == "" { - a.AppName = extensions[meshproto.Application] + if instance != nil && deployState == InstanceDeployStateRunning && strutil.IsNotBlank(instance.UnregisterTime) { + return InstanceLifecycleStateDraining } - a.WorkloadName = extensions[coremodel.ExtensionsWorkLoadKey] - a.DeployState = extensions[coremodel.ExtensionsPodPhaseKey] - a.Node = extensions[coremodel.ExtensionsNodeNameKey] -} -func (a *InstanceDetail) mergeMeta(meta coremodel.ResourceMeta) { - a.CreateTime = meta.GetCreationTime().String() - a.RegisterTime = meta.GetModificationTime().String() // Not sure if it's the right field - a.ReadyTime = a.RegisterTime - // TODO: separate createTime , RegisterTime and ReadyTime - a.Labels = meta.GetLabels() + switch deployState { + case InstanceDeployStatePending, InstanceDeployStateStarting, InstanceDeployStateRunning: + return InstanceLifecycleStateStarting + default: + return InstanceLifecycleStateUnknown + } } -func (a *InstanceDetail) mergeProbes(probes *legacy.Dataplane_Probes) { - if probes == nil { - return - } - portStartup := probes.Endpoints[0].InboundPort - portReadiness := probes.Endpoints[1].InboundPort - portLiveness := probes.Endpoints[2].InboundPort - a.Probes = ProbeStruct{ - StartupProbe: StartupProbe{ - Type: "HTTP", // TODO: support more scheme - - Port: int(portStartup), - Open: true, - }, - ReadinessProbe: ReadinessProbe{ - Type: "HTTP", // TODO: support more scheme - Port: int(portReadiness), - Open: true, - }, - LivenessProbe: LivenessProbe{ - Type: "HTTP", // TODO: support more scheme - Port: int(portLiveness), - Open: true, - }, +func isPodReady(instance *meshproto.Instance) bool { + for _, condition := range instance.Conditions { + if condition == nil { + continue + } + if condition.Type == "Ready" { + return condition.Status == "True" + } } + return false } diff --git a/api/mesh/v1alpha1/mapping_helper.go b/pkg/console/model/mesh.go similarity index 87% rename from api/mesh/v1alpha1/mapping_helper.go rename to pkg/console/model/mesh.go index 8e8e2e7c5..cff05ffe6 100644 --- a/api/mesh/v1alpha1/mapping_helper.go +++ b/pkg/console/model/mesh.go @@ -15,4 +15,10 @@ * limitations under the License. */ -package v1alpha1 +package model + +type MeshResp struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` +} diff --git a/pkg/console/model/observability.go b/pkg/console/model/observability.go index 967a30b7b..81822286d 100644 --- a/pkg/console/model/observability.go +++ b/pkg/console/model/observability.go @@ -17,37 +17,25 @@ package model -type DashboardReq interface { - GetKeyVariable() string -} - type AppDashboardReq struct { - Application string `form:"application"` -} - -func (req *AppDashboardReq) GetKeyVariable() string { - return req.Application + AppName string `form:"appName"` + Mesh string `form:"appName"` } type InstanceDashboardReq struct { - Instance string `form:"instance"` -} - -func (req *InstanceDashboardReq) GetKeyVariable() string { - return req.Instance + InstanceName string `form:"instanceName"` + Mesh string `form:"mesh"` } type ServiceDashboardReq struct { - Service string `form:"service"` -} - -func (req *ServiceDashboardReq) GetKeyVariable() string { - return req.Service + ServiceName string `form:"serviceName"` + Version string `form:"version"` + Group string `form:"group"` + Mesh string `form:"mesh"` } -// DashboardResp TODO add dynamic variables type DashboardResp struct { - BaseURL string `json:"baseURL"` + FullURL string `json:"fullURL"` } // Metric represents a single metric with its name, labels, and value. @@ -59,6 +47,7 @@ type Metric struct { type MetricsReq struct { InstanceName string `form:"instanceName"` + Mesh string `form:"mesh"` } type MetricsResp struct { diff --git a/pkg/console/model/overview.go b/pkg/console/model/overview.go index 2a467a92d..6ffbf0e09 100644 --- a/pkg/console/model/overview.go +++ b/pkg/console/model/overview.go @@ -18,12 +18,12 @@ package model type OverviewResp struct { - AppCount int `json:"appCount"` - ServiceCount int `json:"serviceCount"` - InsCount int `json:"insCount"` - Protocols map[string]int `json:"protocols"` - Releases map[string]int `json:"releases"` - Discoveries map[string]int `json:"discoveries"` + AppCount int64 `json:"appCount"` + ServiceCount int64 `json:"serviceCount"` + InsCount int64 `json:"insCount"` + Protocols map[string]int64 `json:"protocols"` + Releases map[string]int64 `json:"releases"` + Discoveries map[string]int64 `json:"discoveries"` } func NewOverviewResp() *OverviewResp { diff --git a/pkg/console/model/service.go b/pkg/console/model/service.go index a0ffddb98..09b236de8 100644 --- a/pkg/console/model/service.go +++ b/pkg/console/model/service.go @@ -18,22 +18,28 @@ package model import ( - "strconv" + "encoding/json" + "fmt" "strings" - "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - "github.com/apache/dubbo-admin/pkg/console/constants" + "github.com/duke-git/lancet/v2/strutil" + "github.com/gin-gonic/gin" + + "github.com/apache/dubbo-admin/pkg/common/constants" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) type ServiceSearchReq struct { + coremodel.PageReq + ServiceName string `form:"serviceName" json:"serviceName"` Keywords string `form:"keywords" json:"keywords"` - PageReq + Mesh string `form:"mesh" json:"mesh"` } func NewServiceSearchReq() *ServiceSearchReq { return &ServiceSearchReq{ - PageReq: PageReq{ + PageReq: coremodel.PageReq{ PageOffset: 0, PageSize: 15, }, @@ -41,8 +47,10 @@ func NewServiceSearchReq() *ServiceSearchReq { } type ServiceSearchResp struct { - ServiceName string `json:"serviceName"` - VersionGroups []VersionGroup `json:"versionGroups"` + ServiceName string `json:"serviceName"` + Version string `json:"version"` + Group string `json:"group"` + ConsumerAppName string `json:"consumerAppName,omitempty"` } type ByServiceName []*ServiceSearchResp @@ -55,55 +63,14 @@ func (a ByServiceName) Less(i, j int) bool { func (a ByServiceName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -type ServiceSearch struct { - ServiceName string - VersionGroups Set -} - -func (s *ServiceSearch) FromServiceInfo(info *v1alpha1.ServiceInfo) { - s.VersionGroups.Add(info.Version + " " + info.Group) -} - -func NewServiceSearch(serviceName string) *ServiceSearch { - return &ServiceSearch{ - ServiceName: serviceName, - VersionGroups: NewSet(), - } -} - -func NewServiceSearchResp() *ServiceSearchResp { - return &ServiceSearchResp{ - ServiceName: "", - VersionGroups: nil, - } -} - -func NewServiceDistributionResp() *ServiceTabDistributionResp { - return &ServiceTabDistributionResp{ - AppName: "", - InstanceName: "", - Endpoint: "", - TimeOut: "", - Retries: "", - } -} - -func (s *ServiceSearchResp) FromServiceSearch(search *ServiceSearch) { - s.ServiceName = search.ServiceName - versionGroupList := make([]VersionGroup, 0) - for _, gv := range search.VersionGroups.Values() { - groupAndVersion := strings.Split(gv, " ") - versionGroupList = append(versionGroupList, VersionGroup{Version: groupAndVersion[0], Group: groupAndVersion[1]}) - } - s.VersionGroups = versionGroupList -} - type ServiceTabDistributionReq struct { ServiceName string `json:"serviceName" form:"serviceName" binding:"required"` Version string `json:"version" form:"version"` Group string `json:"group" form:"group"` Side string `json:"side" form:"side" binding:"required"` - PageReq + Mesh string `json:"mesh" form:"mesh" binding:"required"` + Keywords string `json:"keywords" form:"keywords"` + coremodel.PageReq } type ServiceTabDistributionResp struct { @@ -133,60 +100,139 @@ type ServiceTabDistribution struct { Retries string } -func NewServiceDistribution() *ServiceTabDistribution { - return &ServiceTabDistribution{ - AppName: "", - InstanceName: "", - Endpoint: "", - TimeOut: "", - Retries: "", +type BaseServiceReq struct { + ServiceName string `json:"serviceName"` + Group string `json:"group"` + Version string `json:"version"` + Mesh string `json:"mesh"` +} + +func (s *BaseServiceReq) Query(c *gin.Context) error { + s.ServiceName = strings.TrimSpace(c.Query("serviceName")) + if strutil.IsBlank(s.ServiceName) { + return fmt.Errorf("service name is empty") } + s.Group = strings.TrimSpace(c.Query("group")) + s.Version = strings.TrimSpace(c.Query("version")) + s.Mesh = strings.TrimSpace(c.Query("mesh")) + return nil +} + +func (s *BaseServiceReq) ServiceKey() string { + return s.ServiceName + constants.ColonSeparator + s.Version + constants.ColonSeparator + s.Group +} + +type ServiceMethodDetailReq struct { + BaseServiceReq + + MethodName string `form:"methodName" json:"methodName"` + Signature string `form:"signature" json:"signature"` } -func (r *ServiceTabDistributionResp) FromServiceDataplaneResource(dataplane *coremesh.DataplaneResource, metadata *coremesh.MetaDataResource, name string, req *ServiceTabDistributionReq) *ServiceTabDistributionResp { - r.AppName = name - inbounds := dataplane.Spec.Networking.Inbound - ip := dataplane.GetIP() - for _, inbound := range inbounds { - r.mergeInbound(inbound, ip) +func (s *ServiceMethodDetailReq) Query(c *gin.Context) error { + if err := s.BaseServiceReq.Query(c); err != nil { + return err } - meta := dataplane.GetMeta() - r.InstanceName = meta.GetName() - r.mergeMetaData(metadata, req) + s.MethodName = strings.TrimSpace(c.Query("methodName")) + if strutil.IsBlank(s.MethodName) { + return fmt.Errorf("method name is empty") + } + s.Signature = strings.TrimSpace(c.Query("signature")) + if strutil.IsBlank(s.Signature) { + return fmt.Errorf("signature is empty") + } + return nil +} - return r +type ServiceMethodSummaryResp struct { + MethodName string `json:"methodName"` + ParameterTypes []string `json:"parameterTypes"` + Signature string `json:"signature,omitempty"` } -func (r *ServiceTabDistributionResp) mergeInbound(inbound *legacy.Dataplane_Networking_Inbound, ip string) { - r.Endpoint = ip + ":" + strconv.Itoa(int(inbound.Port)) +type ServiceMethodParameter struct { + Name string `json:"name"` + Type string `json:"type"` } -func (r *ServiceTabDistributionResp) FromServiceDistribution(distribution *ServiceTabDistribution) *ServiceTabDistributionResp { - r.AppName = distribution.AppName - r.InstanceName = distribution.InstanceName - r.Endpoint = distribution.Endpoint - r.TimeOut = distribution.TimeOut - r.Retries = distribution.Retries - return r +type ServiceMethodDetailResp struct { + MethodName string `json:"methodName"` + Signature string `json:"signature,omitempty"` + ParameterTypes []string `json:"parameterTypes"` + Parameters []ServiceMethodParameter `json:"parameters"` + ReturnType string `json:"returnType"` + Types []ServiceMethodTypeResp `json:"types"` } -func (r *ServiceTabDistributionResp) mergeMetaData(metadata *coremesh.MetaDataResource, req *ServiceTabDistributionReq) { - // key format is '{group}/{interface name}:{version}:{protocol}' - serviceinfos := metadata.Spec.Services +type ServiceMethodTypeResp struct { + Type string `json:"type"` + Properties map[string]string `json:"properties"` + Items []string `json:"items"` + Enums []string `json:"enums"` +} + +const DefaultServiceGenericInvokeTimeoutMs int64 = 3000 + +type ServiceGenericInvokeReq struct { + BaseServiceReq + + InstanceName string `json:"instanceName"` + MethodName string `json:"methodName"` + Signature string `json:"signature"` + Args []json.RawMessage `json:"args"` + TimeoutMs int64 `json:"timeoutMs"` + Attachments map[string]string `json:"attachments"` +} + +func (s *ServiceGenericInvokeReq) Validate() error { + s.Mesh = strings.TrimSpace(s.Mesh) + if strutil.IsBlank(s.Mesh) { + return fmt.Errorf("mesh is empty") + } + + s.ServiceName = strings.TrimSpace(s.ServiceName) + if strutil.IsBlank(s.ServiceName) { + return fmt.Errorf("service name is empty") + } - for _, serviceinfo := range serviceinfos { - if serviceinfo.Name == req.ServiceName && - serviceinfo.Group == req.Group && - serviceinfo.Version == req.Version && - req.Side == serviceinfo.GetParams()[constants.ServiceInfoSide] { - r.Retries = serviceinfo.Params[constants.RetriesKey] - r.TimeOut = serviceinfo.Params[constants.TimeoutKey] - r.Params = serviceinfo.Params - } + s.MethodName = strings.TrimSpace(s.MethodName) + if strutil.IsBlank(s.MethodName) { + return fmt.Errorf("method name is empty") } + + s.Signature = strings.TrimSpace(s.Signature) + if strutil.IsBlank(s.Signature) { + return fmt.Errorf("signature is empty") + } + + s.InstanceName = strings.TrimSpace(s.InstanceName) + if strutil.IsBlank(s.InstanceName) { + return fmt.Errorf("instance name is empty") + } + + s.Group = strings.TrimSpace(s.Group) + s.Version = strings.TrimSpace(s.Version) + + if s.TimeoutMs <= 0 { + s.TimeoutMs = DefaultServiceGenericInvokeTimeoutMs + } + + return nil +} + +type ServiceGenericInvokeResp struct { + ElapsedMs int64 `json:"elapsedMs"` + RawResult any `json:"rawResult"` +} + +type ServiceDetailReq struct { + ServiceName string `form:"serviceName" json:"serviceName" binding:"required"` + Version string `form:"version" json:"version"` + Group string `form:"group" json:"group"` + Mesh string `form:"mesh" json:"mesh" binding:"required"` } -type VersionGroup struct { - Version string `json:"version"` - Group string `json:"group"` +type ServiceDetailResp struct { + Language string `json:"language"` + Methods []string `json:"methods"` } diff --git a/pkg/console/model/tag_rule.go b/pkg/console/model/tag_rule.go index 78335e39f..9428771ea 100644 --- a/pkg/console/model/tag_rule.go +++ b/pkg/console/model/tag_rule.go @@ -18,16 +18,14 @@ package model import ( - "net/http" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/common/constants" ) type TagRuleSearchResp struct { - CreateTime *string `json:"createTime,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - RuleName *string `json:"ruleName,omitempty"` + CreateTime string `json:"createTime,omitempty"` + Enabled bool `json:"enabled,omitempty"` + RuleName string `json:"ruleName,omitempty"` } type TagRuleResp struct { @@ -47,18 +45,14 @@ type RespTagElement struct { func GenTagRouteResp(pb *meshproto.TagRoute) *CommonResp { if pb == nil { - return &CommonResp{ - Code: http.StatusNotFound, - Msg: "tag rule not found", - Data: "", - } + return NewSuccessResp(nil) } else { return NewSuccessResp(TagRuleResp{ ConfigVersion: pb.ConfigVersion, Enabled: pb.Enabled, Key: pb.Key, Runtime: pb.Runtime, - Scope: consts.ScopeApplication, + Scope: constants.ScopeApplication, Tags: tagToRespTagElement(pb.Tags), }) } diff --git a/pkg/console/router/router.go b/pkg/console/router/router.go index 334f9fee4..24cd7d44c 100644 --- a/pkg/console/router/router.go +++ b/pkg/console/router/router.go @@ -25,11 +25,6 @@ import ( ) func InitRouter(r *gin.Engine, ctx consolectx.Context) { - grafanaRouter := r.Group("/grafana") - { - grafanaRouter.Any("/*any", handler.Grafana(ctx)) - } - router := r.Group("/api/v1") { prometheus := router.Group("/promQL") @@ -54,8 +49,8 @@ func InitRouter(r *gin.Engine, ctx consolectx.Context) { instanceConfig.GET("/operatorLog", handler.InstanceConfigOperatorLogGET(ctx)) instanceConfig.PUT("/operatorLog", handler.InstanceConfigOperatorLogPUT(ctx)) } - instance.GET("/metric-dashboard", handler.GetMetricDashBoard(ctx, handler.InstanceDimension)) - instance.GET("/trace-dashboard", handler.GetTraceDashBoard(ctx, handler.InstanceDimension)) + instance.GET("/metric-dashboard", handler.GetGrafanaDashboard(ctx, handler.InstanceDimension, handler.MetricDashboard)) + instance.GET("/trace-dashboard", handler.GetGrafanaDashboard(ctx, handler.InstanceDimension, handler.TraceDashboard)) instance.GET("/metrics-list", handler.GetMetricsList(ctx)) } @@ -65,10 +60,11 @@ func InitRouter(r *gin.Engine, ctx consolectx.Context) { application.GET("/instance/info", handler.GetApplicationTabInstanceInfo(ctx)) application.GET("/service/form", handler.GetApplicationServiceForm(ctx)) application.GET("/search", handler.ApplicationSearch(ctx)) + application.GET("/graph", handler.GetApplicationGraph(ctx)) { applicationConfig := application.Group("/config") - applicationConfig.PUT("/operatorLog", handler.ApplicationConfigOperatorLogPut(ctx)) - applicationConfig.GET("/operatorLog", handler.ApplicationConfigOperatorLogGet(ctx)) + applicationConfig.PUT("/operatorLog", handler.ApplicationConfigAccessLogPut(ctx)) + applicationConfig.GET("/operatorLog", handler.ApplicationConfigAccessLogGet(ctx)) applicationConfig.GET("/flowWeight", handler.ApplicationConfigFlowWeightGET(ctx)) applicationConfig.PUT("/flowWeight", handler.ApplicationConfigFlowWeightPUT(ctx)) @@ -76,8 +72,8 @@ func InitRouter(r *gin.Engine, ctx consolectx.Context) { applicationConfig.GET("/gray", handler.ApplicationConfigGrayGET(ctx)) applicationConfig.PUT("/gray", handler.ApplicationConfigGrayPUT(ctx)) } - application.GET("/metric-dashboard", handler.GetMetricDashBoard(ctx, handler.AppDimension)) - application.GET("/trace-dashboard", handler.GetTraceDashBoard(ctx, handler.AppDimension)) + application.GET("/metric-dashboard", handler.GetGrafanaDashboard(ctx, handler.AppDimension, handler.MetricDashboard)) + application.GET("/trace-dashboard", handler.GetGrafanaDashboard(ctx, handler.AppDimension, handler.TraceDashboard)) } { @@ -96,14 +92,19 @@ func InitRouter(r *gin.Engine, ctx consolectx.Context) { serviceConfig.GET("/argumentRoute", handler.ServiceConfigArgumentRouteGET(ctx)) serviceConfig.PUT("/argumentRoute", handler.ServiceConfigArgumentRoutePUT(ctx)) } - service.GET("/metric-dashboard", handler.GetMetricDashBoard(ctx, handler.ServiceDimension)) - service.GET("/trace-dashboard", handler.GetTraceDashBoard(ctx, handler.ServiceDimension)) + service.GET("/metric-dashboard", handler.GetGrafanaDashboard(ctx, handler.ServiceDimension, handler.MetricDashboard)) + service.GET("/trace-dashboard", handler.GetGrafanaDashboard(ctx, handler.ServiceDimension, handler.TraceDashboard)) } { service := router.Group("/service") + service.POST("/generic/invoke", handler.ServiceGenericInvoke(ctx)) + service.GET("/method/detail", handler.GetServiceMethodDetail(ctx)) service.GET("/distribution", handler.GetServiceTabDistribution(ctx)) + service.GET("/provider-instances", handler.GetServiceProviderInstances(ctx)) + service.GET("/methods", handler.GetServiceMethodNames(ctx)) service.GET("/search", handler.SearchServices(ctx)) + service.GET("/graph", handler.GetServiceGraph(ctx)) service.GET("/detail", handler.GetServiceDetail(ctx)) service.GET("/interfaces", handler.GetServiceInterfaces(ctx)) } @@ -139,4 +140,5 @@ func InitRouter(r *gin.Engine, ctx consolectx.Context) { router.GET("/search", handler.BannerGlobalSearch(ctx)) router.GET("/overview", handler.ClusterOverview(ctx)) router.GET("/metadata", handler.AdminMetadata(ctx)) + router.GET("/meshes", handler.ListMeshes(ctx)) } diff --git a/pkg/console/service/affinity_rule.go b/pkg/console/service/affinity_rule.go new file mode 100644 index 000000000..c7d5f2b2d --- /dev/null +++ b/pkg/console/service/affinity_rule.go @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package service + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func GetAffinityRule(ctx consolectx.Context, name string, mesh string) (*meshresource.AffinityRouteResource, error) { + res, _, err := manager.GetByKey[*meshresource.AffinityRouteResource]( + ctx.ResourceManager(), + meshresource.AffinityRouteKind, + coremodel.BuildResourceKey(mesh, name)) + if err != nil { + logger.Warnf("get affinity rule %s error: %v", name, err) + return nil, err + } + return res, nil +} + +func UpdateAffinityRule(ctx consolectx.Context, res *meshresource.AffinityRouteResource) error { + if err := ctx.ResourceManager().Update(res); err != nil { + logger.Warnf("update %s affinity rule failed with error: %s", res.Name, err.Error()) + return err + } + return nil +} + +func CreateAffinityRule(ctx consolectx.Context, res *meshresource.AffinityRouteResource) error { + if err := ctx.ResourceManager().Add(res); err != nil { + logger.Warnf("create %s condition failed with error: %s", res.Name, err.Error()) + return err + } + return nil +} + +func DeleteAffinityRule(ctx consolectx.Context, name string, mesh string) error { + if err := ctx.ResourceManager().DeleteByKey( + meshresource.AffinityRouteKind, + mesh, + coremodel.BuildResourceKey(mesh, name)); err != nil { + return err + } + return nil +} diff --git a/pkg/console/service/application.go b/pkg/console/service/application.go index d8e0c138b..58133521e 100644 --- a/pkg/console/service/application.go +++ b/pkg/console/service/application.go @@ -18,50 +18,42 @@ package service import ( + "fmt" "strconv" - "strings" - "dubbo.apache.org/dubbo-go/v3/common/constant" + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - "github.com/apache/dubbo-admin/pkg/console/constants" - "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoveryutil "github.com/apache/dubbo-admin/pkg/common/util/discovery" + "github.com/apache/dubbo-admin/pkg/config/app" + consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" - "github.com/apache/dubbo-admin/pkg/core/store" - - "github.com/apache/dubbo-kubernetes/pkg/core/resources/apis/mesh" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) -func GetApplicationDetail(ctx context.Context, req *model.ApplicationDetailReq) (*model.ApplicationDetailResp, error) { - manager := ctx.ResourceManager() - instanceList := &mesh.DataplaneResourceList{} - - manager.ListPageByKey() - if err := manager.List(ctx.AppContext(), instanceList, store.ListByApplication(req.AppName)); err != nil { +func GetApplicationDetail(ctx consolectx.Context, req *model.ApplicationDetailReq) (*model.ApplicationDetailResp, error) { + instanceResources, err := manager.ListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceAppNameIndex, Value: req.AppName, Operator: index.Equals}, + }, + ) + if err != nil { return nil, err } - revisions := make(map[string]*mesh.MetaDataResource, 0) applicationDetail := model.NewApplicationDetail() - for _, dataplane := range instanceList.Items { - if strings.Split(dataplane.GetMeta().GetName(), constant.KeySeparator)[1] == "0" { - continue - } - rev, ok := dataplane.Spec.GetExtensions()[meshproto.RevisionLabel] - if ok { - if metadata, cached := revisions[rev]; !cached { - metadata = &mesh.MetaDataResource{ - Spec: &meshproto.MetaData{}, - } - if err := manager.Get(ctx.AppContext(), metadata, store.GetByRevision(rev), store.GetByType(dataplane.Spec.GetExtensions()["registry-type"])); err != nil { - return nil, err - } - revisions[rev] = metadata - applicationDetail.MergeMetaData(metadata) - } - } - applicationDetail.MergeDataplane(dataplane) - applicationDetail.GetRegistry(ctx) + for _, instanceRes := range instanceResources { + applicationDetail.MergeInstance(instanceRes, ctx.Config()) } respItem := &model.ApplicationDetailResp{ @@ -72,156 +64,747 @@ func GetApplicationDetail(ctx context.Context, req *model.ApplicationDetailReq) return respItem, nil } -func GetApplicationTabInstanceInfo(ctx context.Context, req *model.ApplicationTabInstanceInfoReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByApplication(req.AppName), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { +func GetAppInstanceInfo(ctx consolectx.Context, req *model.ApplicationTabInstanceInfoReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceAppNameIndex, Value: req.AppName, Operator: index.Equals}, + }, + req.PageReq, + ) + if err != nil { return nil, err } - res := model.NewSearchPaginationResult() - list := make([]*model.ApplicationTabInstanceInfoResp, 0, len(dataplaneList.Items)) - for _, dataplane := range dataplaneList.Items { - if strings.Split(dataplane.Meta.GetName(), constant.KeySeparator)[1] == "0" { - continue - } - resItem := &model.ApplicationTabInstanceInfoResp{} - resItem.FromDataplaneResource(dataplane) - resItem.GetRegistry(ctx) - list = append(list, resItem) + list := slice.Map[*meshresource.InstanceResource, *model.AppInstanceInfoResp](pageData.Data, + func(_ int, item *meshresource.InstanceResource) *model.AppInstanceInfoResp { + return buildAppInstanceInfoResp(item, ctx.Config()) + }) + searchResult := &model.SearchPaginationResult{ + List: list, + PageInfo: pageData.Pagination, + } + return searchResult, nil +} + +func buildAppInstanceInfoResp(instanceRes *meshresource.InstanceResource, cfg app.AdminConfig) *model.AppInstanceInfoResp { + instance := instanceRes.Spec + resp := &model.AppInstanceInfoResp{} + resp.Name = instance.Name + resp.AppName = instance.AppName + resp.CreateTime = instance.CreateTime + resp.DeployState = model.DeriveInstanceDeployState(instance) + resp.LifecycleState = model.DeriveInstanceLifecycleState(instance, resp.DeployState, model.DeriveInstanceRegisterState(instance)) + if cfg.Engine.ID == instance.SourceEngine { + resp.DeployClusters = cfg.Engine.Name + } + resp.IP = instance.Ip + resp.Labels = instance.Tags + if d := cfg.FindDiscovery(instanceRes.Mesh); d != nil { + resp.RegisterCluster = d.Name + } + resp.RegisterState = model.DeriveInstanceRegisterState(instance) + resp.RegisterTime = instance.RegisterTime + resp.WorkloadName = instance.WorkloadName + return resp +} + +func GetAppServiceInfo(ctx consolectx.Context, req *model.ApplicationServiceFormReq) (*model.SearchPaginationResult, error) { + if req.Side == constants.ConsumerSide { + return getAppConsumeServiceInfo(ctx, req) + } else { + return getAppProvideServiceInfo(ctx, req) } - res.List = list - res.PageInfo = &dataplaneList.Pagination +} - return res, nil +func getAppProvideServiceInfo(ctx consolectx.Context, req *model.ApplicationServiceFormReq) (*model.SearchPaginationResult, error) { + var conditions []index.IndexCondition + conditions = append(conditions, index.IndexCondition{ + IndexName: index.ByMeshIndex, + Value: req.Mesh, + Operator: index.Equals, + }) + conditions = append(conditions, index.IndexCondition{ + IndexName: index.ByServiceProviderAppName, + Value: req.AppName, + Operator: index.Equals, + }) + if strutil.IsNotBlank(req.ServiceName) { + conditions = append(conditions, index.IndexCondition{ + IndexName: index.ByServiceProviderServiceName, + Value: req.ServiceName, + Operator: index.Equals, + }) + } + pageData, err := manager.PageListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + conditions, + req.PageReq, + ) + if err != nil { + return nil, err + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*meshresource.ServiceProviderMetadataResourceList{}, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + respList := slice.Map(pageData.Data, func(_ int, item *meshresource.ServiceProviderMetadataResource) *model.ServiceSearchResp { + return ToServiceSearchRespByProvider(item) + }) + + pageResult := &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + } + return pageResult, nil } -func GetApplicationServiceFormInfo(ctx context.Context, req *model.ApplicationServiceFormReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} +func getAppConsumeServiceInfo(ctx consolectx.Context, req *model.ApplicationServiceFormReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.ServiceConsumerMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceConsumerMetadataKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerAppName, Value: req.AppName, Operator: index.Equals}, + }, + req.PageReq, + ) + if err != nil { + return nil, err + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*meshresource.ServiceConsumerMetadataResourceList{}, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + respList := slice.Map(pageData.Data, func(_ int, item *meshresource.ServiceConsumerMetadataResource) *model.ServiceSearchResp { + return ToServiceSearchRespByConsumer(item) + }) + pageResult := &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + } + return pageResult, nil +} + +// GraphApplications returns the application-level graph for a given application. +// It collects provider and consumer service relations and transforms them into nodes and edges. +// The current implementation is a simplified version (provider/consumer link traversal). +func GraphApplications(ctx consolectx.Context, req *model.ApplicationGraphReq) (*model.GraphData, error) { + + // Step 1: query all services provided by this application in the namespace. + providerServiceList, err := manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderAppName, Value: req.AppName, Operator: index.Equals}, + }, + ) + if err != nil { + // manager.ListByIndexes An appropriate error has already been generated internally; simply pass it through directly. + return nil, err + } - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByApplication(req.AppName)); err != nil { + // Step 2: query all services consumed by this application in the namespace. + consumerServiceList, err := manager.ListByIndexes[*meshresource.ServiceConsumerMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceConsumerMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerAppName, Value: req.AppName, Operator: index.Equals}, + }, + ) + if err != nil { return nil, err } - res := make([]*model.ApplicationServiceFormResp, 0) - serviceMap := make(map[string]*model.ApplicationServiceForm) - revisions := make(map[string]*mesh.MetaDataResource, 0) - for _, dataplane := range dataplaneList.Items { - rev, ok := dataplane.Spec.GetExtensions()[meshproto.RevisionLabel] - if !ok { + // Step 3: build the graph nodes and edges from provider and consumer relations. + // providerAppSet and consumerAppSet track already-added application nodes. + providerAppSet := make(map[string]struct{}) + consumerAppSet := make(map[string]struct{}) + + nodes := make([]model.GraphNode, 0) + edges := make([]model.GraphEdge, 0) + // init self node + nodes = append(nodes, model.GraphNode{ + ID: req.AppName, + Label: req.AppName, + Type: "application", + Rule: "", // self node doesn't have a rule + Data: nil, + }) + // 3.a: iterate over provided services, collect service nodes and consumer app nodes. + for _, provider := range providerServiceList { + if provider.Spec == nil { continue } - metadata, cached := revisions[rev] - if !cached { - metadata = &mesh.MetaDataResource{ - Spec: &meshproto.MetaData{}, - } - if err := manager.Get(ctx.AppContext(), metadata, store.GetByRevision(rev), store.GetByType(dataplane.Spec.GetExtensions()["registry-type"])); err != nil { - return nil, err - } - revisions[rev] = metadata + // For each provided service, find consuming applications and add them as nodes. + consumerAppServiceList, err := manager.ListByIndexes[*meshresource.ServiceConsumerMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceConsumerMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerServiceKey, Value: provider.Spec.ServiceName + ":" + provider.Spec.Version + ":" + provider.Spec.Group, Operator: index.Equals}, + }, + ) + if err != nil { + logger.Errorf("failed to list consumer apps by provider service key, mesh: %s, serviceKey: %s, err: %s", req.Mesh, provider.Spec.ProviderAppName+":"+provider.Spec.Version+":"+provider.Spec.Group, err) + continue } - for _, serviceInfo := range metadata.Spec.Services { - if serviceInfo.Params[constants.ServiceInfoSide] != req.Side { + for _, item := range consumerAppServiceList { + if item.Spec == nil { continue } - applicationServiceForm := model.NewApplicationServiceForm(serviceInfo.Name) - if _, ok := serviceMap[serviceInfo.Name]; !ok { - serviceMap[serviceInfo.Name] = applicationServiceForm + if _, ok := consumerAppSet[item.Spec.ConsumerAppName]; !ok { + consumerAppSet[item.Spec.ConsumerAppName] = struct{}{} + nodes = append(nodes, model.GraphNode{ + ID: item.Spec.ConsumerAppName, + Label: item.Spec.ConsumerAppName, + Type: "application", + Rule: constants.ConsumerSide, + Data: nil, + }) + edges = append(edges, model.GraphEdge{ + Source: item.Spec.ConsumerAppName, + Target: provider.Spec.ProviderAppName, + Data: nil, + }) } + } + } + + // 3.b: iterate over consumed services, collect service nodes and provider app nodes. + for _, consumer := range consumerServiceList { + if consumer.Spec == nil { + continue + } + + // For each consumed service, find providing applications and add them as nodes. + providerAppList, err := manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderServiceKey, Value: consumer.Spec.ServiceName + ":" + consumer.Spec.Version + ":" + consumer.Spec.Group, Operator: index.Equals}, + }, + ) + if err != nil { + logger.Errorf("failed to list consumer apps by provider service key, mesh: %s, serviceKey: %s, err: %s", req.Mesh, consumer.Spec.ConsumerAppName+":"+consumer.Spec.Version+":"+consumer.Spec.Group, err) + continue + } - if err := applicationServiceForm.FromServiceInfo(serviceInfo); err != nil { - return nil, err + for _, item := range providerAppList { + if item.Spec == nil { + continue + } + if _, ok := providerAppSet[item.Spec.ProviderAppName]; !ok { + providerAppSet[item.Spec.ProviderAppName] = struct{}{} + nodes = append(nodes, model.GraphNode{ + ID: item.Spec.ProviderAppName, + Label: item.Spec.ProviderAppName, + Type: "application", + Rule: constants.ProviderSide, + Data: nil, + }) + edges = append(edges, model.GraphEdge{ + Source: consumer.Spec.ConsumerAppName, + Target: item.Spec.ProviderAppName, + Data: nil, + }) } } } - for _, applicationServiceForm := range serviceMap { - applicationServiceFormResp := model.NewApplicationServiceFormResp() - if err := applicationServiceFormResp.FromApplicationServiceForm(applicationServiceForm); err != nil { + // Step 4: assemble and return graph data (nodes + edges). + return &model.GraphData{ + Nodes: nodes, + Edges: edges, + }, nil +} + +func SearchApplications(ctx consolectx.Context, req *model.ApplicationSearchReq) (*model.SearchPaginationResult, error) { + if strutil.IsNotBlank(req.Keywords) { + appResList, err := SearchApplicationsByKeywords(ctx, &model.SearchReq{ + PageReq: req.PageReq, + SearchType: "appName", + Keywords: req.Keywords, + Mesh: req.Mesh, + }) + if err != nil || appResList == nil { return nil, err } - res = append(res, applicationServiceFormResp) + return &model.SearchPaginationResult{ + List: appResList, + PageInfo: coremodel.Pagination{ + Total: len(appResList), + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + + pageData, err := manager.PageListByIndexes[*meshresource.ApplicationResource]( + ctx.ResourceManager(), + meshresource.ApplicationKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq, + ) + if err != nil { + return nil, err + } + respList := slice.Map[*meshresource.ApplicationResource, *model.ApplicationSearchResp](pageData.Data, + func(_ int, item *meshresource.ApplicationResource) *model.ApplicationSearchResp { + return &model.ApplicationSearchResp{ + AppName: item.Spec.Name, + DeployClusters: []string{ctx.Config().Engine.Name}, + InstanceCount: item.Spec.InstanceCount, + RegistryClusters: []string{discoveryutil.GetOrDefaultRegistryName(ctx.Config(), item.Mesh)}, + } + }) + searchResult := &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, } + return searchResult, nil +} - pagedRes := ToSearchPaginationResult(res, model.ByAppServiceFormName(res), req.PageReq) +// SearchApplicationsByKeywords search applications by keywords, for now only support accurate search by appName +func SearchApplicationsByKeywords(ctx consolectx.Context, req *model.SearchReq) ([]*model.ApplicationSearchResp, error) { + appResKey := coremodel.BuildResourceKey(req.Mesh, req.Keywords) + appRes, exists, err := manager.GetByKey[*meshresource.ApplicationResource]( + ctx.ResourceManager(), + meshresource.ApplicationKind, + appResKey) + if err != nil { + return nil, err + } + if !exists { + return nil, nil + } + searchResp := &model.ApplicationSearchResp{ + AppName: appRes.Spec.Name, + DeployClusters: []string{ctx.Config().Engine.Name}, + InstanceCount: appRes.Spec.InstanceCount, + RegistryClusters: []string{discoveryutil.GetOrDefaultRegistryName(ctx.Config(), appRes.Mesh)}, + } + return []*model.ApplicationSearchResp{searchResp}, nil +} - return pagedRes, nil +func isAppAccessLogConfig(conf *meshproto.OverrideConfig, appName string) bool { + if conf.Side != constants.SideProvider || + conf.Parameters == nil || + conf.Match == nil || + conf.Match.Application == nil || + conf.Match.Application.Oneof == nil || + len(conf.Match.Application.Oneof) != 1 || + conf.Match.Application.Oneof[0].Exact != appName { + return false + } + if _, ok := conf.Parameters[`accesslog`]; !ok { + return false + } + return true } -func GetApplicationSearchInfo(ctx context.Context, req *model.ApplicationSearchReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} +func UpInsertAppAccessLog(ctx consolectx.Context, appName string, openAccessLog bool, mesh string) error { + // check app exists + data, err := GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: appName}) + if err != nil { + return err + } + if data == nil { + return bizerror.New(bizerror.AppNotFound, fmt.Sprintf("%s does not exist", appName)) + } + // check app configurator exists + appConfiguratorName := appName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + if err != nil { + return err + } + // if not exists, create one configurator with access log enable + if res == nil { + return insertConfiguratorWithAccessLog(ctx, res, openAccessLog, appConfiguratorName, appName, mesh) + } + // else we update the configurator + return updateConfiguratorWithAccessLog(ctx, res, openAccessLog, appConfiguratorName, appName, mesh) +} - if req.Keywords != "" { - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByApplicationContains(req.Keywords)); err != nil { - return nil, err +func insertConfiguratorWithAccessLog(ctx consolectx.Context, res *meshresource.DynamicConfigResource, openAccessLog bool, + appConfiguratorName, appName, mesh string) error { + // configurator is nil, accessLog is already closed + if !openAccessLog { + return nil + } + res = meshresource.NewDynamicConfigResourceWithAttributes(appConfiguratorName, mesh) + res.Spec = &meshproto.DynamicConfig{ + Key: appName, + Scope: constants.ScopeApplication, + ConfigVersion: constants.ConfiguratorVersionV3, + Enabled: true, + Configs: make([]*meshproto.OverrideConfig, 0), + } + res.Spec.Configs = append(res.Spec.Configs, newAccessLogEnabledConfig(appName)) + err := CreateConfigurator(ctx, res) + if err != nil { + logger.Errorf("create configurator failed when open accesslog, resourceKey: %s, openAccessLog: %t, err: %s", + coremodel.BuildResourceKey(mesh, appName), openAccessLog, err) + return err + } + return nil +} + +func updateConfiguratorWithAccessLog(ctx consolectx.Context, res *meshresource.DynamicConfigResource, openAccessLog bool, + appConfiguratorName, appName, mesh string) error { + var accessLogConfig *meshproto.OverrideConfig + res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { + if isAppAccessLogConfig(conf, appName) { + accessLogConfig = conf + return true } + return false + }) + // access log config not found + if accessLogConfig == nil { + // access log needs to be closed and already closed + if !openAccessLog { + return nil + } + // insert a access log enabled config + res.Spec.Configs = append(res.Spec.Configs, newAccessLogEnabledConfig(appName)) } else { - if err := manager.List(ctx.AppContext(), dataplaneList); err != nil { - return nil, err + // access log config found and status is the same as needed + if accessLogConfig.Enabled == openAccessLog { + return nil } + // update the access log enabled status as needed + accessLogConfig.Enabled = openAccessLog } + err := UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update configurator failed when opening accesslog, resourceKey: %s, openAccessLog: %t, err: %s", + coremodel.BuildResourceKey(mesh, appName), openAccessLog, err) + return err + } + return nil +} - res := make([]*model.ApplicationSearchResp, 0) - appMap := make(map[string]*model.ApplicationSearch) - for _, dataplane := range dataplaneList.Items { - if strings.Split(dataplane.GetMeta().GetName(), constant.KeySeparator)[1] == "0" { - continue - } - appName := dataplane.Spec.GetExtensions()[meshproto.Application] - if _, ok := appMap[appName]; !ok { - appMap[appName] = model.NewApplicationSearch(appName) +func newAccessLogEnabledConfig(appName string) *meshproto.OverrideConfig { + return &meshproto.OverrideConfig{ + Side: constants.SideProvider, + Parameters: map[string]string{`accesslog`: `true`}, + Enabled: true, + Match: &meshproto.ConditionMatch{ + Application: &meshproto.ListStringMatch{ + Oneof: []*meshproto.StringMatch{ + { + Exact: appName, + }, + }}}, + XGenerateByCp: true, + } +} + +func GetAppAccessLog(ctx consolectx.Context, appName string, mesh string) (*model.AppAccessLogConfigResp, error) { + appConfiguratorName := appName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + resp := &model.AppAccessLogConfigResp{ + AccessLog: false, + } + if err != nil { + logger.Errorf("get configurator failed when get app accesslog, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return nil, err + } + if res == nil { + return resp, nil + } + var appAccessLogConfig *meshproto.OverrideConfig + res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { + if isAppAccessLogConfig(conf, appName) { + appAccessLogConfig = conf + return true } - appMap[appName].MergeDataplane(dataplane) - appMap[appName].GetRegistry(ctx) + return false + }) + if appAccessLogConfig == nil { + return resp, nil + } + resp.AccessLog = appAccessLogConfig.Enabled + return resp, nil +} + +func GetAppFlowWeight(ctx consolectx.Context, appName string, mesh string) (*model.AppFlowWeightConfigResp, error) { + resp := &model.AppFlowWeightConfigResp{ + FlowWeightSets: []model.FlowWeightSet{}, + } + appConfiguratorName := appName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + if err != nil { + logger.Errorf("get configurator failed when get app flow weight, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return nil, err + } + if res == nil { + return resp, nil } - for appName, search := range appMap { - applicationSearchResp := &model.ApplicationSearchResp{ - AppName: appName, + weight := 0 + res.Spec.RangeConfig(func(conf *meshproto.OverrideConfig) (isStop bool) { + if isFlowWeightConfig(conf) { + weight, err = strconv.Atoi(conf.Parameters[`weight`]) + if err != nil { + logger.Error("parse weight failed", err) + return true + } + scope := make([]model.ParamMatch, 0, len(conf.Match.Param)) + for _, param := range conf.Match.Param { + scope = append(scope, model.ParamMatch{ + Key: ¶m.Key, + Value: model.StringMatchToModelStringMatch(param.Value), + }) + } + + resp.FlowWeightSets = append(resp.FlowWeightSets, model.FlowWeightSet{ + Weight: int32(weight), + Scope: scope, + }) } - res = append(res, applicationSearchResp.FromApplicationSearch(search)) + return false + }) + return resp, nil +} + +func isFlowWeightConfig(conf *meshproto.OverrideConfig) bool { + if conf.Side != constants.SideProvider || + conf.Parameters == nil || + conf.Match == nil || + conf.Match.Param == nil { + return false + } + if _, ok := conf.Parameters[`weight`]; !ok { + return false } + return true +} - pagedRes := ToSearchPaginationResult(res, model.ByAppName(res), req.PageReq) - return pagedRes, nil +func UpInsertAppFlowWeightConfig(ctx consolectx.Context, appName string, mesh string, flowWeightSets []model.FlowWeightSet) error { + // check app exists + data, err := GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: appName}) + if err != nil { + return err + } + if data == nil { + return bizerror.New(bizerror.AppNotFound, fmt.Sprintf("%s does not exist", appName)) + } + appConfiguratorName := appName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + if err != nil { + logger.Errorf("get configurator failed when update app flow weight, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + // configurator not exists, insert a new one + if res == nil { + return insertConfiguratorWithFlowWeight(ctx, flowWeightSets, appName, appConfiguratorName, mesh) + } + // configurator exists, update it + + // remove old flow weight config + res.Spec.RangeConfigsToRemove(func(conf *meshproto.OverrideConfig) (IsRemove bool) { + return isFlowWeightConfig(conf) + }) + + // add new flow weight config + flowWeightConfigs := slice.Map(flowWeightSets, func(index int, set model.FlowWeightSet) *meshproto.OverrideConfig { + return fromFlowWeightSet(set) + }) + res.Spec.Configs = slice.Union(res.Spec.Configs, flowWeightConfigs) + + err = UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update configurator failed with app flow weight, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + return nil } -func BannerSearchApplications(ctx context.Context, req *model.SearchReq) ([]*model.ApplicationSearchResp, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - if req.Keywords != "" { - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByApplicationContains(req.Keywords)); err != nil { - return nil, err - } - } else { - if err := manager.List(ctx.AppContext(), dataplaneList); err != nil { - return nil, err - } +func insertConfiguratorWithFlowWeight( + ctx consolectx.Context, + flowWeightSets []model.FlowWeightSet, + appName, appConfiguratorName, mesh string) error { + res := meshresource.NewDynamicConfigResourceWithAttributes(appConfiguratorName, mesh) + res.Spec = &meshproto.DynamicConfig{ + Key: appName, + Scope: constants.ScopeApplication, + ConfigVersion: constants.ConfiguratorVersionV3, + Enabled: true, } + flowWeightConfigs := slice.Map(flowWeightSets, func(index int, set model.FlowWeightSet) *meshproto.OverrideConfig { + return fromFlowWeightSet(set) + }) + res.Spec.Configs = flowWeightConfigs + err := CreateConfigurator(ctx, res) + if err != nil { + logger.Errorf("insert configurator failed with app flow weight, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + return nil +} - res := make([]*model.ApplicationSearchResp, 0) - appMap := make(map[string]*model.ApplicationSearch) - for _, dataplane := range dataplaneList.Items { - appName := dataplane.Spec.GetExtensions()[meshproto.Application] - if _, ok := appMap[appName]; !ok { - appMap[appName] = model.NewApplicationSearch(appName) - } - appMap[appName].MergeDataplane(dataplane) - appMap[appName].GetRegistry(ctx) +func fromFlowWeightSet(set model.FlowWeightSet) *meshproto.OverrideConfig { + paramMatch := make([]*meshproto.ParamMatch, 0, len(set.Scope)) + for _, match := range set.Scope { + paramMatch = append(paramMatch, &meshproto.ParamMatch{ + Key: *match.Key, + Value: model.ModelStringMatchToStringMatch(match.Value), + }) + } + return &meshproto.OverrideConfig{ + Side: constants.SideProvider, + Parameters: map[string]string{`weight`: strconv.Itoa(int(set.Weight))}, + Match: &meshproto.ConditionMatch{ + Param: paramMatch, + }, + XGenerateByCp: true, } +} - for appName, search := range appMap { - applicationSearchResp := &model.ApplicationSearchResp{ - AppName: appName, +func GetGrayConfig(ctx consolectx.Context, appName string, mesh string) (*model.AppGrayConfigResp, error) { + resp := &model.AppGrayConfigResp{} + serviceTagRuleName := appName + constants.TagRuleDotSuffix + res, err := GetTagRule(ctx, serviceTagRuleName, mesh) + if err != nil { + logger.Errorf("get tag rule failed when get gray config, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return nil, err + } + if res == nil { + return resp, err + } + resp.GraySets = make([]model.GraySet, 0, len(res.Spec.Tags)) + + res.Spec.RangeTags(func(tag *meshproto.Tag) (isStop bool) { + if isGrayTag(tag) { + scope := make([]model.ParamMatch, 0, len(tag.Match)) + for _, paramMatch := range tag.Match { + scope = append(scope, model.ParamMatch{ + Key: ¶mMatch.Key, + Value: model.StringMatchToModelStringMatch(paramMatch.Value), + }) + } + resp.GraySets = append(resp.GraySets, model.GraySet{ + EnvName: tag.Name, + Scope: scope, + }) } - res = append(res, applicationSearchResp.FromApplicationSearch(search)) + return false + }) + return resp, nil +} + +func isGrayTag(tag *meshproto.Tag) bool { + if tag.Name == "" || len(tag.Addresses) != 0 { + return false + } + return true +} + +func UpInsertAppGrayConfig(ctx consolectx.Context, appName string, mesh string, graySets []model.GraySet) error { + serviceTagRuleName := appName + constants.TagRuleDotSuffix + res, err := GetTagRule(ctx, serviceTagRuleName, mesh) + if err != nil { + logger.Errorf("get tag rule failed when update app gray config, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + _, err = GetApplicationDetail(ctx, &model.ApplicationDetailReq{AppName: appName, Mesh: mesh}) + if err != nil { + return err + } + // tag rule not exists, insert a new one + if res == nil { + return insertTagRuleWithGrayConfig(ctx, graySets, appName, serviceTagRuleName, mesh) + } + // tag rule exists, update it + return updateTagRuleWithGrayConfig(ctx, graySets, res, appName, mesh) +} + +func insertTagRuleWithGrayConfig( + ctx consolectx.Context, + graySets []model.GraySet, + appName, serviceTagRuleName, mesh string) error { + res := meshresource.NewTagRouteResourceWithAttributes(serviceTagRuleName, mesh) + res.Spec = &meshproto.TagRoute{ + Enabled: true, + Key: appName, + ConfigVersion: constants.ConfiguratorVersionV3, + Force: false, + } + tags := slice.Map(graySets, func(index int, set model.GraySet) *meshproto.Tag { + return fromGraySet(set) + }) + res.Spec.Tags = tags + err := CreateTagRule(ctx, res) + if err != nil { + logger.Errorf("insert tag rule failed with app gray config, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + return nil +} + +func updateTagRuleWithGrayConfig( + ctx consolectx.Context, + graySets []model.GraySet, + res *meshresource.TagRouteResource, + appName string, mesh string) error { + // remove old config, generate config from admin, append + res.Spec.RangeTagsToRemove(func(tag *meshproto.Tag) (IsRemove bool) { + return isGrayTag(tag) + }) + tags := slice.Map(graySets, func(index int, set model.GraySet) *meshproto.Tag { + return fromGraySet(set) + }) + res.Spec.Tags = append(res.Spec.Tags, tags...) + err := UpdateTagRule(ctx, res) + if err != nil { + logger.Errorf("update tag rule failed with app gray config, resourceKey: %s, err: %s", + coremodel.BuildResourceKey(mesh, appName), err) + return err + } + return nil +} + +func fromGraySet(set model.GraySet) *meshproto.Tag { + paramMatches := make([]*meshproto.ParamMatch, 0, len(set.Scope)) + for _, match := range set.Scope { + paramMatches = append(paramMatches, &meshproto.ParamMatch{ + Key: *match.Key, + Value: model.ModelStringMatchToStringMatch(match.Value), + }) + } + + return &meshproto.Tag{ + Name: set.EnvName, + Match: paramMatches, + XGenerateByCp: true, } - return res, nil } diff --git a/pkg/console/service/condition_rule.go b/pkg/console/service/condition_rule.go index 193b6f49b..9fae15940 100644 --- a/pkg/console/service/condition_rule.go +++ b/pkg/console/service/condition_rule.go @@ -18,91 +18,146 @@ package service import ( - "strconv" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/lock" + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" - "github.com/apache/dubbo-admin/pkg/core/consts" "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) func SearchConditionRules(ctx context.Context, req *model.SearchConditionRuleReq) (*model.SearchPaginationResult, error) { - ruleList := &mesh.ConditionRouteResourceList{} - if req.Keywords == "" { - if err := ctx.ResourceManager().List(ctx.AppContext(), ruleList, store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - return nil, err - } - } else { - if err := ctx.ResourceManager().List(ctx.AppContext(), ruleList, store.ListByNameContains(req.Keywords), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - return nil, err - } + if strutil.IsNotBlank(req.Keywords) { + return SearchConditionRuleByKeywords(ctx, req) } + pageData, err := manager.PageListByIndexes[*meshresource.ConditionRouteResource]( + ctx.ResourceManager(), + meshresource.ConditionRouteKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq) + if err != nil { + logger.Errorf("search condition route error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search condition route failed, please try again") + } + respList := slice.FilterMap(pageData.Data, + func(index int, item *meshresource.ConditionRouteResource) (*model.ConditionRuleSearchResp, bool) { + resp := ToSearchConditionRuleResp(item) + return resp, resp != nil + }) + return &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + }, nil +} + +// SearchConditionRuleByKeywords for now, only accurate search is supported +func SearchConditionRuleByKeywords(ctx context.Context, req *model.SearchConditionRuleReq) (*model.SearchPaginationResult, error) { + resKey := coremodel.BuildResourceKey(req.Mesh, req.Keywords) + conditionRuleRes, exists, err := manager.GetByKey[*meshresource.ConditionRouteResource]( + ctx.ResourceManager(), meshresource.ConditionRouteKind, resKey) + if err != nil { + logger.Errorf("search condition rule error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search condition rule failed, please try again") + } + if !exists { + return &model.SearchPaginationResult{ + List: nil, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + return &model.SearchPaginationResult{ + List: []*model.ConditionRuleSearchResp{ToSearchConditionRuleResp(conditionRuleRes)}, + PageInfo: coremodel.Pagination{ + Total: 1, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil +} - var respList []model.ConditionRuleSearchResp - for _, item := range ruleList.Items { - if v3 := item.Spec.ToConditionRouteV3(); v3 != nil { - respList = append(respList, model.ConditionRuleSearchResp{ - RuleName: item.Meta.GetName(), - Scope: v3.GetScope(), - CreateTime: item.Meta.GetCreationTime().String(), - Enabled: v3.GetEnabled(), - }) - } else if v3x1 := item.Spec.ToConditionRouteV3x1(); v3x1 != nil { - respList = append(respList, model.ConditionRuleSearchResp{ - RuleName: item.Meta.GetName(), - Scope: v3x1.GetScope(), - CreateTime: item.Meta.GetCreationTime().String(), - Enabled: v3x1.GetEnabled(), - }) - } else { - logger.Errorf("Invalid condition route %v", item) - } +func ToSearchConditionRuleResp(res *meshresource.ConditionRouteResource) *model.ConditionRuleSearchResp { + return &model.ConditionRuleSearchResp{ + RuleName: res.Name, + Scope: res.Spec.Scope, + CreateTime: res.CreationTimestamp.String(), + Enabled: res.Spec.Enabled, } - result := model.NewSearchPaginationResult() - result.List = respList - result.PageInfo = &ruleList.Pagination - return result, nil } -func GetConditionRule(cs context.Context, name string) (*mesh.ConditionRouteResource, error) { - res := &mesh.ConditionRouteResource{Spec: &meshproto.ConditionRoute{}} - if err := cs.ResourceManager().Get(cs.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.GetByApplication(name), store.GetByKey(name+consts.ConditionRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("get %s condition failed with error: %s", name, err.Error()) +func GetConditionRule(ctx context.Context, name string, mesh string) (*meshresource.ConditionRouteResource, error) { + res, _, err := manager.GetByKey[*meshresource.ConditionRouteResource]( + ctx.ResourceManager(), meshresource.ConditionRouteKind, coremodel.BuildResourceKey(mesh, name)) + if err != nil { + logger.Warnf("get condition route %s error: %v", name, err) return nil, err } return res, nil } -func UpdateConditionRule(cs context.Context, name string, res *mesh.ConditionRouteResource) error { - if err := cs.ResourceManager().Update(cs.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.UpdateByApplication(name), store.UpdateByKey(name+consts.ConditionRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("update %s condition failed with error: %s", name, err.Error()) +func UpdateConditionRule(ctx context.Context, res *meshresource.ConditionRouteResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return updateConditionRuleUnsafe(ctx, res) + } + lockKey := lock.BuildConditionRuleLockKey(res.Mesh, res.Name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return updateConditionRuleUnsafe(ctx, res) + }) +} + +func updateConditionRuleUnsafe(ctx context.Context, res *meshresource.ConditionRouteResource) error { + if err := ctx.ResourceManager().Update(res); err != nil { + logger.Warnf("update %s condition failed with error: %s", res.Name, err.Error()) return err } return nil } -func CreateConditionRule(cs context.Context, name string, res *mesh.ConditionRouteResource) error { - if err := cs.ResourceManager().Create(cs.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.CreateByApplication(name), store.CreateByKey(name+consts.ConditionRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("create %s condition failed with error: %s", name, err.Error()) +func CreateConditionRule(ctx context.Context, res *meshresource.ConditionRouteResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return createConditionRuleUnsafe(ctx, res) + } + lockKey := lock.BuildConditionRuleLockKey(res.Mesh, res.Name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return createConditionRuleUnsafe(ctx, res) + }) +} + +func createConditionRuleUnsafe(ctx context.Context, res *meshresource.ConditionRouteResource) error { + if err := ctx.ResourceManager().Add(res); err != nil { + logger.Warnf("create %s condition failed with error: %s", res.Name, err.Error()) return err } return nil } -func DeleteConditionRule(cs context.Context, name string, res *mesh.ConditionRouteResource) error { - if err := cs.ResourceManager().Delete(cs.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.DeleteByApplication(name), store.DeleteByKey(name+consts.ConditionRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("delete %s condition failed with error: %s", name, err.Error()) +func DeleteConditionRule(ctx context.Context, name string, mesh string) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return deleteConditionRuleUnsafe(ctx, name, mesh) + } + lockKey := lock.BuildConditionRuleLockKey(mesh, name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return deleteConditionRuleUnsafe(ctx, name, mesh) + }) +} + +func deleteConditionRuleUnsafe(ctx context.Context, name string, mesh string) error { + if err := ctx.ResourceManager().DeleteByKey(meshresource.ConditionRouteKind, mesh, coremodel.BuildResourceKey(mesh, name)); err != nil { return err } return nil diff --git a/pkg/console/service/configurator_rule.go b/pkg/console/service/configurator_rule.go index 49338d4c0..13dd2284d 100644 --- a/pkg/console/service/configurator_rule.go +++ b/pkg/console/service/configurator_rule.go @@ -18,50 +18,154 @@ package service import ( - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/lock" + "github.com/duke-git/lancet/v2/slice" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" consolectx "github.com/apache/dubbo-admin/pkg/console/context" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/core/logger" - coreresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) -func GetConfigurator(ctx consolectx.Context, name string) (*meshproto.DynamicConfig, error) { - res := &coreresource.DynamicConfig{Spec: &meshproto.DynamicConfig{}} - if err := ctx.ResourceManager().Get(ctx.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.GetByApplication(name), store.GetByKey(name+consts.ConfiguratorRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("get %s configurator failed with error: %s", name, err.Error()) +func PageListConfiguratorRule(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.DynamicConfigResource]( + ctx.ResourceManager(), + meshresource.DynamicConfigKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq) + if err != nil { + logger.Errorf("search dynamic config rule error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search dynamic config rule failed, please try again") + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: nil, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + respList := slice.Map(pageData.Data, func(_ int, item *meshresource.DynamicConfigResource) *model.ConfiguratorSearchResp { + return &model.ConfiguratorSearchResp{ + Scope: item.Spec.Scope, + CreateTime: "", + Enabled: item.Spec.Enabled, + RuleName: item.Name, + } + }) + return &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + }, nil +} + +// SearchConfiguratorRuleByKeywords for now, only accurate search is supported +func SearchConfiguratorRuleByKeywords(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + resKey := coremodel.BuildResourceKey(req.Mesh, req.Keywords) + configuratorRuleRes, exists, err := manager.GetByKey[*meshresource.DynamicConfigResource]( + ctx.ResourceManager(), meshresource.DynamicConfigKind, resKey) + if err != nil { + logger.Errorf("search dynamic config rule error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search dynamic config rule failed, please try again") + } + if !exists { + return &model.SearchPaginationResult{ + List: nil, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + resp := &model.ConfiguratorSearchResp{ + Scope: configuratorRuleRes.Spec.Scope, + CreateTime: "", + Enabled: configuratorRuleRes.Spec.Enabled, + RuleName: configuratorRuleRes.Name, + } + return &model.SearchPaginationResult{ + List: []*model.ConfiguratorSearchResp{resp}, + PageInfo: coremodel.Pagination{ + Total: 1, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil +} + +func GetConfigurator(ctx consolectx.Context, name string, mesh string) (*meshresource.DynamicConfigResource, error) { + res, _, err := manager.GetByKey[*meshresource.DynamicConfigResource]( + ctx.ResourceManager(), + meshresource.DynamicConfigKind, + coremodel.BuildResourceKey(mesh, name), + ) + if err != nil { return nil, err } return res, nil } -func UpdateConfigurator(ctx consolectx.Context, name string, res *mesh.DynamicConfigResource) error { - if err := ctx.ResourceManager().Update(ctx.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.UpdateByApplication(name), store.UpdateByKey(name+consts.ConfiguratorRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("update %s configurator failed with error: %s", name, err.Error()) +func UpdateConfigurator(ctx consolectx.Context, res *meshresource.DynamicConfigResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return updateConfiguratorUnsafe(ctx, res) + } + lockKey := lock.BuildConfiguratorRuleLockKey(res.Mesh, res.Name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return updateConfiguratorUnsafe(ctx, res) + }) +} + +func updateConfiguratorUnsafe(ctx consolectx.Context, res *meshresource.DynamicConfigResource) error { + if err := ctx.ResourceManager().Update(res); err != nil { + logger.Warnf("update %s configurator failed with error: %s", res.Name, err.Error()) return err } return nil } -func CreateConfigurator(ctx consolectx.Context, name string, res *mesh.DynamicConfigResource) error { - if err := ctx.ResourceManager().Create(ctx.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.CreateByApplication(name), store.CreateByKey(name+consts.ConfiguratorRuleSuffix, coremodel.DefaultMesh)); err != nil { - logger.Warnf("create %s configurator failed with error: %s", name, err.Error()) +func CreateConfigurator(ctx consolectx.Context, res *meshresource.DynamicConfigResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return createConfiguratorUnsafe(ctx, res) + } + lockKey := lock.BuildConfiguratorRuleLockKey(res.Mesh, res.Name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return createConfiguratorUnsafe(ctx, res) + }) +} + +func createConfiguratorUnsafe(ctx consolectx.Context, res *meshresource.DynamicConfigResource) error { + if err := ctx.ResourceManager().Add(res); err != nil { + logger.Warnf("create %s configurator failed with error: %s", res.Name, err.Error()) return err } return nil } -func DeleteConfigurator(ctx consolectx.Context, name string, res *mesh.DynamicConfigResource) error { - if err := ctx.ResourceManager().Delete(ctx.AppContext(), res, - // here `name` may be service-name or app-name, set *ByApplication(`name`) is ok. - store.DeleteByApplication(name), store.DeleteByKey(name+consts.ConfiguratorRuleSuffix, coremodel.DefaultMesh)); err != nil { +func DeleteConfigurator(ctx consolectx.Context, name string, mesh string) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return deleteConfiguratorUnsafe(ctx, name, mesh) + } + lockKey := lock.BuildConfiguratorRuleLockKey(mesh, name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return deleteConfiguratorUnsafe(ctx, name, mesh) + }) +} + +func deleteConfiguratorUnsafe(ctx consolectx.Context, name string, mesh string) error { + if err := ctx.ResourceManager().DeleteByKey(meshresource.DynamicConfigKind, mesh, coremodel.BuildResourceKey(mesh, name)); err != nil { logger.Warnf("delete %s configurator failed with error: %s", name, err.Error()) return err } diff --git a/pkg/console/service/instance.go b/pkg/console/service/instance.go index 47909edff..85a04eb22 100644 --- a/pkg/console/service/instance.go +++ b/pkg/console/service/instance.go @@ -21,164 +21,387 @@ import ( "fmt" "io" "net/http" - "strconv" "strings" - "dubbo.apache.org/dubbo-go/v3/common/constant" + "github.com/duke-git/lancet/v2/convertor" + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" - corers "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) -func BannerSearchIp(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &corers.DataplaneResourceList{} - - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByFilterFunc(searchByIp(req.Keywords)), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { +// SearchInstanceByIp search instance by ip +func SearchInstanceByIp(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceIpIndex, Value: req.Keywords, Operator: index.HasPrefix}, + }, + req.PageReq) + if err != nil { return nil, err } - - res := model.NewSearchPaginationResult() - list := make([]*model.SearchInstanceResp, len(dataplaneList.Items)) - for i, item := range dataplaneList.Items { - list[i] = model.NewSearchInstanceResp() - list[i] = list[i].FromDataplaneResource(item) + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*model.SearchInstanceResp{}, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil } - - res.List = list - res.PageInfo = &dataplaneList.Pagination - - return res, nil + return &model.SearchPaginationResult{ + List: slice.Map(pageData.Data, func(_ int, item *meshresource.InstanceResource) *model.SearchInstanceResp { + return model.NewSearchInstanceResp().FromInstanceResource(item, ctx.Config()) + }), + PageInfo: pageData.Pagination, + }, nil } -func searchByIp(ip string) store.ListFilterFunc { - return func(rs coremodel.Resource) bool { - // make sure that the resource is of type mesh.DataplaneResource - if dp, ok := rs.(*mesh.DataplaneResource); ok { - return dp.GetIP() == ip - } - return false +// SearchInstanceByName search instance by name +func SearchInstanceByName(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceNameIndex, Value: req.Keywords, Operator: index.HasPrefix}, + }, + req.PageReq) + if err != nil { + return nil, err } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*model.SearchInstanceResp{}, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + return &model.SearchPaginationResult{ + List: slice.Map(pageData.Data, func(_ int, item *meshresource.InstanceResource) *model.SearchInstanceResp { + return model.NewSearchInstanceResp().FromInstanceResource(item, ctx.Config()) + }), + PageInfo: pageData.Pagination, + }, nil } -func BannerSearchInstances(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} +func SearchInstances(ctx consolectx.Context, req *model.SearchInstanceReq) (*model.SearchPaginationResult, error) { + if strutil.IsNotBlank(req.Keywords) { + return SearchInstanceByIp(ctx, &model.SearchReq{ + PageReq: req.PageReq, + SearchType: "ip", + Keywords: req.Keywords, + Mesh: req.Mesh, + }) + } + pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq) + if err != nil { + logger.Errorf("Failed to search instance,req: %s, cause: %v", convertor.ToString(req), err) + return nil, err + } + resp := model.NewSearchPaginationResult() + var list []*model.SearchInstanceResp + for _, item := range pageData.Data { + list = append(list, model.NewSearchInstanceResp().FromInstanceResource(item, ctx.Config())) + } + resp.List = list + resp.PageInfo = pageData.Pagination + return resp, nil +} - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByNameContains(req.Keywords), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { +func GetInstanceDetail(ctx consolectx.Context, req *model.InstanceDetailReq) (*model.InstanceDetailResp, error) { + res, _, err := manager.GetByKey[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + coremodel.BuildResourceKey(req.Mesh, req.InstanceName), + ) + if err != nil { return nil, err } + if res == nil { + return nil, bizerror.New(bizerror.NotFoundError, fmt.Sprintf("instance %s not found", req.InstanceName)) + } - res := model.NewSearchPaginationResult() - list := make([]*model.SearchInstanceResp, len(dataplaneList.Items)) - for i, item := range dataplaneList.Items { - list[i] = model.NewSearchInstanceResp() - list[i] = list[i].FromDataplaneResource(item) + resp := model.FromInstanceResource(res, ctx.Config()) + return resp, nil +} + +func GetInstanceMetrics(ctx consolectx.Context, req *model.MetricsReq) ([]*model.MetricsResp, error) { + res, _, err := manager.GetByKey[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + coremodel.BuildResourceKey(req.Mesh, req.InstanceName), + ) + if err != nil { + return nil, err + } + instance := res.Spec + metricsData, err := fetchMetricsData(instance.Ip, instance.QosPort) + if err != nil { + return nil, err } - res.List = list - res.PageInfo = &dataplaneList.Pagination + metricsResp := &model.MetricsResp{ + InstanceName: instance.Name, + Metrics: metricsData, + } - return res, nil + return []*model.MetricsResp{metricsResp}, nil } -func SearchInstances(ctx consolectx.Context, req *model.SearchInstanceReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - - if req.Keywords == "" { - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - return nil, err +func UpdateInstanceTrafficStatus(ctx consolectx.Context, mesh string, appName string, instanceIP string, newDisabled bool) error { + conditionRuleName := appName + constants.ConditionRuleDotSuffix + conditionRuleRes, err := GetConditionRule(ctx, conditionRuleName, mesh) + if err != nil { + logger.Errorf("get condition rule for %s failed, cause: %s", appName, err) + return err + } + // if no condition rule for application exists + if conditionRuleRes == nil || conditionRuleRes.Spec == nil { + // if disable traffic is false, and rule doesn't exist, directly return + if !newDisabled { + return nil } - } else { - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByNameContains(req.Keywords), store.ListByPage(req.PageSize, strconv.Itoa(req.PageOffset))); err != nil { - return nil, err + conditionRoute := generateDefaultConditionV3(true, true, true, appName, constants.ScopeApplication) + conditionRoute.Conditions = append(conditionRoute.Conditions, disableExpression(instanceIP)) + resName := appName + constants.ConditionRuleDotSuffix + conditionRuleRes = meshresource.NewConditionRouteResourceWithAttributes(resName, mesh) + conditionRuleRes.Spec = conditionRoute + err := CreateConditionRule(ctx, conditionRuleRes) + if err != nil { + logger.Errorf("create condition rule for app %s failed, cause: %s", appName, err) + return err } + return nil } - - res := model.NewSearchPaginationResult() - var list []*model.SearchInstanceResp - for _, item := range dataplaneList.Items { - if strings.Split(item.Meta.GetName(), constant.KeySeparator)[1] == "0" { - continue + // otherwise, checkout condition one by one + for i, condition := range conditionRuleRes.Spec.Conditions { + oldDisabled := isInstanceTrafficDisabled(condition, instanceIP) + // if user needs to disable traffic and instance's traffic is already disabled, skip updating, directly return + if newDisabled && oldDisabled { + logger.Warnf("The instance %s has been disabled, skip updating condition rule", instanceIP) + return nil + } + // if user needs to enable traffic while instance's traffic is disabled, update condition rule + if !newDisabled && oldDisabled { + conditionRuleRes.Spec.Conditions = append(conditionRuleRes.Spec.Conditions[:i], conditionRuleRes.Spec.Conditions[i+1:]...) + if err = UpdateConditionRule(ctx, conditionRuleRes); err != nil { + logger.Errorf("update condition rule for app %s failed, cause: %s", appName, err) + return err + } + return nil } - list = append(list, model.NewSearchInstanceResp().FromDataplaneResource(item)) } + // if user needs to enable traffic while instance's traffic is already enabled, directly return + if !newDisabled { + logger.Warnf("the instance %s has been enabled, skip updating condition rule", instanceIP) + return nil + } + // else user needs ato disable traffic, add a disable condition + conditionRuleRes.Spec.Conditions = append(conditionRuleRes.Spec.Conditions, disableExpression(instanceIP)) + if err := UpdateConditionRule(ctx, conditionRuleRes); err != nil { + logger.Errorf("update condition rule for app %s failed, cause: %s", appName, err) + return err + } + return nil +} - res.List = list - res.PageInfo = &dataplaneList.Pagination - - return res, nil +func GetInstanceTrafficStatus(ctx consolectx.Context, mesh string, appName string, instanceIP string) (bool, error) { + resName := appName + constants.ConditionRuleDotSuffix + res, err := GetConditionRule(ctx, resName, mesh) + if err != nil { + logger.Errorf("get condition rule for %s failed, cause: %s", appName, err) + return true, err + } + if res == nil { + return false, nil + } + disabled := false + slice.ForEachWithBreak(res.Spec.Conditions, func(_ int, condition string) bool { + disabled = isInstanceTrafficDisabled(condition, instanceIP) + return disabled + }) + return disabled, nil } -func GetInstanceDetail(ctx consolectx.Context, req *model.InstanceDetailReq) ([]*model.InstanceDetailResp, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} +func disableExpression(instanceIP string) string { + return "=>host!=" + instanceIP +} - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByNameContains(req.InstanceName)); err != nil { - return nil, err +func generateDefaultConditionV3(Enabled, Force, Runtime bool, Key, Scope string) *meshproto.ConditionRoute { + return &meshproto.ConditionRoute{ + ConfigVersion: constants.ConfiguratorVersionV3, + Priority: 0, + Enabled: true, + Force: Force, + Runtime: Runtime, + Key: Key, + Scope: Scope, + Conditions: make([]string, 0), } +} - instMap := make(map[string]*model.InstanceDetail) - for _, dataplane := range dataplaneList.Items { +// isInstanceTrafficDisabled judge if a condition is instance traffic disable expression or not. +// A condition include fromCondition and toCondition which is seperated by `=>`. +// return true if the instance traffic is disabled, otherwise return false. +func isInstanceTrafficDisabled(condition string, targetIP string) bool { + if len(condition) == 0 { + return false + } + condition = strings.ReplaceAll(condition, " ", "") + // only accept string start with `=>` + if !strings.HasPrefix(condition, "=>") { + return false + } + toCondition := strings.TrimPrefix(condition, "=>") - // instName := dataplane.Meta.GetLabels()[mesh_proto.InstanceTag]//This tag is "" in universal mode - instName := dataplane.Meta.GetName() - var instanceDetail *model.InstanceDetail - if _, ok := instMap[instName]; ok { - // found previously recorded instance detail in instMap - // the detail should be merged with the new instance detail - instanceDetail = instMap[instName] - } else { - // the instance information appears for the 1st time - instanceDetail = model.NewInstanceDetail() - } - instanceDetail.Merge(dataplane) // convert dataplane info to instance detail - instMap[instName] = instanceDetail + if !strings.Contains(toCondition, targetIP) { + return false } + targetExpression := "host!=" + targetIP + if targetExpression != toCondition { + return false + } + return true +} - resp := make([]*model.InstanceDetailResp, 0, len(instMap)) - for _, instDetail := range instMap { - respItem := &model.InstanceDetailResp{} - resp = append(resp, respItem.FromInstanceDetail(instDetail)) +func GetInstanceAccessLogOpenStatus(ctx consolectx.Context, mesh string, applicationName string, instanceIP string) (bool, error) { + appConfiguratorName := applicationName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + if err != nil { + logger.Errorf("get configurator for %s failed, cause: %s", appConfiguratorName, err) + return false, err } - return resp, nil + if res == nil || res.Spec == nil { + return false, nil + } + openAccessLog := false + if res.Spec.Enabled { + slice.ForEachWithBreak(res.Spec.Configs, func(_ int, conf *meshproto.OverrideConfig) bool { + openAccessLog = isInstanceAccessLogOpen(conf, instanceIP) + return openAccessLog + }) + } + return openAccessLog, nil } -func GetInstanceMetrics(ctx consolectx.Context, req *model.MetricsReq) ([]*model.MetricsResp, error) { - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByNameContains(req.InstanceName)); err != nil { - return nil, err +func UpdateInstanceAccessLogOpenStatus( + ctx consolectx.Context, + mesh string, + appName string, + instanceIP string, + openStatus bool) error { + appConfiguratorName := appName + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, appConfiguratorName, mesh) + if err != nil { + logger.Errorf("get configurator for %s failed, cause: %s", appConfiguratorName, err) + return err } - instMap := make(map[string]*model.InstanceDetail) - resp := make([]*model.MetricsResp, 0) - for _, dataplane := range dataplaneList.Items { - instName := dataplane.Meta.GetName() - var instanceDetail *model.InstanceDetail - if detail, ok := instMap[instName]; ok { - instanceDetail = detail - } else { - instanceDetail = model.NewInstanceDetail() + // if configurator doesn't exist + if res == nil || res.Spec == nil { + // if user needs to disable accesslog, directly return + if !openStatus { + logger.Warnf("the instance %s accesslog is disabled, skip updating configurator", instanceIP) + return nil } - instanceDetail.Merge(dataplane) - metrics, err := fetchMetricsData(dataplane.GetIP(), 22222) + // otherwise create a new configurator with accesslog opened + res = meshresource.NewDynamicConfigResourceWithAttributes(appConfiguratorName, mesh) + res.Spec = &meshproto.DynamicConfig{ + Key: appName, + Scope: constants.ScopeApplication, + ConfigVersion: constants.ConfiguratorVersionV3, + Enabled: true, + Configs: []*meshproto.OverrideConfig{ + { + Side: constants.SideProvider, + Match: &meshproto.ConditionMatch{Address: &meshproto.AddressMatch{Wildcard: instanceIP + `:*`}}, + Parameters: map[string]string{`accesslog`: `true`}, + XGenerateByCp: true, + }, + }, + } + err := CreateConfigurator(ctx, res) if err != nil { - continue + logger.Errorf("create configurator for instance %s%s failed, cause: %s", appName, instanceIP, err) + return err } - metricsResp := &model.MetricsResp{ - InstanceName: instName, - Metrics: metrics, + return nil + } + + // otherwise we need to match config one by one + for i, config := range res.Spec.Configs { + accessLogOpened := isInstanceAccessLogOpen(config, instanceIP) + // if user needs to open accesslog and accesslog is already opened, directly return + if openStatus && accessLogOpened { + logger.Warnf("the instance %s accesslog is already opened, skip updating configurator", instanceIP) + return nil + } + // if user needs to close accesslog and accesslog is opened, remove the config and return + if !openStatus && accessLogOpened { + res.Spec.Configs = slice.Concat(res.Spec.Configs[:i], res.Spec.Configs[i+1:]) + err := UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update configurator for instance %s%s failed, cause: %s", appName, instanceIP, err) + return err + } + return nil } - resp = append(resp, metricsResp) } - return resp, nil + // if user needs to close accesslog and accesslog is not opened, directly return + if !openStatus { + logger.Warnf("the instance %s accesslog is already disabled, skip updating configurator", instanceIP) + return nil + } + // otherwise we need to add a new config to open accesslog + res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ + Side: constants.SideProvider, + Match: &meshproto.ConditionMatch{Address: &meshproto.AddressMatch{Wildcard: instanceIP + `:*`}}, + Parameters: map[string]string{`accesslog`: `true`}, + XGenerateByCp: true, + }) + err = UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update configurator for instance %s%s failed, cause: %s", appName, instanceIP, err) + return err + } + return nil } -func fetchMetricsData(ip string, port int) ([]model.Metric, error) { +func isInstanceAccessLogOpen(conf *meshproto.OverrideConfig, IP string) bool { + if conf != nil && + conf.Match != nil && + conf.Match.Address != nil && + conf.Match.Address.Wildcard == IP+`:*` && + conf.Side == constants.SideProvider && + conf.Parameters != nil && + conf.Parameters[`accesslog`] == `true` { + return true + } + return false +} +func fetchMetricsData(ip string, port int64) ([]model.Metric, error) { url := fmt.Sprintf("http://%s:%d/metrics", ip, port) response, err := http.Get(url) if err != nil { diff --git a/pkg/console/service/observability.go b/pkg/console/service/observability.go new file mode 100644 index 000000000..e4df63e03 --- /dev/null +++ b/pkg/console/service/observability.go @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package service + +import ( + "fmt" + "net/url" + + "github.com/duke-git/lancet/v2/maputil" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func GetAppDashboard(baseURL *url.URL, req *model.AppDashboardReq) (string, error) { + if baseURL == nil { + return "", bizerror.New(bizerror.NotFoundError, "grafana url is not configured") + } + variables := map[string]string{ + "var-application": req.AppName, + } + fullURL := concatURLWithQueryVars(baseURL, variables) + return fullURL, nil +} + +func GetServiceDashboard(baseURL *url.URL, req *model.ServiceDashboardReq) (string, error) { + if baseURL == nil { + return "", bizerror.New(bizerror.NotFoundError, "grafana url is not configured") + } + variables := map[string]string{ + "var-service": req.ServiceName, + } + return concatURLWithQueryVars(baseURL, variables), nil +} + +func GetInstanceDashboard(ctx consolectx.Context, baseURL *url.URL, req *model.InstanceDashboardReq) (string, error) { + if baseURL == nil { + return "", bizerror.New(bizerror.NotFoundError, "grafana url is not configured") + } + variables, err := GetInstanceDashboardVariables(ctx, req) + if err != nil { + return "", err + } + return concatURLWithQueryVars(baseURL, variables), nil +} + +func GetInstanceDashboardVariables(ctx consolectx.Context, req *model.InstanceDashboardReq) (map[string]string, error) { + resKey := coremodel.BuildResourceKey(req.Mesh, req.InstanceName) + res, exists, err := manager.GetByKey[*meshresource.InstanceResource](ctx.ResourceManager(), meshresource.InstanceKind, resKey) + if err != nil { + return nil, err + } + if !exists { + return nil, bizerror.New(bizerror.NotFoundError, + fmt.Sprintf("instance %s not found", req.InstanceName)) + } + var instanceValue string + if res.Spec.QosPort != 0 { + instanceValue = fmt.Sprintf("%s:%d", res.Spec.Ip, res.Spec.QosPort) + } else { + instanceValue = fmt.Sprintf("%s:%d", res.Spec.Ip, 22222) + } + + return map[string]string{ + "var-application": res.Spec.AppName, + "var-instance": instanceValue, + }, nil +} + +func concatURLWithQueryVars(baseURL *url.URL, vars map[string]string) string { + q := baseURL.Query() + maputil.ForEach(vars, func(key string, value string) { + q.Set(key, value) + }) + baseURL.RawQuery = q.Encode() + return baseURL.String() +} diff --git a/pkg/console/service/service.go b/pkg/console/service/service.go index e46ac6e5c..a58347341 100644 --- a/pkg/console/service/service.go +++ b/pkg/console/service/service.go @@ -18,177 +18,898 @@ package service import ( + "fmt" "sort" "strconv" + "strings" - "dubbo.apache.org/dubbo-go/v3/common/constant" + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" - "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoveryutil "github.com/apache/dubbo-admin/pkg/common/util/discovery" consolectx "github.com/apache/dubbo-admin/pkg/console/context" "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) +// GetServiceTabDistribution get service distribution func GetServiceTabDistribution(ctx consolectx.Context, req *model.ServiceTabDistributionReq) (*model.SearchPaginationResult, error) { - manager := ctx.ResourceManager() - mappingList := &mesh.MappingResourceList{} + conditions := []index.IndexCondition{ + {IndexName: index.ByServiceConsumerServiceName, Value: req.ServiceName, Operator: index.Equals}, + } + // for now, only support accurate name match + if strutil.IsNotBlank(req.Keywords) { + conditions = append(conditions, index.IndexCondition{ + IndexName: index.ByServiceConsumerAppName, + Value: req.Keywords, + Operator: index.Equals, + }) + } + pageData, err := manager.PageListByIndexes[*meshresource.ServiceConsumerMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceConsumerMetadataKind, + conditions, + req.PageReq) + if err != nil { + logger.Errorf("get service consumer %s failed, cause: %v", req.ServiceName, err) + return nil, bizerror.New(bizerror.InternalError, "get service consumer failed, please try again") + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*meshresource.ServiceConsumerMetadataResourceList{}, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + appResKeys := slice.Map(pageData.Data, func(_ int, item *meshresource.ServiceConsumerMetadataResource) string { + return coremodel.BuildResourceKey(req.Mesh, item.Spec.ConsumerAppName) + }) + appResList, err := manager.GetByKeys[*meshresource.ApplicationResource]( + ctx.ResourceManager(), meshresource.ApplicationKind, appResKeys) + if err != nil { + logger.Errorf("get application list %v failed, cause: %s", appResKeys, err) + return nil, err + } + respList := slice.Map(appResList, func(_ int, item *meshresource.ApplicationResource) model.ApplicationSearchResp { + return model.ApplicationSearchResp{ + AppName: item.Spec.Name, + InstanceCount: item.Spec.InstanceCount, + DeployClusters: []string{ctx.Config().Engine.Name}, + RegistryClusters: []string{discoveryutil.GetOrDefaultRegistryName(ctx.Config(), item.Mesh)}, + } + }) + return &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + }, nil +} - serviceName := req.ServiceName +// SearchServices search services pageably +func SearchServices(ctx consolectx.Context, req *model.ServiceSearchReq) (*model.SearchPaginationResult, error) { + if strutil.IsNotBlank(req.Keywords) { + return SearchServicesByKeywords(ctx, req) + } + pageData, err := manager.PageListByIndexes[*meshresource.ServiceResource]( + ctx.ResourceManager(), + meshresource.ServiceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq, + ) + if err != nil { + logger.Errorf("get service provider failed, cause: %v", err) + return nil, err + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: []*model.ServiceSearchResp{}, + PageInfo: pageData.Pagination, + }, nil + } + serviceSearchResps := slice.Map(pageData.Data, + func(_ int, item *meshresource.ServiceResource) *model.ServiceSearchResp { + return ToServiceSearchRespByService(item) + }) + return &model.SearchPaginationResult{ + List: serviceSearchResps, + PageInfo: pageData.Pagination, + }, nil +} - if err := manager.List(ctx.AppContext(), mappingList); err != nil { +// SearchServicesByKeywords search services by keywords with prefix matching +func SearchServicesByKeywords(ctx consolectx.Context, req *model.ServiceSearchReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.ServiceResource]( + ctx.ResourceManager(), + meshresource.ServiceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceName, Value: req.Keywords, Operator: index.HasPrefix}, + }, + req.PageReq, + ) + if err != nil { return nil, err } + searchRespList := slice.Map( + pageData.Data, + func(_ int, item *meshresource.ServiceResource) *model.ServiceSearchResp { + return ToServiceSearchRespByService(item) + }, + ) + return &model.SearchPaginationResult{ + List: searchRespList, + PageInfo: pageData.Pagination, + }, nil +} + +func ToServiceSearchRespByService(res *meshresource.ServiceResource) *model.ServiceSearchResp { + return &model.ServiceSearchResp{ + ServiceName: res.Spec.Name, + Group: res.Spec.Group, + Version: res.Spec.Version, + } +} - res := make([]*model.ServiceTabDistributionResp, 0) - - for _, mapping := range mappingList.Items { - // 找到对应serviceName的appNames - if mapping.Spec.InterfaceName == serviceName { - for _, appName := range mapping.Spec.ApplicationNames { - dataplaneList := &mesh.DataplaneResourceList{} - // 每拿到一个appName,都将对应的实例数据填充进dataplaneList, 再通过dataplane拿到这个appName对应的所有实例 - if err := manager.List(ctx.AppContext(), dataplaneList, store.ListByApplication(appName)); err != nil { - return nil, err - } - - // 拿到了appName,接下来从dataplane取实例信息 - for _, dataplane := range dataplaneList.Items { - metadata := &mesh.MetaDataResource{ - Spec: &v1alpha1.MetaData{}, - } - if err := manager.Get(ctx.AppContext(), metadata, store.GetByRevision(dataplane.Spec.GetExtensions()[v1alpha1.RevisionLabel]), store.GetByType(dataplane.Spec.GetExtensions()["registry-type"])); err != nil { - return nil, err - } - respItem := &model.ServiceTabDistributionResp{} - - serviceInfos := metadata.GetSpec().(*v1alpha1.MetaData).Services - var sideServiceInfos []*v1alpha1.ServiceInfo - for _, serviceInfo := range serviceInfos { - if serviceInfo.GetParams()[constant.SideKey] == req.Side && - serviceInfo.Name == req.ServiceName { - sideServiceInfos = append(sideServiceInfos, serviceInfo) - } - } - if len(sideServiceInfos) > 0 { - res = append(res, respItem.FromServiceDataplaneResource(dataplane, metadata, appName, req)) - } - } +func ToServiceSearchRespByProvider(res *meshresource.ServiceProviderMetadataResource) *model.ServiceSearchResp { + return &model.ServiceSearchResp{ + ServiceName: res.Spec.ServiceName, + Group: res.Spec.Group, + Version: res.Spec.Version, + } +} + +func ToServiceSearchRespByConsumer(res *meshresource.ServiceConsumerMetadataResource) *model.ServiceSearchResp { + return &model.ServiceSearchResp{ + ServiceName: res.Spec.ServiceName, + Group: res.Spec.Group, + Version: res.Spec.Version, + ConsumerAppName: res.Spec.ConsumerAppName, + } +} + +func GetServiceMethodNames(ctx consolectx.Context, req model.BaseServiceReq) ([]model.ServiceMethodSummaryResp, error) { + metadataList, err := listProviderMeta(ctx, req) + if err != nil { + return nil, err + } + + return buildMethodSummaries(metadataList), nil +} + +func GetServiceMethodDetail(ctx consolectx.Context, req model.ServiceMethodDetailReq) (*model.ServiceMethodDetailResp, error) { + metadataList, err := listProviderMeta(ctx, req.BaseServiceReq) + if err != nil { + return nil, err + } + method := findMethod(metadataList, req.MethodName, req.Signature) + if method == nil { + return nil, bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("method %s not found for service %s", req.MethodName, req.ServiceName), + ) + } + + detail := toMethodDetail(method) + detail.Types = buildRelatedTypes(metadataList, method) + return detail, nil +} + +// providerIndexes defines the canonical indexes for provider metadata +func providerIndexes(req model.BaseServiceReq) []index.IndexCondition { + return []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderServiceKey, Value: req.ServiceKey(), Operator: index.Equals}, + } +} + +// listProviderMeta loads provider metadata by the canonical mesh + serviceKey indexes. +func listProviderMeta(ctx consolectx.Context, req model.BaseServiceReq) ([]*meshresource.ServiceProviderMetadataResource, error) { + return manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + providerIndexes(req), + ) +} + +func buildMethodSummaries(metadataList []*meshresource.ServiceProviderMetadataResource) []model.ServiceMethodSummaryResp { + methods := collectMethods(metadataList) + summaries := make([]model.ServiceMethodSummaryResp, 0, len(methods)) + for _, method := range methods { + detail := toMethodDetail(method) + summaries = append(summaries, model.ServiceMethodSummaryResp{ + MethodName: detail.MethodName, + ParameterTypes: detail.ParameterTypes, + Signature: detail.Signature, + }) + } + return summaries +} + +// collectMethods flattens provider metadata into a unique, sorted method list. +func collectMethods(metadataList []*meshresource.ServiceProviderMetadataResource) []*meshproto.Method { + methodByKey := make(map[string]*meshproto.Method) + + for _, metadata := range metadataList { + if metadata == nil || metadata.Spec == nil { + continue + } + for _, method := range metadata.Spec.Methods { + methodName := method.GetName() + if method == nil || methodName == "" { + continue + } + methodByKey[methodKey(methodName, methodSig(method))] = method + } + } + + methods := make([]*meshproto.Method, 0, len(methodByKey)) + for _, method := range methodByKey { + methods = append(methods, method) + } + sort.Slice(methods, func(i, j int) bool { + leftName := methods[i].GetName() + rightName := methods[j].GetName() + if leftName != rightName { + return leftName < rightName + } + return methodSig(methods[i]) < methodSig(methods[j]) + }) + return methods +} + +// findMethod scans the current metadata snapshot for one exact method signature. +func findMethod(metadataList []*meshresource.ServiceProviderMetadataResource, methodName string, signature string) *meshproto.Method { + for _, metadata := range metadataList { + if metadata == nil || metadata.Spec == nil { + continue + } + for _, method := range metadata.Spec.Methods { + if method == nil { + continue + } + if method.GetName() == methodName && methodSig(method) == signature { + return method } } } + return nil +} - pagedRes := ToSearchPaginationResult(res, model.ByServiceInstanceName(res), req.PageReq) +func methodKey(methodName, signature string) string { + return methodName + "\x00" + signature +} - return pagedRes, nil +// toMethodDetail projects proto metadata into the API response shape. +func toMethodDetail(method *meshproto.Method) *model.ServiceMethodDetailResp { + resp := &model.ServiceMethodDetailResp{ + MethodName: method.GetName(), + Signature: methodSig(method), + ParameterTypes: method.GetParameterTypes(), + Parameters: make([]model.ServiceMethodParameter, 0, len(method.GetParameters())), + ReturnType: method.GetReturnType(), + Types: []model.ServiceMethodTypeResp{}, + } + for _, parameter := range method.GetParameters() { + if parameter == nil { + continue + } + resp.Parameters = append(resp.Parameters, model.ServiceMethodParameter{ + Name: parameter.GetName(), + Type: parameter.GetType(), + }) + } + return resp } -func GetSearchServices(ctx consolectx.Context, req *model.ServiceSearchReq) (*model.SearchPaginationResult, error) { - if req.Keywords != "" { - return BannerSearchServices(ctx, req) +// buildRelatedTypes walks parameter and return types against the current metadata snapshot. +func buildRelatedTypes(metadataList []*meshresource.ServiceProviderMetadataResource, method *meshproto.Method) []model.ServiceMethodTypeResp { + if method == nil { + return []model.ServiceMethodTypeResp{} } - res := make([]*model.ServiceSearchResp, 0) - serviceMap := make(map[string]*model.ServiceSearch) - manager := ctx.ResourceManager() - dataplaneList := &mesh.DataplaneResourceList{} + // Index all declared types once, then resolve only the subset reachable from this method. + typesByName := buildTypeMap(metadataList) + visited := make(map[string]struct{}) + for _, parameterType := range method.GetParameterTypes() { + collectRelatedTypes(typesByName, parameterType, visited) + } + collectRelatedTypes(typesByName, method.GetReturnType(), visited) - if err := manager.List(ctx.AppContext(), dataplaneList); err != nil { - return nil, err + // Sort for stable API output and deterministic tests. + typeNames := make([]string, 0, len(visited)) + for typeName := range visited { + typeNames = append(typeNames, typeName) } - // 通过dataplane extension字段获取所有revision - revisions := make(map[string]string, 0) - for _, dataplane := range dataplaneList.Items { - rev, ok := dataplane.Spec.GetExtensions()[v1alpha1.RevisionLabel] - if ok { - revisions[rev] = dataplane.Spec.GetExtensions()["registry-type"] + sort.Strings(typeNames) + + resp := make([]model.ServiceMethodTypeResp, 0, len(typeNames)) + for _, typeName := range typeNames { + typeSpec, ok := typesByName[typeName] + if !ok { + continue } + resp = append(resp, toServiceMethodTypeResp(typeSpec)) } + return resp +} - // 遍历 revisions - for rev, t := range revisions { - metadata := &mesh.MetaDataResource{ - Spec: &v1alpha1.MetaData{}, +// buildTypeMap keeps the first declaration for each type name in the current metadata snapshot. +func buildTypeMap(metadataList []*meshresource.ServiceProviderMetadataResource) map[string]*meshproto.Type { + typesByName := make(map[string]*meshproto.Type) + for _, metadata := range metadataList { + if metadata == nil || metadata.Spec == nil { + continue } - err := manager.Get(ctx.AppContext(), metadata, store.GetByRevision(rev), store.GetByType(t)) - if err != nil { - return nil, err - } - for _, serviceInfo := range metadata.Spec.Services { - if _, ok := serviceMap[serviceInfo.Name]; ok { - serviceMap[serviceInfo.Name].FromServiceInfo(serviceInfo) - } else { - serviceSearch := model.NewServiceSearch(serviceInfo.Name) - serviceSearch.FromServiceInfo(serviceInfo) - serviceMap[serviceInfo.Name] = serviceSearch + for _, typeSpec := range metadata.Spec.Types { + if typeSpec == nil { + continue + } + typeName := typeSpec.GetType() + if typeName == "" { + continue + } + if _, exists := typesByName[typeName]; !exists { + typesByName[typeName] = typeSpec } } } + return typesByName +} - for _, serviceSearch := range serviceMap { - serviceSearchResp := model.NewServiceSearchResp() - serviceSearchResp.FromServiceSearch(serviceSearch) - res = append(res, serviceSearchResp) +// collectRelatedTypes follows nested item/property references and uses visited to stop cycles. +func collectRelatedTypes(typesByName map[string]*meshproto.Type, typeName string, visited map[string]struct{}) { + if strutil.IsBlank(typeName) { + return + } + typeSpec, ok := typesByName[typeName] + if !ok { + return + } + if _, exists := visited[typeName]; exists { + return } + visited[typeName] = struct{}{} - pagedRes := ToSearchPaginationResult(res, model.ByServiceName(res), req.PageReq) - return pagedRes, nil + for _, itemType := range typeSpec.GetItems() { + collectRelatedTypes(typesByName, itemType, visited) + } + for _, propertyType := range typeSpec.GetProperties() { + collectRelatedTypes(typesByName, propertyType, visited) + } } -func BannerSearchServices(ctx consolectx.Context, req *model.ServiceSearchReq) (*model.SearchPaginationResult, error) { - res := make([]*model.ServiceSearchResp, 0) +func toServiceMethodTypeResp(typeSpec *meshproto.Type) model.ServiceMethodTypeResp { + return model.ServiceMethodTypeResp{ + Type: typeSpec.GetType(), + Properties: typeSpec.GetProperties(), + Items: typeSpec.GetItems(), + Enums: typeSpec.GetEnums(), + } +} - manager := ctx.ResourceManager() - mappingList := &mesh.MappingResourceList{} +func methodSig(method *meshproto.Method) string { + return strings.Join(method.GetParameterTypes(), ",") + + "->" + method.GetReturnType() +} - if req.Keywords != "" { - if err := manager.List(ctx.AppContext(), mappingList, store.ListByNameContains(req.Keywords)); err != nil { - return nil, err +func GetServiceTimeoutConfig(ctx consolectx.Context, req model.BaseServiceReq) (int32, error) { + serviceConfiguratorName := req.ServiceKey() + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, serviceConfiguratorName, req.Mesh) + if err != nil { + logger.Errorf("get service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return 0, err + } + if res == nil || res.Spec == nil { + logger.Infof("service configurator %s not found, return default timeout", serviceConfiguratorName) + return constants.ServiceDefaultTimeout, nil + } + timeout := constants.ServiceDefaultTimeout + slice.ForEachWithBreak(res.Spec.Configs, func(_ int, conf *meshproto.OverrideConfig) bool { + t, found := getServiceTimeout(conf) + if found { + timeout = t + return true } + return found + }) + return timeout, nil +} - for _, mapping := range mappingList.Items { - serviceSearchResp := model.NewServiceSearchResp() - serviceSearchResp.ServiceName = mapping.GetMeta().GetName() - res = append(res, serviceSearchResp) +func UpInsertServiceConfigTimeoutConfig(ctx consolectx.Context, req model.BaseServiceReq, timeout int32) error { + serviceConfiguratorName := req.ServiceKey() + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, serviceConfiguratorName, req.Mesh) + if err != nil { + logger.Errorf("get service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + // if configurator doesn't exist + if res == nil || res.Spec == nil { + // if timeout config is default value, skip updating + if timeout == constants.ServiceDefaultTimeout { + logger.Infof("service configurator %s not found, timeout config is default value, "+ + "skip updating configurator", serviceConfiguratorName) + return nil + } + // otherwise create a new configurator with timeout config + res = meshresource.NewDynamicConfigResourceWithAttributes(serviceConfiguratorName, req.Mesh) + res.Spec = &meshproto.DynamicConfig{ + Key: req.ServiceName, + Scope: constants.ScopeService, + ConfigVersion: constants.ConfiguratorVersionV3, + Enabled: true, + Configs: []*meshproto.OverrideConfig{ + { + Side: constants.SideProvider, + Parameters: map[string]string{`timeout`: strconv.Itoa(int(timeout))}, + XGenerateByCp: true, + }, + }, + } + err = CreateConfigurator(ctx, res) + if err != nil { + logger.Errorf("create service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err } + return nil } + // if configurator exists, match config one by one + for _, conf := range res.Spec.Configs { + oldTimeout, found := getServiceTimeout(conf) + if !found { + continue + } + // if timeout config is same as input, skip updating + if oldTimeout == timeout { + logger.Infof("service configurator %s already exists, timeout config is same as input, "+ + "skip updating configurator", serviceConfiguratorName) + return nil + } + // if timeout config is different from input, update + conf.Parameters[`timeout`] = strconv.Itoa(int(timeout)) + err := UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + return nil + } + // if timeout config is not found, create a new one + res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ + Side: constants.SideProvider, + Parameters: map[string]string{`timeout`: strconv.Itoa(int(timeout))}, + XGenerateByCp: true, + }) + err = UpdateConfigurator(ctx, res) + if err != nil { + logger.Errorf("update service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + return nil +} + +func getServiceTimeout(conf *meshproto.OverrideConfig) (int32, bool) { + if conf.Side == constants.SideProvider && conf.Parameters != nil && conf.Parameters[`timeout`] != "" { + timeout, err := strconv.Atoi(conf.Parameters[`timeout`]) + if err == nil { + return int32(timeout), true + } + } + return 0, false +} + +func GetServiceRetryConfig(ctx consolectx.Context, req model.BaseServiceReq) (int32, error) { + serviceConfiguratorName := req.ServiceKey() + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, serviceConfiguratorName, req.Mesh) + if err != nil { + logger.Errorf("get service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return 0, err + } + if res == nil || res.Spec == nil { + logger.Infof("service configurator %s not found, return default retries", serviceConfiguratorName) + return constants.ServiceDefaultRetries, nil + } + retries := constants.ServiceDefaultRetries + slice.ForEachWithBreak(res.Spec.Configs, func(_ int, conf *meshproto.OverrideConfig) bool { + t, found := getServiceRetryTimes(conf) + if found { + retries = t + return true + } + return found + }) + return retries, nil +} + +func UpInsertServiceRetryConfig(ctx consolectx.Context, req model.BaseServiceReq, retries int32) error { + serviceConfiguratorName := req.ServiceKey() + constants.ConfiguratorRuleDotSuffix + res, err := GetConfigurator(ctx, serviceConfiguratorName, req.Mesh) + if err != nil { + logger.Errorf("get service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + // if configurator doesn't exist + if res == nil || res.Spec == nil { + // if retries config is default value, skip updating + if retries == constants.ServiceDefaultRetries { + logger.Infof("service configurator %s not found, retries config is default value, "+ + "skip updating configurator", serviceConfiguratorName) + return nil + } + // otherwise create a new configurator with retries config + res = meshresource.NewDynamicConfigResourceWithAttributes(serviceConfiguratorName, req.Mesh) + res.Spec = &meshproto.DynamicConfig{ + Key: req.ServiceName, + Scope: constants.ScopeService, + ConfigVersion: constants.ConfiguratorVersionV3, + Enabled: true, + Configs: []*meshproto.OverrideConfig{ + { + Side: constants.SideConsumer, + Parameters: map[string]string{`retries`: strconv.Itoa(int(retries))}, + XGenerateByCp: true, + }, + }, + } + if err := CreateConfigurator(ctx, res); err != nil { + logger.Errorf("create service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + return nil + } + // if configurator exists, match config one by one + for _, conf := range res.Spec.Configs { + retryTimes, found := getServiceRetryTimes(conf) + if !found { + continue + } + // if retries config is same as input, skip updating + if retryTimes == retries { + logger.Infof("service configurator %s already exists, retries config is same as input, "+ + "skip updating configurator", serviceConfiguratorName) + return nil + } + // if retries config is different from input, update + conf.Parameters[`retries`] = strconv.Itoa(int(retries)) + if err := UpdateConfigurator(ctx, res); err != nil { + logger.Errorf("update service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + } + // no retry config found and retries is default value, skip updating + if retries == constants.ServiceDefaultRetries { + logger.Infof("service configurator %s already exists, retries config is default value, "+ + "skip updating configurator", serviceConfiguratorName) + return nil + } + // otherwise create a new one + res.Spec.Configs = append(res.Spec.Configs, &meshproto.OverrideConfig{ + Side: constants.SideConsumer, + Parameters: map[string]string{`retries`: strconv.Itoa(int(retries))}, + XGenerateByCp: true, + }) + if err = UpdateConfigurator(ctx, res); err != nil { + logger.Errorf("update service configurator %s failed, cause: %v", serviceConfiguratorName, err) + return err + } + return nil +} + +func getServiceRetryTimes(conf *meshproto.OverrideConfig) (int32, bool) { + if conf.Side == constants.SideConsumer && conf.Parameters != nil && conf.Parameters[`retries`] != "" { + retries, err := strconv.Atoi(conf.Parameters[`retries`]) + if err == nil { + return int32(retries), true + } + } + return 0, false +} + +func GetServiceRegionPriorityConfig(ctx consolectx.Context, req model.BaseServiceReq) (bool, error) { + serviceConditionRuleName := req.ServiceKey() + constants.ConditionRuleDotSuffix + res, err := GetConditionRule(ctx, serviceConditionRuleName, req.Mesh) + if err != nil { + logger.Errorf("get service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return true, err + } + if res == nil { + return false, nil + } + openSameRegionPrior := false + slice.ForEachWithBreak(res.Spec.Conditions, func(_ int, condition string) bool { + openSameRegionPrior = isServiceSameRegion(condition) + return openSameRegionPrior + }) + return openSameRegionPrior, nil +} + +func UpInsertServiceRegionPriorityConfig(ctx consolectx.Context, req model.BaseServiceReq, enabled bool) error { + serviceConditionRuleName := req.ServiceKey() + constants.ConditionRuleDotSuffix + res, err := GetConditionRule(ctx, serviceConditionRuleName, req.Mesh) + if err != nil { + logger.Errorf("get service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + // if condition rule doesn't exist + if res == nil || res.Spec == nil { + // if same region priority is needed to disable, skip updating + if !enabled { + logger.Infof("service condition rule %s not found, and same region priority is needed to disable, "+ + "skip updating condition rule", serviceConditionRuleName) + return nil + } + // otherwise create a new condition rule + res := meshresource.NewConditionRouteResourceWithAttributes(serviceConditionRuleName, req.Mesh) + res.Spec = &meshproto.ConditionRoute{ + ConfigVersion: "v3.0", + Priority: 0, + Enabled: true, + Force: false, + Runtime: true, + Key: req.ServiceName, + Scope: constants.ScopeService, + Conditions: []string{"=>region=$region"}, + } + if err := CreateConditionRule(ctx, res); err != nil { + logger.Errorf("create service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + return nil + } + // if condition rule exists, match condition one by one + for i, condition := range res.Spec.Conditions { + isSameRegion := isServiceSameRegion(condition) + if !isSameRegion { + continue + } + // if same region priority is needed to enable, and condition is already enabled, skip updating + if enabled { + logger.Infof("same region prior is already opened, skip updating service condition rule %s", serviceConditionRuleName) + return nil + } + // otherwise we need to remove the condition and update condition rule + res.Spec.Conditions = slice.Concat(res.Spec.Conditions[:i], res.Spec.Conditions[i+1:]) + if err := UpdateConditionRule(ctx, res); err != nil { + logger.Errorf("update service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + return nil + } + // no same region priority found and region priority is needed to disable, skip updating + if !enabled { + logger.Infof("enabled is false and same region prior config is not exists, "+ + "skip updating service condition rule %s", serviceConditionRuleName) + return nil + } + // otherwise create a new condition + res.Spec.Conditions = append(res.Spec.Conditions, "=>region=$region") + if err := UpdateConditionRule(ctx, res); err != nil { + logger.Errorf("update service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + return nil +} + +func isServiceSameRegion(condition string) bool { + c := strings.TrimSpace(condition) + return strings.Contains(c, "=>region=$region") +} + +func GetServiceArgumentRouteConfig(ctx consolectx.Context, req model.BaseServiceReq) (*model.ServiceArgumentRoute, error) { + serviceConditionRuleName := req.ServiceKey() + constants.ConditionRuleDotSuffix + rawRes, err := GetConditionRule(ctx, serviceConditionRuleName, req.Mesh) + if err != nil { + logger.Errorf("get service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return nil, err + } + if rawRes == nil || rawRes.Spec == nil { + return nil, nil + } + argumentRoutes := slice.Map(rawRes.Spec.Conditions, func(index int, condition string) model.ServiceArgument { + return model.ParseConditionExpression(condition) + }) + return &model.ServiceArgumentRoute{ + Routes: argumentRoutes, + }, nil +} + +func UpInsertServiceArgumentRouteConfig(ctx consolectx.Context, req model.BaseServiceReq, route model.ServiceArgumentRoute) error { + serviceConditionRuleName := req.ServiceKey() + constants.ConditionRuleDotSuffix + conditionRouteRes, err := GetConditionRule(ctx, serviceConditionRuleName, req.Mesh) + if err != nil { + logger.Errorf("get service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + if conditionRouteRes == nil { + conditionRouteRes = meshresource.NewConditionRouteResourceWithAttributes(serviceConditionRuleName, req.Mesh) + conditionRouteRes.Spec.Conditions = make([]string, 0) + } + conditions := slice.Filter(conditionRouteRes.Spec.Conditions, func(index int, condition string) bool { + return !isArgumentRoute(condition) + }) + conditions = slice.Concat(conditions, + slice.Map(route.Routes, func(index int, item model.ServiceArgument) string { + return item.ToExpression() + })) + conditionRouteRes.Spec = &meshproto.ConditionRoute{ + ConfigVersion: "v3.0", + Priority: 0, + Enabled: true, + Force: false, + Runtime: true, + Key: req.ServiceName, + Scope: constants.ScopeService, + Conditions: conditions, + } + if err = UpdateConditionRule(ctx, conditionRouteRes); err != nil { + logger.Errorf("create service condition rule %s failed, cause: %v", serviceConditionRuleName, err) + return err + } + return nil +} + +// isArgumentRoute judge whether the condition is argument route +func isArgumentRoute(condition string) bool { + if strings.Contains(condition, "method") { + return true + } + return false +} - pagedRes := ToSearchPaginationResult(res, model.ByServiceName(res), req.PageReq) +func GetServiceDetail(ctx consolectx.Context, req *model.ServiceDetailReq) (*model.ServiceDetailResp, error) { + serviceKey := coremodel.BuildResourceKey(req.Mesh, meshresource.BuildServiceIdentityKey(req.ServiceName, req.Version, req.Group)) + serviceRes, exists, err := manager.GetByKey[*meshresource.ServiceResource]( + ctx.ResourceManager(), + meshresource.ServiceKind, + serviceKey, + ) + if err != nil { + logger.Errorf("get service detail failed, serviceKey: %s, cause: %v", serviceKey, err) + return nil, err + } + if !exists || serviceRes.Spec == nil { + return nil, bizerror.New(bizerror.NotFoundError, "service not found") + } - return pagedRes, nil + return &model.ServiceDetailResp{ + Language: serviceRes.Spec.Language, + Methods: serviceRes.Spec.Methods, + }, nil } -func ToSearchPaginationResult[T any](services []T, data sort.Interface, req model.PageReq) *model.SearchPaginationResult { - res := model.NewSearchPaginationResult() +// GraphServices builds a service dependency graph for the given service key. +// +// It gathers both provider and consumer metadata for serviceKey and creates +// graph nodes/edges where: +// - application nodes are marked as provider/consumer +// - service node is the target/subject service +// - edges describe provide/consume relationships +// +// This API is used by topology view to visualize service-level dependencies. +func GraphServices(ctx consolectx.Context, req *model.ServiceGraphReq) (*model.GraphData, error) { + serviceKey := req.ServiceKey() + + providers, err := manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceProviderMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderServiceKey, Value: serviceKey, Operator: index.Equals}, + }, + ) + if err != nil { + logger.Errorf("get service providers for mesh %s, serviceKey %s failed, cause: %v", req.Mesh, serviceKey, err) + return nil, bizerror.New(bizerror.InternalError, "get service providers failed, please try again") + } - list := make([]T, 0) + if len(providers) == 0 { + logger.Errorf("no providers found for service %s in mesh %s", serviceKey, req.Mesh) + return nil, bizerror.New(bizerror.NotFoundError, "no providers found for this service") + } - sort.Sort(data) - lenFilteredItems := len(services) - pageSize := lenFilteredItems - offset := 0 - paginationEnabled := req.PageSize != 0 - if paginationEnabled { - pageSize = req.PageSize - offset = req.PageOffset + // Nodes for this graph: provider apps, service itself, consumer apps. + // Edges represent provider->service and consumer->service relationships. + + consumers, err := manager.ListByIndexes[*meshresource.ServiceConsumerMetadataResource]( + ctx.ResourceManager(), + meshresource.ServiceConsumerMetadataKind, + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerServiceKey, Value: serviceKey, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("get service consumers for mesh %s, serviceKey %s failed, cause: %v", req.Mesh, serviceKey, err) + return nil, bizerror.New(bizerror.InternalError, "get service consumers failed, please try again") } - for i := offset; i < offset+pageSize && i < lenFilteredItems; i++ { - list = append(list, services[i]) + nodes := make([]model.GraphNode, 0) + edges := make([]model.GraphEdge, 0) + + // use struct{} as a zero-size value for a lightweight deduplication set + // this prevents duplicate application nodes when multiple providers are recorded. + providerAppSet := make(map[string]struct{}) + for _, provider := range providers { + if provider.Spec == nil { + continue + } + if _, ok := providerAppSet[provider.Spec.ProviderAppName]; !ok { + providerAppSet[provider.Spec.ProviderAppName] = struct{}{} + nodes = append(nodes, model.GraphNode{ + ID: provider.Spec.ProviderAppName, + Label: provider.Spec.ProviderAppName, + Type: "application", + Rule: "provider", + Data: nil, + }) + } } - nextOffset := "" - if paginationEnabled { - if offset+pageSize < lenFilteredItems { // set new offset only if we did not reach the end of the collection - nextOffset = strconv.Itoa(offset + req.PageSize) + nodes = append(nodes, model.GraphNode{ + ID: serviceKey, + Label: serviceKey, + Type: "service", + Rule: "", + Data: nil, + }) + + consumerAppSet := make(map[string]struct{}) + for _, consumer := range consumers { + if consumer.Spec == nil { + continue + } + if _, ok := consumerAppSet[consumer.Spec.ConsumerAppName]; !ok { + consumerAppSet[consumer.Spec.ConsumerAppName] = struct{}{} + nodes = append(nodes, model.GraphNode{ + ID: consumer.Spec.ConsumerAppName, + Label: consumer.Spec.ConsumerAppName, + Type: "application", + Rule: "consumer", + Data: nil, + }) } } - res.List = list - res.PageInfo = &coremodel.Pagination{ - Total: uint32(lenFilteredItems), - NextOffset: nextOffset, + // Connect provider applications to service node. + for providerApp := range providerAppSet { + edges = append(edges, model.GraphEdge{ + Source: serviceKey, + Target: providerApp, + Data: map[string]interface{}{ + "type": "provides", + }, + }) } - return res + // Connect consumer applications to service node. + for consumerApp := range consumerAppSet { + edges = append(edges, model.GraphEdge{ + Source: consumerApp, + Target: serviceKey, + Data: map[string]interface{}{ + "type": "consumes", + }, + }) + } + + return &model.GraphData{ + Nodes: nodes, + Edges: edges, + }, nil +} + +func sortedKeys(items map[string]struct{}) []string { + keys := make([]string, 0, len(items)) + for key := range items { + keys = append(keys, key) + } + sort.Strings(keys) + return keys } diff --git a/pkg/console/service/service_generic_invoke.go b/pkg/console/service/service_generic_invoke.go new file mode 100644 index 000000000..8fa5b8b05 --- /dev/null +++ b/pkg/console/service/service_generic_invoke.go @@ -0,0 +1,437 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package service + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "reflect" + "strings" + "time" + + hessian "github.com/apache/dubbo-go-hessian2" + + dubbo "dubbo.apache.org/dubbo-go/v3" + "dubbo.apache.org/dubbo-go/v3/client" + dubboconstant "dubbo.apache.org/dubbo-go/v3/common/constant" + _ "dubbo.apache.org/dubbo-go/v3/imports" + protocolbase "dubbo.apache.org/dubbo-go/v3/protocol/base" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const genericInvokeInstanceName = "dubbo-admin-generic-invoke" + +type genericInvocation struct { + URL string + Protocol string + Serialization string + ServiceName string + Group string + Version string + MethodName string + ParameterTypes []string + Args []hessian.Object +} + +type genericInvokeTarget struct { + instance *meshresource.RPCInstanceResource + protocol string + port int64 + serialization string +} + +var invokeGenericServiceRPC = func(callCtx context.Context, invocation genericInvocation) (any, error) { + // TODO: Cache generic invoke clients to avoid recreating the Dubbo instance/client on every call. + ins, err := dubbo.NewInstance(dubbo.WithName(genericInvokeInstanceName)) + if err != nil { + return nil, err + } + + clientOpts := []client.ClientOption{ + client.WithClientSerialization(invocation.Serialization), + } + switch invocation.Protocol { + case dubboconstant.TriProtocol: + clientOpts = append(clientOpts, client.WithClientProtocolTriple()) + case dubboconstant.DubboProtocol: + clientOpts = append(clientOpts, client.WithClientProtocolDubbo()) + default: + return nil, fmt.Errorf("unsupported invoke protocol %s", invocation.Protocol) + } + + cli, err := ins.NewClient(clientOpts...) + if err != nil { + return nil, err + } + + svc, err := cli.NewGenericService( + invocation.ServiceName, + client.WithURL(invocation.URL), + client.WithVersion(invocation.Version), + client.WithGroup(invocation.Group), + client.WithProtocol(invocation.Protocol), + client.WithSerialization(invocation.Serialization), + ) + if err != nil { + return nil, err + } + + return svc.Invoke(callCtx, invocation.MethodName, invocation.ParameterTypes, invocation.Args) +} + +func InvokeServiceGeneric(ctx consolectx.Context, req model.ServiceGenericInvokeReq) (*model.ServiceGenericInvokeResp, error) { + instanceRes, err := getGenericInvokeInstance(ctx, req.Mesh, req.InstanceName) + if err != nil { + return nil, err + } + + metadataList, err := listProviderMeta(ctx, req.BaseServiceReq) + if err != nil { + return nil, err + } + resolvedMethod := findMethod(metadataList, req.MethodName, req.Signature) + if resolvedMethod == nil { + err := bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("method %s not found for service %s", req.MethodName, req.ServiceName), + ) + logger.Errorf("resolve service method failed, service=%s, mesh=%s, instance=%s, method=%s, cause: %v", + req.ServiceName, req.Mesh, req.InstanceName, req.MethodName, err) + return nil, err + } + + parameterTypes := resolvedMethod.GetParameterTypes() + if len(parameterTypes) != len(req.Args) { + return nil, bizerror.New(bizerror.InvalidArgument, "resolved method parameter count does not match args length") + } + + decodedArgs, err := decodeGenericInvokeArgs(parameterTypes, req.Args) + if err != nil { + return nil, bizerror.New(bizerror.InvalidArgument, err.Error()) + } + + rpcInstanceRes, err := findRPCInstanceByInstance(ctx, instanceRes) + if err != nil { + return nil, err + } + + targets, err := buildGenericInvokeTargets(rpcInstanceRes) + if err != nil { + return nil, err + } + + parentCtx := context.Background() + if ctx != nil && ctx.AppContext() != nil { + parentCtx = ctx.AppContext() + } + callCtx, cancel := context.WithTimeout(parentCtx, time.Duration(req.TimeoutMs)*time.Millisecond) + defer cancel() + + if len(req.Attachments) > 0 { + attachmentValues := make(map[string]any, len(req.Attachments)) + for key, value := range req.Attachments { + attachmentValues[key] = value + } + callCtx = context.WithValue(callCtx, dubboconstant.AttachmentKey, attachmentValues) + } + + hessianArgs := make([]hessian.Object, len(decodedArgs)) + for i, arg := range decodedArgs { + hessianArgs[i] = arg + } + + startedAt := time.Now() + result, err := invokeGenericServiceWithTargets(callCtx, req, targets, genericInvocation{ + ServiceName: req.ServiceName, + Group: req.Group, + Version: req.Version, + MethodName: req.MethodName, + ParameterTypes: parameterTypes, + Args: hessianArgs, + }) + elapsedMs := time.Since(startedAt).Milliseconds() + if err != nil { + logger.Errorf("generic invoke failed, service=%s, method=%s, instance=%s, cause: %v", + req.ServiceName, req.MethodName, req.InstanceName, err) + return nil, bizerror.New(bizerror.InternalError, "generic invoke failed, please check server logs") + } + + return &model.ServiceGenericInvokeResp{ + ElapsedMs: elapsedMs, + RawResult: normalizeJSONValue(reflect.ValueOf(result)), + }, nil +} + +func normalizeJSONValue(value reflect.Value) any { + if !value.IsValid() { + return nil + } + + for value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer { + if value.IsNil() { + return nil + } + value = value.Elem() + } + + if value.CanInterface() { + if _, ok := value.Interface().(json.Marshaler); ok { + return value.Interface() + } + } + + switch value.Kind() { + case reflect.Map: + normalized := make(map[string]any, value.Len()) + iter := value.MapRange() + for iter.Next() { + normalized[fmt.Sprint(normalizeJSONValue(iter.Key()))] = normalizeJSONValue(iter.Value()) + } + return normalized + case reflect.Slice, reflect.Array: + normalized := make([]any, value.Len()) + for index := 0; index < value.Len(); index++ { + normalized[index] = normalizeJSONValue(value.Index(index)) + } + return normalized + case reflect.Struct: + return normalizeJSONStruct(value) + default: + if value.CanInterface() { + return value.Interface() + } + return fmt.Sprint(value) + } +} + +func normalizeJSONStruct(value reflect.Value) map[string]any { + structType := value.Type() + normalized := make(map[string]any, structType.NumField()) + for index := 0; index < structType.NumField(); index++ { + field := structType.Field(index) + if field.PkgPath != "" { + continue + } + + fieldName := field.Name + if jsonTag := field.Tag.Get("json"); jsonTag != "" { + tagName := strings.TrimSpace(strings.Split(jsonTag, ",")[0]) + if tagName == "-" { + continue + } + if tagName != "" { + fieldName = tagName + } + } + + normalized[fieldName] = normalizeJSONValue(value.Field(index)) + } + return normalized +} + +func getGenericInvokeInstance( + ctx consolectx.Context, + mesh string, + instanceName string, +) (*meshresource.InstanceResource, error) { + instanceRes, exists, err := manager.GetByKey[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + coremodel.BuildResourceKey(mesh, instanceName), + ) + if err != nil { + logger.Errorf("get instance failed, mesh=%s, instance=%s, cause: %v", mesh, instanceName, err) + return nil, err + } + if !exists || instanceRes == nil || instanceRes.Spec == nil { + return nil, bizerror.New(bizerror.NotFoundError, fmt.Sprintf("instance %s not found", instanceName)) + } + if instanceRes.Spec.AppName == "" || instanceRes.Spec.Ip == "" || instanceRes.Spec.RpcPort <= 0 { + return nil, bizerror.New( + bizerror.InvalidArgument, + fmt.Sprintf("instance %s is not a valid rpc invoke target", instanceName), + ) + } + return instanceRes, nil +} + +func buildGenericInvokeTargets(rpcInstanceRes *meshresource.RPCInstanceResource) ([]*genericInvokeTarget, error) { + if rpcInstanceRes == nil || rpcInstanceRes.Spec == nil { + return nil, bizerror.New(bizerror.InvalidArgument, "rpc instance is empty") + } + if len(rpcInstanceRes.Spec.GetEndpoints()) == 0 { + return nil, bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("rpc instance %s has no available rpc endpoints", rpcInstanceRes.Spec.GetName()), + ) + } + + serializations := buildGenericInvokeSerializations(rpcInstanceRes) + if len(serializations) == 0 { + return nil, bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("rpc instance %s has no available serialization metadata", rpcInstanceRes.Spec.GetName()), + ) + } + targets := make([]*genericInvokeTarget, 0, len(rpcInstanceRes.Spec.GetEndpoints())*len(serializations)) + for _, endpoint := range rpcInstanceRes.Spec.GetEndpoints() { + + // Try every serialization on the current endpoint before moving to the next endpoint. + for _, serialization := range serializations { + targets = append(targets, &genericInvokeTarget{ + instance: rpcInstanceRes, + protocol: endpoint.GetProtocol(), + port: endpoint.GetPort(), + serialization: serialization, + }) + } + } + if len(targets) == 0 { + return nil, bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("rpc instance %s has no supported rpc endpoints", rpcInstanceRes.Spec.GetName()), + ) + } + return targets, nil +} + +func buildGenericInvokeSerializations(rpcInstanceRes *meshresource.RPCInstanceResource) []string { + candidates := make([]string, 0, 4) + seen := make(map[string]struct{}, 4) + + appendCandidate := func(value string) { + value = strings.TrimSpace(value) + if value == "" { + return + } + if _, ok := seen[value]; ok { + return + } + seen[value] = struct{}{} + candidates = append(candidates, value) + } + + appendCandidate(rpcInstanceRes.Spec.GetSerialization()) + for _, item := range strings.Split(rpcInstanceRes.Spec.GetPreferSerialization(), ",") { + appendCandidate(item) + } + if len(candidates) == 0 { + appendCandidate(dubboconstant.Hessian2Serialization) + } + return candidates +} + +func invokeGenericServiceWithTargets( + callCtx context.Context, + req model.ServiceGenericInvokeReq, + targets []*genericInvokeTarget, + invocation genericInvocation, +) (any, error) { + var lastErr error + for index, target := range targets { + if callCtx.Err() != nil { + return nil, callCtx.Err() + } + + // Copy the base invocation so each attempt can override transport-specific fields safely. + attemptInvocation := invocation + attemptInvocation.Protocol = target.protocol + attemptInvocation.Serialization = target.serialization + attemptInvocation.URL = fmt.Sprintf("%s://%s:%d", target.protocol, target.instance.Spec.GetIp(), target.port) + + result, err := invokeGenericServiceRPC(callCtx, attemptInvocation) + if err == nil { + return result, nil + } + + lastErr = err + logger.Warnf( + "generic invoke attempt failed, service=%s, method=%s, instance=%s, target=%s, protocol=%s, serialization=%s, attempt=%d/%d, cause: %v", + req.ServiceName, + req.MethodName, + req.InstanceName, + attemptInvocation.URL, + target.protocol, + target.serialization, + index+1, + len(targets), + err, + ) + if !isRetryableGenericInvokeError(err) { + return nil, err + } + } + + return nil, lastErr +} + +func isRetryableGenericInvokeError(err error) bool { + if err == nil { + return false + } + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return false + } + if errors.Is(err, protocolbase.ErrClientClosed) || + errors.Is(err, protocolbase.ErrDestroyedInvoker) || + errors.Is(err, protocolbase.ErrNoReply) { + return true + } + return false +} + +func findRPCInstanceByInstance( + ctx consolectx.Context, + instanceRes *meshresource.InstanceResource, +) (*meshresource.RPCInstanceResource, error) { + if instanceRes == nil || instanceRes.Spec == nil { + return nil, bizerror.New(bizerror.InvalidArgument, "instance is empty") + } + + rpcInstanceName := meshresource.BuildInstanceResName( + instanceRes.Spec.AppName, + instanceRes.Spec.Ip, + instanceRes.Spec.RpcPort, + ) + rpcInstanceRes, exists, err := manager.GetByKey[*meshresource.RPCInstanceResource]( + ctx.ResourceManager(), + meshresource.RPCInstanceKind, + coremodel.BuildResourceKey(instanceRes.Mesh, rpcInstanceName), + ) + if err != nil { + logger.Errorf("get rpc instance failed, mesh=%s, instance=%s, cause: %v", + instanceRes.Mesh, instanceRes.Spec.Name, err) + return nil, err + } + if exists && rpcInstanceRes != nil && rpcInstanceRes.Spec != nil { + return rpcInstanceRes, nil + } + return nil, bizerror.New( + bizerror.NotFoundError, + fmt.Sprintf("rpc instance not found for instance %s", instanceRes.Spec.Name), + ) +} diff --git a/pkg/console/service/service_generic_invoke_decode.go b/pkg/console/service/service_generic_invoke_decode.go new file mode 100644 index 000000000..36b16428c --- /dev/null +++ b/pkg/console/service/service_generic_invoke_decode.go @@ -0,0 +1,283 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package service + +import ( + "encoding/json" + "fmt" + "math" + "strconv" + "strings" +) + +func decodeGenericInvokeArgs(parameterTypes []string, args []json.RawMessage) ([]any, error) { + if len(parameterTypes) != len(args) { + return nil, fmt.Errorf("parameter types count %d does not match args count %d", len(parameterTypes), len(args)) + } + + decodedArgs := make([]any, len(args)) + for index, arg := range args { + decodedArg, err := decodeGenericInvokeArg(parameterTypes[index], arg) + if err != nil { + return nil, fmt.Errorf("invalid argument at index %d for type %s: %w", index, strings.TrimSpace(parameterTypes[index]), err) + } + decodedArgs[index] = decodedArg + } + return decodedArgs, nil +} + +func decodeGenericInvokeArg(parameterType string, raw json.RawMessage) (any, error) { + if isNullRawMessage(raw) { + return nil, nil + } + if parameterType == "" { + return decodeJSONValue(raw) + } + + if elementType, isArray := splitGenericArrayType(parameterType); isArray { + return decodeGenericInvokeArrayArg(elementType, raw) + } + + switch parameterType { + case "byte", "java.lang.Byte": + return decodeInt8Raw(raw) + case "short", "java.lang.Short": + return decodeInt16Raw(raw) + case "int", "java.lang.Integer": + return decodeInt32Raw(raw) + case "long", "java.lang.Long": + return decodeInt64Raw(raw) + case "float", "java.lang.Float": + return decodeFloat32Raw(raw) + case "double", "java.lang.Double": + return decodeFloat64Raw(raw) + case "char", "java.lang.Character": + return decodeCharRaw(raw) + default: + return decodeJSONValue(raw) + } +} + +func decodeGenericInvokeArrayArg(elementType string, raw json.RawMessage) (any, error) { + switch strings.TrimSpace(elementType) { + case "byte", "java.lang.Byte": + return decodeRawArray(raw, decodeInt8Raw) + case "short", "java.lang.Short": + return decodeRawArray(raw, decodeInt16Raw) + case "int", "java.lang.Integer": + return decodeRawArray(raw, decodeInt32Raw) + case "long", "java.lang.Long": + return decodeRawArray(raw, decodeInt64Raw) + case "float", "java.lang.Float": + return decodeRawArray(raw, decodeFloat32Raw) + case "double", "java.lang.Double": + return decodeRawArray(raw, decodeFloat64Raw) + case "char", "java.lang.Character": + return decodeRawArray(raw, decodeCharRaw) + default: + return decodeRawArray(raw, func(item json.RawMessage) (any, error) { + return decodeGenericInvokeArg(elementType, item) + }) + } +} + +func splitGenericArrayType(parameterType string) (string, bool) { + if strings.HasSuffix(parameterType, "[]") { + return strings.TrimSuffix(parameterType, "[]"), true + } + return "", false +} + +func decodeRawArray[T any](raw json.RawMessage, decode func(json.RawMessage) (T, error)) ([]T, error) { + if isNullRawMessage(raw) { + return nil, nil + } + + var elements []json.RawMessage + if err := json.Unmarshal(raw, &elements); err != nil { + return nil, fmt.Errorf("expected JSON array: %w", err) + } + + result := make([]T, len(elements)) + for index, element := range elements { + decoded, err := decode(element) + if err != nil { + return nil, fmt.Errorf("invalid array element at index %d: %w", index, err) + } + result[index] = decoded + } + return result, nil +} + +func decodeInt8Raw(raw json.RawMessage) (int8, error) { + value, err := parseBoundedInt64Raw(raw, math.MinInt8, math.MaxInt8) + if err != nil { + return 0, err + } + return int8(value), nil +} + +func decodeInt16Raw(raw json.RawMessage) (int16, error) { + value, err := parseBoundedInt64Raw(raw, math.MinInt16, math.MaxInt16) + if err != nil { + return 0, err + } + return int16(value), nil +} + +func decodeInt32Raw(raw json.RawMessage) (int32, error) { + value, err := parseBoundedInt64Raw(raw, math.MinInt32, math.MaxInt32) + if err != nil { + return 0, err + } + return int32(value), nil +} + +func decodeInt64Raw(raw json.RawMessage) (int64, error) { + return parseBoundedInt64Raw(raw, math.MinInt64, math.MaxInt64) +} + +func decodeFloat32Raw(raw json.RawMessage) (float32, error) { + value, err := parseFloat64Raw(raw) + if err != nil { + return 0, err + } + return float32(value), nil +} + +func decodeFloat64Raw(raw json.RawMessage) (float64, error) { + return parseFloat64Raw(raw) +} + +func decodeCharRaw(raw json.RawMessage) (uint16, error) { + if text, ok, err := parseJSONStringRaw(raw); err != nil { + return 0, err + } else if ok { + runes := []rune(text) + if len(runes) != 1 { + return 0, fmt.Errorf("expected single character") + } + if runes[0] < 0 || runes[0] > math.MaxUint16 { + return 0, fmt.Errorf("character %q out of range", text) + } + return uint16(runes[0]), nil + } + + value, err := parseBoundedInt64Raw(raw, 0, math.MaxUint16) + if err != nil { + return 0, err + } + return uint16(value), nil +} + +func parseBoundedInt64Raw(raw json.RawMessage, minValue, maxValue int64) (int64, error) { + value, err := parseInt64Raw(raw) + if err != nil { + return 0, err + } + if value < minValue || value > maxValue { + return 0, fmt.Errorf("value %d out of range", value) + } + return value, nil +} + +func decodeJSONValue(raw json.RawMessage) (any, error) { + var value any + if err := json.Unmarshal(raw, &value); err != nil { + return nil, err + } + return value, nil +} + +func parseInt64Raw(raw json.RawMessage) (int64, error) { + if text, ok, err := parseJSONStringRaw(raw); err != nil { + return 0, err + } else if ok { + return parseInt64Text(text) + } + return parseInt64Text(strings.TrimSpace(string(raw))) +} + +func parseFloat64Raw(raw json.RawMessage) (float64, error) { + if text, ok, err := parseJSONStringRaw(raw); err != nil { + return 0, err + } else if ok { + return parseFloat64Text(text) + } + return parseFloat64Text(strings.TrimSpace(string(raw))) +} + +func parseJSONStringRaw(raw json.RawMessage) (string, bool, error) { + trimmed := strings.TrimSpace(string(raw)) + if trimmed == "" || trimmed[0] != '"' { + return "", false, nil + } + + var value string + if err := json.Unmarshal(raw, &value); err != nil { + return "", true, err + } + return value, true, nil +} + +func parseInt64Text(text string) (int64, error) { + text = strings.TrimSpace(text) + if text == "" { + return 0, fmt.Errorf("empty value") + } + if strings.ContainsAny(text, ".eE") { + value, err := parseFloat64Text(text) + if err != nil { + return 0, err + } + return int64FromFloat(value) + } + return strconv.ParseInt(text, 10, 64) +} + +func parseFloat64Text(text string) (float64, error) { + text = strings.TrimSpace(text) + if text == "" { + return 0, fmt.Errorf("empty value") + } + value, err := strconv.ParseFloat(text, 64) + if err != nil { + return 0, err + } + if math.IsNaN(value) || math.IsInf(value, 0) { + return 0, fmt.Errorf("invalid numeric value") + } + return value, nil +} + +func int64FromFloat(value float64) (int64, error) { + if math.IsNaN(value) || math.IsInf(value, 0) { + return 0, fmt.Errorf("invalid numeric value") + } + if math.Trunc(value) != value { + return 0, fmt.Errorf("value %v is not an integer", value) + } + if value < math.MinInt64 || value > math.MaxInt64 { + return 0, fmt.Errorf("value %v out of range", value) + } + return int64(value), nil +} + +func isNullRawMessage(raw json.RawMessage) bool { + return strings.TrimSpace(string(raw)) == "null" +} diff --git a/pkg/console/service/service_provider_instances.go b/pkg/console/service/service_provider_instances.go new file mode 100644 index 000000000..3ea90e819 --- /dev/null +++ b/pkg/console/service/service_provider_instances.go @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package service + +import ( + "sort" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +// GetServiceProviderInstances returns all provider instances for a service so the caller can build a full selector. +func GetServiceProviderInstances(ctx consolectx.Context, req model.BaseServiceReq) ([]*model.SearchInstanceResp, error) { + metadataList, err := listProviderMeta(ctx, req) + if err != nil { + logger.Errorf("list service provider metadata failed, service=%s, mesh=%s, cause: %v", req.ServiceName, req.Mesh, err) + return nil, err + } + if len(metadataList) == 0 { + return emptyServiceProviderInstancesResult(), nil + } + + providerAppNames := collectProviderAppNames(metadataList) + if len(providerAppNames) == 0 { + return emptyServiceProviderInstancesResult(), nil + } + + responses := make([]*model.SearchInstanceResp, 0) + seen := make(map[string]struct{}) + for _, providerAppName := range providerAppNames { + instanceList, err := manager.ListByIndexes[*meshresource.InstanceResource]( + ctx.ResourceManager(), + meshresource.InstanceKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceAppNameIndex, Value: providerAppName, Operator: index.Equals}, + }, + ) + if err != nil { + logger.Errorf("list instances failed, service=%s, mesh=%s, providerApp=%s, cause: %v", + req.ServiceName, req.Mesh, providerAppName, err) + return nil, err + } + for _, instance := range instanceList { + if instance == nil || instance.Spec == nil { + continue + } + key := instance.ResourceKey() + if _, exists := seen[key]; exists { + continue + } + seen[key] = struct{}{} + responses = append(responses, model.NewSearchInstanceResp().FromInstanceResource(instance, ctx.Config())) + } + } + if len(responses) == 0 { + return emptyServiceProviderInstancesResult(), nil + } + + sort.Slice(responses, func(i, j int) bool { + if responses[i].AppName != responses[j].AppName { + return responses[i].AppName < responses[j].AppName + } + if responses[i].Name != responses[j].Name { + return responses[i].Name < responses[j].Name + } + return responses[i].Ip < responses[j].Ip + }) + + return responses, nil +} + +// collectProviderAppNames extracts unique provider application names from service metadata. +func collectProviderAppNames(metadataList []*meshresource.ServiceProviderMetadataResource) []string { + providerAppNames := make([]string, 0, len(metadataList)) + seen := make(map[string]struct{}, len(metadataList)) + for _, metadata := range metadataList { + if metadata == nil || metadata.Spec == nil || metadata.Spec.ProviderAppName == "" { + continue + } + providerAppName := metadata.Spec.ProviderAppName + if _, exists := seen[providerAppName]; exists { + continue + } + seen[providerAppName] = struct{}{} + providerAppNames = append(providerAppNames, providerAppName) + } + sort.Strings(providerAppNames) + return providerAppNames +} + +func emptyServiceProviderInstancesResult() []*model.SearchInstanceResp { + return []*model.SearchInstanceResp{} +} diff --git a/pkg/console/service/tag_rule.go b/pkg/console/service/tag_rule.go index 77ae1fa5d..a051117ca 100644 --- a/pkg/console/service/tag_rule.go +++ b/pkg/console/service/tag_rule.go @@ -18,52 +18,158 @@ package service import ( - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/lock" + "github.com/duke-git/lancet/v2/slice" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" consolectx "github.com/apache/dubbo-admin/pkg/console/context" - "github.com/apache/dubbo-admin/pkg/core/consts" + "github.com/apache/dubbo-admin/pkg/console/model" "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/manager" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" - "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) -func GetTagRule(ctx consolectx.Context, name string) (*mesh.TagRouteResource, error) { - res := &mesh.TagRouteResource{Spec: &meshproto.TagRoute{}} - err := ctx.ResourceManager().Get(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.GetByApplication(name), store.GetByKey(name+consts.TagRuleSuffix, coremodel.DefaultMesh)) +func PageListTagRule(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + pageData, err := manager.PageListByIndexes[*meshresource.TagRouteResource]( + ctx.ResourceManager(), + meshresource.TagRouteKind, + []index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: req.Mesh, Operator: index.Equals}, + }, + req.PageReq) + if err != nil { + logger.Errorf("search tag rule error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search tag rule failed, please try again") + } + if pageData.Data == nil || len(pageData.Data) == 0 { + return &model.SearchPaginationResult{ + List: nil, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + respList := slice.Map(pageData.Data, func(_ int, item *meshresource.TagRouteResource) *model.TagRuleSearchResp { + return &model.TagRuleSearchResp{ + CreateTime: "", + Enabled: item.Spec.Enabled, + RuleName: item.Name, + } + }) + return &model.SearchPaginationResult{ + List: respList, + PageInfo: pageData.Pagination, + }, nil +} + +// SearchTagRuleByKeywords for now, only accurate search is supported +func SearchTagRuleByKeywords(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) { + resKey := coremodel.BuildResourceKey(req.Mesh, req.Keywords) + tagRuleRes, exists, err := manager.GetByKey[*meshresource.TagRouteResource](ctx.ResourceManager(), meshresource.TagRouteKind, resKey) + if err != nil { + logger.Errorf("search tag rule error: %v", err) + return nil, bizerror.New(bizerror.InternalError, "search tag rule failed, please try again") + } + if !exists { + return &model.SearchPaginationResult{ + List: nil, + PageInfo: coremodel.Pagination{ + Total: 0, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil + } + return &model.SearchPaginationResult{ + List: []*model.TagRuleSearchResp{ + { + CreateTime: "", + Enabled: tagRuleRes.Spec.Enabled, + RuleName: tagRuleRes.Name, + }, + }, + PageInfo: coremodel.Pagination{ + Total: 1, + PageSize: req.PageReq.PageSize, + PageOffset: req.PageReq.PageOffset, + }, + }, nil +} + +func GetTagRule(ctx consolectx.Context, name string, mesh string) (*meshresource.TagRouteResource, error) { + res, _, err := manager.GetByKey[*meshresource.TagRouteResource]( + ctx.ResourceManager(), + meshresource.TagRouteKind, + coremodel.BuildResourceKey(mesh, name), + ) if err != nil { - logger.Warnf("get tag rule %s error: %v", name, err) return nil, err } return res, nil } -func UpdateTagRule(ctx consolectx.Context, name string, res *mesh.TagRouteResource) error { - err := ctx.ResourceManager().Update(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.UpdateByApplication(name), store.UpdateByKey(name+consts.TagRuleSuffix, coremodel.DefaultMesh)) +func UpdateTagRule(ctx consolectx.Context, res *meshresource.TagRouteResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return updateTagRuleUnsafe(ctx, res) + } + + lockKey := lock.BuildTagRouteLockKey(res.Mesh, res.Name) + + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return updateTagRuleUnsafe(ctx, res) + }) +} + +func updateTagRuleUnsafe(ctx consolectx.Context, res *meshresource.TagRouteResource) error { + err := ctx.ResourceManager().Update(res) if err != nil { - logger.Warnf("update tag rule %s error: %v", name, err) + logger.Warnf("update tag rule %s error: %v", res.Name, err) return err } return nil } -func CreateTagRule(ctx consolectx.Context, name string, res *mesh.TagRouteResource) error { - err := ctx.ResourceManager().Create(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.CreateByApplication(name), store.CreateByKey(name+consts.TagRuleSuffix, coremodel.DefaultMesh)) +func CreateTagRule(ctx consolectx.Context, res *meshresource.TagRouteResource) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return createTagRuleUnsafe(ctx, res) + } + + lockKey := lock.BuildTagRouteLockKey(res.Mesh, res.Name) + + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return createTagRuleUnsafe(ctx, res) + }) +} + +func createTagRuleUnsafe(ctx consolectx.Context, res *meshresource.TagRouteResource) error { + err := ctx.ResourceManager().Add(res) if err != nil { - logger.Warnf("create tag rule %s error: %v", name, err) + logger.Warnf("create tag rule %s error: %v", res.Name, err) return err } return nil } -func DeleteTagRule(ctx consolectx.Context, name string, res *mesh.TagRouteResource) error { - err := ctx.ResourceManager().Delete(ctx.AppContext(), res, - // here `name` may be service name or app name, set *ByApplication(`name`) is ok. - store.DeleteByApplication(name), store.DeleteByKey(name+consts.TagRuleSuffix, coremodel.DefaultMesh)) +func DeleteTagRule(ctx consolectx.Context, name string, mesh string) error { + lockMgr := ctx.LockManager() + if lockMgr == nil { + return deleteTagRuleUnsafe(ctx, name, mesh) + } + lockKey := lock.BuildTagRouteLockKey(mesh, name) + return lockMgr.WithLock(ctx.AppContext(), lockKey, constants.DefaultLockTimeout, func() error { + return deleteTagRuleUnsafe(ctx, name, mesh) + }) +} + +func deleteTagRuleUnsafe(ctx consolectx.Context, name string, mesh string) error { + err := ctx.ResourceManager().DeleteByKey(meshresource.TagRouteKind, mesh, coremodel.BuildResourceKey(mesh, name)) if err != nil { logger.Warnf("delete tag rule %s error: %v", name, err) return err diff --git a/pkg/console/util/error.go b/pkg/console/util/error.go new file mode 100644 index 000000000..9bbda2cf5 --- /dev/null +++ b/pkg/console/util/error.go @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util + +import ( + "errors" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/console/model" +) + +func HandleServiceError(ctx *gin.Context, err error) { + var e bizerror.Error + if !errors.As(err, &e) { + e = bizerror.New(bizerror.UnknownError, err.Error()) + } + ctx.JSON(http.StatusOK, model.NewBizErrorResp(e)) +} + +func HandleArgumentError(ctx *gin.Context, err error) { + e := bizerror.New(bizerror.InvalidArgument, err.Error()) + ctx.JSON(http.StatusOK, model.NewBizErrorResp(e)) +} + +func HandleNotFoundError(ctx *gin.Context, resName string) { + e := bizerror.New(bizerror.NotFoundError, fmt.Sprintf("%s not found", resName)) + ctx.JSON(http.StatusOK, model.NewBizErrorResp(e)) +} diff --git a/pkg/core/alias.go b/pkg/core/alias.go deleted file mode 100644 index 228aa5356..000000000 --- a/pkg/core/alias.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package core - -import ( - "context" - "os" - "os/signal" - "syscall" - "time" - - "github.com/google/uuid" - kubelog "sigs.k8s.io/controller-runtime/pkg/log" - - dubbolog "github.com/apache/dubbo-admin/pkg/common/log" -) - -var ( - // TODO remove dependency on kubernetes see: https://github.com/apache/dubbo-admin/issues/2798 - Log = kubelog.Log - NewLogger = dubbolog.NewLogger - NewLoggerTo = dubbolog.NewLoggerTo - NewLoggerWithRotation = dubbolog.NewLoggerWithRotation - SetLogger = kubelog.SetLogger - Now = time.Now - - SetupSignalHandler = func() (context.Context, context.Context) { - gracefulCtx, gracefulCancel := context.WithCancel(context.Background()) - ctx, cancel := context.WithCancel(context.Background()) - c := make(chan os.Signal, 3) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - go func() { - logger := Log.WithName("runtime") - s := <-c - logger.Info("received signal, stopping instance gracefully", "signal", s.String()) - gracefulCancel() - s = <-c - logger.Info("received second signal, stopping instance", "signal", s.String()) - cancel() - s = <-c - logger.Info("received third signal, force exit", "signal", s.String()) - os.Exit(1) - }() - return gracefulCtx, ctx - } -) - -func NewUUID() string { - return uuid.NewString() -} diff --git a/pkg/core/bootstrap/bootstrap.go b/pkg/core/bootstrap/bootstrap.go index 1c8cd63bc..d1ee2c0dc 100644 --- a/pkg/core/bootstrap/bootstrap.go +++ b/pkg/core/bootstrap/bootstrap.go @@ -19,10 +19,12 @@ package bootstrap import ( "context" + "fmt" - "github.com/pkg/errors" - + "github.com/apache/dubbo-admin/pkg/common/bizerror" "github.com/apache/dubbo-admin/pkg/config/app" + "github.com/apache/dubbo-admin/pkg/console/counter" + "github.com/apache/dubbo-admin/pkg/core/lock" "github.com/apache/dubbo-admin/pkg/core/logger" "github.com/apache/dubbo-admin/pkg/core/runtime" "github.com/apache/dubbo-admin/pkg/diagnostics" @@ -33,30 +35,16 @@ func Bootstrap(appCtx context.Context, cfg app.AdminConfig) (runtime.Runtime, er if err != nil { return nil, err } - // 1. initialize resource store - if err := initResourceStore(cfg, builder); err != nil { - return nil, err - } - // 2. initialize discovery engine - if err := initializeResourceDiscovery(builder); err != nil { - return nil, err - } - // 3. initialize runtime engine - if err := initializeResourceEngine(builder); err != nil { - return nil, err - } - // 4. initialize resource manager - if err := initResourceManager(builder); err != nil { - return nil, err - } - // 5. initialize console - if err := initializeConsole(builder); err != nil { + + // Use smart bootstrapper for intelligent component initialization + bootstrapper := NewSmartBootstrapper(builder) + + // Initialize all components in dependency order + if err := bootstrapper.bootstrapComponents(appCtx, cfg); err != nil { return nil, err } - // 6. initialize diagnotics - if err := initializeDiagnoticsServer(builder); err != nil { - logger.Errorf("got error when init diagnotics server %s", err) - } + + // Build and return runtime rt, err := builder.Build() if err != nil { return nil, err @@ -64,51 +52,121 @@ func Bootstrap(appCtx context.Context, cfg app.AdminConfig) (runtime.Runtime, er return rt, nil } -func initResourceStore(cfg app.AdminConfig, builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().ResourceStore() - if err != nil { - return errors.Wrapf(err, "could not retrieve resource store %s component", cfg.Store.Type) - } - return initAndActivateComponent(builder, comp) +// SmartBootstrapper handles intelligent component initialization +type SmartBootstrapper struct { + builder *runtime.Builder } -func initResourceManager(builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().ResourceManager() - if err != nil { - return err + +// NewSmartBootstrapper creates a new smart bootstrapper +func NewSmartBootstrapper(builder *runtime.Builder) *SmartBootstrapper { + return &SmartBootstrapper{ + builder: builder, } - return initAndActivateComponent(builder, comp) } -func initializeConsole(builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().Console() +// bootstrapComponents initializes all components in dependency order +func (sb *SmartBootstrapper) bootstrapComponents( + ctx context.Context, + cfg app.AdminConfig, +) error { + logger.Info("Starting smart component bootstrap...") + + // Gather all components to initialize + components, err := sb.gatherComponents() if err != nil { - return err + return bizerror.Wrap(err, bizerror.UnknownError, "failed to gather components") } - return initAndActivateComponent(builder, comp) -} -func initializeResourceDiscovery(builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().ResourceDiscovery() + // Sort components by dependencies + ordered, err := sb.sortComponents(components) if err != nil { - return err + return bizerror.Wrap(err, bizerror.UnknownError, "failed to sort components by dependencies") + } + + // Initialize components in order + for i, comp := range ordered { + logger.Infof("[%d/%d] Initializing %s...", i+1, len(ordered), comp.Type()) + if err := initAndActivateComponent(sb.builder, comp); err != nil { + return bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to initialize component %s", comp.Type())) + } + logger.Infof("[%d/%d] %s initialized successfully", i+1, len(ordered), comp.Type()) } - return initAndActivateComponent(builder, comp) + + logger.Info("All components bootstrapped successfully") + return nil } -func initializeResourceEngine(builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().ResourceEngine() - if err != nil { - return err +// gatherComponents collects all components that need to be initialized +func (sb *SmartBootstrapper) gatherComponents() ([]runtime.Component, error) { + components := []runtime.Component{} + + // Core components + coreComps := []struct { + name string + getter func() (runtime.Component, error) + }{ + {"EventBus", runtime.ComponentRegistry().EventBus}, + {"ResourceStore", runtime.ComponentRegistry().ResourceStore}, + {"ResourceDiscovery", runtime.ComponentRegistry().ResourceDiscovery}, + {"ResourceEngine", runtime.ComponentRegistry().ResourceEngine}, + {"ResourceManager", runtime.ComponentRegistry().ResourceManager}, + {"Console", runtime.ComponentRegistry().Console}, + {"RuleGovernor", runtime.ComponentRegistry().RuleGovernor}, + } + + for _, comp := range coreComps { + c, err := comp.getter() + if err != nil { + return nil, bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to get component %s", comp.name)) + } + components = append(components, c) } - return initAndActivateComponent(builder, comp) + + // Optional components + optionalComps := []struct { + name string + typ runtime.ComponentType + }{ + {"CounterManager", counter.ComponentType}, + {"DiagnosticsServer", diagnostics.DiagnosticsServer}, + {"DistributedLock", lock.DistributedLockComponent}, + } + + for _, comp := range optionalComps { + c, err := runtime.ComponentRegistry().Get(comp.typ) + if err != nil { + logger.Warnf("Optional component %s not available: %v", comp.name, err) + continue + } + components = append(components, c) + } + + return components, nil } -func initializeDiagnoticsServer(builder *runtime.Builder) error { - comp, err := runtime.ComponentRegistry().Get(diagnostics.DiagnosticsServer) +// sortComponents sorts components by dependency order +func (sb *SmartBootstrapper) sortComponents( + components []runtime.Component, +) ([]runtime.Component, error) { + // Build dependency graph and perform topological sort + graph := runtime.NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() if err != nil { - return err + return nil, err } - return initAndActivateComponent(builder, comp) + + // Log initialization order + logger.Info("Component initialization order:") + for i, comp := range sorted { + deps := comp.RequiredDependencies() + if len(deps) > 0 { + logger.Infof(" %d. %s (depends on: %v)", i+1, comp.Type(), deps) + } else { + logger.Infof(" %d. %s (no dependencies)", i+1, comp.Type()) + } + } + + return sorted, nil } func initAndActivateComponent(builder *runtime.Builder, comp runtime.Component) error { @@ -118,7 +176,7 @@ func initAndActivateComponent(builder *runtime.Builder, comp runtime.Component) } logger.Infof("%s initialized successfully", comp.Type()) if err := builder.ActivateComponent(comp); err != nil { - return errors.Wrapf(err, "failed to activate %s", comp.Type()) + return bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to activate %s", comp.Type())) } return nil } diff --git a/pkg/core/bootstrap/init.go b/pkg/core/bootstrap/init.go new file mode 100644 index 000000000..7a61f9df9 --- /dev/null +++ b/pkg/core/bootstrap/init.go @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package bootstrap + +// import all components registered by init function +import ( + _ "github.com/apache/dubbo-admin/pkg/console" + _ "github.com/apache/dubbo-admin/pkg/console/counter" + _ "github.com/apache/dubbo-admin/pkg/core/discovery" + _ "github.com/apache/dubbo-admin/pkg/core/engine" + _ "github.com/apache/dubbo-admin/pkg/core/events" + _ "github.com/apache/dubbo-admin/pkg/core/governor" + _ "github.com/apache/dubbo-admin/pkg/core/manager" + _ "github.com/apache/dubbo-admin/pkg/core/store" + _ "github.com/apache/dubbo-admin/pkg/discovery/mock" + _ "github.com/apache/dubbo-admin/pkg/discovery/nacos2" + _ "github.com/apache/dubbo-admin/pkg/discovery/zk" + _ "github.com/apache/dubbo-admin/pkg/engine/kubernetes" + _ "github.com/apache/dubbo-admin/pkg/engine/mock" + _ "github.com/apache/dubbo-admin/pkg/governor/mock" + _ "github.com/apache/dubbo-admin/pkg/governor/nacos2" + _ "github.com/apache/dubbo-admin/pkg/governor/zk" + _ "github.com/apache/dubbo-admin/pkg/mcp" + _ "github.com/apache/dubbo-admin/pkg/store/memory" + _ "github.com/apache/dubbo-admin/pkg/store/mysql" + _ "github.com/apache/dubbo-admin/pkg/store/postgres" +) diff --git a/pkg/core/clients/nacos.go b/pkg/core/clients/nacos.go new file mode 100644 index 000000000..44b84d1b4 --- /dev/null +++ b/pkg/core/clients/nacos.go @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package clients + +import ( + "fmt" + + dubbogocom "dubbo.apache.org/dubbo-go/v3/common" + dubbogoconstant "dubbo.apache.org/dubbo-go/v3/common/constant" + dubbogonacos "dubbo.apache.org/dubbo-go/v3/remoting/nacos" + nacosconfigclient "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" + nacosnamingclient "github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" +) + +// CreateNacosClients creates nacos clients by url +// format: nacos://host:port?username=${uname}&password=${pwd} +func CreateNacosClients(url string) (nacosconfigclient.IConfigClient, nacosnamingclient.INamingClient, error) { + nacosUrl, err := dubbogocom.NewURL(url) + if err != nil { + return nil, nil, err + } + nacosUrl.AddParam(dubbogoconstant.ClientNameKey, url) + configClient, err := dubbogonacos.NewNacosConfigClientByUrl(nacosUrl) + if err != nil { + return nil, nil, bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("cannot create nacos config client for %s", url)) + } + namingClient, err := dubbogonacos.NewNacosClientByURL(nacosUrl) + if err != nil { + return nil, nil, bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("cannot create nacos naming client for %s", url)) + } + return configClient.Client(), namingClient.Client(), nil +} diff --git a/pkg/core/clients/zk.go b/pkg/core/clients/zk.go new file mode 100644 index 000000000..866d2b517 --- /dev/null +++ b/pkg/core/clients/zk.go @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package clients + +import ( + "fmt" + "net/url" + "time" + + "github.com/dubbogo/go-zookeeper/zk" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/logger" +) + +type ZKLogger struct{} + +func (z *ZKLogger) Printf(s string, i ...interface{}) { + logger.Debugf(s, i...) +} + +// NewZKConnection creates a new zookeeper connection +// address format: zookeeper://host:port +func NewZKConnection(address string) (*zk.Conn, error) { + zkUrl, err := url.Parse(address) + if err != nil { + return nil, bizerror.Wrap(err, bizerror.ZKError, + fmt.Sprintf("cannot parse url for zookeeper, url: %s", address)) + } + conn, _, err := zk.Connect([]string{zkUrl.Host}, time.Second*1, func(c *zk.Conn) { + c.SetLogger(&ZKLogger{}) + }) + if err != nil { + logger.Errorf("cannot connect to zookeeper, url: %s", address) + return nil, bizerror.Wrap(err, bizerror.ZKError, + fmt.Sprintf("cannot connect to zookeeper, url: %s", address)) + } + return conn, nil +} diff --git a/pkg/core/consts/const.go b/pkg/core/consts/const.go deleted file mode 100644 index 4ca45a460..000000000 --- a/pkg/core/consts/const.go +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package consts - -import ( - set "github.com/dubbogo/gost/container/set" -) - -const ( - DubboPropertyKey = "dubbo.properties" - RegistryAddressKey = "dubbo.registry.address" - MetadataReportAddressKey = "dubbo.metadata-report.address" -) - -const ( - AnyValue = "*" - AnyHostValue = "0.0.0.0" - InterfaceKey = "interface" - GroupKey = "group" - VersionKey = "version" - ClassifierKey = "classifier" - CategoryKey = "category" - ProvidersCategory = "providers" - ConsumersCategory = "consumers" - RoutersCategory = "routers" - ConfiguratorsCategory = "configurators" - ConfiguratorRuleSuffix = ".configurators" - EnabledKey = "enabled" - CheckKey = "check" - AdminProtocol = "admin" - Side = "side" - ConsumerSide = "consumer" - ProviderSide = "provider" - ConsumerProtocol = "consumer" - EmptyProtocol = "empty" - OverrideProtocol = "override" - DefaultGroup = "dubbo" - ApplicationKey = "application" - DynamicKey = "dynamic" - SerializationKey = "serialization" - TimeoutKey = "timeout" - DefaultTimeout = 1000 - WeightKey = "weight" - BalancingKey = "balancing" - DefaultWeight = 100 - OwnerKey = "owner" - Application = "application" - Service = "service" - Colon = ":" - InterrogationPoint = "?" - IP = "ip" - PlusSigns = "+" - PunctuationPoint = "." - ConditionRoute = "condition_route" - TagRoute = "tag_route" - AffinityRoute = "affinity_route" - ConditionRuleSuffix = ".condition-router" - TagRuleSuffix = ".tag-router" - AffinityRuleSuffix = ".affinity-router" - ConfigFileEnvKey = "conf" // config file path - RegistryAll = "ALL" - RegistryInterface = "INTERFACE" - RegistryInstance = "INSTANCE" - RegistryType = "TYPE" - NamespaceKey = "namespace" -) - -var Configs = set.NewSet(WeightKey, BalancingKey) - -const ( - ConfiguratorVersionV3 = `v3.0` - ConfiguratorVersionV3x1 = `v3.1` - ConfigVersionKey = `configVersion` - ScopeApplication = `application` - ScopeService = `service` - SideProvider = `provider` - SideConsumer = `consumer` -) - -const ( - NotEqual = "!=" - Equal = "=" -) diff --git a/pkg/core/controller/informer.go b/pkg/core/controller/informer.go new file mode 100644 index 000000000..cf0003e3b --- /dev/null +++ b/pkg/core/controller/informer.go @@ -0,0 +1,301 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package controller + +import ( + "errors" + "fmt" + "reflect" + "sync" + "time" + + "github.com/go-logr/zapr" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +// Informer is transferred from cache.SharedInformer, and modified to support event distribution in events.EventBus +type Informer interface { + // Run starts and runs the shared informer, returning after it stops. + // The informer will be stopped when stopCh is closed. + Run(stopCh <-chan struct{}) + // IsStopped reports whether the informer has already been stopped. + // Adding event handlers to already stopped informers is not possible. + // An informer already stopped will never be started again. + IsStopped() bool + + // SetTransform The TransformFunc is called for each object which is about to be stored. + // + // This function is intended for you to take the opportunity to + // remove, transform, or normalize fields. One use case is to strip unused + // metadata fields out of objects to save on RAM cost. + // + // Must be set before starting the informer. + // + // Please see the comment on TransformFunc for more details. + SetTransform(handler cache.TransformFunc) error +} + +// Options configures an informer. +type Options struct { + // ResyncPeriod is the default event handler resync period and resync check + // period. If unset/unspecified, these are defaulted to 0 (do not resync). + ResyncPeriod time.Duration +} + +func ResourceKeyFunc(obj interface{}) (string, error) { + if r, ok := obj.(model.Resource); ok { + return r.ResourceKey(), nil + } + return "", bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) +} + +// informer implements Informer and has three +// main components. One is the cache.Indexer which provides curd operations for objects. +// The second main component is a cache.Controller that pulls +// objects/notifications using the ListerWatcher and pushes them into +// a cache.DeltaFIFO --- whose knownObjects is the informer's indexer +// --- while concurrently Popping Deltas values from that fifo and +// processing them with informer.HandleDeltas. Each +// invocation of HandleDeltas, which is done with the fifo's lock +// held, processes each Delta in turn. For each cache.Delta this both +// updates the store and emit the event to the events.EventBus +// The third main component is emitter, which is responsible for +// event distribution +type informer struct { + // see store.ResourceStore + indexer cache.Indexer + // controller is the underlying cache.Controller that pop cache.Delta from the fifo queue + controller cache.Controller + // listerWatcher is where we got our initial list of objects and where we perform a watch from. + listerWatcher cache.ListerWatcher + // emitter is used to emit events to events.EventBus + emitter events.Emitter + // objectType is an example object of the type this informer is expected to handle. If set, an event + // with an object with a mismatching type is dropped instead of being delivered to listeners. + objectType runtime.Object + // resyncCheckPeriod is how often we want the reflector's resync timer to fire so it can call + // ShouldResync to check if any of our listeners need a resync. + resyncCheckPeriod time.Duration + + started, stopped bool + startedLock sync.Mutex + // blockDeltas gives a way to stop all event distribution so that a late event handler + // can safely join the shared informer. + blockDeltas sync.Mutex + // Called whenever the ListAndWatch drops the connection with an error. + watchErrorHandler cache.WatchErrorHandler + // transform is an optional function that is called on each object before it is pushed into the queue. + transform cache.TransformFunc + // keyFunc see cache.KeyFunc + keyFunc cache.KeyFunc +} + +func NewInformerWithOptions( + lw cache.ListerWatcher, + emitter events.Emitter, + store store.ResourceStore, + keyFunc cache.KeyFunc, + options Options) Informer { + return &informer{ + indexer: store, + listerWatcher: lw, + emitter: emitter, + keyFunc: keyFunc, + resyncCheckPeriod: options.ResyncPeriod, + } +} + +func (s *informer) SetWatchErrorHandler(handler cache.WatchErrorHandler) error { + s.startedLock.Lock() + defer s.startedLock.Unlock() + + if s.started { + return fmt.Errorf("informer has already started") + } + + s.watchErrorHandler = handler + return nil +} + +func (s *informer) SetTransform(handler cache.TransformFunc) error { + s.startedLock.Lock() + defer s.startedLock.Unlock() + + if s.started { + return fmt.Errorf("informer has already started") + } + + s.transform = handler + return nil +} + +func (s *informer) SetObjectType(objectType runtime.Object) error { + s.startedLock.Lock() + defer s.startedLock.Unlock() + + if s.started { + return fmt.Errorf("informer has already started") + } + s.objectType = objectType + return nil +} + +func (s *informer) Run(stopCh <-chan struct{}) { + defer utilruntime.HandleCrash() + defer func() { + s.startedLock.Lock() + defer s.startedLock.Unlock() + s.stopped = true // Don't want any new listeners + }() + + if s.HasStarted() { + klog.Warningf("The informer has started, run more than once is not allowed") + return + } + + func() { + s.startedLock.Lock() + defer s.startedLock.Unlock() + zapLogr := zapr.NewLogger(logger.Logger()) + fifo := cache.NewDeltaFIFOWithOptions(cache.DeltaFIFOOptions{ + KnownObjects: s.indexer, + EmitDeltaTypeReplaced: true, + Transformer: s.transform, + Logger: &zapLogr, + KeyFunction: s.keyFunc, + }) + + // We turn off the resync mechanism because we don't want to re-list all objects. + cfg := &cache.Config{ + Queue: fifo, + ListerWatcher: s.listerWatcher, + ObjectType: s.objectType, + FullResyncPeriod: s.resyncCheckPeriod, + ShouldResync: s.ShouldResync, + Process: s.HandleDeltas, + WatchErrorHandler: s.watchErrorHandler, + } + + s.controller = cache.New(cfg) + s.started = true + }() + + s.controller.Run(stopCh) +} + +func (s *informer) HasStarted() bool { + s.startedLock.Lock() + defer s.startedLock.Unlock() + return s.started +} + +// ShouldResync if the informer's resyncPeriod is non-zero, resync will be periodically triggered. +func (s *informer) ShouldResync() bool { + return s.resyncCheckPeriod != 0 +} + +// HandleDeltas is called for each delta when pop out from queue. +func (s *informer) HandleDeltas(obj interface{}, _ bool) error { + s.blockDeltas.Lock() + defer s.blockDeltas.Unlock() + + deltas, ok := obj.(cache.Deltas) + if !ok { + return errors.New("object given as Process argument is not Deltas") + } + // from oldest to newest + for _, d := range deltas { + resource, err := s.toResource(d.Object) + if err != nil { + logger.Errorf("object from ListWatcher is not conformed to Resource, obj: %v, err: %v", obj, err) + return err + } + switch d.Type { + case cache.Sync, cache.Replaced, cache.Added, cache.Updated: + if old, exists, err := s.indexer.Get(resource); err == nil && exists { + if err := s.indexer.Update(resource); err != nil { + logger.Errorf("failed to update resource in informer, cause: %v, resource: %s,", err, resource.String()) + return err + } + s.EmitEvent(cache.Updated, old.(model.Resource), resource) + } else { + if err := s.indexer.Add(resource); err != nil { + logger.Errorf("failed to add resource to informer, cause %v, resource: %s,", err, resource.String()) + return err + } + s.EmitEvent(cache.Added, nil, resource) + } + case cache.Deleted: + logger.Infof("informer processing delete delta, resource kind: %s, key: %s", + resource.ResourceKind().ToString(), resource.ResourceKey()) + if err := s.indexer.Delete(resource); err != nil { + logger.Errorf("failed to delete resource from informer, cause %v, resource: %s,", err, resource.String()) + return err + } + s.EmitEvent(cache.Deleted, resource, nil) + } + } + return nil +} + +func (s *informer) toResource(obj interface{}) (model.Resource, error) { + object := obj + if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok { + logger.Debugf("informer resolved tombstone object during delete handling, key: %s", tombstone.Key) + object = tombstone.Obj + } + if resource, ok := object.(model.Resource); ok { + return resource, nil + } + if s.transform != nil { + transformed, err := s.transform(object) + if err != nil { + return nil, err + } + if resource, ok := transformed.(model.Resource); ok { + return resource, nil + } + object = transformed + } + if object == nil { + return nil, bizerror.NewAssertionError("Resource", "nil") + } + return nil, bizerror.NewAssertionError("Resource", reflect.TypeOf(object).Name()) +} + +// EmitEvent emits an event to the event bus. +func (s *informer) EmitEvent(typ cache.DeltaType, oldObj model.Resource, newObj model.Resource) { + event := events.NewResourceChangedEvent(typ, oldObj, newObj) + s.emitter.Send(event) +} + +// IsStopped reports whether the informer has already been stopped. +func (s *informer) IsStopped() bool { + s.startedLock.Lock() + defer s.startedLock.Unlock() + return s.stopped +} diff --git a/pkg/common/util/http/client.go b/pkg/core/controller/listwatcher.go similarity index 52% rename from pkg/common/util/http/client.go rename to pkg/core/controller/listwatcher.go index 343696543..4978f0116 100644 --- a/pkg/common/util/http/client.go +++ b/pkg/core/controller/listwatcher.go @@ -15,34 +15,25 @@ * limitations under the License. */ -package http +package controller import ( - nethttp "net/http" - "net/url" - "path" -) - -type Client interface { - Do(req *nethttp.Request) (*nethttp.Response, error) -} + "k8s.io/client-go/tools/cache" -type ClientFunc func(req *nethttp.Request) (*nethttp.Response, error) + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) -func (f ClientFunc) Do(req *nethttp.Request) (*nethttp.Response, error) { - return f(req) +type ResourceListerWatcher interface { + cache.ListerWatcher + // ResourceKind returns the kind of resource this listerwatcher is for + ResourceKind() coremodel.ResourceKind + // TransformFunc transform the raw resource into your need before the raw resource pushing into the delta fifo, + // return nil if there is no need to transform, see cache.SharedInformer for detail + TransformFunc() cache.TransformFunc } -func ClientWithBaseURL(delegate Client, baseURL *url.URL, headers map[string]string) Client { - return ClientFunc(func(req *nethttp.Request) (*nethttp.Response, error) { - if req.URL != nil { - req.URL.Scheme = baseURL.Scheme - req.URL.Host = baseURL.Host - req.URL.Path = path.Join(baseURL.Path, req.URL.Path) - for k, v := range headers { - req.Header.Add(k, v) - } - } - return delegate.Do(req) - }) +// ResourceKeyProvider can be optionally implemented by a ResourceListerWatcher when +// raw watch objects need a key that is consistent with the transformed resource key. +type ResourceKeyProvider interface { + KeyFunc() cache.KeyFunc } diff --git a/pkg/core/discovery/base.go b/pkg/core/discovery/base.go deleted file mode 100644 index f3ef5329e..000000000 --- a/pkg/core/discovery/base.go +++ /dev/null @@ -1,7 +0,0 @@ -package discovery - -// ResourceDiscovery is the component which discovers the rpc services and convert them to Application, Instance, Service -// resources etc. -// TODO need to define the interface and implement it -type ResourceDiscovery interface { -} diff --git a/pkg/core/discovery/component.go b/pkg/core/discovery/component.go index 28542dc7c..0911eab5c 100644 --- a/pkg/core/discovery/component.go +++ b/pkg/core/discovery/component.go @@ -1,36 +1,289 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package discovery import ( + "context" + "fmt" "math" + "reflect" + "sync/atomic" + + "github.com/duke-git/lancet/v2/slice" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/config/engine" + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/discovery/subscriber" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/leader" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" ) +func init() { + runtime.RegisterComponent(newDiscoveryComponent()) +} + type Component interface { runtime.Component - ResourceDiscovery() ResourceDiscovery + ResourceDiscovery +} + +var _ Component = &discoveryComponent{} + +type Informers []controller.Informer + +type discoveryComponent struct { + configs []*discovery.Config + informers map[string]Informers + subscribers []events.Subscriber + subscriptionMgr events.SubscriptionManager + leaderElection *leader.LeaderElection + needsLeaderElection bool + subscribed atomic.Bool } -var _ Component = &BaseResourceDiscoveryComponent{} +func (d *discoveryComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.EventBus, // Discovery needs EventBus for event emission + runtime.ResourceStore, // Discovery needs Store for resource storage + } +} -type BaseResourceDiscoveryComponent struct{} +func newDiscoveryComponent() Component { + return &discoveryComponent{ + informers: make(map[string]Informers), + subscribers: make([]events.Subscriber, 0), + } +} -func (b *BaseResourceDiscoveryComponent) Type() runtime.ComponentType { +func (d *discoveryComponent) Type() runtime.ComponentType { return runtime.ResourceDiscovery } -func (b *BaseResourceDiscoveryComponent) Order() int { - return math.MaxInt +func (d *discoveryComponent) Order() int { + return math.MaxInt - 2 +} + +func (d *discoveryComponent) Init(ctx runtime.BuilderContext) error { + eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) + if err != nil { + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("can not retrieve event bus from runtime in discovery, %s", err)) + } + eventBus, ok := eventBusComponent.(events.EventBus) + if !ok { + return bizerror.NewAssertionError("EventBus", reflect.TypeOf(eventBusComponent).Name()) + } + d.subscriptionMgr = eventBus + storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) + if err != nil { + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("can not retrieve store from runtime in discovery, %s", err)) + } + storeRouter, ok := storeComponent.(store.Router) + if !ok { + return bizerror.NewAssertionError("store.Router", reflect.TypeOf(storeComponent).Name()) + } + d.configs = ctx.Config().Discovery + for _, cfg := range d.configs { + informers, err := d.initInformers(cfg, storeRouter, eventBus) + if err != nil { + return err + } + d.informers[cfg.ID] = informers + } + err = d.initSubscribes(storeRouter, eventBus, ctx.Config().Engine) + if err != nil { + return err + } + + // Memory store runs single-replica; leader election is not needed. + if ctx.Config().Store.Type == storecfg.Memory { + return nil + } + + dbSrc, ok := storeComponent.(leader.DBSource) + if !ok { + return nil + } + db, hasDB := dbSrc.GetDB() + if !hasDB { + return nil + } + holderID, err := leader.GenerateHolderID() + if err != nil { + logger.Warnf("discovery: failed to generate holder ID, skipping leader election: %v", err) + return nil + } + le := leader.NewLeaderElection(db, runtime.ResourceDiscovery, holderID) + if err := le.EnsureTable(); err != nil { + logger.Warnf("discovery: failed to ensure leader lease table: %v", err) + return nil + } + d.leaderElection = le + d.needsLeaderElection = true + logger.Infof("discovery: leader election initialized (holder: %s)", holderID) + return nil +} + +func (d *discoveryComponent) Start(_ runtime.Runtime, ch <-chan struct{}) error { + if !d.needsLeaderElection { + return d.startBusinessLogic(ch) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + <-ch + cancel() + }() + + var leaderStopCh chan struct{} + + d.leaderElection.RunLeaderElection(ctx, ch, + func() { // onStartLeading: create a fresh stopCh for this leadership term + leaderStopCh = make(chan struct{}) + logger.Infof("discovery: became leader, starting business logic") + if err := d.startBusinessLogic(leaderStopCh); err != nil { + logger.Errorf("discovery: failed to start business logic: %v", err) + } + }, + func() { // onStopLeading: stop informers from the current term + logger.Warnf("discovery: lost leadership, stopping business logic") + if leaderStopCh != nil { + close(leaderStopCh) + leaderStopCh = nil + } + }, + ) + + return nil } -func (b *BaseResourceDiscoveryComponent) Init(_ runtime.BuilderContext) error { - panic("Init() must be implemented by concrete BaseResourceDiscoveryComponent") +// startBusinessLogic starts subscribers and informers using the provided stopCh. +// When stopCh is closed all informer goroutines will exit. +func (d *discoveryComponent) startBusinessLogic(stopCh <-chan struct{}) error { + // 1. subscribe resource changed events (only once for the process lifetime) + if !d.subscribed.Load() { + for _, sub := range d.subscribers { + err := d.subscriptionMgr.Subscribe(sub) + if err != nil { + return bizerror.Wrap(err, bizerror.EventError, + fmt.Sprintf("subscriber %s can not subscribe resource changed events", sub.Name())) + } + } + d.subscribed.Store(true) + } + // 2. start informers + for name, informers := range d.informers { + for _, informer := range informers { + go informer.Run(stopCh) + } + logger.Infof("resource discovery %s has started successfully", name) + } + return nil } -func (b *BaseResourceDiscoveryComponent) Start(_ runtime.Runtime, _ <-chan struct{}) error { - panic("Start() must be implemented by concrete BaseResourceDiscoveryComponent") +func (d *discoveryComponent) initInformers(cfg *discovery.Config, storeRouter store.Router, eventBus events.EventBus) (Informers, error) { + factory, err := ListWatcherFactoryRegistry().GetListWatcherFactory(cfg.Type) + if err != nil { + return nil, err + } + lwList, err := factory.NewListWatchers(cfg) + if err != nil { + return nil, err + } + var informers = make([]controller.Informer, len(lwList)) + for i, lw := range lwList { + resourceStore, err := storeRouter.ResourceKindRoute(lw.ResourceKind()) + if err != nil { + return nil, fmt.Errorf("cannot find store for resource kind %s", lw.ResourceKind()) + } + informer := controller.NewInformerWithOptions(lw, eventBus, resourceStore, keyFunc, controller.Options{ResyncPeriod: 0}) + informers[i] = informer + } + return informers, nil } +func keyFunc(obj interface{}) (string, error) { + if r, ok := obj.(coremodel.Resource); ok { + return r.ResourceKey(), nil + } + return "", bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) +} + +func (d *discoveryComponent) initSubscribes(storeRouter store.Router, emitter events.Emitter, engineConfig *engine.Config) error { + instanceStore, err := storeRouter.ResourceKindRoute(meshresource.InstanceKind) + if err != nil { + return bizerror.Wrap(err, bizerror.StoreError, + fmt.Sprintf("can not find store for resource kind %s", meshresource.InstanceKind)) + } + rtInstanceStore, err := storeRouter.ResourceKindRoute(meshresource.RuntimeInstanceKind) + if err != nil { + return bizerror.Wrap(err, bizerror.StoreError, + fmt.Sprintf("can not find store for resource kind %s", meshresource.RuntimeInstanceKind)) + } + rpcInstanceSub := subscriber.NewRPCInstanceEventSubscriber(instanceStore, rtInstanceStore, emitter, engineConfig) + + appStore, err := storeRouter.ResourceKindRoute(meshresource.ApplicationKind) + if err != nil { + return bizerror.Wrap(err, bizerror.StoreError, + fmt.Sprintf("can not find store for resource kind %s", meshresource.ApplicationKind)) + } + serviceStore, err := storeRouter.ResourceKindRoute(meshresource.ServiceKind) + if err != nil { + return bizerror.Wrap(err, bizerror.StoreError, + fmt.Sprintf("can not find store for resource kind %s", meshresource.ServiceKind)) + } + serviceProviderMetadataStore, err := storeRouter.ResourceKindRoute(meshresource.ServiceProviderMetadataKind) + if err != nil { + return bizerror.Wrap(err, bizerror.StoreError, + fmt.Sprintf("can not find store for resource kind %s", meshresource.ServiceProviderMetadataKind)) + } + serviceConsumerMetadataSub := subscriber.NewServiceConsumerMetadataEventSubscriber(appStore, emitter) + serviceProviderMetadataSub := subscriber.NewServiceProviderMetadataEventSubscriber( + appStore, serviceStore, serviceProviderMetadataStore, emitter) + instanceSub := subscriber.NewInstanceEventSubscriber(appStore, instanceStore, emitter) + d.subscribers = append(d.subscribers, rpcInstanceSub, serviceConsumerMetadataSub, serviceProviderMetadataSub, instanceSub) -func (b *BaseResourceDiscoveryComponent) ResourceDiscovery() ResourceDiscovery { - panic("Discovery() must be implemented by concrete BaseResourceDiscoveryComponent") + // if there is a nacos discovery, a NacosServiceEventSubscriber is needed + _, hasNacosDiscovery := slice.FindBy(d.configs, func(index int, item *discovery.Config) bool { + return item.Type == discovery.Nacos2 + }) + if hasNacosDiscovery { + nacosServiceSub := subscriber.NewNacosServiceEventSubscriber(emitter, storeRouter) + d.subscribers = append(d.subscribers, nacosServiceSub) + } + // if there is a zk discovery, a ZKMetadataEventSubscriber and ZKConfigEventSubscriber is needed + _, hasZkDiscovery := slice.FindBy(d.configs, func(index int, item *discovery.Config) bool { + return item.Type == discovery.Zookeeper + }) + if hasZkDiscovery { + zkMetadataSub := subscriber.NewZKMetadataEventSubscriber(emitter, storeRouter) + zkConfigSub := subscriber.NewZKConfigEventSubscriber(emitter, storeRouter) + d.subscribers = append(d.subscribers, zkMetadataSub, zkConfigSub) + } + return nil } diff --git a/pkg/version/cobra.go b/pkg/core/discovery/discovery.go similarity index 83% rename from pkg/version/cobra.go rename to pkg/core/discovery/discovery.go index 8b8d2493e..95971d4d7 100644 --- a/pkg/version/cobra.go +++ b/pkg/core/discovery/discovery.go @@ -15,12 +15,7 @@ * limitations under the License. */ -package version +package discovery -type Version struct { - ClientVersion *BuildInfo `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"` -} - -var ( - Info BuildInfo -) +// ResourceDiscovery is the component which discovers the rpc services and save them into store.ResourceStore +type ResourceDiscovery interface{} diff --git a/pkg/core/discovery/factory.go b/pkg/core/discovery/factory.go new file mode 100644 index 000000000..ef6a11707 --- /dev/null +++ b/pkg/core/discovery/factory.go @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package discovery + +import ( + "fmt" + + "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/controller" +) + +var registry = newDiscoveryFactoryRegistry() + +func RegisterListWatcherFactory(f Factory) { + registry.Register(f) +} + +func ListWatcherFactoryRegistry() Registry { + return registry +} + +// Factory creates informers for the given type +type Factory interface { + // Support returns true if the factory can create ListWatchers for the given discovery type + Support(discovery.Type) bool + // NewListWatchers creates series of list watchers for the given discovery type + NewListWatchers(config *discovery.Config) ([]controller.ResourceListerWatcher, error) +} + +type Registry interface { + GetListWatcherFactory(discovery.Type) (Factory, error) +} + +type RegistryMutator interface { + Register(Factory) +} + +type MutableRegistry interface { + Registry + RegistryMutator +} + +var _ MutableRegistry = &discoveryRegistry{} + +type discoveryRegistry struct { + factories []Factory +} + +func newDiscoveryFactoryRegistry() MutableRegistry { + return &discoveryRegistry{ + factories: make([]Factory, 0), + } +} + +func (d *discoveryRegistry) GetListWatcherFactory(t discovery.Type) (Factory, error) { + for _, factory := range d.factories { + if factory.Support(t) { + return factory, nil + } + } + return nil, fmt.Errorf("discovery type %s not supported", t) +} + +func (d *discoveryRegistry) Register(factory Factory) { + d.factories = append(d.factories, factory) +} diff --git a/pkg/core/discovery/subscriber/instance.go b/pkg/core/discovery/subscriber/instance.go new file mode 100644 index 000000000..529e0465e --- /dev/null +++ b/pkg/core/discovery/subscriber/instance.go @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "k8s.io/client-go/tools/cache" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type InstanceEventSubscriber struct { + appStore store.ResourceStore + instanceStore store.ResourceStore + emitter events.Emitter +} + +func NewInstanceEventSubscriber( + appStore store.ResourceStore, + instanceStore store.ResourceStore, + emitter events.Emitter) *InstanceEventSubscriber { + return &InstanceEventSubscriber{ + appStore: appStore, + instanceStore: instanceStore, + emitter: emitter, + } +} + +func (s *InstanceEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.InstanceKind +} + +func (s *InstanceEventSubscriber) Name() string { + return "Discovery-" + s.ResourceKind().ToString() +} + +func (s *InstanceEventSubscriber) AsyncEnabled() bool { + return true +} + +func (s *InstanceEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.InstanceResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(meshresource.InstanceKind, event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.InstanceResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(meshresource.InstanceKind, event.OldObj()) + } + var instanceRes *meshresource.InstanceResource + if newObj != nil { + instanceRes = newObj + } else { + instanceRes = oldObj + } + instanceResList, err := s.instanceStore.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: instanceRes.Mesh, Operator: index.Equals}, + {IndexName: index.ByInstanceAppNameIndex, Value: instanceRes.Spec.AppName, Operator: index.Equals}, + }) + + appResKey := coremodel.BuildResourceKey(instanceRes.Mesh, instanceRes.Spec.AppName) + res, exists, err := s.appStore.GetByKey(appResKey) + if err != nil { + return err + } + if !exists { + appRes := BuildAppResource(instanceRes.Mesh, instanceRes.Spec.AppName, int64(len(instanceResList))) + err := s.appStore.Add(appRes) + if err != nil { + logger.Errorf("add app resource failed, app: %s, err: %s", appResKey, err.Error()) + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, appRes)) + return nil + } + appRes, ok := res.(*meshresource.ApplicationResource) + if !ok { + return bizerror.NewAssertionError(meshresource.ApplicationKind, res) + } + appRes.Spec.InstanceCount = int64(len(instanceResList)) + err = s.appStore.Update(appRes) + if err != nil { + logger.Errorf("update app resource failed, app: %s, err: %s", appResKey, err.Error()) + return err + } + return nil +} + +func BuildAppResource(mesh string, name string, instanceCount int64) *meshresource.ApplicationResource { + appRes := meshresource.NewApplicationResourceWithAttributes(name, mesh) + appRes.Spec = &meshproto.Application{ + Name: name, + InstanceCount: instanceCount, + } + return appRes +} diff --git a/pkg/core/discovery/subscriber/nacos_service.go b/pkg/core/discovery/subscriber/nacos_service.go new file mode 100644 index 000000000..4d8495cec --- /dev/null +++ b/pkg/core/discovery/subscriber/nacos_service.go @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "fmt" + "reflect" + "regexp" + "strings" + + "github.com/duke-git/lancet/v2/maputil" + "github.com/duke-git/lancet/v2/slice" + "k8s.io/client-go/tools/cache" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type NacosServiceEventSubscriber struct { + emitter events.Emitter + storeRouter store.Router +} + +func NewNacosServiceEventSubscriber(eventEmitter events.Emitter, storeRouter store.Router) *NacosServiceEventSubscriber { + return &NacosServiceEventSubscriber{ + emitter: eventEmitter, + storeRouter: storeRouter, + } +} + +func (n *NacosServiceEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.NacosServiceKind +} + +func (n *NacosServiceEventSubscriber) Name() string { + return "Nacos2Discovery-" + n.ResourceKind().ToString() +} + +func (n *NacosServiceEventSubscriber) AsyncEnabled() bool { + return true +} + +func (n *NacosServiceEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.NacosServiceResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(newObj), event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.NacosServiceResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(oldObj), event.OldObj()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil { + errStr := "process nacos service upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = n.processUpsert(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process nacos service delete event, but old obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = n.processDelete(oldObj) + } + if processErr != nil { + logger.Errorf("process nacos service event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process nacos service event successfully, event: %s", event.String()) + return nil +} + +func (n *NacosServiceEventSubscriber) processUpsert(serviceRes *meshresource.NacosServiceResource) error { + providerRe := regexp.MustCompile(`^providers:[\w.]+(?::[\w.]*:|::[\w.]*)?$`) + consumerRe := regexp.MustCompile(`^consumers:[\w.]+(?::[\w.]*:|::[\w.]*)?$`) + if providerRe.MatchString(serviceRes.Name) { + logger.Infof("interface-level service ignored, service name: %s", serviceRes.Name) + return nil + } + if consumerRe.MatchString(serviceRes.Name) { + return n.processConsumerMetadataUpsert(serviceRes) + } + return n.processRPCInstanceUpsert(serviceRes) + +} + +func (n *NacosServiceEventSubscriber) processConsumerMetadataUpsert(serviceRes *meshresource.NacosServiceResource) error { + serviceName, err := parseServiceName(serviceRes.Name) + if err != nil { + return bizerror.Wrap(err, bizerror.UnknownError, "parse service name error, raw nacos service is"+serviceRes.String()) + } + convertFunc := func(i int, instance *meshproto.NacosInstance) maputil.Entry[string, *meshresource.ServiceConsumerMetadataResource] { + res := meshresource.ToServiceConsumerMetadataByMap(instance.Metadata, serviceRes.Mesh) + if res == nil { + logger.Warnf("service consumer metadata is invalid, dataId: %s, raw metadata: %s", serviceRes.Name, instance.Metadata) + return maputil.Entry[string, *meshresource.ServiceConsumerMetadataResource]{} + } + return maputil.Entry[string, *meshresource.ServiceConsumerMetadataResource]{ + Key: res.ResourceKey(), + Value: res, + } + } + newConsumers := maputil.FromEntries(slice.Map(serviceRes.Spec.Instances, convertFunc)) + st, err := n.storeRouter.ResourceKindRoute(meshresource.ServiceConsumerMetadataKind) + if err != nil { + logger.Errorf("process service consumer metadata upsert event, but cannot route to service consumer metadata resource, cause: %v", err) + return err + } + resources, err := st.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: serviceRes.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerServiceName, Value: serviceName, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("process service consumer metadata upsert event, but cannot list service consumer metadata resource of %s, cause: %v", serviceRes.Name, err) + return err + } + oldConsumers := make(map[string]*meshresource.ServiceConsumerMetadataResource) + for _, res := range resources { + oldConsumer, ok := res.(*meshresource.ServiceConsumerMetadataResource) + if !ok { + return bizerror.NewAssertionError(meshresource.ServiceConsumerMetadataKind, reflect.TypeOf(res).Name()) + } + oldConsumers[oldConsumer.ResourceKey()] = oldConsumer + } + // Find offline consumers and delete them + offlineConsumers := maputil.Minus(oldConsumers, newConsumers) + slice.ForEach(maputil.Values(offlineConsumers), func(_ int, item *meshresource.ServiceConsumerMetadataResource) { + err := st.Delete(item) + if err != nil { + logger.Errorf("delete service consumer metadata %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Deleted, item, nil)) + }) + // Find consumers need to add and add them + addConsumers := maputil.Minus(newConsumers, oldConsumers) + slice.ForEach(maputil.Values(addConsumers), func(_ int, item *meshresource.ServiceConsumerMetadataResource) { + err := st.Add(item) + if err != nil { + logger.Errorf("add service consumer metadata %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, item)) + }) + // Find consumers need to update and update them + updateConsumers := make([]*meshresource.ServiceConsumerMetadataResource, 0) + for k, consumer := range newConsumers { + if _, exists := oldConsumers[k]; exists { + updateConsumers = append(updateConsumers, consumer) + } + } + slice.ForEach(updateConsumers, func(_ int, item *meshresource.ServiceConsumerMetadataResource) { + err := st.Update(item) + if err != nil { + logger.Errorf("update service consumer metadata %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Updated, item, item)) + }) + + return nil +} + +func parseServiceName(s string) (string, error) { + const prefix = "consumers:" + if !strings.HasPrefix(s, prefix) { + return "", fmt.Errorf("invalid prefix") + } + + parts := strings.SplitN(s[len(prefix):], ":", 3) + + if len(parts) < 1 { + return "", fmt.Errorf("invalid format") + } + + return parts[0], nil +} + +func (n *NacosServiceEventSubscriber) processRPCInstanceUpsert(serviceRes *meshresource.NacosServiceResource) error { + convertFunc := func(i int, instance *meshproto.NacosInstance) maputil.Entry[string, *meshresource.RPCInstanceResource] { + + res := meshresource.ToRPCInstance(serviceRes.Mesh, serviceRes.Name, instance.Ip, instance.Port, instance.Metadata) + return maputil.Entry[string, *meshresource.RPCInstanceResource]{ + Key: res.ResourceKey(), + Value: res, + } + } + newInstances := maputil.FromEntries(slice.Map(serviceRes.Spec.Instances, convertFunc)) + st, err := n.storeRouter.ResourceKindRoute(meshresource.RPCInstanceKind) + if err != nil { + logger.Errorf("process rpc instance upsert event, but cannot route to rpc instance resource, cause: %v", err) + return err + } + resources, err := st.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: serviceRes.Mesh, Operator: index.Equals}, + {IndexName: index.ByRPCInstanceAppName, Value: serviceRes.Name, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("process rpc instance upsert event, but cannot list rpc instance resource of %s, cause: %v", serviceRes.Name, err) + return err + } + oldInstances := make(map[string]*meshresource.RPCInstanceResource) + for _, res := range resources { + oldInstance, ok := res.(*meshresource.RPCInstanceResource) + if !ok { + return bizerror.NewAssertionError(meshresource.RPCInstanceKind, reflect.TypeOf(res).Name()) + } + oldInstances[oldInstance.ResourceKey()] = oldInstance + } + // find offline instances and delete them + offlineInstances := maputil.Minus(oldInstances, newInstances) + slice.ForEach(maputil.Values(offlineInstances), func(_ int, item *meshresource.RPCInstanceResource) { + err := st.Delete(item) + if err != nil { + logger.Errorf("delete rpc instance %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Deleted, item, nil)) + }) + // find instances need to add and add them + addInstances := maputil.Minus(newInstances, oldInstances) + slice.ForEach(maputil.Values(addInstances), func(_ int, item *meshresource.RPCInstanceResource) { + err := st.Add(item) + if err != nil { + logger.Errorf("add rpc instance %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, item)) + }) + // find instances need to update and update them + updateInstances := make([]*meshresource.RPCInstanceResource, 0) + for key, instance := range newInstances { + if _, exists := oldInstances[key]; exists { + updateInstances = append(updateInstances, instance) + } + } + slice.ForEach(updateInstances, func(_ int, item *meshresource.RPCInstanceResource) { + err := st.Update(item) + if err != nil { + logger.Errorf("update rpc instance %s failed, cause: %v", item.ResourceKey(), err) + return + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Updated, item, item)) + }) + logger.Debugf("process rpc instance upsert event, oldInstances: %s, newInstances: %s, offlineInstances: %s, addInstances: %s, updateInstances: %s", + maputil.Keys(oldInstances), maputil.Keys(newInstances), maputil.Keys(offlineInstances), maputil.Keys(addInstances), updateInstances) + return nil +} + +func (n *NacosServiceEventSubscriber) processDelete(serviceRes *meshresource.NacosServiceResource) error { + providerRe := regexp.MustCompile(`^providers:[\w.]+(?::[\w.]*:|::[\w.]*)?$`) + consumerRe := regexp.MustCompile(`^consumers:[\w.]+(?::[\w.]*:|::[\w.]*)?$`) + if providerRe.MatchString(serviceRes.Name) { + logger.Infof("interface-level service ignored, service name: %s", serviceRes.Name) + return nil + } + if consumerRe.MatchString(serviceRes.Name) { + return n.processServiceConsumerDelete(serviceRes) + } + return n.processRPCInstanceDelete(serviceRes) +} + +func (n *NacosServiceEventSubscriber) processServiceConsumerDelete(serviceRes *meshresource.NacosServiceResource) error { + st, err := n.storeRouter.ResourceKindRoute(meshresource.ServiceConsumerMetadataKind) + if err != nil { + logger.Errorf("process service consumer delete event, but cannot route to service consumer metadata resource, cause: %v", err) + return err + } + resources, err := st.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: serviceRes.Mesh, Operator: index.Equals}, + {IndexName: index.ByServiceConsumerServiceName, Value: serviceRes.Name, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("process service consumer delete event, but cannot list service consumer metadata resource of %s, cause: %v", serviceRes.Name, err) + return err + } + slice.ForEach(resources, func(_ int, item coremodel.Resource) { + err := st.Delete(item) + if err != nil { + logger.Errorf("delete resource failed, resource: %s, cause: %v", item.String(), err) + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Deleted, item, nil)) + }) + return nil +} + +func (n *NacosServiceEventSubscriber) processRPCInstanceDelete(serviceRes *meshresource.NacosServiceResource) error { + st, err := n.storeRouter.ResourceKindRoute(meshresource.RPCInstanceKind) + if err != nil { + logger.Errorf("process rpc instance delete event, but cannot route to rpc instance resource, cause: %v", err) + return err + } + resources, err := st.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByMeshIndex, Value: serviceRes.Mesh, Operator: index.Equals}, + {IndexName: index.ByRPCInstanceAppName, Value: serviceRes.Name, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("process rpc instance delete event, but cannot list rpc instance resource of %s, cause: %v", serviceRes.Name, err) + return err + } + slice.ForEach(resources, func(_ int, item coremodel.Resource) { + err := st.Delete(item) + if err != nil { + logger.Errorf("delete resource failed, resource: %s, cause: %v", item.String(), err) + } + n.emitter.Send(events.NewResourceChangedEvent(cache.Deleted, item, nil)) + }) + return nil +} diff --git a/pkg/core/discovery/subscriber/rpc_instance.go b/pkg/core/discovery/subscriber/rpc_instance.go new file mode 100644 index 000000000..411f454d5 --- /dev/null +++ b/pkg/core/discovery/subscriber/rpc_instance.go @@ -0,0 +1,254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "reflect" + + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type RPCInstanceEventSubscriber struct { + instanceStore store.ResourceStore + rtInstanceStore store.ResourceStore + eventEmitter events.Emitter + engineCfg *enginecfg.Config +} + +func NewRPCInstanceEventSubscriber( + instanceStore store.ResourceStore, + rtInstanceStore store.ResourceStore, + emitter events.Emitter, + engineCfg *enginecfg.Config) *RPCInstanceEventSubscriber { + return &RPCInstanceEventSubscriber{ + instanceStore: instanceStore, + rtInstanceStore: rtInstanceStore, + eventEmitter: emitter, + engineCfg: engineCfg, + } +} + +func (s *RPCInstanceEventSubscriber) Name() string { + return "Discovery-" + s.ResourceKind().ToString() +} + +func (s *RPCInstanceEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.RPCInstanceKind +} + +func (s *RPCInstanceEventSubscriber) AsyncEnabled() bool { + return true +} + +func (s *RPCInstanceEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.RPCInstanceResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(meshresource.RPCInstanceKind, event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.RPCInstanceResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(meshresource.RPCInstanceKind, event.OldObj()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil { + errStr := "process rpc instance upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processUpsert(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process rpc instance delete event, but old obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processDelete(oldObj) + } + if processErr != nil { + logger.Errorf("process rpc instance event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process rpc instance event successfully, event: %s", event.String()) + return nil +} + +func (s *RPCInstanceEventSubscriber) processUpsert(rpcInstanceRes *meshresource.RPCInstanceResource) error { + // If the conditions follow are not met, we cannot identify it as a dubbo instance, so we skip it + if !s.checkAttributeEnough(rpcInstanceRes) { + logger.Warnf("cannot identify rpc instance %s as a dubbo instance, skipped updating instance", rpcInstanceRes.Name) + return nil + } + instanceRes, err := s.getRelatedInstanceRes(rpcInstanceRes) + if err != nil { + return err + } + // if instance resource exists, that is to say the runtime instance exists and has been watched by engine + // We should merge the rpc info into it + if instanceRes != nil { + meshresource.MergeRPCInstanceIntoInstance(rpcInstanceRes, instanceRes) + if err := s.instanceStore.Update(instanceRes); err != nil { + return err + } + logger.Infof("instance lifecycle merged rpc source, instance: %s, rpc: %s, registerState: registered, deployState: %s", + instanceRes.ResourceKey(), rpcInstanceRes.ResourceKey(), instanceRes.Spec.DeployState) + return nil + } + // Otherwise we can create a new instance resource by rpc instance + instanceRes = meshresource.FromRPCInstance(rpcInstanceRes) + s.findRelatedRuntimeInstanceAndMerge(instanceRes) + if err := s.instanceStore.Add(instanceRes); err != nil { + logger.Errorf("add instance resource failed, instance: %s, err: %s", instanceRes.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle created rpc-only instance, instance: %s, rpc: %s, registerState: registered", + instanceRes.ResourceKey(), rpcInstanceRes.ResourceKey()) + + instanceAddEvent := events.NewResourceChangedEvent(cache.Added, nil, instanceRes) + s.eventEmitter.Send(instanceAddEvent) + logger.Debugf("rpc instance upsert trigger instance add event, event: %s", instanceAddEvent.String()) + return nil +} + +func (s *RPCInstanceEventSubscriber) processDelete(rpcInstanceRes *meshresource.RPCInstanceResource) error { + instanceRes, err := s.getRelatedInstanceRes(rpcInstanceRes) + if err != nil { + return err + } + if instanceRes == nil { + logger.Warnf("cannot find instance resource for rpc instance %s, skipped deleting instance", rpcInstanceRes.Name) + return nil + } + meshresource.ClearRPCInstanceFromInstance(instanceRes) + if meshresource.HasRuntimeInstanceSource(instanceRes) { + if err := s.instanceStore.Update(instanceRes); err != nil { + logger.Errorf("update instance resource failed after rpc delete, instance: %s, err: %s", + instanceRes.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle rpc source removed, keep instance by runtime source, instance: %s, rpc: %s, deployState: %s", + instanceRes.ResourceKey(), rpcInstanceRes.ResourceKey(), instanceRes.Spec.DeployState) + instanceUpdateEvent := events.NewResourceChangedEvent(cache.Updated, instanceRes, instanceRes) + s.eventEmitter.Send(instanceUpdateEvent) + logger.Debugf("rpc instance delete trigger instance update event, event: %s", instanceUpdateEvent.String()) + return nil + } + if err := s.instanceStore.Delete(instanceRes); err != nil { + logger.Errorf("delete instance resource failed, instance: %s, err: %s", instanceRes.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle rpc source removed and no runtime source remains, deleted instance: %s, rpc: %s", + instanceRes.ResourceKey(), rpcInstanceRes.ResourceKey()) + instanceDeleteEvent := events.NewResourceChangedEvent(cache.Deleted, instanceRes, nil) + s.eventEmitter.Send(instanceDeleteEvent) + logger.Debugf("rpc instance delete trigger instance delete event, event: %s", instanceDeleteEvent.String()) + return nil +} + +func (s *RPCInstanceEventSubscriber) checkAttributeEnough(rpcInstanceRes *meshresource.RPCInstanceResource) bool { + if rpcInstanceRes.Spec == nil || strutil.IsBlank(rpcInstanceRes.Spec.AppName) || + strutil.IsBlank(rpcInstanceRes.Spec.Ip) || rpcInstanceRes.Spec.Port <= 0 || + strutil.IsBlank(rpcInstanceRes.Mesh) || constants.DefaultMesh == rpcInstanceRes.Mesh { + return false + } + return true +} + +func (s *RPCInstanceEventSubscriber) getRelatedInstanceRes( + rpcInstanceRes *meshresource.RPCInstanceResource) (*meshresource.InstanceResource, error) { + res, exists, err := s.instanceStore.GetByKey(coremodel.BuildResourceKey(rpcInstanceRes.Mesh, rpcInstanceRes.Name)) + if err != nil { + return nil, err + } + if !exists { + return nil, nil + } + instanceRes, ok := res.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.InstanceKind, reflect.TypeOf(res).Name()) + } + return instanceRes, nil +} + +func (s *RPCInstanceEventSubscriber) findRelatedRuntimeInstanceAndMerge(instanceRes *meshresource.InstanceResource) { + switch s.engineCfg.Type { + case enginecfg.Kubernetes: + rtInstance := s.getRuntimeInstanceForInstance(instanceRes) + if rtInstance == nil { + logger.Warnf("cannot find runtime instance for instace %s, skipping merging", instanceRes.ResourceKey()) + return + } + meshresource.MergeRuntimeInstanceIntoInstance(rtInstance, instanceRes) + default: + return + } +} + +func (s *RPCInstanceEventSubscriber) getRuntimeInstanceForInstance(instanceRes *meshresource.InstanceResource) *meshresource.RuntimeInstanceResource { + ip := instanceRes.Spec.Ip + resources, err := s.rtInstanceStore.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByRuntimeInstanceIPIndex, Value: ip, Operator: index.Equals}, + }) + if err != nil { + logger.Errorf("list runtime instance by ip index failed, ip: %s, err: %s", ip, err.Error()) + return nil + } + if len(resources) == 0 { + return nil + } + candidates := make([]*meshresource.RuntimeInstanceResource, 0, len(resources)) + for _, item := range resources { + res, ok := item.(*meshresource.RuntimeInstanceResource) + if !ok { + continue + } + candidates = append(candidates, res) + } + // Prefer exact runtime identity match by app + rpcPort + mesh. + for _, candidate := range candidates { + if candidate.Spec == nil { + continue + } + if candidate.Mesh == instanceRes.Mesh && + candidate.Spec.AppName == instanceRes.Spec.AppName && + candidate.Spec.RpcPort == instanceRes.Spec.RpcPort { + return candidate + } + } + if len(candidates) > 1 { + keys := slice.Map(candidates, func(_ int, item *meshresource.RuntimeInstanceResource) string { + return item.ResourceKey() + }) + logger.Warnf("multiple runtime instances share same ip %s, fallback to first candidate, runtime keys: %v, target instance: %s", + ip, keys, instanceRes.ResourceKey()) + } + return candidates[0] +} diff --git a/pkg/core/discovery/subscriber/service_consumer_metadata.go b/pkg/core/discovery/subscriber/service_consumer_metadata.go new file mode 100644 index 000000000..042728743 --- /dev/null +++ b/pkg/core/discovery/subscriber/service_consumer_metadata.go @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "reflect" + + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +type ServiceConsumerMetadataEventSubscriber struct { + appStore store.ResourceStore + emitter events.Emitter +} + +func NewServiceConsumerMetadataEventSubscriber( + appStore store.ResourceStore, + emitter events.Emitter) *ServiceConsumerMetadataEventSubscriber { + return &ServiceConsumerMetadataEventSubscriber{ + appStore: appStore, + emitter: emitter, + } +} + +func (s *ServiceConsumerMetadataEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.ServiceConsumerMetadataKind +} + +func (s *ServiceConsumerMetadataEventSubscriber) Name() string { + return "Discovery-" + s.ResourceKind().ToString() +} + +func (s *ServiceConsumerMetadataEventSubscriber) AsyncEnabled() bool { + return true +} + +func (s *ServiceConsumerMetadataEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.ServiceConsumerMetadataResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(newObj), event.NewObj()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil { + errStr := "process consumer metadata resource upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processUpsert(newObj) + case cache.Deleted: + logger.Warnf("ignored consumer metadata resource deleted event in ServiceConsumerMetadataEventSubscriber") + } + if processErr != nil { + logger.Errorf("process consumer metadata resource event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process consumer metadata resource event successfully, event: %s", event.String()) + return nil +} + +func (s *ServiceConsumerMetadataEventSubscriber) processUpsert(r *meshresource.ServiceConsumerMetadataResource) error { + if r.Spec == nil { + return bizerror.New(bizerror.UnknownError, "consumer metadata resource spec is nil") + } + if strutil.IsBlank(r.Spec.ConsumerAppName) { + logger.Warnf("skip processing service consumer metadata event because spec.consumerAppName is blank, res:%s", r.String()) + return nil + } + _, exists, err := s.appStore.GetByKey(coremodel.BuildResourceKey(r.Mesh, r.Spec.ConsumerAppName)) + if err != nil { + logger.Errorf("get application resource failed, appName: %s, mesh: %s, cause: %s", + r.Spec.ConsumerAppName, r.Mesh, err.Error()) + return err + } + if exists { + logger.Infof("application resource already exists, appName: %s, mesh: %s", r.Spec.ConsumerAppName, r.Mesh) + return nil + } + appRes := meshresource.NewApplicationResourceWithAttributes(r.Spec.ConsumerAppName, r.Mesh) + appRes.Spec.Name = r.Spec.ConsumerAppName + if err := s.appStore.Add(appRes); err != nil { + logger.Errorf("add application resource failed, appName: %s, mesh: %s, cause: %s", + r.Spec.ConsumerAppName, r.Mesh, err.Error()) + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, appRes)) + return nil +} diff --git a/pkg/core/discovery/subscriber/service_provider_metadata.go b/pkg/core/discovery/subscriber/service_provider_metadata.go new file mode 100644 index 000000000..0defc7d18 --- /dev/null +++ b/pkg/core/discovery/subscriber/service_provider_metadata.go @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "reflect" + "sort" + "strings" + + "k8s.io/client-go/tools/cache" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type ServiceProviderMetadataEventSubscriber struct { + appStore store.ResourceStore + serviceStore store.ResourceStore + providerStore store.ResourceStore + emitter events.Emitter +} + +func NewServiceProviderMetadataEventSubscriber( + appStore store.ResourceStore, + serviceStore store.ResourceStore, + providerStore store.ResourceStore, + emitter events.Emitter) *ServiceProviderMetadataEventSubscriber { + return &ServiceProviderMetadataEventSubscriber{ + appStore: appStore, + serviceStore: serviceStore, + providerStore: providerStore, + emitter: emitter, + } +} + +func (s *ServiceProviderMetadataEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.ServiceProviderMetadataKind +} + +func (s *ServiceProviderMetadataEventSubscriber) Name() string { + return "Discovery-" + s.ResourceKind().ToString() +} + +func (s *ServiceProviderMetadataEventSubscriber) AsyncEnabled() bool { + return true +} + +func (s *ServiceProviderMetadataEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.ServiceProviderMetadataResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(newObj), event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.ServiceProviderMetadataResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(oldObj), event.OldObj()) + } + + var processErr error + switch event.Type() { + case cache.Added, cache.Replaced, cache.Sync: + if newObj == nil { + errStr := "process provider metadata resource upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processUpsert(newObj) + case cache.Updated: + if newObj == nil { + errStr := "process provider metadata resource update event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processUpdate(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process provider metadata resource delete event, but old obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = s.processDelete(oldObj) + } + if processErr != nil { + logger.Errorf("process provider metadata resource event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process provider metadata resource event successfully, event: %s", event.String()) + return nil +} + +func (s *ServiceProviderMetadataEventSubscriber) processUpsert(r *meshresource.ServiceProviderMetadataResource) error { + if r.Spec == nil { + return bizerror.New(bizerror.UnknownError, "provider metadata resource spec is nil") + } + if err := s.ensureApplication(r); err != nil { + return err + } + return s.syncService(r.Mesh, r.Spec.ServiceName, r.Spec.Version, r.Spec.Group) +} + +func (s *ServiceProviderMetadataEventSubscriber) processDelete(r *meshresource.ServiceProviderMetadataResource) error { + if r.Spec == nil { + return bizerror.New(bizerror.UnknownError, "provider metadata resource spec is nil") + } + return s.syncService(r.Mesh, r.Spec.ServiceName, r.Spec.Version, r.Spec.Group) +} + +func (s *ServiceProviderMetadataEventSubscriber) processUpdate(newRes *meshresource.ServiceProviderMetadataResource) error { + if newRes.Spec == nil { + return bizerror.New(bizerror.UnknownError, "provider metadata resource spec is nil") + } + if err := s.ensureApplication(newRes); err != nil { + return err + } + return s.syncService(newRes.Mesh, newRes.Spec.ServiceName, newRes.Spec.Version, newRes.Spec.Group) +} + +func (s *ServiceProviderMetadataEventSubscriber) ensureApplication(r *meshresource.ServiceProviderMetadataResource) error { + if r.Spec.ProviderAppName == "" { + logger.Warnf("skip processing application sync because spec.providerAppName is blank, res:%s", r.String()) + return nil + } + _, exists, err := s.appStore.GetByKey(coremodel.BuildResourceKey(r.Mesh, r.Spec.ProviderAppName)) + if err != nil { + logger.Errorf("get application resource failed, appName: %s, mesh: %s, cause: %s", + r.Spec.ProviderAppName, r.Mesh, err.Error()) + return err + } + if exists { + return nil + } + + appRes := meshresource.NewApplicationResourceWithAttributes(r.Spec.ProviderAppName, r.Mesh) + appRes.Spec.Name = r.Spec.ProviderAppName + if err := s.appStore.Add(appRes); err != nil { + logger.Errorf("add application resource failed, appName: %s, mesh: %s, cause: %s", + r.Spec.ProviderAppName, r.Mesh, err.Error()) + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, appRes)) + return nil +} + +func (s *ServiceProviderMetadataEventSubscriber) syncService(mesh, serviceName, version, group string) error { + serviceKey := meshresource.BuildServiceIdentityKey(serviceName, version, group) + resources, err := s.providerStore.ListByIndexes( + []index.IndexCondition{{IndexName: index.ByMeshIndex, Value: mesh, Operator: index.Equals}, + {IndexName: index.ByServiceProviderServiceKey, Value: serviceKey, Operator: index.Equals}, + }) + if err != nil { + return err + } + + providers := make([]*meshresource.ServiceProviderMetadataResource, 0, len(resources)) + for _, item := range resources { + res, ok := item.(*meshresource.ServiceProviderMetadataResource) + if !ok { + return bizerror.NewAssertionError(meshresource.ServiceProviderMetadataKind, reflect.TypeOf(item).Name()) + } + providers = append(providers, res) + } + + rawOldRes, exists, err := s.serviceStore.GetByKey(coremodel.BuildResourceKey(mesh, serviceKey)) + if err != nil { + return err + } + + var oldRes *meshresource.ServiceResource + if exists { + var ok bool + oldRes, ok = rawOldRes.(*meshresource.ServiceResource) + if !ok { + return bizerror.NewAssertionError(meshresource.ServiceKind, reflect.TypeOf(rawOldRes).Name()) + } + } + + if len(providers) == 0 { + if !exists { + return nil + } + if err := s.serviceStore.Delete(oldRes); err != nil { + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Deleted, oldRes, nil)) + return nil + } + + newRes := meshresource.NewServiceResourceWithAttributes(serviceKey, mesh) + newRes.Spec = buildServiceSpec(serviceName, version, group, providers) + if !exists { + if err := s.serviceStore.Add(newRes); err != nil { + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, newRes)) + return nil + } + + if err := s.serviceStore.Update(newRes); err != nil { + return err + } + s.emitter.Send(events.NewResourceChangedEvent(cache.Updated, oldRes, newRes)) + return nil +} + +func buildServiceSpec(serviceName, version, group string, providers []*meshresource.ServiceProviderMetadataResource) *meshproto.Service { + methodSet := make(map[string]struct{}) + language := "" + + for _, provider := range providers { + if provider.Spec == nil { + continue + } + if language == "" { + language = inferProviderLanguage(provider.Spec) + } + for _, method := range provider.Spec.Methods { + if method == nil || method.Name == "" { + continue + } + methodSet[method.Name] = struct{}{} + } + } + + methods := make([]string, 0, len(methodSet)) + for methodName := range methodSet { + methods = append(methods, methodName) + } + sort.Strings(methods) + + return &meshproto.Service{ + Name: serviceName, + Group: group, + Version: version, + Language: language, + Methods: methods, + } +} + +func inferProviderLanguage(spec *meshproto.ServiceProviderMetadata) string { + if spec == nil { + return "" + } + if spec.Parameters != nil && spec.Parameters["language"] != "" { + return spec.Parameters["language"] + } + // Current SDKs do not reliably publish an explicit language field, so we + // fall back to SDK-specific metadata fingerprints when the source field is absent. + if looksLikeDubboGo(spec) { + return "golang" + } + if looksLikeDubboJava(spec) { + return "java" + } + return "" +} + +func looksLikeDubboGo(spec *meshproto.ServiceProviderMetadata) bool { + if spec == nil || spec.Parameters == nil { + return false + } + // dubbo-go writes a release like "dubbo-golang-", which is the + // most stable discriminator we can use without requiring provider changes. + release := strings.ToLower(spec.Parameters["release"]) + return strings.HasPrefix(release, "dubbo-golang-") || strings.HasPrefix(release, "dubbo-go-") +} + +func looksLikeDubboJava(spec *meshproto.ServiceProviderMetadata) bool { + if spec == nil { + return false + } + // Java providers usually expose Java type names in method signatures and + // exported type definitions, even when "language" itself is missing. + for _, method := range spec.Methods { + if methodHasJavaTypeHint(method) { + return true + } + } + for _, typ := range spec.Types { + if metadataTypeHasJavaHint(typ) { + return true + } + } + return false +} + +func methodHasJavaTypeHint(method *meshproto.Method) bool { + if method == nil { + return false + } + for _, parameterType := range method.ParameterTypes { + if isJavaTypeHint(parameterType) { + return true + } + } + if isJavaTypeHint(method.ReturnType) { + return true + } + for _, parameter := range method.Parameters { + if parameter != nil && isJavaTypeHint(parameter.Type) { + return true + } + } + return false +} + +func metadataTypeHasJavaHint(typ *meshproto.Type) bool { + if typ == nil { + return false + } + if isJavaTypeHint(typ.Type) { + return true + } + for _, item := range typ.Items { + if isJavaTypeHint(item) { + return true + } + } + for _, propertyType := range typ.Properties { + if isJavaTypeHint(propertyType) { + return true + } + } + return false +} + +func isJavaTypeHint(typeName string) bool { + typeName = strings.ToLower(typeName) + return strings.HasPrefix(typeName, "java.") || strings.Contains(typeName, ".java.") +} diff --git a/pkg/core/discovery/subscriber/zk_config.go b/pkg/core/discovery/subscriber/zk_config.go new file mode 100644 index 000000000..07f9a2620 --- /dev/null +++ b/pkg/core/discovery/subscriber/zk_config.go @@ -0,0 +1,222 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "fmt" + "reflect" + "strings" + + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +type ZKConfigEventSubscriber struct { + emitter events.Emitter + storeRouter store.Router +} + +func NewZKConfigEventSubscriber(eventEmitter events.Emitter, storeRouter store.Router) *ZKConfigEventSubscriber { + return &ZKConfigEventSubscriber{ + emitter: eventEmitter, + storeRouter: storeRouter, + } +} + +func (z *ZKConfigEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.ZKConfigKind +} + +func (z *ZKConfigEventSubscriber) Name() string { + return "Discovery-" + z.ResourceKind().ToString() +} + +func (z *ZKConfigEventSubscriber) AsyncEnabled() bool { + return true +} + +func (z *ZKConfigEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.ZKConfigResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(newObj), event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.ZKConfigResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(oldObj), event.OldObj()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil || newObj.Spec == nil { + errStr := "process zk config upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = z.processUpsert(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process zk config delete event, but old obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = z.processDelete(oldObj) + } + if processErr != nil { + logger.Errorf("process zk config event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process zk config event successfully, event: %s", event.String()) + return nil +} + +func (z *ZKConfigEventSubscriber) processUpsert(configRes *meshresource.ZKConfigResource) error { + parts := strings.Split(configRes.Spec.NodeName, constants.DotSeparator) + suffix := parts[len(parts)-1] + if !constants.RuleSuffixSet.Contain(suffix) { + logger.Warnf("node name is not end with rule suffix, skipped processing, nodeName: %s", configRes.Spec.NodeName) + return nil + } + logger.Debugf("process zk config upsert event, config res: %s", configRes.String()) + switch suffix { + case constants.TagRuleSuffix: + return processConfigUpsert[*meshresource.TagRouteResource]( + configRes, meshresource.ToTagRouteResource, z.storeRouter, z.emitter) + case constants.ConditionRuleSuffix: + return processConfigUpsert[*meshresource.ConditionRouteResource]( + configRes, meshresource.ToConditionRouteResource, z.storeRouter, z.emitter) + case constants.ConfiguratorsSuffix: + return processConfigUpsert[*meshresource.DynamicConfigResource]( + configRes, meshresource.ToDynamicConfigResource, z.storeRouter, z.emitter) + default: + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("unknown rule type in mesh %s, skipped processing, path: %s, raw content: %s", + configRes.Mesh, configRes.Spec.NodeName, configRes.Spec.NodeData)) + } +} + +func (z *ZKConfigEventSubscriber) processDelete(configRes *meshresource.ZKConfigResource) error { + parts := strings.Split(configRes.Spec.NodeName, constants.DotSeparator) + suffix := parts[len(parts)-1] + if !constants.RuleSuffixSet.Contain(suffix) { + logger.Warnf("node name is not end with rule suffix, skipped processing, nodeName: %s", configRes.Spec.NodeName) + return nil + } + logger.Debugf("process zk config delete event, config res: %s", configRes.String()) + switch suffix { + case constants.TagRuleSuffix: + return processConfigDelete[*meshresource.TagRouteResource]( + configRes, meshresource.ToTagRouteResource, z.storeRouter, z.emitter) + case constants.ConditionRuleSuffix: + return processConfigDelete[*meshresource.ConditionRouteResource]( + configRes, meshresource.ToConditionRouteResource, z.storeRouter, z.emitter) + case constants.ConfiguratorsSuffix: + return processConfigDelete[*meshresource.DynamicConfigResource]( + configRes, meshresource.ToDynamicConfigResource, z.storeRouter, z.emitter) + default: + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("unknown rule type in mesh %s, skipped processing, node: %s", + configRes.Mesh, configRes.Spec.NodeName)) + } +} + +func processConfigUpsert[T coremodel.Resource]( + configRes *meshresource.ZKConfigResource, + toRuleRes meshresource.ToRuleResourceFunc, + router store.Router, + emitter events.Emitter) error { + newRuleRes := toRuleRes(configRes.Mesh, configRes.Name, configRes.Spec.NodeData) + if newRuleRes == nil { + logger.Errorf("cannot unmarshal config in zk %s, raw content: %s", configRes.Mesh, configRes.Spec.NodeData) + return bizerror.New(bizerror.ZKError, "cannot unmarshal rule") + } + st, err := router.ResourceKindRoute(newRuleRes.ResourceKind()) + if err != nil { + logger.Errorf("get %s store failed, cause: %s", newRuleRes.ResourceKind(), err.Error()) + return err + } + oldRes, exists, err := st.GetByKey(newRuleRes.ResourceKey()) + if err != nil { + logger.Errorf("get rule %s from store failed, cause: %s", newRuleRes.ResourceKey(), err.Error()) + return err + } + if !exists { + err := st.Add(newRuleRes) + if err != nil { + logger.Errorf("add rule %s to store failed, cause: %s", newRuleRes.ResourceKey(), err.Error()) + return err + } + emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, newRuleRes)) + return nil + } + + err = st.Update(newRuleRes) + if err != nil { + logger.Errorf("update rule %s to store failed, cause: %s", newRuleRes.ResourceKey(), err.Error()) + return err + } + + var oldMetadataRes T + oldMetadataRes, ok := oldRes.(T) + if !ok { + logger.Errorf("cannot convert old rule %s to %T", newRuleRes.ResourceKey(), oldMetadataRes) + return bizerror.NewAssertionError(reflect.TypeOf(oldMetadataRes), oldRes) + } + + emitter.Send(events.NewResourceChangedEvent(cache.Updated, oldMetadataRes, newRuleRes)) + return nil +} + +func processConfigDelete[T coremodel.Resource]( + configRes *meshresource.ZKConfigResource, + toRuleRes meshresource.ToRuleResourceFunc, + router store.Router, + emitter events.Emitter) error { + ruleRes := toRuleRes(configRes.Mesh, configRes.Name, configRes.Spec.NodeData) + st, err := router.ResourceKindRoute(ruleRes.ResourceKind()) + if err != nil { + logger.Errorf("get %s store failed, cause: %s", ruleRes.ResourceKind(), err.Error()) + return err + } + oldRes, exists, err := st.GetByKey(ruleRes.ResourceKey()) + if err != nil { + logger.Errorf("get rule %s from store failed, cause: %s", ruleRes.ResourceKey(), err.Error()) + return err + } + if !exists { + logger.Infof("rule %s not exists in store, skipped deleting", ruleRes.ResourceKey()) + return nil + } + oldRuleRes, ok := oldRes.(T) + if !ok { + return bizerror.NewAssertionError(reflect.TypeOf(oldRuleRes), oldRes) + } + err = st.Delete(ruleRes) + if err != nil { + logger.Errorf("delete rule %s from store failed, cause: %s", ruleRes.ResourceKey(), err.Error()) + return err + } + emitter.Send(events.NewResourceChangedEvent(cache.Deleted, oldRuleRes, nil)) + return nil +} diff --git a/pkg/core/discovery/subscriber/zk_metadata.go b/pkg/core/discovery/subscriber/zk_metadata.go new file mode 100644 index 000000000..4a744119e --- /dev/null +++ b/pkg/core/discovery/subscriber/zk_metadata.go @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "fmt" + "reflect" + "strings" + + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +type ZKMetadataEventSubscriber struct { + emitter events.Emitter + storeRouter store.Router +} + +func NewZKMetadataEventSubscriber(eventEmitter events.Emitter, storeRouter store.Router) *ZKMetadataEventSubscriber { + return &ZKMetadataEventSubscriber{ + emitter: eventEmitter, + storeRouter: storeRouter, + } +} + +func (z *ZKMetadataEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.ZKMetadataKind +} + +func (z *ZKMetadataEventSubscriber) Name() string { + return "Discovery-" + z.ResourceKind().ToString() +} + +func (z *ZKMetadataEventSubscriber) AsyncEnabled() bool { + return true +} + +func (z *ZKMetadataEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.ZKMetadataResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(newObj), event.NewObj()) + } + oldObj, ok := event.OldObj().(*meshresource.ZKMetadataResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(reflect.TypeOf(oldObj), event.OldObj()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil || newObj.Spec == nil { + errStr := "process zk metadata upsert event, but new obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + processErr = z.processUpsert(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process zk metadata delete event, but old obj is nil, skipped processing" + logger.Errorf(errStr) + return bizerror.New(bizerror.EventError, errStr) + } + // Metadata is an ephemeral znode, dubbo client only adds/updates the metadata znode and never deletes. + // And we can't identify the service only by the node path, so for delete event, we just ignored + logger.Infof("ignored zk metadata delete event") + } + if processErr != nil { + logger.Errorf("process zk metadata event failed, cause: %s, event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process zk metadata event successfully, event: %s", event.String()) + return nil +} + +func (z *ZKMetadataEventSubscriber) processUpsert(metadataRes *meshresource.ZKMetadataResource) error { + paths := strings.Split(metadataRes.Spec.NodePath, constants.PathSeparator) + if len(paths) < 2 { + return bizerror.New(bizerror.ZKError, fmt.Sprintf("invalid zk metadata node path: %s", metadataRes.Spec.NodePath)) + } + if paths[len(paths)-2] == constants.ProviderSide { + return processMetadataUpsert[*meshresource.ServiceProviderMetadataResource]( + metadataRes, meshresource.ToServiceProviderMetadataRes, z.storeRouter, z.emitter) + } else if paths[len(paths)-2] == constants.ConsumerSide { + return processMetadataUpsert[*meshresource.ServiceConsumerMetadataResource]( + metadataRes, meshresource.ToServiceConsumerMetadataByRawData, z.storeRouter, z.emitter) + } + logger.Warnf("unknown metadata, node path: %s, node data: %s", metadataRes.Spec.NodePath, metadataRes.Spec.NodeData) + return nil +} + +// processMetadataUpsert handle service provider/consumer metadata upsert +func processMetadataUpsert[T coremodel.Resource]( + zkMetadataRes *meshresource.ZKMetadataResource, + toMetadataRes meshresource.ToMetadataResFunc, + router store.Router, + emitter events.Emitter) error { + newMetadataRes := toMetadataRes(zkMetadataRes.Mesh, zkMetadataRes.Spec.NodeData) + if newMetadataRes == nil { + logger.Errorf("cannot unmarshal metadata in zk %s, raw content: %s", zkMetadataRes.Mesh, zkMetadataRes.Spec.NodeData) + return bizerror.New(bizerror.ZKError, "cannot unmarshal metadata") + } + st, err := router.ResourceKindRoute(newMetadataRes.ResourceKind()) + if err != nil { + logger.Errorf("get %s store failed, cause: %s", newMetadataRes.ResourceKind(), err.Error()) + return err + } + oldRes, exists, err := st.GetByKey(newMetadataRes.ResourceKey()) + if err != nil { + logger.Errorf("get metadata %s from store failed, cause: %s", newMetadataRes.ResourceKey(), err.Error()) + return err + } + if !exists { + err := st.Add(newMetadataRes) + if err != nil { + logger.Errorf("add metadata %s to store failed, cause: %s", newMetadataRes.ResourceKey(), err.Error()) + return err + } + emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, newMetadataRes)) + return nil + } + + err = st.Update(newMetadataRes) + if err != nil { + logger.Errorf("update metadata %s to store failed, cause: %s", newMetadataRes.ResourceKey(), err.Error()) + return err + } + + var oldMetadataRes T + oldMetadataRes, ok := oldRes.(T) + if !ok { + logger.Errorf("cannot convert old metadata %s to %T", newMetadataRes.ResourceKey(), oldMetadataRes) + return bizerror.NewAssertionError(reflect.TypeOf(oldMetadataRes), oldRes) + } + + emitter.Send(events.NewResourceChangedEvent(cache.Updated, oldMetadataRes, newMetadataRes)) + return nil +} diff --git a/pkg/core/engine/base.go b/pkg/core/engine/base.go deleted file mode 100644 index 380e8310e..000000000 --- a/pkg/core/engine/base.go +++ /dev/null @@ -1,6 +0,0 @@ -package engine - -// ResourceEngine is the component which list and watch the runtime infrastructure of resources, like kubernetes, docker etc. -// TODO need to define the interface and implement it -type ResourceEngine interface { -} diff --git a/pkg/core/engine/component.go b/pkg/core/engine/component.go index 5a4f0c953..8c893a9e3 100644 --- a/pkg/core/engine/component.go +++ b/pkg/core/engine/component.go @@ -1,38 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package engine import ( + "context" + "fmt" "math" + "reflect" + "sync/atomic" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/engine/subscriber" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/leader" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" + "k8s.io/client-go/tools/cache" ) +func init() { + runtime.RegisterComponent(newEngineComponent()) +} + type Component interface { runtime.Component - ResourceEngine() ResourceEngine + ResourceEngine +} + +var _ Component = &engineComponent{} + +type engineComponent struct { + name string + storeRouter store.Router + informers []controller.Informer + subscriptionManager events.SubscriptionManager + subscribers []events.Subscriber + leaderElection *leader.LeaderElection + needsLeaderElection bool + subscribed atomic.Bool } -var _ Component = &BaseResourceEngineComponent{} +func newEngineComponent() Component { + return &engineComponent{ + informers: make([]controller.Informer, 0), + subscribers: make([]events.Subscriber, 0), + } +} -type BaseResourceEngineComponent struct{} +func (e *engineComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.EventBus, + runtime.ResourceStore, + } +} -func (b BaseResourceEngineComponent) Type() runtime.ComponentType { +func (e *engineComponent) Type() runtime.ComponentType { return runtime.ResourceEngine } -func (b BaseResourceEngineComponent) Order() int { - return math.MaxInt +func (e *engineComponent) Order() int { + return math.MaxInt - 3 +} + +func (e *engineComponent) Init(ctx runtime.BuilderContext) error { + cfg := ctx.Config().Engine + e.name = cfg.ID + eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) + if err != nil { + return fmt.Errorf("can not retrieve event bus from runtime in engine %s, %w", e.name, err) + } + eventBus, ok := eventBusComponent.(events.EventBus) + if !ok { + return bizerror.NewAssertionError("EventBus", reflect.TypeOf(eventBusComponent).Name()) + } + e.subscriptionManager = eventBus + storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) + if err != nil { + return fmt.Errorf("can not retrieve store from runtime in engine %s, %w", e.name, err) + } + storeRouter, ok := storeComponent.(store.Router) + if !ok { + return bizerror.NewAssertionError("store.Router", reflect.TypeOf(storeComponent).Name()) + } + e.storeRouter = storeRouter + if err = e.initInformers(cfg, eventBus); err != nil { + return fmt.Errorf("init informer failed, %w", err) + } + if err = e.initSubscribers(eventBus); err != nil { + return fmt.Errorf("init subscribers failed, %w", err) + } + + defer logger.Infof("resource engine %s has been inited successfully", e.name) + + // Memory store runs single-replica; leader election is not needed. + if ctx.Config().Store.Type == storecfg.Memory { + return nil + } + + dbSrc, ok := storeComponent.(leader.DBSource) + if !ok { + return nil + } + db, hasDB := dbSrc.GetDB() + if !hasDB { + return nil + } + holderID, err := leader.GenerateHolderID() + if err != nil { + logger.Warnf("engine: failed to generate holder ID, skipping leader election: %v", err) + return nil + } + le := leader.NewLeaderElection(db, runtime.ResourceEngine, holderID) + if err := le.EnsureTable(); err != nil { + logger.Warnf("engine: failed to ensure leader lease table: %v", err) + return nil + } + e.leaderElection = le + e.needsLeaderElection = true + logger.Infof("engine: leader election initialized (holder: %s)", holderID) + return nil } -func (b BaseResourceEngineComponent) Init(runtime.BuilderContext) error { - panic("Init() must be implemented by concrete BaseResourceEngineComponent") +func (e *engineComponent) initInformers(cfg *enginecfg.Config, emitter events.Emitter) error { + factory, err := FactoryRegistry().GetListWatcherFactory(cfg.Type) + if err != nil { + return err + } + lwList, err := factory.NewListWatchers(cfg) + if err != nil { + return err + } + for _, lw := range lwList { + rk := lw.ResourceKind() + rs, err := e.storeRouter.ResourceKindRoute(rk) + if err != nil { + return fmt.Errorf("can not find store for resource kind %s, %w", rk, err) + } + informer := controller.NewInformerWithOptions(lw, emitter, rs, resolveInformerKeyFunc(lw), controller.Options{ResyncPeriod: 0}) + if lw.TransformFunc() != nil { + err = informer.SetTransform(lw.TransformFunc()) + if err != nil { + return fmt.Errorf("can not set transform for informer of resource kind %s, %w", rk, err) + } + } + e.informers = append(e.informers, informer) + logger.Infof("resource engine %s has added informer for resource kind %s", e.name, rk) + } + return nil +} +func resolveInformerKeyFunc(lw controller.ResourceListerWatcher) cache.KeyFunc { + if provider, ok := lw.(controller.ResourceKeyProvider); ok { + return provider.KeyFunc() + } + return cache.MetaNamespaceKeyFunc } -func (b BaseResourceEngineComponent) Start(runtime.Runtime, <-chan struct{}) error { - panic("Start() must be implemented by concrete BaseResourceEngineComponent") +func (e *engineComponent) initSubscribers(eventbus events.EventBus) error { + rs, err := e.storeRouter.ResourceKindRoute(meshresource.InstanceKind) + if err != nil { + return fmt.Errorf("can not find store for resource kind %s, %w", meshresource.InstanceKind, err) + } + runtimeInstanceSub := subscriber.NewRuntimeInstanceEventSubscriber(rs, eventbus) + e.subscribers = append(e.subscribers, runtimeInstanceSub) + return nil } -func (b BaseResourceEngineComponent) ResourceEngine() ResourceEngine { - panic("Discovery() must be implemented by concrete BaseResourceEngineComponent") +func (e *engineComponent) Start(_ runtime.Runtime, ch <-chan struct{}) error { + if !e.needsLeaderElection { + return e.startBusinessLogic(ch) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + <-ch + cancel() + }() + + var leaderStopCh chan struct{} + + e.leaderElection.RunLeaderElection(ctx, ch, + func() { // onStartLeading: create a fresh stopCh for this leadership term + leaderStopCh = make(chan struct{}) + logger.Infof("engine: became leader, starting business logic") + if err := e.startBusinessLogic(leaderStopCh); err != nil { + logger.Errorf("engine: failed to start business logic: %v", err) + } + }, + func() { // onStopLeading: stop informers from the current term + logger.Warnf("engine: lost leadership, stopping business logic") + if leaderStopCh != nil { + close(leaderStopCh) + leaderStopCh = nil + } + }, + ) + + return nil +} +// startBusinessLogic starts subscribers and informers using the provided stopCh. +// When stopCh is closed all informer goroutines will exit. +func (e *engineComponent) startBusinessLogic(stopCh <-chan struct{}) error { + // 1. subscribe resource changed events (only once for the process lifetime) + if !e.subscribed.Load() { + for _, sub := range e.subscribers { + if err := e.subscriptionManager.Subscribe(sub); err != nil { + return fmt.Errorf("could not subscribe %s to eventbus, %w", sub.Name(), err) + } + } + e.subscribed.Store(true) + } + // 2. start informers + for _, informer := range e.informers { + go informer.Run(stopCh) + } + logger.Infof("resource engine %s has started successfully", e.name) + return nil } diff --git a/pkg/core/engine/engine.go b/pkg/core/engine/engine.go new file mode 100644 index 000000000..06cb57d14 --- /dev/null +++ b/pkg/core/engine/engine.go @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package engine + +// ResourceEngine is the component which list and watch the runtime infrastructure of resources, like kubernetes, docker etc. +type ResourceEngine interface{} diff --git a/pkg/core/engine/factory.go b/pkg/core/engine/factory.go new file mode 100644 index 000000000..19f27d46e --- /dev/null +++ b/pkg/core/engine/factory.go @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package engine + +import ( + "fmt" + + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/controller" +) + +var factoryRegistry = newListWatchFactoryRegistry() + +func RegisterFactory(f Factory) { + factoryRegistry.Register(f) +} + +func FactoryRegistry() Registry { + return factoryRegistry +} + +// Factory defines if a specific engine type is supported and how to create ListWatchers +type Factory interface { + Support(enginecfg.Type) bool + NewListWatchers(*enginecfg.Config) ([]controller.ResourceListerWatcher, error) +} + +type Registry interface { + GetListWatcherFactory(enginecfg.Type) (Factory, error) +} + +type RegistryMutator interface { + // Register a new engine factory + Register(Factory) +} + +type MutableRegistry interface { + Registry + RegistryMutator +} + +var _ MutableRegistry = &listWatchFactoryRegistry{} + +type listWatchFactoryRegistry struct { + factories []Factory +} + +func newListWatchFactoryRegistry() MutableRegistry { + return &listWatchFactoryRegistry{ + factories: make([]Factory, 0), + } +} + +func (e *listWatchFactoryRegistry) Register(factory Factory) { + e.factories = append(e.factories, factory) +} + +func (e *listWatchFactoryRegistry) GetListWatcherFactory(t enginecfg.Type) (Factory, error) { + for _, factory := range e.factories { + if factory.Support(t) { + return factory, nil + } + } + return nil, fmt.Errorf("engine type %s not supported", t) +} diff --git a/pkg/core/engine/subscriber/runtime_instance.go b/pkg/core/engine/subscriber/runtime_instance.go new file mode 100644 index 000000000..f4325e229 --- /dev/null +++ b/pkg/core/engine/subscriber/runtime_instance.go @@ -0,0 +1,328 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package subscriber + +import ( + "errors" + "reflect" + + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type RuntimeInstanceEventSubscriber struct { + instanceStore store.ResourceStore + eventEmitter events.Emitter +} + +func NewRuntimeInstanceEventSubscriber(instanceResourceStore store.ResourceStore, emitter events.Emitter) events.Subscriber { + return &RuntimeInstanceEventSubscriber{ + instanceStore: instanceResourceStore, + eventEmitter: emitter, + } +} + +func (s *RuntimeInstanceEventSubscriber) ResourceKind() coremodel.ResourceKind { + return meshresource.RuntimeInstanceKind +} + +func (s *RuntimeInstanceEventSubscriber) Name() string { + return "Engine-" + s.ResourceKind().ToString() +} + +func (s *RuntimeInstanceEventSubscriber) AsyncEnabled() bool { + return true +} + +func (s *RuntimeInstanceEventSubscriber) ProcessEvent(event events.Event) error { + newObj, ok := event.NewObj().(*meshresource.RuntimeInstanceResource) + if !ok && event.NewObj() != nil { + return bizerror.NewAssertionError(meshresource.RuntimeInstanceKind, reflect.TypeOf(event.NewObj()).Name()) + } + oldObj, ok := event.OldObj().(*meshresource.RuntimeInstanceResource) + if !ok && event.OldObj() != nil { + return bizerror.NewAssertionError(meshresource.RuntimeInstanceKind, reflect.TypeOf(event.OldObj()).Name()) + } + var processErr error + switch event.Type() { + case cache.Added, cache.Updated, cache.Replaced, cache.Sync: + if newObj == nil { + errStr := "process runtime instance upsert event, but new obj is nil, skipped processing" + logger.Error(errStr) + return errors.New(errStr) + } + processErr = s.processUpsert(newObj) + case cache.Deleted: + if oldObj == nil { + errStr := "process runtime instance delete event, but old obj is nil, skipped processing" + logger.Error(errStr) + return errors.New(errStr) + } + processErr = s.processDelete(oldObj) + } + if processErr != nil { + logger.Errorf("process runtime instance event failed, cause: %s event: %s", processErr.Error(), event.String()) + return processErr + } + logger.Infof("process runtime instance event successfully, event: %s", event.String()) + return nil +} + +// processUpsert when runtime instance added or updated, we should add/update the corresponding instance resource +func (s *RuntimeInstanceEventSubscriber) processUpsert(rtInstanceRes *meshresource.RuntimeInstanceResource) error { + instanceResource, err := s.getRelatedInstance(rtInstanceRes) + if err != nil { + return err + } + // if instance resource exists, that is to say the rpc instance exists in remote registry and has been watched by discovery. + // so we should merge the runtime info into it + if instanceResource != nil { + meshresource.MergeRuntimeInstanceIntoInstance(rtInstanceRes, instanceResource) + if err = s.instanceStore.Update(instanceResource); err != nil { + return err + } + logger.Infof("instance lifecycle merged runtime source, instance: %s, runtime: %s, deployState: %s, hasRPCSource: %t", + instanceResource.ResourceKey(), rtInstanceRes.ResourceKey(), instanceResource.Spec.DeployState, + meshresource.HasRPCInstanceSource(instanceResource)) + return nil + } + // if instance resource does not exist, that is to say the rpc instance does not exist in remote registry. + // we need to check whether the runtime instance resource is enough to create a new instance resource + if !checkAttributesEnough(rtInstanceRes) { + logger.Warnf("cannot identify runtime instance %s to a dubbo instance, skipped creating new instance, reason: %s", + rtInstanceRes.ResourceKey(), runtimeIdentityMissingReason(rtInstanceRes)) + return nil + } + // if conditions met, we should create a new instance resource by runtime instance + instanceRes := meshresource.FromRuntimeInstance(rtInstanceRes) + if err = s.instanceStore.Add(instanceRes); err != nil { + logger.Errorf("add instance resource failed, instance: %s, err: %s", instanceRes.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle created runtime-only instance, instance: %s, runtime: %s, deployState: %s", + instanceRes.ResourceKey(), rtInstanceRes.ResourceKey(), instanceRes.Spec.DeployState) + instanceAddEvent := events.NewResourceChangedEvent(cache.Added, nil, instanceRes) + s.eventEmitter.Send(instanceAddEvent) + logger.Debugf("runtime instance upsert trigger instance add event, event: %s", instanceAddEvent.String()) + return nil +} + +// processDelete when runtime instance deleted, we should delete the corresponding instance resource +func (s *RuntimeInstanceEventSubscriber) processDelete(rtInstanceRes *meshresource.RuntimeInstanceResource) error { + instanceResource, err := s.getRelatedInstance(rtInstanceRes) + if err != nil { + return err + } + if instanceResource == nil { + logger.Warnf("cannot find instance resource by runtime instance %s, skipped deleting instance", rtInstanceRes.ResourceKey()) + return nil + } + meshresource.ClearRuntimeInstanceFromInstance(instanceResource) + if meshresource.HasRPCInstanceSource(instanceResource) { + if err = s.instanceStore.Update(instanceResource); err != nil { + logger.Errorf("update instance resource failed after runtime delete, instance: %s, err: %s", + instanceResource.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle runtime source removed, keep instance by rpc source, instance: %s, runtime: %s, registerState: registered", + instanceResource.ResourceKey(), rtInstanceRes.ResourceKey()) + instanceUpdateEvent := events.NewResourceChangedEvent(cache.Updated, instanceResource, instanceResource) + s.eventEmitter.Send(instanceUpdateEvent) + logger.Debugf("runtime instance delete trigger instance update event, event: %s", instanceUpdateEvent.String()) + return nil + } + if err = s.instanceStore.Delete(instanceResource); err != nil { + logger.Errorf("delete instance resource failed, instance: %s, err: %s", instanceResource.ResourceKey(), err.Error()) + return err + } + logger.Infof("instance lifecycle runtime source removed and no rpc source remains, deleted instance: %s, runtime: %s", + instanceResource.ResourceKey(), rtInstanceRes.ResourceKey()) + instanceDeleteEvent := events.NewResourceChangedEvent(cache.Deleted, instanceResource, nil) + s.eventEmitter.Send(instanceDeleteEvent) + logger.Debugf("runtime instance delete trigger instance delete event, event: %s", instanceDeleteEvent.String()) + return nil +} + +func (s *RuntimeInstanceEventSubscriber) getRelatedInstance( + rtInstanceRes *meshresource.RuntimeInstanceResource) (*meshresource.InstanceResource, error) { + if rtInstanceRes == nil || rtInstanceRes.Spec == nil { + return nil, nil + } + switch rtInstanceRes.Spec.SourceEngineType { + case string(enginecfg.Kubernetes): + return s.getRelatedKubernetesInstance(rtInstanceRes) + default: + return s.getRelatedInstanceByName(rtInstanceRes) + } +} + +func (s *RuntimeInstanceEventSubscriber) getRelatedKubernetesInstance( + rtInstanceRes *meshresource.RuntimeInstanceResource) (*meshresource.InstanceResource, error) { + if rtInstanceRes == nil || rtInstanceRes.Spec == nil { + return nil, nil + } + if hasRuntimeIdentity(rtInstanceRes) { + instanceResName := meshresource.BuildInstanceResName(rtInstanceRes.Spec.AppName, rtInstanceRes.Spec.Ip, rtInstanceRes.Spec.RpcPort) + if strutil.IsNotBlank(rtInstanceRes.Mesh) && constants.DefaultMesh != rtInstanceRes.Mesh { + res, exists, err := s.instanceStore.GetByKey(coremodel.BuildResourceKey(rtInstanceRes.Mesh, instanceResName)) + if err != nil { + return nil, err + } + if exists { + instanceRes, ok := res.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError("InstanceResource", reflect.TypeOf(res).Name()) + } + return instanceRes, nil + } + } + instanceRes, err := s.getRelatedInstanceByName(rtInstanceRes) + if err != nil { + return nil, err + } + if instanceRes != nil { + return instanceRes, nil + } + } + return s.getRelatedInstanceByIP(rtInstanceRes) +} + +func (s *RuntimeInstanceEventSubscriber) getRelatedInstanceByName( + rtInstanceRes *meshresource.RuntimeInstanceResource) (*meshresource.InstanceResource, error) { + if rtInstanceRes.Spec == nil || strutil.IsBlank(rtInstanceRes.Spec.AppName) || + strutil.IsBlank(rtInstanceRes.Spec.Ip) || rtInstanceRes.Spec.RpcPort <= 0 { + return nil, nil + } + instanceResName := meshresource.BuildInstanceResName(rtInstanceRes.Spec.AppName, rtInstanceRes.Spec.Ip, rtInstanceRes.Spec.RpcPort) + resources, err := s.instanceStore.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByInstanceNameIndex, Value: instanceResName, Operator: index.Equals}, + }) + if err != nil { + return nil, err + } + if len(resources) == 0 { + return nil, nil + } + instanceResList := make([]*meshresource.InstanceResource, len(resources)) + filtered := make([]*meshresource.InstanceResource, 0, len(resources)) + for i, item := range resources { + res, ok := item.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError("InstanceResource", reflect.TypeOf(item).Name()) + } + instanceResList[i] = res + if strutil.IsBlank(rtInstanceRes.Mesh) || res.Mesh == rtInstanceRes.Mesh { + filtered = append(filtered, res) + } + } + if len(filtered) == 0 { + return nil, nil + } + if len(filtered) > 1 { + resKeys := slice.Map(filtered, func(index int, item *meshresource.InstanceResource) string { + return item.ResourceKey() + }) + logger.Warnf("there are more than two instances which have the same name, instance keys: %s, name: %s", resKeys, instanceResName) + return nil, nil + } + return filtered[0], nil +} + +func (s *RuntimeInstanceEventSubscriber) getRelatedInstanceByIP( + rtInstanceRes *meshresource.RuntimeInstanceResource) (*meshresource.InstanceResource, error) { + resources, err := s.instanceStore.ListByIndexes([]index.IndexCondition{ + {IndexName: index.ByInstanceIpIndex, Value: rtInstanceRes.Spec.Ip, Operator: index.Equals}, + }) + if err != nil { + return nil, err + } + if len(resources) == 0 { + return nil, nil + } + instanceResList := make([]*meshresource.InstanceResource, len(resources)) + for i, item := range resources { + res, ok := item.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError("InstanceResource", reflect.TypeOf(item).Name()) + } + instanceResList[i] = res + } + if len(instanceResList) > 1 { + resKeys := slice.Map(instanceResList, func(index int, item *meshresource.InstanceResource) string { + return item.ResourceKey() + }) + logger.Warnf("there are instances which have same ip, instance keys: %s, ip: %s", resKeys, rtInstanceRes.Spec.Ip) + return nil, nil + } + return instanceResList[0], nil +} + +func checkAttributesEnough(rtInstanceRes *meshresource.RuntimeInstanceResource) bool { + if rtInstanceRes.Spec == nil || strutil.IsBlank(rtInstanceRes.Spec.AppName) || + strutil.IsBlank(rtInstanceRes.Spec.Ip) || rtInstanceRes.Spec.RpcPort <= 0 || + strutil.IsBlank(rtInstanceRes.Mesh) || constants.DefaultMesh == rtInstanceRes.Mesh { + return false + } + return true +} + +func runtimeIdentityMissingReason(rtInstanceRes *meshresource.RuntimeInstanceResource) string { + if rtInstanceRes == nil { + return "runtime instance is nil" + } + if rtInstanceRes.Spec == nil { + return "runtime instance spec is nil" + } + if strutil.IsBlank(rtInstanceRes.Spec.AppName) { + return "appName is empty" + } + if strutil.IsBlank(rtInstanceRes.Spec.Ip) { + return "pod ip is empty" + } + if rtInstanceRes.Spec.RpcPort <= 0 { + return "rpcPort is not configured" + } + if strutil.IsBlank(rtInstanceRes.Mesh) { + return "mesh is empty" + } + if constants.DefaultMesh == rtInstanceRes.Mesh { + return "mesh is default, missing registry identifier" + } + return "unknown" +} + +func hasRuntimeIdentity(rtInstanceRes *meshresource.RuntimeInstanceResource) bool { + if rtInstanceRes == nil || rtInstanceRes.Spec == nil { + return false + } + return strutil.IsNotBlank(rtInstanceRes.Spec.AppName) && + strutil.IsNotBlank(rtInstanceRes.Spec.Ip) && + rtInstanceRes.Spec.RpcPort > 0 && + strutil.IsNotBlank(rtInstanceRes.Mesh) +} diff --git a/pkg/common/util/channels/closed.go b/pkg/core/events/async.go similarity index 77% rename from pkg/common/util/channels/closed.go rename to pkg/core/events/async.go index f687b72d1..9364aa414 100644 --- a/pkg/common/util/channels/closed.go +++ b/pkg/core/events/async.go @@ -15,14 +15,15 @@ * limitations under the License. */ -package channels +package events -// IsClosed checks if channel is closed by reading the value. It is useful for checking -func IsClosed[T any](ch <-chan T) bool { - select { - case <-ch: - return true - default: - } - return false +import "sync/atomic" + +type subscriberState struct { + subscriber Subscriber + async bool + ch chan Event + done chan struct{} + closed atomic.Bool + drainerStarted atomic.Bool } diff --git a/pkg/core/events/component.go b/pkg/core/events/component.go new file mode 100644 index 000000000..7592dbaa6 --- /dev/null +++ b/pkg/core/events/component.go @@ -0,0 +1,240 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package events + +import ( + "fmt" + "math" + "sync" + "sync/atomic" + + eventbusconfig "github.com/apache/dubbo-admin/pkg/config/eventbus" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" +) + +func init() { + runtime.RegisterComponent(&eventBus{}) +} + +type EventBusComponent interface { + EventBus + runtime.Component +} + +var _ EventBusComponent = &eventBus{} +var _ runtime.GracefulComponent = &eventBus{} + +type eventBus struct { + rwMutex sync.RWMutex + subscriberDir map[model.ResourceKind][]*subscriberState + bufferSize int + started atomic.Bool + stopped atomic.Bool + wg sync.WaitGroup +} + +func (b *eventBus) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{} // EventBus has no dependencies +} + +func (b *eventBus) Type() runtime.ComponentType { + return runtime.EventBus +} + +func (b *eventBus) Order() int { + return math.MaxInt +} + +func (b *eventBus) Init(ctx runtime.BuilderContext) error { + b.subscriberDir = make(map[model.ResourceKind][]*subscriberState) + if cfg := ctx.Config().EventBus; cfg != nil { + b.bufferSize = int(cfg.BufferSize) + } else { + b.bufferSize = int(eventbusconfig.Default().BufferSize) + } + return nil +} + +func (b *eventBus) Start(_ runtime.Runtime, _ <-chan struct{}) error { + if !b.started.CompareAndSwap(false, true) { + return fmt.Errorf("eventBus already started") + } + b.rwMutex.RLock() + for _, states := range b.subscriberDir { + for _, st := range states { + if st.async { + b.launchDrainer(st) + } + } + } + b.rwMutex.RUnlock() + return nil +} + +// Subscribe subscribes to a resource kind, ProcessEventFunc is synchronous which is used to avoid event loss +func (b *eventBus) Subscribe(subscriber Subscriber) error { + b.rwMutex.Lock() + defer b.rwMutex.Unlock() + if b.stopped.Load() { + return fmt.Errorf("eventBus already stopped") + } + rk := subscriber.ResourceKind() + states, exists := b.subscriberDir[rk] + if !exists { + states = make([]*subscriberState, 0) + } + // check name if is unique + for _, st := range states { + if st.subscriber.Name() == subscriber.Name() { + return fmt.Errorf("duplicated subscriber name %s, skipped subscribing", subscriber.Name()) + } + } + isAsync := false + if b.bufferSize > 0 { + if subscriber.AsyncEnabled() { + isAsync = true + } + } + state := &subscriberState{ + subscriber: subscriber, + async: isAsync, + } + if isAsync { + state.ch = make(chan Event, b.bufferSize) + state.done = make(chan struct{}) + } + b.subscriberDir[rk] = append(states, state) + if isAsync && b.started.Load() { + b.launchDrainer(state) + } + return nil +} + +func (b *eventBus) Unsubscribe(subscriber Subscriber) error { + var asyncState *subscriberState + var drainerRunning bool + + b.rwMutex.Lock() + rk := subscriber.ResourceKind() + name := subscriber.Name() + states, exists := b.subscriberDir[rk] + if !exists { + b.rwMutex.Unlock() + return fmt.Errorf("no subscriber for resource %s, skipped unsubscribing", rk) + } + found := false + for i, st := range states { + if st.subscriber.Name() == name { + b.subscriberDir[rk] = append(states[:i], states[i+1:]...) + if st.async && st.ch != nil { + st.closed.Store(true) + close(st.ch) + asyncState = st + drainerRunning = st.drainerStarted.Load() + } + found = true + break + } + } + b.rwMutex.Unlock() + if !found { + return fmt.Errorf("no subscriber named %s for resource %s, skipped unsubscribing", name, rk) + } + if asyncState != nil && drainerRunning { + <-asyncState.done + } + return nil +} + +func (b *eventBus) Send(event Event) { + if b.stopped.Load() { + return + } + + b.rwMutex.RLock() + defer b.rwMutex.RUnlock() + var rk model.ResourceKind + if event.NewObj() != nil { + rk = event.NewObj().ResourceKind() + } else if event.OldObj() != nil { + rk = event.OldObj().ResourceKind() + } + states, exists := b.subscriberDir[rk] + if !exists { + logger.Infof("no subscriber for resource %s, skipped sending event%v", rk, event) + return + } + for _, st := range states { + if st.async && !st.closed.Load() { + select { + case st.ch <- event: + default: + logger.Warnf("async subscriber %s channel full (cap=%d), event dropped: %v", + st.subscriber.Name(), cap(st.ch), event) + } + continue + } + if !st.async { + // TODO Do we need to support reprocess + if err := st.subscriber.ProcessEvent(event); err != nil { + logger.Errorf("failed to process event in %s, cause: %s, event: %v", + st.subscriber.Name(), err.Error(), event) + } + } + } +} + +func (b *eventBus) WaitForDone() { + b.stopped.Store(true) + + b.rwMutex.Lock() + for _, states := range b.subscriberDir { + for _, st := range states { + if st.async && st.ch != nil && !st.closed.Load() { + st.closed.Store(true) + close(st.ch) + } + } + } + b.rwMutex.Unlock() + + b.wg.Wait() +} + +func (b *eventBus) launchDrainer(st *subscriberState) { + if b.stopped.Load() { + return + } + if !st.drainerStarted.CompareAndSwap(false, true) { + return + } + + b.wg.Add(1) + go func() { + defer b.wg.Done() + defer close(st.done) + for event := range st.ch { + if err := st.subscriber.ProcessEvent(event); err != nil { + logger.Errorf("async: failed to process event in %s, cause: %s, event: %v", + st.subscriber.Name(), err.Error(), event) + } + } + }() +} diff --git a/pkg/core/events/enventbus_test.go b/pkg/core/events/enventbus_test.go deleted file mode 100644 index 9146d6f0b..000000000 --- a/pkg/core/events/enventbus_test.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package events_test - -import ( - . "github.com/onsi/ginkgo/v2" - - . "github.com/onsi/gomega" - - "github.com/apache/dubbo-admin/pkg/core/events" -) - -var _ = Describe("EventBus", func() { - chHadEvent := func(ch <-chan events.Event) bool { - select { - case <-ch: - return true - default: - return false - } - } - - It("should not block on Send", func() { - // given - eventBus, err := events.NewEventBus(1) - Expect(err).ToNot(HaveOccurred()) - listener := eventBus.Subscribe() - event1 := events.ResourceChangedEvent{TenantID: "1"} - event2 := events.ResourceChangedEvent{TenantID: "2"} - - // when - eventBus.Send(event1) - eventBus.Send(event2) - - // then - event := <-listener.Recv() - Expect(event).To(Equal(event1)) - - // and second event was ignored because buffer was full - Expect(chHadEvent(listener.Recv())).To(BeFalse()) - }) - - It("should only send events matched predicate", func() { - // given - eventBus, err := events.NewEventBus(10) - Expect(err).ToNot(HaveOccurred()) - listener := eventBus.Subscribe(func(event events.Event) bool { - return event.(events.ResourceChangedEvent).TenantID == "1" - }) - event1 := events.ResourceChangedEvent{TenantID: "1"} - event2 := events.ResourceChangedEvent{TenantID: "2"} - - // when - eventBus.Send(event1) - eventBus.Send(event2) - - // then - event := <-listener.Recv() - Expect(event).To(Equal(event1)) - - // and second event was ignored, because it did not match predicate - Expect(chHadEvent(listener.Recv())).To(BeFalse()) - }) -}) diff --git a/pkg/core/events/eventbus.go b/pkg/core/events/eventbus.go index 7111f5352..51393c4d2 100644 --- a/pkg/core/events/eventbus.go +++ b/pkg/core/events/eventbus.go @@ -18,86 +18,106 @@ package events import ( - "sync" + "fmt" - "github.com/apache/dubbo-admin/pkg/core" -) + "github.com/duke-git/lancet/v2/convertor" + "k8s.io/client-go/tools/cache" -var log = core.Log.WithName("eventbus") + "github.com/apache/dubbo-admin/pkg/core/resource/model" +) -type subscriber struct { - ch chan Event - predicates []Predicate +type Event interface { + // Type returns the type of the event, see definitions in cache.DeltaType + Type() cache.DeltaType + // OldObj returns the old object, nil if old object doesn't exist in store + OldObj() model.Resource + // NewObj returns the new object, nil if event type is in [cache.Deleted] + NewObj() model.Resource + // Context returns the context of the event, if event provider want to pass extra info to the consumer, just use context + Context() map[string]string + // String returns the string representation of the event + String() string } -func NewEventBus(bufferSize uint) (EventBus, error) { - return &eventBus{ - subscribers: map[string]subscriber{}, - bufferSize: bufferSize, - }, nil +type Subscriber interface { + ResourceKind() model.ResourceKind + + Name() string + + ProcessEvent(event Event) error + + // AsyncEnabled controls whether this subscriber should be dispatched asynchronously. + // + // Return true when the subscriber may execute relatively slow logic and should not + // block EventBus.Send(). In async mode, EventBus enqueues events into a buffered + // channel and processes them in a dedicated drainer goroutine. + // + // Async dispatch is best-effort: when the subscriber queue is full, new events are + // dropped with a warning log. + AsyncEnabled() bool } -type eventBus struct { - mtx sync.RWMutex - subscribers map[string]subscriber - bufferSize uint +type Subscribers []Subscriber + +type ResourceChangedEvent struct { + typ cache.DeltaType + oldObj model.Resource + newObj model.Resource + context map[string]string } -// Subscribe subscribes to a stream of events given Predicates -// Predicate should not block on I/O, otherwise the whole event bus can block. -// All predicates must pass for the event to enqueued. -func (b *eventBus) Subscribe(predicates ...Predicate) Listener { - id := core.NewUUID() - b.mtx.Lock() - defer b.mtx.Unlock() - - events := make(chan Event, b.bufferSize) - b.subscribers[id] = subscriber{ - ch: events, - predicates: predicates, - } - return &reader{ - events: events, - close: func() { - b.mtx.Lock() - defer b.mtx.Unlock() - delete(b.subscribers, id) - }, +var _ Event = &ResourceChangedEvent{} + +func NewResourceChangedEvent(typ cache.DeltaType, oldObj model.Resource, newObj model.Resource) *ResourceChangedEvent { + return &ResourceChangedEvent{ + typ: typ, + oldObj: oldObj, + newObj: newObj, + context: map[string]string{}, } } -func (b *eventBus) Send(event Event) { - b.mtx.RLock() - defer b.mtx.RUnlock() - for _, sub := range b.subscribers { - matched := true - for _, predicate := range sub.predicates { - if !predicate(event) { - matched = false - } - } - if matched { - select { - case sub.ch <- event: - default: - log.Info("[WARNING] event is not sent because the channel is full. Ignoring event. Consider increasing buffer size using dubbo_EVENT_BUS_BUFFER_SIZE", - "bufferSize", b.bufferSize, - "event", event, - ) - } - } +func NewResourceChangedEventWithContext(typ cache.DeltaType, oldObj model.Resource, + newObj model.Resource, ctx map[string]string) *ResourceChangedEvent { + return &ResourceChangedEvent{ + typ: typ, + oldObj: oldObj, + newObj: newObj, + context: ctx, } } -type reader struct { - events chan Event - close func() +func (e *ResourceChangedEvent) Type() cache.DeltaType { + return e.typ +} + +func (e *ResourceChangedEvent) OldObj() model.Resource { + return e.oldObj +} + +func (e *ResourceChangedEvent) NewObj() model.Resource { + return e.newObj +} + +func (e *ResourceChangedEvent) Context() map[string]string { + return e.context +} + +func (e *ResourceChangedEvent) String() string { + return fmt.Sprintf("\n[type]: %s, \n[oldObj]: %s, \n[newObj]: %s", + e.typ, convertor.ToString(e.oldObj), convertor.ToString(e.newObj)) +} + +type Emitter interface { + Send(event Event) } -func (k *reader) Recv() <-chan Event { - return k.events +type SubscriptionManager interface { + Subscribe(subscriber Subscriber) error + Unsubscribe(subscriber Subscriber) error } -func (k *reader) Close() { - k.close() +type EventBus interface { + Emitter + SubscriptionManager } diff --git a/pkg/core/governor/component.go b/pkg/core/governor/component.go new file mode 100644 index 000000000..323cba04b --- /dev/null +++ b/pkg/core/governor/component.go @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package governor + +import ( + "fmt" + "math" + "reflect" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +func init() { + runtime.RegisterComponent(newGovernorComponent()) +} + +type Router interface { + ResourceRoute(r coremodel.Resource) (RuleGovernor, error) + ResourceMeshRoute(mesh string) (RuleGovernor, error) +} + +type Component interface { + runtime.Component + Router +} + +var _ Component = &ruleGovernorComponent{} + +type ruleGovernorComponent struct { + configs []*discovery.Config + governors map[string]RuleGovernor +} + +func newGovernorComponent() Component { + return &ruleGovernorComponent{ + governors: make(map[string]RuleGovernor), + } +} + +func (g *ruleGovernorComponent) Type() runtime.ComponentType { + return runtime.RuleGovernor +} + +func (g *ruleGovernorComponent) Order() int { + return math.MaxInt - 2 +} + +func (g *ruleGovernorComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.EventBus, + runtime.ResourceStore, + } +} +func (g *ruleGovernorComponent) Init(ctx runtime.BuilderContext) error { + eventBusComponent, err := ctx.GetActivatedComponent(runtime.EventBus) + if err != nil { + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("can not retrieve event bus from runtime in discovery, %s", err)) + } + eventBus, ok := eventBusComponent.(events.EventBus) + if !ok { + return bizerror.NewAssertionError("EventBus", reflect.TypeOf(eventBusComponent).Name()) + } + + storeComponent, err := ctx.GetActivatedComponent(runtime.ResourceStore) + if err != nil { + return bizerror.New(bizerror.UnknownError, + fmt.Sprintf("can not retrieve store from runtime in discovery, %s", err)) + } + storeRouter, ok := storeComponent.(store.Router) + if !ok { + return bizerror.NewAssertionError("store.Router", reflect.TypeOf(storeComponent).Name()) + } + g.configs = ctx.Config().Discovery + for _, cfg := range g.configs { + factory, err := FactoryRegistry().GetGovernorFactory(cfg.Type) + if err != nil { + return err + } + governor, err := factory.New(cfg.ID, cfg, storeRouter, eventBus) + if err != nil { + return err + } + g.governors[cfg.ID] = governor + } + return nil +} + +func (g *ruleGovernorComponent) Start(_ runtime.Runtime, _ <-chan struct{}) error { + return nil +} + +func (g *ruleGovernorComponent) ResourceRoute(r coremodel.Resource) (RuleGovernor, error) { + return g.ResourceMeshRoute(r.ResourceMesh()) +} + +func (g *ruleGovernorComponent) ResourceMeshRoute(mesh string) (RuleGovernor, error) { + if governor, exists := g.governors[mesh]; exists { + return governor, nil + } + return nil, bizerror.New(bizerror.GovernorError, fmt.Sprintf("mesh %s not found for governor", mesh)) +} diff --git a/pkg/core/governor/factory.go b/pkg/core/governor/factory.go new file mode 100644 index 000000000..75364546e --- /dev/null +++ b/pkg/core/governor/factory.go @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package governor + +import ( + "fmt" + + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +var factoryRegistry = newGovernorFactoryRegistry() + +func RegisterFactory(f Factory) { + factoryRegistry.Register(f) +} + +func FactoryRegistry() Registry { + return factoryRegistry +} + +// Factory is the interface for create a specific type of RuleGovernor +type Factory interface { + // Support returns true if the factory supports the given type in config + Support(t discoverycfg.Type) bool + // New returns a new RuleGovernor for the mesh using the given config and other components + New(mesh string, config *discoverycfg.Config, router store.Router, emitter events.Emitter) (RuleGovernor, error) +} + +type Registry interface { + GetGovernorFactory(discoverycfg.Type) (Factory, error) +} + +type RegistryMutator interface { + // Register registers a new factory + Register(Factory) +} + +type MutableRegistry interface { + Registry + RegistryMutator +} + +var _ MutableRegistry = &governorFactoryRegistry{} + +type governorFactoryRegistry struct { + factories []Factory +} + +func newGovernorFactoryRegistry() MutableRegistry { + return &governorFactoryRegistry{ + factories: make([]Factory, 0), + } +} + +func (g *governorFactoryRegistry) GetGovernorFactory(t discoverycfg.Type) (Factory, error) { + for _, factory := range g.factories { + if factory.Support(t) { + return factory, nil + } + } + return nil, fmt.Errorf("governor type %s not supported", t) +} + +func (g *governorFactoryRegistry) Register(factory Factory) { + g.factories = append(g.factories, factory) +} diff --git a/pkg/core/governor/governor.go b/pkg/core/governor/governor.go new file mode 100644 index 000000000..d29fd156a --- /dev/null +++ b/pkg/core/governor/governor.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package governor + +import ( + set "github.com/duke-git/lancet/v2/datastructure/set" + + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +var RuleResourceKinds = set.New(meshresource.DynamicConfigKind, meshresource.ConditionRouteKind, meshresource.TagRouteKind) + +// RuleGovernor makes the rule operations effective +type RuleGovernor interface { + // CreateRule creates a resource in the registry + CreateRule(model.Resource) error + // UpdateRule updates a resource in the registry + UpdateRule(model.Resource) error + // DeleteRule deletes a resource from the registry + DeleteRule(model.Resource) error +} diff --git a/pkg/common/util/xds/metric_sanitizer.go b/pkg/core/leader/db_source.go similarity index 64% rename from pkg/common/util/xds/metric_sanitizer.go rename to pkg/core/leader/db_source.go index 7cabf8e14..66d37146b 100644 --- a/pkg/common/util/xds/metric_sanitizer.go +++ b/pkg/core/leader/db_source.go @@ -15,17 +15,14 @@ * limitations under the License. */ -package xds +package leader -import ( - "regexp" -) +import "gorm.io/gorm" -var illegalChars = regexp.MustCompile(`[^a-zA-Z_\-0-9]`) - -// We need to sanitize metrics in order to not break statsd and prometheus format. -// StatsD only allow [a-zA-Z_\-0-9.] characters, everything else is removed -// Extra dots breaks many regexes that converts statsd metric to prometheus one with tags -func SanitizeMetric(metric string) string { - return illegalChars.ReplaceAllString(metric, "_") +// DBSource is an interface for components that provide access to a database connection +// Used by leader election to access the shared database for leader lease management +type DBSource interface { + // GetDB returns the shared database connection and a boolean indicating if a DB is available + // Returns (db, true) if the component is backed by a database, (nil, false) otherwise + GetDB() (*gorm.DB, bool) } diff --git a/pkg/core/leader/leader.go b/pkg/core/leader/leader.go new file mode 100644 index 000000000..e6f831475 --- /dev/null +++ b/pkg/core/leader/leader.go @@ -0,0 +1,285 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package leader + +import ( + "context" + "fmt" + "os" + "sync/atomic" + "time" + + "github.com/google/uuid" + "gorm.io/gorm" + + "github.com/apache/dubbo-admin/pkg/core/logger" +) + +const ( + // DefaultLeaseDuration is the default duration for a leader lease + DefaultLeaseDuration = 30 * time.Second + // DefaultRenewInterval is the default interval for renewing the lease + DefaultRenewInterval = 10 * time.Second + // DefaultAcquireRetryInterval is the default retry interval for acquiring leadership + DefaultAcquireRetryInterval = 5 * time.Second +) + +// LeaderElection manages leader election for distributed components +// It uses database-based optimistic locking to ensure only one replica holds the lease at any time +type LeaderElection struct { + db *gorm.DB + component string + holderID string + leaseDuration time.Duration + renewInterval time.Duration + acquireRetry time.Duration + isLeader atomic.Bool + currentVersion int64 + stopCh chan struct{} +} + +// Option is a functional option for configuring LeaderElection +type Option func(*LeaderElection) + +// WithLeaseDuration sets the lease duration +func WithLeaseDuration(d time.Duration) Option { + return func(le *LeaderElection) { + le.leaseDuration = d + } +} + +// WithRenewInterval sets the renewal interval +func WithRenewInterval(d time.Duration) Option { + return func(le *LeaderElection) { + le.renewInterval = d + } +} + +// WithAcquireRetryInterval sets the acquisition retry interval +func WithAcquireRetryInterval(d time.Duration) Option { + return func(le *LeaderElection) { + le.acquireRetry = d + } +} + +// NewLeaderElection creates a new LeaderElection instance +func NewLeaderElection(db *gorm.DB, component, holderID string, opts ...Option) *LeaderElection { + le := &LeaderElection{ + db: db, + component: component, + holderID: holderID, + leaseDuration: DefaultLeaseDuration, + renewInterval: DefaultRenewInterval, + acquireRetry: DefaultAcquireRetryInterval, + stopCh: make(chan struct{}), + } + + for _, opt := range opts { + opt(le) + } + + return le +} + +// EnsureTable creates the leader_leases table if it doesn't exist +// This is idempotent and can be called multiple times +func (le *LeaderElection) EnsureTable() error { + return le.db.AutoMigrate(&LeaderLease{}) +} + +// TryAcquire attempts to acquire the leader lease from an expired holder. +// It only competes for leases that have already expired and does NOT renew an +// existing self-held lease — use Renew for that. +// Returns true if the current holder successfully acquired the lease. +func (le *LeaderElection) TryAcquire(ctx context.Context) bool { + now := time.Now() + expiresAt := now.Add(le.leaseDuration) + + // Only take over an expired lease; never pre-empt an active holder. + result := le.db.WithContext(ctx).Model(&LeaderLease{}). + Where("component = ? AND expires_at < ?", le.component, now). + Updates(map[string]interface{}{ + "holder_id": le.holderID, + "acquired_at": now, + "expires_at": expiresAt, + "version": gorm.Expr("version + 1"), + }) + + if result.Error != nil { + logger.Warnf("leader election: failed to update lease for component %s: %v", le.component, result.Error) + le.isLeader.Store(false) + return false + } + + // If the update succeeded (found a row to update) + if result.RowsAffected > 0 { + // Fetch the updated version + var lease LeaderLease + err := le.db.WithContext(ctx). + Where("component = ?", le.component). + First(&lease).Error + if err != nil { + logger.Warnf("leader election: failed to read back updated lease for component %s: %v", le.component, err) + le.isLeader.Store(false) + return false + } + le.currentVersion = lease.Version + le.isLeader.Store(true) + return true + } + + // No row was updated, try to insert a new record (lease doesn't exist) + result = le.db.WithContext(ctx).Create(&LeaderLease{ + Component: le.component, + HolderID: le.holderID, + AcquiredAt: now, + ExpiresAt: expiresAt, + Version: 1, + }) + + if result.Error != nil { + // If insertion fails, it means another replica just created it + // This is expected in concurrent scenarios + logger.Debugf("leader election: failed to insert lease for component %s (probably created by another replica): %v", le.component, result.Error) + le.isLeader.Store(false) + return false + } + + le.currentVersion = 1 + le.isLeader.Store(true) + return true +} + +// Renew attempts to renew the current leader lease +// Returns true if the renewal was successful +func (le *LeaderElection) Renew(ctx context.Context) bool { + if !le.isLeader.Load() { + return false + } + + now := time.Now() + expiresAt := now.Add(le.leaseDuration) + + result := le.db.WithContext(ctx).Model(&LeaderLease{}). + Where("component = ? AND holder_id = ? AND version = ?", le.component, le.holderID, le.currentVersion). + Updates(map[string]interface{}{ + "acquired_at": now, + "expires_at": expiresAt, + "version": gorm.Expr("version + 1"), + }) + + if result.Error != nil { + logger.Warnf("leader election: failed to renew lease for component %s: %v", le.component, result.Error) + le.isLeader.Store(false) + return false + } + + if result.RowsAffected > 0 { + le.currentVersion++ + return true + } + + // Lease was lost (likely held by another replica now) + logger.Warnf("leader election: lost leader lease for component %s (renewal failed, version mismatch)", le.component) + le.isLeader.Store(false) + return false +} + +// Release releases the leader lease for this holder +// This should be called when the holder voluntarily gives up leadership +func (le *LeaderElection) Release(ctx context.Context) { + le.isLeader.Store(false) + + expiresAt := time.Now().Add(-1 * time.Second) // Immediately expire the lease + + result := le.db.WithContext(ctx).Model(&LeaderLease{}). + Where("component = ? AND holder_id = ?", le.component, le.holderID). + Update("expires_at", expiresAt) + + if result.Error != nil { + logger.Warnf("leader election: failed to release lease for component %s: %v", le.component, result.Error) + } +} + +// IsLeader returns true if this holder currently holds the leader lease +func (le *LeaderElection) IsLeader() bool { + return le.isLeader.Load() +} + +// RunLeaderElection runs the leader election loop +// It blocks and runs onStartLeading/onStopLeading callbacks as leadership changes +// This is designed to be run in a separate goroutine +func (le *LeaderElection) RunLeaderElection(ctx context.Context, stopCh <-chan struct{}, + onStartLeading func(), onStopLeading func()) { + + ticker := time.NewTicker(le.acquireRetry) + defer ticker.Stop() + + renewTicker := time.NewTicker(le.renewInterval) + defer renewTicker.Stop() + renewTicker.Stop() // Don't start renewal ticker yet + + isLeader := false + + for { + select { + case <-ctx.Done(): + if isLeader { + le.Release(context.Background()) + onStopLeading() + } + return + case <-stopCh: + if isLeader { + le.Release(context.Background()) + onStopLeading() + } + return + case <-ticker.C: + // Try to acquire leadership if not already leader + if !isLeader { + if le.TryAcquire(ctx) { + logger.Infof("leader election: component %s acquired leadership (holder: %s)", le.component, le.holderID) + isLeader = true + renewTicker.Reset(le.renewInterval) + onStartLeading() + } + } + case <-renewTicker.C: + // Renew leadership if currently leader + if isLeader { + if !le.Renew(ctx) { + logger.Warnf("leader election: component %s lost leadership (holder: %s)", le.component, le.holderID) + isLeader = false + renewTicker.Stop() + ticker.Reset(le.acquireRetry) + onStopLeading() + } + } + } + } +} + +// GenerateHolderID generates a unique holder ID combining hostname and UUID +func GenerateHolderID() (string, error) { + hostname, err := os.Hostname() + if err != nil { + hostname = "unknown" + } + return fmt.Sprintf("%s-%s", hostname, uuid.New().String()), nil +} diff --git a/pkg/core/leader/leader_test.go b/pkg/core/leader/leader_test.go new file mode 100644 index 000000000..525a1bb23 --- /dev/null +++ b/pkg/core/leader/leader_test.go @@ -0,0 +1,202 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package leader + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +// setupTestDB creates an in-memory SQLite database for testing +func setupTestDB(t *testing.T) *gorm.DB { + db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) + require.NoError(t, err) + return db +} + +func TestLeaderElection_EnsureTable(t *testing.T) { + db := setupTestDB(t) + le := NewLeaderElection(db, "test-component", "holder-1") + + err := le.EnsureTable() + assert.NoError(t, err) + + // Verify the table exists by creating another instance and checking again + err = le.EnsureTable() + assert.NoError(t, err) +} + +func TestLeaderElection_TryAcquire(t *testing.T) { + db := setupTestDB(t) + le := NewLeaderElection(db, "test-component", "holder-1") + err := le.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // First attempt should succeed (no lease exists) + acquired := le.TryAcquire(ctx) + assert.True(t, acquired) + assert.True(t, le.IsLeader()) + + // Verify the lease was created + var lease LeaderLease + result := db.Where("component = ?", "test-component").First(&lease) + assert.NoError(t, result.Error) + assert.Equal(t, "holder-1", lease.HolderID) +} + +func TestLeaderElection_TryAcquire_AlreadyHeld(t *testing.T) { + db := setupTestDB(t) + le1 := NewLeaderElection(db, "test-component", "holder-1") + le2 := NewLeaderElection(db, "test-component", "holder-2") + + err := le1.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // First holder acquires + acquired := le1.TryAcquire(ctx) + assert.True(t, acquired) + + // Second holder tries to acquire (should fail because lease is not expired) + acquired = le2.TryAcquire(ctx) + assert.False(t, acquired) + assert.False(t, le2.IsLeader()) +} + +func TestLeaderElection_Renew(t *testing.T) { + db := setupTestDB(t) + le := NewLeaderElection(db, "test-component", "holder-1", + WithLeaseDuration(1*time.Second), + WithRenewInterval(500*time.Millisecond)) + + err := le.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // Acquire the lease first + acquired := le.TryAcquire(ctx) + assert.True(t, acquired) + + oldVersion := le.currentVersion + + // Renew should succeed + renewed := le.Renew(ctx) + assert.True(t, renewed) + assert.Greater(t, le.currentVersion, oldVersion) + + // Verify the lease was updated + var lease LeaderLease + result := db.Where("component = ?", "test-component").First(&lease) + assert.NoError(t, result.Error) + assert.Greater(t, lease.Version, int64(1)) +} + +func TestLeaderElection_Release(t *testing.T) { + db := setupTestDB(t) + le := NewLeaderElection(db, "test-component", "holder-1") + err := le.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // Acquire the lease + acquired := le.TryAcquire(ctx) + assert.True(t, acquired) + + // Release it + le.Release(ctx) + assert.False(t, le.IsLeader()) + + // Verify the lease has expired + var lease LeaderLease + result := db.Where("component = ?", "test-component").First(&lease) + assert.NoError(t, result.Error) + assert.True(t, lease.ExpiresAt.Before(time.Now())) +} + +func TestLeaderElection_Failover(t *testing.T) { + db := setupTestDB(t) + le1 := NewLeaderElection(db, "test-component", "holder-1", + WithLeaseDuration(100*time.Millisecond)) + le2 := NewLeaderElection(db, "test-component", "holder-2", + WithLeaseDuration(100*time.Millisecond)) + + err := le1.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // First holder acquires + acquired := le1.TryAcquire(ctx) + assert.True(t, acquired) + + // Second holder cannot acquire yet + acquired = le2.TryAcquire(ctx) + assert.False(t, acquired) + + // Wait for lease to expire + time.Sleep(150 * time.Millisecond) + + // Now second holder should be able to acquire + acquired = le2.TryAcquire(ctx) + assert.True(t, acquired) + assert.True(t, le2.IsLeader()) +} + +func TestGenerateHolderID(t *testing.T) { + id1, err := GenerateHolderID() + assert.NoError(t, err) + assert.NotEmpty(t, id1) + + id2, err := GenerateHolderID() + assert.NoError(t, err) + assert.NotEmpty(t, id2) + + // IDs should be different (due to UUID) + assert.NotEqual(t, id1, id2) +} + +func TestLeaderElection_IsLeader(t *testing.T) { + db := setupTestDB(t) + le := NewLeaderElection(db, "test-component", "holder-1") + err := le.EnsureTable() + require.NoError(t, err) + + ctx := context.Background() + + // Initially not leader + assert.False(t, le.IsLeader()) + + // After acquiring, should be leader + le.TryAcquire(ctx) + assert.True(t, le.IsLeader()) + + // After releasing, should not be leader + le.Release(ctx) + assert.False(t, le.IsLeader()) +} diff --git a/pkg/core/leader/model.go b/pkg/core/leader/model.go new file mode 100644 index 000000000..a6180955a --- /dev/null +++ b/pkg/core/leader/model.go @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package leader + +import "time" + +// LeaderLease is the GORM model for the leader_leases table +// It uses optimistic locking via the Version field to ensure atomic leader elections +type LeaderLease struct { + ID uint `gorm:"primaryKey;autoIncrement"` + Component string `gorm:"uniqueIndex;size:64;not null"` + HolderID string `gorm:"size:255;not null"` + AcquiredAt time.Time `gorm:"not null"` + ExpiresAt time.Time `gorm:"not null"` + Version int64 `gorm:"not null;default:0"` +} + +// TableName returns the table name for LeaderLease +func (LeaderLease) TableName() string { + return "leader_leases" +} diff --git a/pkg/core/lock/component.go b/pkg/core/lock/component.go new file mode 100644 index 000000000..11814d28a --- /dev/null +++ b/pkg/core/lock/component.go @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lock + +import ( + "context" + "math" + "time" + + "github.com/pkg/errors" + + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/runtime" +) + +func init() { + runtime.RegisterComponent(NewComponent()) +} + +const ( + // DistributedLockComponent is the component type for distributed lock + DistributedLockComponent runtime.ComponentType = "distributed lock" +) + +// Component implements the runtime.Component interface for distributed lock +type Component struct { + lock Lock +} + +// NewComponent creates a new distributed lock component +func NewComponent() *Component { + return &Component{} +} + +// Type returns the component type +func (c *Component) Type() runtime.ComponentType { + return DistributedLockComponent +} + +// Order indicates the initialization order +// Lock should be initialized after Store (Order math.MaxInt - 1) +// Higher order values are initialized first, so we use math.MaxInt - 2 +func (c *Component) Order() int { + return math.MaxInt - 2 // After Store, before other services +} + +// Init initializes the distributed lock component +func (c *Component) Init(ctx runtime.BuilderContext) error { + factory, err := LockFactoryRegistry().GetSupportedFactory(ctx) + if err != nil { + // No supporting factory found + logger.Warnf("No supported lock factory found: %v", err) + logger.Warn("Distributed lock will not be available") + return nil + } + + // Lock created using a factory + lock, err := factory.NewLock(ctx) + if err != nil { + return errors.Wrap(err, "failed to create distributed lock") + } + + c.lock = lock + logger.Info("Distributed lock component initialized successfully") + return nil +} + +// Start starts the distributed lock component +func (c *Component) Start(rt runtime.Runtime, stop <-chan struct{}) error { + if c.lock == nil { + logger.Warn("Distributed lock not available, skipping") + return nil + } + + // Start background cleanup task + ticker := time.NewTicker(constants.DefaultCleanupInterval) // Cleanup every 5 minutes + defer ticker.Stop() + + for { + select { + case <-stop: + return nil + case <-ticker.C: + ctx, cancel := context.WithTimeout(context.Background(), constants.DefaultCleanupTimeout) + if err := c.lock.CleanupExpiredLocks(ctx); err != nil { + logger.Errorf("Failed to cleanup expired locks: %v", err) + } + cancel() + } + } +} + +// GetLock returns the lock instance +func (c *Component) GetLock() Lock { + return c.lock +} + +// GetLockFromRuntime extracts the lock instance from runtime +func GetLockFromRuntime(rt runtime.Runtime) (Lock, error) { + comp, err := rt.GetComponent(DistributedLockComponent) + if err != nil { + return nil, err + } + + lockComp, ok := comp.(*Component) + if !ok { + return nil, errors.Errorf("component %s is not a valid lock component", DistributedLockComponent) + } + + if lockComp.lock == nil { + return nil, errors.New("distributed lock is not available (possibly using memory store)") + } + + return lockComp.GetLock(), nil +} + +func (c *Component) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.ResourceStore, + } +} diff --git a/pkg/core/lock/factory.go b/pkg/core/lock/factory.go new file mode 100644 index 000000000..afa38d8d9 --- /dev/null +++ b/pkg/core/lock/factory.go @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lock + +import ( + "fmt" + "github.com/apache/dubbo-admin/pkg/core/runtime" +) + +var registry = newLockFactoryRegistry() + +// RegisterLockFactory registers a Lock factory +func RegisterLockFactory(f Factory) { + registry.Register(f) +} + +// LockFactoryRegistry returns the global factory registry +func LockFactoryRegistry() Registry { + return registry +} + +// Factory defines the factory interface for creating Locks +type Factory interface { + // Support determines whether the factory supports creating a Lock from a given context + // Determines this by inspecting the components in the context + Support(ctx runtime.BuilderContext) bool + + // NewLock creates a Lock instance from the BuilderContext + // The factory decides for itself how to extract dependencies from the context + NewLock(ctx runtime.BuilderContext) (Lock, error) +} + +// Registry defines the query interface for the factory registry +type Registry interface { + // GetSupportedFactory returns the first supported factory + GetSupportedFactory(ctx runtime.BuilderContext) (Factory, error) + // GetAllSupportedFactories returns all supported factories + GetAllSupportedFactories(ctx runtime.BuilderContext) []Factory +} + +// RegistryMutator defines the interface for modifying the factory registry +type RegistryMutator interface { + Register(Factory) +} + +// MutableRegistry combines query and modification interfaces +type MutableRegistry interface { + Registry + RegistryMutator +} + +var _ MutableRegistry = &lockFactoryRegistry{} + +type lockFactoryRegistry struct { + factories []Factory +} + +func newLockFactoryRegistry() MutableRegistry { + return &lockFactoryRegistry{ + factories: make([]Factory, 0), + } +} + +func (r *lockFactoryRegistry) GetSupportedFactory(ctx runtime.BuilderContext) (Factory, error) { + for _, factory := range r.factories { + if factory.Support(ctx) { + return factory, nil + } + } + return nil, fmt.Errorf("no supported lock factory found") +} + +func (r *lockFactoryRegistry) GetAllSupportedFactories(ctx runtime.BuilderContext) []Factory { + supported := make([]Factory, 0) + for _, factory := range r.factories { + if factory.Support(ctx) { + supported = append(supported, factory) + } + } + return supported +} + +func (r *lockFactoryRegistry) Register(factory Factory) { + r.factories = append(r.factories, factory) +} diff --git a/pkg/core/lock/key.go b/pkg/core/lock/key.go new file mode 100644 index 000000000..29994e0b8 --- /dev/null +++ b/pkg/core/lock/key.go @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lock + +import ( + "fmt" + + "github.com/apache/dubbo-admin/pkg/common/constants" +) + +// BuildLockKey constructs a lock key from a prefix and parts +func BuildLockKey(prefix string, parts ...string) string { + key := prefix + for _, part := range parts { + key += ":" + part + } + return key +} + +// BuildTagRouteLockKey constructs a lock key for tag route operations +func BuildTagRouteLockKey(mesh, name string) string { + return fmt.Sprintf("%s:%s:%s", constants.TagRouteKeyPrefix, mesh, name) +} + +// BuildConfiguratorRuleLockKey constructs a lock key for configurator rule operations +func BuildConfiguratorRuleLockKey(mesh, name string) string { + return fmt.Sprintf("%s:%s:%s", constants.ConfiguratorRuleKeyPrefix, mesh, name) +} + +// BuildConditionRuleLockKey constructs a lock key for condition rule operations +func BuildConditionRuleLockKey(mesh, name string) string { + return fmt.Sprintf("%s:%s:%s", constants.ConditionRuleKeyPrefix, mesh, name) +} diff --git a/pkg/core/lock/lock.go b/pkg/core/lock/lock.go new file mode 100644 index 000000000..4b3bd781c --- /dev/null +++ b/pkg/core/lock/lock.go @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lock + +import ( + "context" + "time" +) + +// Lock defines the distributed lock interface +// This abstraction allows for multiple implementations (GORM, Redis, etcd, etc.) +type Lock interface { + // Lock acquires a distributed lock, blocking until successful or context cancelled + Lock(ctx context.Context, key string, ttl time.Duration) error + + // TryLock attempts to acquire a lock without blocking + // Returns true if lock was acquired, false otherwise + TryLock(ctx context.Context, key string, ttl time.Duration) (bool, error) + + // Unlock releases a lock held by this instance + Unlock(ctx context.Context, key string) error + + // Renew extends the TTL of a lock held by this instance + Renew(ctx context.Context, key string, ttl time.Duration) error + + // IsLocked checks if a lock is currently held by anyone + IsLocked(ctx context.Context, key string) (bool, error) + + // WithLock executes a function while holding a lock + // Automatically acquires the lock, executes the function, and releases the lock + WithLock(ctx context.Context, key string, ttl time.Duration, fn func() error) error + + // CleanupExpiredLocks removes expired locks (maintenance task) + CleanupExpiredLocks(ctx context.Context) error +} diff --git a/pkg/core/logger/log.go b/pkg/core/logger/log.go index 8794ed01f..52b7b08e2 100644 --- a/pkg/core/logger/log.go +++ b/pkg/core/logger/log.go @@ -22,45 +22,52 @@ import ( grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" "go.uber.org/zap" "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" + + logcfg "github.com/apache/dubbo-admin/pkg/config/log" ) var ( - mutex = &sync.Mutex{} - hasInit = false - encoder = zapcore.NewConsoleEncoder( + mutex = &sync.Mutex{} + hasInit = false + consoleEncoder = zapcore.NewConsoleEncoder( zapcore.EncoderConfig{ MessageKey: "msg", LevelKey: "level", TimeKey: "time", CallerKey: "line", NameKey: "logger", - FunctionKey: "", StacktraceKey: "stacktrace", - EncodeLevel: zapcore.CapitalLevelEncoder, - EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05"), + EncodeLevel: zapcore.CapitalColorLevelEncoder, + EncodeTime: zapcore.RFC3339TimeEncoder, EncodeCaller: zapcore.ShortCallerEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, }) - logger *zap.Logger - sugar *zap.SugaredLogger - cmdLogger *zap.Logger - cmdSugar *CmdSugarLogger + jsonEncoder = zapcore.NewJSONEncoder( + zapcore.EncoderConfig{ + MessageKey: "msg", + LevelKey: "level", + TimeKey: "time", + CallerKey: "caller", + NameKey: "logger", + StacktraceKey: "stacktrace", + EncodeLevel: zapcore.LowercaseLevelEncoder, + EncodeTime: zapcore.ISO8601TimeEncoder, + EncodeDuration: zapcore.SecondsDurationEncoder, + EncodeCaller: zapcore.FullCallerEncoder, + }) + logger *zap.Logger + sugar *zap.SugaredLogger ) -// CmdSugarLogger wraps zap.SugaredLogger and zapcore.WriteSyncer in order to use Sugar -// while being able to use low-level writers. -type CmdSugarLogger struct { - *zap.SugaredLogger - // wrap ws to print directly - ws zapcore.WriteSyncer +var logLevelMap = map[logcfg.Level]zapcore.Level{ + logcfg.LevelDebug: zap.DebugLevel, + logcfg.LevelInfo: zap.InfoLevel, + logcfg.LevelWarn: zap.WarnLevel, + logcfg.LevelError: zap.ErrorLevel, } -func (log *CmdSugarLogger) Print(s string) { - _, _ = log.ws.Write([]byte(s)) -} - -// nolint -func Init() { +func Init(cfg *logcfg.Config) { mutex.Lock() defer mutex.Unlock() if hasInit { @@ -68,46 +75,42 @@ func Init() { } hasInit = true - core := zapcore.NewCore(encoder, os.Stdout, zap.DebugLevel) - logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2)) + var cores []zapcore.Core + + // output in terminal + cores = append(cores, zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), logLevelMap[cfg.Level])) + // output in file + fileWriter := &lumberjack.Logger{ + Filename: cfg.OutputPath, + MaxSize: cfg.MaxSize, + MaxBackups: cfg.MaxBackups, + MaxAge: cfg.MaxAge, + Compress: true, + } + cores = append(cores, zapcore.NewCore(jsonEncoder, zapcore.AddSync(fileWriter), logLevelMap[cfg.Level])) + combinedCore := zapcore.NewTee(cores...) + + logger = zap.New(combinedCore, zap.AddCaller(), zap.AddCallerSkip(2)) defer logger.Sync() // flushes buffer, if any sugar = logger.Sugar() + // Create a separate logger for gRPC with higher log level to suppress INFO logs + grpcCore := zapcore.NewCore(consoleEncoder, os.Stdout, zap.WarnLevel) + grpcLogger := zap.New(grpcCore, zap.AddCaller(), zap.AddCallerSkip(2)) // Make sure that log statements internal to gRPC library are logged using the zapLogger as well. - grpcZap.ReplaceGrpcLoggerV2(logger) -} - -// nolint -func InitCmdSugar(ws zapcore.WriteSyncer) { - mutex.Lock() - defer mutex.Unlock() - - core := zapcore.NewCore(encoder, ws, zap.DebugLevel) - cmdLogger = zap.New(core) - defer cmdLogger.Sync() // flushes buffer, if any - cmdSugar = &CmdSugarLogger{ - SugaredLogger: cmdLogger.Sugar(), - ws: ws, - } + grpcZap.ReplaceGrpcLoggerV2(grpcLogger) } func Sugar() *zap.SugaredLogger { if sugar == nil { - Init() + Init(logcfg.DefaultLogConfig()) } return sugar } func Logger() *zap.Logger { if logger == nil { - Init() + Init(logcfg.DefaultLogConfig()) } return logger } - -func CmdSugar() *CmdSugarLogger { - if cmdSugar == nil { - InitCmdSugar(os.Stdout) - } - return cmdSugar -} diff --git a/pkg/core/manager/component.go b/pkg/core/manager/component.go index 8a0eb0e34..661ef9fae 100644 --- a/pkg/core/manager/component.go +++ b/pkg/core/manager/component.go @@ -1,10 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package manager import ( + "fmt" "math" - "github.com/pkg/errors" - + "github.com/apache/dubbo-admin/pkg/core/governor" "github.com/apache/dubbo-admin/pkg/core/runtime" "github.com/apache/dubbo-admin/pkg/core/store" ) @@ -24,20 +41,31 @@ type resourceManagerComponent struct { rm ResourceManager } +func (r *resourceManagerComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.ResourceStore, + runtime.RuleGovernor, + } +} + func (r *resourceManagerComponent) Type() runtime.ComponentType { return runtime.ResourceManager } func (r *resourceManagerComponent) Order() int { - return math.MaxInt + return math.MaxInt - 4 } func (r *resourceManagerComponent) Init(ctx runtime.BuilderContext) error { rsc, err := ctx.GetActivatedComponent(runtime.ResourceStore) if err != nil { - return errors.Wrap(err, "failed to init resource manager") + return fmt.Errorf("failed to init resource manager, cause: %s", err) + } + rgc, err := ctx.GetActivatedComponent(runtime.RuleGovernor) + if err != nil { + return fmt.Errorf("failed to init resource manager, cause: %w", err) } - r.rm = NewResourceManager(rsc.(store.Router)) + r.rm = NewResourceManager(rsc.(store.Router), rgc.(governor.Router)) return nil } diff --git a/pkg/core/manager/manager.go b/pkg/core/manager/manager.go index e56c9b6ed..3e4ce0942 100644 --- a/pkg/core/manager/manager.go +++ b/pkg/core/manager/manager.go @@ -18,23 +18,25 @@ package manager import ( - "errors" "fmt" - "time" + "reflect" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/governor" "github.com/apache/dubbo-admin/pkg/core/resource/model" "github.com/apache/dubbo-admin/pkg/core/store" - "github.com/duke-git/lancet/v2/slice" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) type ReadOnlyResourceManager interface { // GetByKey returns the resource with the given resource key GetByKey(rk model.ResourceKind, key string) (r model.Resource, exist bool, err error) - // ListByIndex returns the resource with the given index name - ListByIndex(rk model.ResourceKind, indexName string, indexKey interface{}) ([]model.Resource, error) - // ListPageByIndex page list the resources with the given index - ListPageByIndex(rk model.ResourceKind, indexName string, - indexValue interface{}, pq model.PageQuery) ([]model.Resource, model.Pagination, error) + // GetByKeys returns the resources with the given resource keys + GetByKeys(rk model.ResourceKind, keys []string) ([]model.Resource, error) + // ListByIndexes returns the resources with the given index conditions + ListByIndexes(rk model.ResourceKind, indexes []index.IndexCondition) ([]model.Resource, error) + // PageListByIndexes page list the resources with the given index conditions + PageListByIndexes(rk model.ResourceKind, indexes []index.IndexCondition, pr model.PageReq) (*model.PageData[model.Resource], error) } type WriteOnlyResourceManager interface { @@ -45,7 +47,7 @@ type WriteOnlyResourceManager interface { // Upsert upserts the resource Upsert(r model.Resource) error // DeleteByKey deletes the resource with the given resource key - DeleteByKey(rk model.ResourceKind, key string) error + DeleteByKey(rk model.ResourceKind, mesh string, key string) error } type ResourceManager interface { @@ -54,78 +56,102 @@ type ResourceManager interface { WriteOnlyResourceManager } -func NewResourceManager(router store.Router) ResourceManager { - return &resourcesManager{ - StoreRouter: router, - } -} - var _ ResourceManager = &resourcesManager{} type resourcesManager struct { - StoreRouter store.Router + storeRouter store.Router + governorRouter governor.Router +} + +func NewResourceManager(router store.Router, governorRouter governor.Router) ResourceManager { + return &resourcesManager{ + storeRouter: router, + governorRouter: governorRouter, + } } func (rm *resourcesManager) GetByKey(rk model.ResourceKind, key string) (r model.Resource, exist bool, err error) { - rs, err := rm.StoreRouter.ResourceKindRoute(rk) + rs, err := rm.storeRouter.ResourceKindRoute(rk) if err != nil { return nil, false, err } item, exist, err := rs.GetByKey(key) - return item.(model.Resource), exist, err + if !exist { + return nil, false, nil + } + res, ok := item.(model.Resource) + if !ok { + return nil, false, bizerror.NewAssertionError("Resource", reflect.TypeOf(res).Name()) + } + return res, exist, err } -func (rm *resourcesManager) ListByIndex(rk model.ResourceKind, indexName string, indexKey interface{}) ([]model.Resource, error) { - rs, err := rm.StoreRouter.ResourceKindRoute(rk) +func (rm *resourcesManager) GetByKeys(rk model.ResourceKind, keys []string) ([]model.Resource, error) { + rs, err := rm.storeRouter.ResourceKindRoute(rk) if err != nil { return nil, err } - objList, err := rs.Index(indexName, indexKey) + resources, err := rs.GetByKeys(keys) if err != nil { return nil, err } - resources := slice.Map(objList, func(_ int, item interface{}) model.Resource { - return item.(model.Resource) - }) return resources, nil } -func (rm *resourcesManager) ListPageByIndex( +func (rm *resourcesManager) ListByIndexes(rk model.ResourceKind, indexes []index.IndexCondition) ([]model.Resource, error) { + rs, err := rm.storeRouter.ResourceKindRoute(rk) + if err != nil { + return nil, err + } + resources, err := rs.ListByIndexes(indexes) + if err != nil { + return nil, err + } + return resources, nil +} + +func (rm *resourcesManager) PageListByIndexes( rk model.ResourceKind, - indexName string, - indexValue interface{}, - pageQuery model.PageQuery) ([]model.Resource, model.Pagination, error) { - rs, err := rm.StoreRouter.ResourceKindRoute(rk) + indexes []index.IndexCondition, + pr model.PageReq) (*model.PageData[model.Resource], error) { + + rs, err := rm.storeRouter.ResourceKindRoute(rk) if err != nil { - return nil, model.Pagination{}, err + return nil, err } - items, p, err := rs.ListPageByIndex(indexName, indexValue, pageQuery) + pageData, err := rs.PageListByIndexes(indexes, pr) if err != nil { - return nil, p, err + return nil, err } - rsList := slice.Map(items, func(_ int, item interface{}) model.Resource { - return item.(model.Resource) - }) - return rsList, p, nil + return pageData, nil } func (rm *resourcesManager) Add(r model.Resource) error { - rs, err := rm.StoreRouter.ResourceRoute(r) + if !governor.RuleResourceKinds.Contain(r.ResourceKind()) { + return bizerror.New(bizerror.InvalidArgument, "invalid resource kind") + } + rs, err := rm.governorRouter.ResourceRoute(r) if err != nil { return err } - return rs.Add(r) + return rs.CreateRule(r) } func (rm *resourcesManager) Update(r model.Resource) error { - rs, err := rm.StoreRouter.ResourceRoute(r) + if !governor.RuleResourceKinds.Contain(r.ResourceKind()) { + return bizerror.New(bizerror.InvalidArgument, "invalid resource kind") + } + rs, err := rm.governorRouter.ResourceRoute(r) if err != nil { return err } - return rs.Update(r) + return rs.UpdateRule(r) } func (rm *resourcesManager) Upsert(r model.Resource) error { + if !governor.RuleResourceKinds.Contain(r.ResourceKind()) { + return bizerror.New(bizerror.InvalidArgument, "invalid resource kind") + } if _, exists, _ := rm.GetByKey(r.ResourceKind(), r.ResourceKey()); exists { return rm.Update(r) } else { @@ -133,8 +159,11 @@ func (rm *resourcesManager) Upsert(r model.Resource) error { } } -func (rm *resourcesManager) DeleteByKey(rk model.ResourceKind, key string) error { - rs, err := rm.StoreRouter.ResourceKindRoute(rk) +func (rm *resourcesManager) DeleteByKey(rk model.ResourceKind, mesh string, key string) error { + if !governor.RuleResourceKinds.Contain(rk) { + return bizerror.New(bizerror.InvalidArgument, "invalid resource kind") + } + gov, err := rm.governorRouter.ResourceMeshRoute(mesh) if err != nil { return err } @@ -145,60 +174,5 @@ func (rm *resourcesManager) DeleteByKey(rk model.ResourceKind, key string) error if !exists { return fmt.Errorf("%s %s does not exist", rk, key) } - return rs.Delete(r) -} - -type ConflictRetry struct { - BaseBackoff time.Duration - MaxTimes uint - JitterPercent uint -} - -type UpsertOpts struct { - ConflictRetry ConflictRetry - Transactions store.Transactions -} - -type UpsertFunc func(opts *UpsertOpts) - -func WithConflictRetry(baseBackoff time.Duration, maxTimes uint, jitterPercent uint) UpsertFunc { - return func(opts *UpsertOpts) { - opts.ConflictRetry.BaseBackoff = baseBackoff - opts.ConflictRetry.MaxTimes = maxTimes - opts.ConflictRetry.JitterPercent = jitterPercent - } -} - -func WithTransactions(transactions store.Transactions) UpsertFunc { - return func(opts *UpsertOpts) { - opts.Transactions = transactions - } -} - -func NewUpsertOpts(fs ...UpsertFunc) UpsertOpts { - opts := UpsertOpts{ - Transactions: store.NoTransactions{}, - } - for _, f := range fs { - f(&opts) - } - return opts -} - -type MeshNotFoundError struct { - Mesh string -} - -func (m *MeshNotFoundError) Error() string { - return fmt.Sprintf("mesh of name %s is not found", m.Mesh) -} - -func MeshNotFound(meshName string) error { - return &MeshNotFoundError{meshName} -} - -func IsMeshNotFound(err error) bool { - var meshNotFoundError *MeshNotFoundError - ok := errors.As(err, &meshNotFoundError) - return ok + return gov.DeleteRule(r) } diff --git a/pkg/core/manager/manager_helper.go b/pkg/core/manager/manager_helper.go new file mode 100644 index 000000000..48a333631 --- /dev/null +++ b/pkg/core/manager/manager_helper.go @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package manager + +import ( + "reflect" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +// GetByKey is a helper function of ResourceManager.GeyByKey +func GetByKey[T model.Resource](rm ReadOnlyResourceManager, rk model.ResourceKind, key string) (r T, exist bool, err error) { + resource, exist, err := rm.GetByKey(rk, key) + if err != nil || !exist { + var zero T + return zero, exist, err + } + + typedResource, ok := resource.(T) + if !ok { + var zero T + return zero, false, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name()) + } + return typedResource, true, nil +} + +func GetByKeys[T model.Resource](rm ReadOnlyResourceManager, rk model.ResourceKind, keys []string) ([]T, error) { + resources, err := rm.GetByKeys(rk, keys) + if err != nil { + return nil, err + } + + typedResources := make([]T, len(resources)) + for i, resource := range resources { + typedResource, ok := resource.(T) + if !ok { + return nil, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name()) + } + typedResources[i] = typedResource + } + + return typedResources, nil +} + +// ListByIndexes is a helper function of ResourceManager.ListByIndexes +func ListByIndexes[T model.Resource](rm ReadOnlyResourceManager, rk model.ResourceKind, indexes []index.IndexCondition) ([]T, error) { + resources, err := rm.ListByIndexes(rk, indexes) + if err != nil { + return nil, err + } + + typedResources := make([]T, len(resources)) + for i, resource := range resources { + typedResource, ok := resource.(T) + if !ok { + return nil, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name()) + } + typedResources[i] = typedResource + } + + return typedResources, nil +} + +// PageListByIndexes is a helper function of ResourceManager.PageListByIndexes +func PageListByIndexes[T model.Resource]( + rm ReadOnlyResourceManager, + rk model.ResourceKind, + indexes []index.IndexCondition, + pr model.PageReq) (*model.PageData[T], error) { + + pageData, err := rm.PageListByIndexes(rk, indexes, pr) + if err != nil { + return nil, err + } + + typedResources := make([]T, len(pageData.Data)) + for i, resource := range pageData.Data { + typedResource, ok := resource.(T) + if !ok { + return nil, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name()) + } + typedResources[i] = typedResource + } + newPageData := &model.PageData[T]{ + Pagination: model.Pagination{ + Total: pageData.Total, + PageOffset: pageData.PageOffset, + PageSize: pageData.PageSize, + }, + Data: typedResources, + } + return newPageData, nil +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go b/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go index 7a932c6af..93847a715 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - const AffinityRouteKind coremodel.ResourceKind = "AffinityRoute" func init() { - coremodel.RegisterResourceKind(AffinityRouteKind) + coremodel.RegisterResourceSchema(AffinityRouteKind, NewAffinityRouteResource, NewAffinityRouteResourceList) } type AffinityRouteResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo AffinityRoute resource. - // +kubebuilder:validation:Optional Spec *meshproto.AffinityRoute `json:"spec,omitempty"` + // Status is the status of the Dubbo AffinityRoute resource. Status AffinityRouteResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type AffinityRouteResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type AffinityRouteResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []AffinityRouteResource `json:"items"` -} - func (r *AffinityRouteResource) ResourceKind() coremodel.ResourceKind { return AffinityRouteKind } -func (r *AffinityRouteResource) MeshName() string { +func (r *AffinityRouteResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *AffinityRouteResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewAffinityRouteResource(name string, mesh string, apiVersion string) *AffinityRouteResource { +func (r *AffinityRouteResource) DeepCopyObject() k8sruntime.Object { + out := &AffinityRouteResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.AffinityRoute) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *AffinityRouteResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode AffinityRouteResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewAffinityRouteResourceWithAttributes(name string, mesh string) *AffinityRouteResource { return &AffinityRouteResource{ TypeMeta: metav1.TypeMeta{ Kind: string(AffinityRouteKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.AffinityRoute{}, + } +} + +func NewAffinityRouteResource() coremodel.Resource { + return &AffinityRouteResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(AffinityRouteKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.AffinityRoute{}, + } +} + +type AffinityRouteResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*AffinityRouteResource `json:"items"` +} + +func (r *AffinityRouteResourceList) DeepCopyObject() k8sruntime.Object { + out := &AffinityRouteResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*AffinityRouteResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*AffinityRouteResource) + } + return out +} + +func NewAffinityRouteResourceList() coremodel.ResourceList { + return &AffinityRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(AffinityRouteKind), + APIVersion: "v1alpha1", + }, + Items: make([]*AffinityRouteResource, 0), + } +} + +func (r *AffinityRouteResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*AffinityRouteResource, len(items)) + for i := range items { + res, ok := items[i].(*AffinityRouteResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", AffinityRouteKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewAffinityRouteResourceListWithItems(items ...*AffinityRouteResource) *AffinityRouteResourceList { + return &AffinityRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(AffinityRouteKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/application_types.go b/pkg/core/resource/apis/mesh/v1alpha1/application_types.go index 0a2b03ecc..7fe4b414b 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/application_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/application_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Namespaced - const ApplicationKind coremodel.ResourceKind = "Application" func init() { - coremodel.RegisterResourceKind(ApplicationKind) + coremodel.RegisterResourceSchema(ApplicationKind, NewApplicationResource, NewApplicationResourceList) } type ApplicationResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo Application resource. - // +kubebuilder:validation:Optional Spec *meshproto.Application `json:"spec,omitempty"` + // Status is the status of the Dubbo Application resource. Status ApplicationResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type ApplicationResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster -type ApplicationResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ApplicationResource `json:"items"` -} - func (r *ApplicationResource) ResourceKind() coremodel.ResourceKind { return ApplicationKind } -func (r *ApplicationResource) MeshName() string { +func (r *ApplicationResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *ApplicationResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewApplicationResource(name string, mesh string, apiVersion string) *ApplicationResource { +func (r *ApplicationResource) DeepCopyObject() k8sruntime.Object { + out := &ApplicationResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.Application) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ApplicationResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ApplicationResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewApplicationResourceWithAttributes(name string, mesh string) *ApplicationResource { return &ApplicationResource{ TypeMeta: metav1.TypeMeta{ Kind: string(ApplicationKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.Application{}, + } +} + +func NewApplicationResource() coremodel.Resource { + return &ApplicationResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ApplicationKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.Application{}, + } +} + +type ApplicationResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ApplicationResource `json:"items"` +} + +func (r *ApplicationResourceList) DeepCopyObject() k8sruntime.Object { + out := &ApplicationResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ApplicationResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ApplicationResource) + } + return out +} + +func NewApplicationResourceList() coremodel.ResourceList { + return &ApplicationResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ApplicationKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ApplicationResource, 0), + } +} + +func (r *ApplicationResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ApplicationResource, len(items)) + for i := range items { + res, ok := items[i].(*ApplicationResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ApplicationKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewApplicationResourceListWithItems(items ...*ApplicationResource) *ApplicationResourceList { + return &ApplicationResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ApplicationKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/common/util/os/fs.go b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_helper.go similarity index 56% rename from pkg/common/util/os/fs.go rename to pkg/core/resource/apis/mesh/v1alpha1/conditionroute_helper.go index 6d4d60cf3..6a79c60c8 100644 --- a/pkg/common/util/os/fs.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_helper.go @@ -15,29 +15,25 @@ * limitations under the License. */ -package os +package v1alpha1 import ( - "os" + "sigs.k8s.io/yaml" - "github.com/pkg/errors" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -func TryWriteToDir(dir string) error { - file, err := os.CreateTemp(dir, "write-access-check") +func BuildConditionRouteResName(scopeEntity string) string { + return scopeEntity + constants.ConditionRuleDotSuffix +} + +func ToConditionRouteResource(mesh, name, data string) coremodel.Resource { + res := NewConditionRouteResourceWithAttributes(name, mesh) + err := yaml.Unmarshal([]byte(data), res.Spec) if err != nil { - if os.IsNotExist(err) { - if err := os.MkdirAll(dir, os.ModeDir|0o755); err != nil { - return errors.Wrapf(err, "unable to create a directory %q", dir) - } - file, err = os.CreateTemp(dir, "write-access-check") - } - if err != nil { - return errors.Wrapf(err, "unable to create temporary files in directory %q", dir) - } - } - if err := os.Remove(file.Name()); err != nil { - return errors.Wrapf(err, "unable to remove temporary files in directory %q", dir) + logger.Warnf("cannot unmarshal condition route %s in %s, cause: %s, raw content:\n %s, ", name, mesh, err, data) } - return nil + return res } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go index c118cd50c..499a01317 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - const ConditionRouteKind coremodel.ResourceKind = "ConditionRoute" func init() { - coremodel.RegisterResourceKind(ConditionRouteKind) + coremodel.RegisterResourceSchema(ConditionRouteKind, NewConditionRouteResource, NewConditionRouteResourceList) } type ConditionRouteResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo ConditionRoute resource. - // +kubebuilder:validation:Optional Spec *meshproto.ConditionRoute `json:"spec,omitempty"` + // Status is the status of the Dubbo ConditionRoute resource. Status ConditionRouteResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type ConditionRouteResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type ConditionRouteResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ConditionRouteResource `json:"items"` -} - func (r *ConditionRouteResource) ResourceKind() coremodel.ResourceKind { return ConditionRouteKind } -func (r *ConditionRouteResource) MeshName() string { +func (r *ConditionRouteResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *ConditionRouteResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewConditionRouteResource(name string, mesh string, apiVersion string) *ConditionRouteResource { +func (r *ConditionRouteResource) DeepCopyObject() k8sruntime.Object { + out := &ConditionRouteResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ConditionRoute) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ConditionRouteResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ConditionRouteResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewConditionRouteResourceWithAttributes(name string, mesh string) *ConditionRouteResource { return &ConditionRouteResource{ TypeMeta: metav1.TypeMeta{ Kind: string(ConditionRouteKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.ConditionRoute{}, + } +} + +func NewConditionRouteResource() coremodel.Resource { + return &ConditionRouteResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ConditionRouteKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ConditionRoute{}, + } +} + +type ConditionRouteResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ConditionRouteResource `json:"items"` +} + +func (r *ConditionRouteResourceList) DeepCopyObject() k8sruntime.Object { + out := &ConditionRouteResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ConditionRouteResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ConditionRouteResource) + } + return out +} + +func NewConditionRouteResourceList() coremodel.ResourceList { + return &ConditionRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ConditionRouteKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ConditionRouteResource, 0), + } +} + +func (r *ConditionRouteResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ConditionRouteResource, len(items)) + for i := range items { + res, ok := items[i].(*ConditionRouteResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ConditionRouteKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewConditionRouteResourceListWithItems(items ...*ConditionRouteResource) *ConditionRouteResourceList { + return &ConditionRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ConditionRouteKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_helper.go new file mode 100644 index 000000000..65a7c12e4 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_helper.go @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "sigs.k8s.io/yaml" + + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func ToDynamicConfigResource(mesh, name, data string) coremodel.Resource { + res := NewDynamicConfigResourceWithAttributes(name, mesh) + err := yaml.Unmarshal([]byte(data), res.Spec) + if err != nil { + logger.Warnf("cannot unmarshal dynamic config %s in %s, cause %s, raw content:\n %s, ", name, mesh, err, data) + } + return res +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go index 9838fdc8b..a76c5afc9 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - const DynamicConfigKind coremodel.ResourceKind = "DynamicConfig" func init() { - coremodel.RegisterResourceKind(DynamicConfigKind) + coremodel.RegisterResourceSchema(DynamicConfigKind, NewDynamicConfigResource, NewDynamicConfigResourceList) } type DynamicConfigResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo DynamicConfig resource. - // +kubebuilder:validation:Optional Spec *meshproto.DynamicConfig `json:"spec,omitempty"` + // Status is the status of the Dubbo DynamicConfig resource. Status DynamicConfigResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type DynamicConfigResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type DynamicConfigResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []DynamicConfigResource `json:"items"` -} - func (r *DynamicConfigResource) ResourceKind() coremodel.ResourceKind { return DynamicConfigKind } -func (r *DynamicConfigResource) MeshName() string { +func (r *DynamicConfigResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *DynamicConfigResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewDynamicConfigResource(name string, mesh string, apiVersion string) *DynamicConfigResource { +func (r *DynamicConfigResource) DeepCopyObject() k8sruntime.Object { + out := &DynamicConfigResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.DynamicConfig) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *DynamicConfigResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode DynamicConfigResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewDynamicConfigResourceWithAttributes(name string, mesh string) *DynamicConfigResource { return &DynamicConfigResource{ TypeMeta: metav1.TypeMeta{ Kind: string(DynamicConfigKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.DynamicConfig{}, + } +} + +func NewDynamicConfigResource() coremodel.Resource { + return &DynamicConfigResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(DynamicConfigKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.DynamicConfig{}, + } +} + +type DynamicConfigResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*DynamicConfigResource `json:"items"` +} + +func (r *DynamicConfigResourceList) DeepCopyObject() k8sruntime.Object { + out := &DynamicConfigResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*DynamicConfigResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*DynamicConfigResource) + } + return out +} + +func NewDynamicConfigResourceList() coremodel.ResourceList { + return &DynamicConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(DynamicConfigKind), + APIVersion: "v1alpha1", + }, + Items: make([]*DynamicConfigResource, 0), + } +} + +func (r *DynamicConfigResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*DynamicConfigResource, len(items)) + for i := range items { + res, ok := items[i].(*DynamicConfigResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", DynamicConfigKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewDynamicConfigResourceListWithItems(items ...*DynamicConfigResource) *DynamicConfigResourceList { + return &DynamicConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(DynamicConfigKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/instance_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/instance_helper.go new file mode 100644 index 000000000..f7b86c346 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/instance_helper.go @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "fmt" + "time" + + "github.com/apache/dubbo-admin/pkg/common/constants" +) + +func BuildInstanceResName(appName string, ip string, rpcPort int64) string { + return fmt.Sprintf("%s%s:%d", appName, ip, rpcPort) +} + +// FromRPCInstance create an instance resource from a rpc instance resource +func FromRPCInstance(rpcInstanceRes *RPCInstanceResource) *InstanceResource { + resName := BuildInstanceResName(rpcInstanceRes.Spec.AppName, rpcInstanceRes.Spec.Ip, rpcInstanceRes.Spec.Port) + instanceRes := NewInstanceResourceWithAttributes(resName, rpcInstanceRes.Mesh) + instanceRes.Spec.Name = rpcInstanceRes.Spec.Name + instanceRes.Spec.AppName = rpcInstanceRes.Spec.AppName + instanceRes.Spec.Ip = rpcInstanceRes.Spec.Ip + instanceRes.Spec.RpcPort = rpcInstanceRes.Spec.Port + MergeRPCInstanceIntoInstance(rpcInstanceRes, instanceRes) + return instanceRes +} + +// MergeRPCInstanceIntoInstance merge rpc instance resource into instance resource +func MergeRPCInstanceIntoInstance( + rpcInstanceRes *RPCInstanceResource, + instanceRes *InstanceResource) { + instanceRes.Spec.ReleaseVersion = rpcInstanceRes.Spec.ReleaseVersion + instanceRes.Spec.RegisterTime = rpcInstanceRes.Spec.RegisterTime + instanceRes.Spec.UnregisterTime = rpcInstanceRes.Spec.UnregisterTime + instanceRes.Spec.Protocol = rpcInstanceRes.Spec.Protocol + instanceRes.Spec.Serialization = rpcInstanceRes.Spec.Serialization + instanceRes.Spec.PreferSerialization = rpcInstanceRes.Spec.PreferSerialization + instanceRes.Spec.Tags = rpcInstanceRes.Spec.Tags +} + +// FromRuntimeInstance create an instance resource from a runtime instance resource +func FromRuntimeInstance(rtInstanceRes *RuntimeInstanceResource) *InstanceResource { + resName := BuildInstanceResName(rtInstanceRes.Spec.AppName, rtInstanceRes.Spec.Ip, rtInstanceRes.Spec.RpcPort) + instanceRes := NewInstanceResourceWithAttributes(resName, rtInstanceRes.Mesh) + instanceRes.Spec.Name = resName + instanceRes.Spec.AppName = rtInstanceRes.Spec.AppName + instanceRes.Spec.Ip = rtInstanceRes.Spec.Ip + instanceRes.Spec.RpcPort = rtInstanceRes.Spec.RpcPort + MergeRuntimeInstanceIntoInstance(rtInstanceRes, instanceRes) + return instanceRes +} + +// MergeRuntimeInstanceIntoInstance merge runtime instance resource into instance resource +func MergeRuntimeInstanceIntoInstance( + rtInstanceRes *RuntimeInstanceResource, + instanceRes *InstanceResource) { + instanceRes.Labels = rtInstanceRes.Labels + instanceRes.Spec.Image = rtInstanceRes.Spec.Image + instanceRes.Spec.CreateTime = rtInstanceRes.Spec.CreateTime + instanceRes.Spec.StartTime = rtInstanceRes.Spec.StartTime + instanceRes.Spec.ReadyTime = rtInstanceRes.Spec.ReadyTime + instanceRes.Spec.DeployState = rtInstanceRes.Spec.Phase + instanceRes.Spec.WorkloadType = rtInstanceRes.Spec.WorkloadType + instanceRes.Spec.WorkloadName = rtInstanceRes.Spec.WorkloadName + instanceRes.Spec.Node = rtInstanceRes.Spec.Node + instanceRes.Spec.Probes = rtInstanceRes.Spec.Probes + instanceRes.Spec.Conditions = rtInstanceRes.Spec.Conditions + instanceRes.Spec.SourceEngine = rtInstanceRes.Spec.SourceEngine +} + +func ClearRPCInstanceFromInstance(instanceRes *InstanceResource) { + if instanceRes == nil || instanceRes.Spec == nil { + return + } + instanceRes.Spec.ReleaseVersion = "" + instanceRes.Spec.RegisterTime = "" + instanceRes.Spec.UnregisterTime = time.Now().Format(constants.TimeFormatStr) + instanceRes.Spec.Protocol = "" + instanceRes.Spec.Serialization = "" + instanceRes.Spec.PreferSerialization = "" + instanceRes.Spec.Tags = nil +} + +func ClearRuntimeInstanceFromInstance(instanceRes *InstanceResource) { + if instanceRes == nil || instanceRes.Spec == nil { + return + } + instanceRes.Labels = nil + instanceRes.Spec.Image = "" + instanceRes.Spec.CreateTime = "" + instanceRes.Spec.StartTime = "" + instanceRes.Spec.ReadyTime = "" + instanceRes.Spec.DeployState = "" + instanceRes.Spec.WorkloadType = "" + instanceRes.Spec.WorkloadName = "" + instanceRes.Spec.Node = "" + instanceRes.Spec.Probes = nil + instanceRes.Spec.Conditions = nil + instanceRes.Spec.SourceEngine = "" +} + +func HasRuntimeInstanceSource(instanceRes *InstanceResource) bool { + if instanceRes == nil || instanceRes.Spec == nil { + return false + } + return instanceRes.Spec.SourceEngine != "" || + instanceRes.Spec.DeployState != "" || + instanceRes.Spec.WorkloadName != "" || + instanceRes.Spec.Node != "" || + instanceRes.Spec.Image != "" || + instanceRes.Spec.StartTime != "" || + instanceRes.Spec.ReadyTime != "" || + len(instanceRes.Spec.Conditions) > 0 +} + +func HasRPCInstanceSource(instanceRes *InstanceResource) bool { + if instanceRes == nil || instanceRes.Spec == nil { + return false + } + return instanceRes.Spec.RegisterTime != "" +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/instance_index.go b/pkg/core/resource/apis/mesh/v1alpha1/instance_index.go deleted file mode 100644 index 32240c19b..000000000 --- a/pkg/core/resource/apis/mesh/v1alpha1/instance_index.go +++ /dev/null @@ -1,25 +0,0 @@ -package v1alpha1 - -import ( - "fmt" - - "github.com/apache/dubbo-admin/pkg/core/store" - "k8s.io/client-go/tools/cache" -) - -func init() { - store.RegisterIndexers(InstanceKind, map[string]cache.IndexFunc{ - "AppName": byAppName, - }) -} - -func byAppName(obj interface{}) ([]string, error) { - instance, ok := obj.(InstanceResource) - if !ok { - return nil, fmt.Errorf("invalid object type, required %s, got %v", InstanceKind, obj) - } - if instance.Spec == nil { - return []string{}, nil - } - return []string{instance.Spec.AppName}, nil -} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go b/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go index a71b253b1..7556b4706 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Namespaced - const InstanceKind coremodel.ResourceKind = "Instance" func init() { - coremodel.RegisterResourceKind(InstanceKind) + coremodel.RegisterResourceSchema(InstanceKind, NewInstanceResource, NewInstanceResourceList) } type InstanceResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo Instance resource. - // +kubebuilder:validation:Optional Spec *meshproto.Instance `json:"spec,omitempty"` + // Status is the status of the Dubbo Instance resource. Status InstanceResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type InstanceResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster -type InstanceResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []InstanceResource `json:"items"` -} - func (r *InstanceResource) ResourceKind() coremodel.ResourceKind { return InstanceKind } -func (r *InstanceResource) MeshName() string { +func (r *InstanceResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *InstanceResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewInstanceResource(name string, mesh string, apiVersion string) *InstanceResource { +func (r *InstanceResource) DeepCopyObject() k8sruntime.Object { + out := &InstanceResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.Instance) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *InstanceResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode InstanceResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewInstanceResourceWithAttributes(name string, mesh string) *InstanceResource { return &InstanceResource{ TypeMeta: metav1.TypeMeta{ Kind: string(InstanceKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.Instance{}, + } +} + +func NewInstanceResource() coremodel.Resource { + return &InstanceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(InstanceKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.Instance{}, + } +} + +type InstanceResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*InstanceResource `json:"items"` +} + +func (r *InstanceResourceList) DeepCopyObject() k8sruntime.Object { + out := &InstanceResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*InstanceResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*InstanceResource) + } + return out +} + +func NewInstanceResourceList() coremodel.ResourceList { + return &InstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(InstanceKind), + APIVersion: "v1alpha1", + }, + Items: make([]*InstanceResource, 0), + } +} + +func (r *InstanceResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*InstanceResource, len(items)) + for i := range items { + res, ok := items[i].(*InstanceResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", InstanceKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewInstanceResourceListWithItems(items ...*InstanceResource) *InstanceResourceList { + return &InstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(InstanceKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go b/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go deleted file mode 100644 index bf194f274..000000000 --- a/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Namespaced - -const MappingKind coremodel.ResourceKind = "Mapping" - -func init() { - coremodel.RegisterResourceKind(MappingKind) -} - -type MappingResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo Mapping resource. - // +kubebuilder:validation:Optional - Spec *meshproto.Mapping `json:"spec,omitempty"` - // Status is the status of the Dubbo Mapping resource. - Status MappingResourceStatus `json:"status,omitempty"` -} - -type MappingResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster -type MappingResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []MappingResource `json:"items"` -} - -func (r *MappingResource) ResourceKind() coremodel.ResourceKind { - return MappingKind -} - -func (r *MappingResource) MeshName() string { - return r.Mesh -} - -func (r *MappingResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *MappingResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *MappingResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewMappingResource(name string, mesh string, apiVersion string) *MappingResource { - return &MappingResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(MappingKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/api/system/v1alpha1/zone_helpers.go b/pkg/core/resource/apis/mesh/v1alpha1/metadata_helper.go similarity index 84% rename from api/system/v1alpha1/zone_helpers.go rename to pkg/core/resource/apis/mesh/v1alpha1/metadata_helper.go index a673e2981..13a1f4ebb 100644 --- a/api/system/v1alpha1/zone_helpers.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/metadata_helper.go @@ -17,9 +17,6 @@ package v1alpha1 -func (x *Zone) IsEnabled() bool { - if x.Enabled == nil { - return true - } - return x.Enabled.GetValue() -} +import coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + +type ToMetadataResFunc func(mesh string, data string) coremodel.Resource diff --git a/pkg/core/resource/apis/mesh/v1alpha1/nacosconfig_types.go b/pkg/core/resource/apis/mesh/v1alpha1/nacosconfig_types.go new file mode 100644 index 000000000..b0d28cf50 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/nacosconfig_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const NacosConfigKind coremodel.ResourceKind = "NacosConfig" + +func init() { + coremodel.RegisterResourceSchema(NacosConfigKind, NewNacosConfigResource, NewNacosConfigResourceList) +} + +type NacosConfigResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo NacosConfig resource. + Spec *meshproto.NacosConfig `json:"spec,omitempty"` + + // Status is the status of the Dubbo NacosConfig resource. + Status NacosConfigResourceStatus `json:"status,omitempty"` +} + +type NacosConfigResourceStatus struct { + // define resource-specific status here +} + +func (r *NacosConfigResource) ResourceKind() coremodel.ResourceKind { + return NacosConfigKind +} + +func (r *NacosConfigResource) ResourceMesh() string { + return r.Mesh +} + +func (r *NacosConfigResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *NacosConfigResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *NacosConfigResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *NacosConfigResource) DeepCopyObject() k8sruntime.Object { + out := &NacosConfigResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.NacosConfig) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *NacosConfigResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode NacosConfigResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewNacosConfigResourceWithAttributes(name string, mesh string) *NacosConfigResource { + return &NacosConfigResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosConfigKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.NacosConfig{}, + } +} + +func NewNacosConfigResource() coremodel.Resource { + return &NacosConfigResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosConfigKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.NacosConfig{}, + } +} + +type NacosConfigResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*NacosConfigResource `json:"items"` +} + +func (r *NacosConfigResourceList) DeepCopyObject() k8sruntime.Object { + out := &NacosConfigResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*NacosConfigResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*NacosConfigResource) + } + return out +} + +func NewNacosConfigResourceList() coremodel.ResourceList { + return &NacosConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosConfigKind), + APIVersion: "v1alpha1", + }, + Items: make([]*NacosConfigResource, 0), + } +} + +func (r *NacosConfigResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*NacosConfigResource, len(items)) + for i := range items { + res, ok := items[i].(*NacosConfigResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", NacosConfigKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewNacosConfigResourceListWithItems(items ...*NacosConfigResource) *NacosConfigResourceList { + return &NacosConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosConfigKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/nacosservice_types.go b/pkg/core/resource/apis/mesh/v1alpha1/nacosservice_types.go new file mode 100644 index 000000000..ec4b07730 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/nacosservice_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const NacosServiceKind coremodel.ResourceKind = "NacosService" + +func init() { + coremodel.RegisterResourceSchema(NacosServiceKind, NewNacosServiceResource, NewNacosServiceResourceList) +} + +type NacosServiceResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo NacosService resource. + Spec *meshproto.NacosService `json:"spec,omitempty"` + + // Status is the status of the Dubbo NacosService resource. + Status NacosServiceResourceStatus `json:"status,omitempty"` +} + +type NacosServiceResourceStatus struct { + // define resource-specific status here +} + +func (r *NacosServiceResource) ResourceKind() coremodel.ResourceKind { + return NacosServiceKind +} + +func (r *NacosServiceResource) ResourceMesh() string { + return r.Mesh +} + +func (r *NacosServiceResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *NacosServiceResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *NacosServiceResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *NacosServiceResource) DeepCopyObject() k8sruntime.Object { + out := &NacosServiceResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.NacosService) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *NacosServiceResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode NacosServiceResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewNacosServiceResourceWithAttributes(name string, mesh string) *NacosServiceResource { + return &NacosServiceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosServiceKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.NacosService{}, + } +} + +func NewNacosServiceResource() coremodel.Resource { + return &NacosServiceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosServiceKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.NacosService{}, + } +} + +type NacosServiceResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*NacosServiceResource `json:"items"` +} + +func (r *NacosServiceResourceList) DeepCopyObject() k8sruntime.Object { + out := &NacosServiceResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*NacosServiceResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*NacosServiceResource) + } + return out +} + +func NewNacosServiceResourceList() coremodel.ResourceList { + return &NacosServiceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosServiceKind), + APIVersion: "v1alpha1", + }, + Items: make([]*NacosServiceResource, 0), + } +} + +func (r *NacosServiceResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*NacosServiceResource, len(items)) + for i := range items { + res, ok := items[i].(*NacosServiceResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", NacosServiceKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewNacosServiceResourceListWithItems(items ...*NacosServiceResource) *NacosServiceResourceList { + return &NacosServiceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(NacosServiceKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/rpc_instance_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/rpc_instance_helper.go new file mode 100644 index 000000000..b3232cf91 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/rpc_instance_helper.go @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "encoding/json" + "strconv" + "time" + + set "github.com/duke-git/lancet/v2/datastructure/set" + "github.com/duke-git/lancet/v2/maputil" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/logger" +) + +func ToRPCInstance( + mesh string, appName string, ip string, + port int64, metadata map[string]string) *RPCInstanceResource { + resName := BuildInstanceResName(appName, ip, port) + var registerTime string + timestamp, err := strconv.ParseInt(metadata[constants.TimestampKey], 10, 64) + if err == nil { + registerTime = time.UnixMilli(timestamp).Format(constants.TimeFormatStr) + } + revision := metadata[constants.MetadataRevisionKey] + metadataStorageType := metadata[constants.MetadataStorageTypeKey] + urlParams, exists := metadata[constants.URLParamsKey] + releaseVersion := "" + protocol := "" + serialization := "" + preferSerialization := "" + if exists { + paramsMap := make(map[string]string) + err := json.Unmarshal([]byte(urlParams), ¶msMap) + if err != nil { + logger.Warnf("parse url params failed, raw url params string: %s, cause: %v", urlParams, err) + } + releaseVersion = paramsMap[constants.ReleaseKey] + protocol = paramsMap[constants.ProtocolKey] + serialization = paramsMap[constants.SerializationKey] + preferSerialization = paramsMap[constants.PreferSerializationKey] + } + var endpoints []*meshproto.Endpoint + err = json.Unmarshal([]byte(metadata[constants.EndpointsKey]), &endpoints) + if err != nil { + logger.Warnf("parse endpoints failed, raw endpoints string: %s, cause: %v", metadata[constants.EndpointsKey], err) + } + res := NewRPCInstanceResourceWithAttributes(resName, mesh) + res.Spec = &meshproto.RPCInstance{ + Name: resName, + AppName: appName, + Ip: ip, + Port: port, + RegisterTime: registerTime, + UnregisterTime: "", + Revision: revision, + MetadataStorageType: metadataStorageType, + ReleaseVersion: releaseVersion, + Protocol: protocol, + Serialization: serialization, + PreferSerialization: preferSerialization, + Tags: getRPCInstanceTags(metadata), + Endpoints: endpoints, + Metadata: metadata, + } + return res +} + +func getRPCInstanceTags(metadata map[string]string) map[string]string { + knownKeys := set.New[string](constants.URLParamsKey, constants.EndpointsKey, + constants.MetadataRevisionKey, constants.MetadataStorageTypeKey, constants.TimestampKey) + return maputil.Filter(metadata, func(key string, value string) bool { + return !knownKeys.Contain(key) + }) +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/rpcinstance_types.go b/pkg/core/resource/apis/mesh/v1alpha1/rpcinstance_types.go new file mode 100644 index 000000000..b9eef5930 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/rpcinstance_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const RPCInstanceKind coremodel.ResourceKind = "RPCInstance" + +func init() { + coremodel.RegisterResourceSchema(RPCInstanceKind, NewRPCInstanceResource, NewRPCInstanceResourceList) +} + +type RPCInstanceResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo RPCInstance resource. + Spec *meshproto.RPCInstance `json:"spec,omitempty"` + + // Status is the status of the Dubbo RPCInstance resource. + Status RPCInstanceResourceStatus `json:"status,omitempty"` +} + +type RPCInstanceResourceStatus struct { + // define resource-specific status here +} + +func (r *RPCInstanceResource) ResourceKind() coremodel.ResourceKind { + return RPCInstanceKind +} + +func (r *RPCInstanceResource) ResourceMesh() string { + return r.Mesh +} + +func (r *RPCInstanceResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *RPCInstanceResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *RPCInstanceResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *RPCInstanceResource) DeepCopyObject() k8sruntime.Object { + out := &RPCInstanceResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.RPCInstance) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *RPCInstanceResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode RPCInstanceResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewRPCInstanceResourceWithAttributes(name string, mesh string) *RPCInstanceResource { + return &RPCInstanceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.RPCInstance{}, + } +} + +func NewRPCInstanceResource() coremodel.Resource { + return &RPCInstanceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.RPCInstance{}, + } +} + +type RPCInstanceResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*RPCInstanceResource `json:"items"` +} + +func (r *RPCInstanceResourceList) DeepCopyObject() k8sruntime.Object { + out := &RPCInstanceResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*RPCInstanceResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*RPCInstanceResource) + } + return out +} + +func NewRPCInstanceResourceList() coremodel.ResourceList { + return &RPCInstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceKind), + APIVersion: "v1alpha1", + }, + Items: make([]*RPCInstanceResource, 0), + } +} + +func (r *RPCInstanceResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*RPCInstanceResource, len(items)) + for i := range items { + res, ok := items[i].(*RPCInstanceResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", RPCInstanceKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewRPCInstanceResourceListWithItems(items ...*RPCInstanceResource) *RPCInstanceResourceList { + return &RPCInstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/rpcinstancemetadata_types.go b/pkg/core/resource/apis/mesh/v1alpha1/rpcinstancemetadata_types.go new file mode 100644 index 000000000..1f17e9eb3 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/rpcinstancemetadata_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const RPCInstanceMetadataKind coremodel.ResourceKind = "RPCInstanceMetadata" + +func init() { + coremodel.RegisterResourceSchema(RPCInstanceMetadataKind, NewRPCInstanceMetadataResource, NewRPCInstanceMetadataResourceList) +} + +type RPCInstanceMetadataResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo RPCInstanceMetadata resource. + Spec *meshproto.RPCInstanceMetadata `json:"spec,omitempty"` + + // Status is the status of the Dubbo RPCInstanceMetadata resource. + Status RPCInstanceMetadataResourceStatus `json:"status,omitempty"` +} + +type RPCInstanceMetadataResourceStatus struct { + // define resource-specific status here +} + +func (r *RPCInstanceMetadataResource) ResourceKind() coremodel.ResourceKind { + return RPCInstanceMetadataKind +} + +func (r *RPCInstanceMetadataResource) ResourceMesh() string { + return r.Mesh +} + +func (r *RPCInstanceMetadataResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *RPCInstanceMetadataResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *RPCInstanceMetadataResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *RPCInstanceMetadataResource) DeepCopyObject() k8sruntime.Object { + out := &RPCInstanceMetadataResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.RPCInstanceMetadata) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *RPCInstanceMetadataResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode RPCInstanceMetadataResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewRPCInstanceMetadataResourceWithAttributes(name string, mesh string) *RPCInstanceMetadataResource { + return &RPCInstanceMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceMetadataKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.RPCInstanceMetadata{}, + } +} + +func NewRPCInstanceMetadataResource() coremodel.Resource { + return &RPCInstanceMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceMetadataKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.RPCInstanceMetadata{}, + } +} + +type RPCInstanceMetadataResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*RPCInstanceMetadataResource `json:"items"` +} + +func (r *RPCInstanceMetadataResourceList) DeepCopyObject() k8sruntime.Object { + out := &RPCInstanceMetadataResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*RPCInstanceMetadataResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*RPCInstanceMetadataResource) + } + return out +} + +func NewRPCInstanceMetadataResourceList() coremodel.ResourceList { + return &RPCInstanceMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceMetadataKind), + APIVersion: "v1alpha1", + }, + Items: make([]*RPCInstanceMetadataResource, 0), + } +} + +func (r *RPCInstanceMetadataResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*RPCInstanceMetadataResource, len(items)) + for i := range items { + res, ok := items[i].(*RPCInstanceMetadataResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", RPCInstanceMetadataKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewRPCInstanceMetadataResourceListWithItems(items ...*RPCInstanceMetadataResource) *RPCInstanceMetadataResourceList { + return &RPCInstanceMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RPCInstanceMetadataKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/rule_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/rule_helper.go new file mode 100644 index 000000000..36f60538d --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/rule_helper.go @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import "github.com/apache/dubbo-admin/pkg/core/resource/model" + +// ToRuleResourceFunc is the function which converts the raw data to resource +type ToRuleResourceFunc func(mesh string, configName string, rawData string) model.Resource diff --git a/pkg/core/resource/apis/mesh/v1alpha1/runtimeinstance_types.go b/pkg/core/resource/apis/mesh/v1alpha1/runtimeinstance_types.go new file mode 100644 index 000000000..1fbc31ed3 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/runtimeinstance_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const RuntimeInstanceKind coremodel.ResourceKind = "RuntimeInstance" + +func init() { + coremodel.RegisterResourceSchema(RuntimeInstanceKind, NewRuntimeInstanceResource, NewRuntimeInstanceResourceList) +} + +type RuntimeInstanceResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo RuntimeInstance resource. + Spec *meshproto.RuntimeInstance `json:"spec,omitempty"` + + // Status is the status of the Dubbo RuntimeInstance resource. + Status RuntimeInstanceResourceStatus `json:"status,omitempty"` +} + +type RuntimeInstanceResourceStatus struct { + // define resource-specific status here +} + +func (r *RuntimeInstanceResource) ResourceKind() coremodel.ResourceKind { + return RuntimeInstanceKind +} + +func (r *RuntimeInstanceResource) ResourceMesh() string { + return r.Mesh +} + +func (r *RuntimeInstanceResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *RuntimeInstanceResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *RuntimeInstanceResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *RuntimeInstanceResource) DeepCopyObject() k8sruntime.Object { + out := &RuntimeInstanceResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.RuntimeInstance) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *RuntimeInstanceResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode RuntimeInstanceResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewRuntimeInstanceResourceWithAttributes(name string, mesh string) *RuntimeInstanceResource { + return &RuntimeInstanceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RuntimeInstanceKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.RuntimeInstance{}, + } +} + +func NewRuntimeInstanceResource() coremodel.Resource { + return &RuntimeInstanceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RuntimeInstanceKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.RuntimeInstance{}, + } +} + +type RuntimeInstanceResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*RuntimeInstanceResource `json:"items"` +} + +func (r *RuntimeInstanceResourceList) DeepCopyObject() k8sruntime.Object { + out := &RuntimeInstanceResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*RuntimeInstanceResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*RuntimeInstanceResource) + } + return out +} + +func NewRuntimeInstanceResourceList() coremodel.ResourceList { + return &RuntimeInstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RuntimeInstanceKind), + APIVersion: "v1alpha1", + }, + Items: make([]*RuntimeInstanceResource, 0), + } +} + +func (r *RuntimeInstanceResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*RuntimeInstanceResource, len(items)) + for i := range items { + res, ok := items[i].(*RuntimeInstanceResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", RuntimeInstanceKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewRuntimeInstanceResourceListWithItems(items ...*RuntimeInstanceResource) *RuntimeInstanceResourceList { + return &RuntimeInstanceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(RuntimeInstanceKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/service_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/service_helper.go new file mode 100644 index 000000000..36fcaf6d5 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/service_helper.go @@ -0,0 +1,16 @@ +package v1alpha1 + +import "github.com/apache/dubbo-admin/pkg/common/constants" + +// BuildServiceKey builds a metadata key with app name. +// {service}:{version}:{group}:{appName} +func BuildServiceKey(serviceName, version, group, appName string) string { + return serviceName + constants.ColonSeparator + version + + constants.ColonSeparator + group + constants.ColonSeparator + appName +} + +// BuildServiceIdentityKey builds the unique service identity key. +// {service}:{version}:{group} +func BuildServiceIdentityKey(serviceName, version, group string) string { + return serviceName + constants.ColonSeparator + version + constants.ColonSeparator + group +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/service_types.go b/pkg/core/resource/apis/mesh/v1alpha1/service_types.go index f3abeb289..74ba69a4b 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/service_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/service_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Namespaced - const ServiceKind coremodel.ResourceKind = "Service" func init() { - coremodel.RegisterResourceKind(ServiceKind) + coremodel.RegisterResourceSchema(ServiceKind, NewServiceResource, NewServiceResourceList) } type ServiceResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo Service resource. - // +kubebuilder:validation:Optional Spec *meshproto.Service `json:"spec,omitempty"` + // Status is the status of the Dubbo Service resource. Status ServiceResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type ServiceResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster -type ServiceResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ServiceResource `json:"items"` -} - func (r *ServiceResource) ResourceKind() coremodel.ResourceKind { return ServiceKind } -func (r *ServiceResource) MeshName() string { +func (r *ServiceResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *ServiceResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewServiceResource(name string, mesh string, apiVersion string) *ServiceResource { +func (r *ServiceResource) DeepCopyObject() k8sruntime.Object { + out := &ServiceResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.Service) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ServiceResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ServiceResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewServiceResourceWithAttributes(name string, mesh string) *ServiceResource { return &ServiceResource{ TypeMeta: metav1.TypeMeta{ Kind: string(ServiceKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.Service{}, + } +} + +func NewServiceResource() coremodel.Resource { + return &ServiceResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.Service{}, + } +} + +type ServiceResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ServiceResource `json:"items"` +} + +func (r *ServiceResourceList) DeepCopyObject() k8sruntime.Object { + out := &ServiceResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ServiceResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ServiceResource) + } + return out +} + +func NewServiceResourceList() coremodel.ResourceList { + return &ServiceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ServiceResource, 0), + } +} + +func (r *ServiceResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ServiceResource, len(items)) + for i := range items { + res, ok := items[i].(*ServiceResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ServiceKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewServiceResourceListWithItems(items ...*ServiceResource) *ServiceResourceList { + return &ServiceResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_helper.go new file mode 100644 index 000000000..9c83a504a --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_helper.go @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "encoding/json" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func ToServiceConsumerMetadataByRawData(mesh string, data string) coremodel.Resource { + metadataMap := make(map[string]string) + err := json.Unmarshal([]byte(data), &metadataMap) + if err != nil { + logger.Errorf("parse service consumer metadata failed, cause: %v, raw data:\n %s", err, data) + return nil + } + return ToServiceConsumerMetadataByMap(metadataMap, mesh) +} + +func ToServiceConsumerMetadataByMap(metadata map[string]string, mesh string) *ServiceConsumerMetadataResource { + consumerAppName, exists := metadata[constants.Application] + if !exists { + logger.Errorf("service consumer metadata is invalid because no application name found, raw metadata: %v", metadata) + } + serviceName, exists := metadata[constants.InterfaceKey] + if !exists { + logger.Errorf("service consumer metadata is invalid because no service name found, raw metadata: %v", metadata) + return nil + } + version := metadata[constants.VersionKey] + group := metadata[constants.GroupKey] + resKey := BuildServiceKey(serviceName, version, group, consumerAppName) + res := NewServiceConsumerMetadataResourceWithAttributes(resKey, mesh) + res.Spec = &meshproto.ServiceConsumerMetadata{ + ServiceName: serviceName, + ConsumerAppName: consumerAppName, + Version: version, + Group: group, + Metadata: metadata, + } + return res +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_types.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_types.go new file mode 100644 index 000000000..44996d896 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceconsumermetadata_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ServiceConsumerMetadataKind coremodel.ResourceKind = "ServiceConsumerMetadata" + +func init() { + coremodel.RegisterResourceSchema(ServiceConsumerMetadataKind, NewServiceConsumerMetadataResource, NewServiceConsumerMetadataResourceList) +} + +type ServiceConsumerMetadataResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo ServiceConsumerMetadata resource. + Spec *meshproto.ServiceConsumerMetadata `json:"spec,omitempty"` + + // Status is the status of the Dubbo ServiceConsumerMetadata resource. + Status ServiceConsumerMetadataResourceStatus `json:"status,omitempty"` +} + +type ServiceConsumerMetadataResourceStatus struct { + // define resource-specific status here +} + +func (r *ServiceConsumerMetadataResource) ResourceKind() coremodel.ResourceKind { + return ServiceConsumerMetadataKind +} + +func (r *ServiceConsumerMetadataResource) ResourceMesh() string { + return r.Mesh +} + +func (r *ServiceConsumerMetadataResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *ServiceConsumerMetadataResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *ServiceConsumerMetadataResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *ServiceConsumerMetadataResource) DeepCopyObject() k8sruntime.Object { + out := &ServiceConsumerMetadataResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ServiceConsumerMetadata) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ServiceConsumerMetadataResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ServiceConsumerMetadataResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewServiceConsumerMetadataResourceWithAttributes(name string, mesh string) *ServiceConsumerMetadataResource { + return &ServiceConsumerMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceConsumerMetadataKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.ServiceConsumerMetadata{}, + } +} + +func NewServiceConsumerMetadataResource() coremodel.Resource { + return &ServiceConsumerMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceConsumerMetadataKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ServiceConsumerMetadata{}, + } +} + +type ServiceConsumerMetadataResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ServiceConsumerMetadataResource `json:"items"` +} + +func (r *ServiceConsumerMetadataResourceList) DeepCopyObject() k8sruntime.Object { + out := &ServiceConsumerMetadataResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ServiceConsumerMetadataResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ServiceConsumerMetadataResource) + } + return out +} + +func NewServiceConsumerMetadataResourceList() coremodel.ResourceList { + return &ServiceConsumerMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceConsumerMetadataKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ServiceConsumerMetadataResource, 0), + } +} + +func (r *ServiceConsumerMetadataResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ServiceConsumerMetadataResource, len(items)) + for i := range items { + res, ok := items[i].(*ServiceConsumerMetadataResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ServiceConsumerMetadataKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewServiceConsumerMetadataResourceListWithItems(items ...*ServiceConsumerMetadataResource) *ServiceConsumerMetadataResourceList { + return &ServiceConsumerMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceConsumerMetadataKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_helper.go new file mode 100644 index 000000000..f3ecd04d1 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_helper.go @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "strings" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func ToServiceProviderMappingResource(mesh, name, data string) coremodel.Resource { + appNames := strings.Split(data, constants.CommaSeparator) + mappingRes := NewServiceProviderMappingResourceWithAttributes(name, mesh) + mappingRes.Spec = &meshproto.ServiceProviderMapping{ + ServiceName: name, + AppNames: appNames, + } + return mappingRes +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_types.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_types.go new file mode 100644 index 000000000..903b0d98d --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermapping_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ServiceProviderMappingKind coremodel.ResourceKind = "ServiceProviderMapping" + +func init() { + coremodel.RegisterResourceSchema(ServiceProviderMappingKind, NewServiceProviderMappingResource, NewServiceProviderMappingResourceList) +} + +type ServiceProviderMappingResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo ServiceProviderMapping resource. + Spec *meshproto.ServiceProviderMapping `json:"spec,omitempty"` + + // Status is the status of the Dubbo ServiceProviderMapping resource. + Status ServiceProviderMappingResourceStatus `json:"status,omitempty"` +} + +type ServiceProviderMappingResourceStatus struct { + // define resource-specific status here +} + +func (r *ServiceProviderMappingResource) ResourceKind() coremodel.ResourceKind { + return ServiceProviderMappingKind +} + +func (r *ServiceProviderMappingResource) ResourceMesh() string { + return r.Mesh +} + +func (r *ServiceProviderMappingResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *ServiceProviderMappingResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *ServiceProviderMappingResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *ServiceProviderMappingResource) DeepCopyObject() k8sruntime.Object { + out := &ServiceProviderMappingResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ServiceProviderMapping) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ServiceProviderMappingResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ServiceProviderMappingResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewServiceProviderMappingResourceWithAttributes(name string, mesh string) *ServiceProviderMappingResource { + return &ServiceProviderMappingResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMappingKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.ServiceProviderMapping{}, + } +} + +func NewServiceProviderMappingResource() coremodel.Resource { + return &ServiceProviderMappingResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMappingKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ServiceProviderMapping{}, + } +} + +type ServiceProviderMappingResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ServiceProviderMappingResource `json:"items"` +} + +func (r *ServiceProviderMappingResourceList) DeepCopyObject() k8sruntime.Object { + out := &ServiceProviderMappingResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ServiceProviderMappingResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ServiceProviderMappingResource) + } + return out +} + +func NewServiceProviderMappingResourceList() coremodel.ResourceList { + return &ServiceProviderMappingResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMappingKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ServiceProviderMappingResource, 0), + } +} + +func (r *ServiceProviderMappingResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ServiceProviderMappingResource, len(items)) + for i := range items { + res, ok := items[i].(*ServiceProviderMappingResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ServiceProviderMappingKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewServiceProviderMappingResourceListWithItems(items ...*ServiceProviderMappingResource) *ServiceProviderMappingResourceList { + return &ServiceProviderMappingResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMappingKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_helper.go new file mode 100644 index 000000000..250474d63 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_helper.go @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "encoding/json" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func ToServiceProviderMetadataResource(mesh, name, data string) coremodel.Resource { + metadataSpec := &meshproto.ServiceProviderMetadata{} + err := json.Unmarshal([]byte(data), metadataSpec) + if err != nil { + logger.Errorf("cannot unmarshal service provider metadata %s in %s, cause: %s, raw content:\n %s,", name, mesh, err, data) + return nil + } + metadataSpec.ServiceName = metadataSpec.CanonicalName + metadataSpec.ProviderAppName = metadataSpec.Parameters[constants.Application] + metadataSpec.Version = metadataSpec.Parameters[constants.VersionKey] + metadataSpec.Group = metadataSpec.Parameters[constants.GroupKey] + serviceKey := BuildServiceKey(metadataSpec.ServiceName, metadataSpec.Version, metadataSpec.Group, metadataSpec.ProviderAppName) + metadataRes := NewServiceProviderMetadataResourceWithAttributes(serviceKey, mesh) + metadataRes.Spec = metadataSpec + return metadataRes +} + +func ToServiceProviderMetadataRes(mesh, data string) coremodel.Resource { + return ToServiceProviderMetadataResource(mesh, "", data) +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_types.go b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_types.go new file mode 100644 index 000000000..840bcd52d --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/serviceprovidermetadata_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ServiceProviderMetadataKind coremodel.ResourceKind = "ServiceProviderMetadata" + +func init() { + coremodel.RegisterResourceSchema(ServiceProviderMetadataKind, NewServiceProviderMetadataResource, NewServiceProviderMetadataResourceList) +} + +type ServiceProviderMetadataResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo ServiceProviderMetadata resource. + Spec *meshproto.ServiceProviderMetadata `json:"spec,omitempty"` + + // Status is the status of the Dubbo ServiceProviderMetadata resource. + Status ServiceProviderMetadataResourceStatus `json:"status,omitempty"` +} + +type ServiceProviderMetadataResourceStatus struct { + // define resource-specific status here +} + +func (r *ServiceProviderMetadataResource) ResourceKind() coremodel.ResourceKind { + return ServiceProviderMetadataKind +} + +func (r *ServiceProviderMetadataResource) ResourceMesh() string { + return r.Mesh +} + +func (r *ServiceProviderMetadataResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *ServiceProviderMetadataResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *ServiceProviderMetadataResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *ServiceProviderMetadataResource) DeepCopyObject() k8sruntime.Object { + out := &ServiceProviderMetadataResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ServiceProviderMetadata) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ServiceProviderMetadataResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ServiceProviderMetadataResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewServiceProviderMetadataResourceWithAttributes(name string, mesh string) *ServiceProviderMetadataResource { + return &ServiceProviderMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMetadataKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.ServiceProviderMetadata{}, + } +} + +func NewServiceProviderMetadataResource() coremodel.Resource { + return &ServiceProviderMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMetadataKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ServiceProviderMetadata{}, + } +} + +type ServiceProviderMetadataResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ServiceProviderMetadataResource `json:"items"` +} + +func (r *ServiceProviderMetadataResourceList) DeepCopyObject() k8sruntime.Object { + out := &ServiceProviderMetadataResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ServiceProviderMetadataResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ServiceProviderMetadataResource) + } + return out +} + +func NewServiceProviderMetadataResourceList() coremodel.ResourceList { + return &ServiceProviderMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMetadataKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ServiceProviderMetadataResource, 0), + } +} + +func (r *ServiceProviderMetadataResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ServiceProviderMetadataResource, len(items)) + for i := range items { + res, ok := items[i].(*ServiceProviderMetadataResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ServiceProviderMetadataKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewServiceProviderMetadataResourceListWithItems(items ...*ServiceProviderMetadataResource) *ServiceProviderMetadataResourceList { + return &ServiceProviderMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ServiceProviderMetadataKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/tagroute_helper.go b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_helper.go new file mode 100644 index 000000000..92b7aeea9 --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_helper.go @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package v1alpha1 + +import ( + "sigs.k8s.io/yaml" + + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +func ToTagRouteResource(mesh, name, data string) coremodel.Resource { + res := NewTagRouteResourceWithAttributes(name, mesh) + err := yaml.Unmarshal([]byte(data), res.Spec) + if err != nil { + logger.Warnf("cannot unmarshal tag route %s in %s, cause: %s, raw content:\n %s, ", name, mesh, err, data) + } + return res +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go index 516c16430..90c82be3d 100644 --- a/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go +++ b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go @@ -21,33 +21,35 @@ package v1alpha1 import ( + "encoding/json" + + "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" ) -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - const TagRouteKind coremodel.ResourceKind = "TagRoute" func init() { - coremodel.RegisterResourceKind(TagRouteKind) + coremodel.RegisterResourceSchema(TagRouteKind, NewTagRouteResource, NewTagRouteResourceList) } type TagRouteResource struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` // Mesh is the name of the dubbo mesh this resource belongs to. // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional Mesh string `json:"mesh,omitempty"` + // Spec is the specification of the Dubbo TagRoute resource. - // +kubebuilder:validation:Optional Spec *meshproto.TagRoute `json:"spec,omitempty"` + // Status is the status of the Dubbo TagRoute resource. Status TagRouteResourceStatus `json:"status,omitempty"` } @@ -56,19 +58,11 @@ type TagRouteResourceStatus struct { // define resource-specific status here } -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type TagRouteResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []TagRouteResource `json:"items"` -} - func (r *TagRouteResource) ResourceKind() coremodel.ResourceKind { return TagRouteKind } -func (r *TagRouteResource) MeshName() string { +func (r *TagRouteResource) ResourceMesh() string { return r.Mesh } @@ -84,16 +78,111 @@ func (r *TagRouteResource) ResourceSpec() coremodel.ResourceSpec { return r.Spec } -func NewTagRouteResource(name string, mesh string, apiVersion string) *TagRouteResource { +func (r *TagRouteResource) DeepCopyObject() k8sruntime.Object { + out := &TagRouteResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.TagRoute) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *TagRouteResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode TagRouteResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewTagRouteResourceWithAttributes(name string, mesh string) *TagRouteResource { return &TagRouteResource{ TypeMeta: metav1.TypeMeta{ Kind: string(TagRouteKind), - APIVersion: apiVersion, + APIVersion: "v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{}, }, Mesh: mesh, + Spec: &meshproto.TagRoute{}, + } +} + +func NewTagRouteResource() coremodel.Resource { + return &TagRouteResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(TagRouteKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.TagRoute{}, + } +} + +type TagRouteResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*TagRouteResource `json:"items"` +} + +func (r *TagRouteResourceList) DeepCopyObject() k8sruntime.Object { + out := &TagRouteResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*TagRouteResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*TagRouteResource) + } + return out +} + +func NewTagRouteResourceList() coremodel.ResourceList { + return &TagRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(TagRouteKind), + APIVersion: "v1alpha1", + }, + Items: make([]*TagRouteResource, 0), + } +} + +func (r *TagRouteResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*TagRouteResource, len(items)) + for i := range items { + res, ok := items[i].(*TagRouteResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", TagRouteKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewTagRouteResourceListWithItems(items ...*TagRouteResource) *TagRouteResourceList { + return &TagRouteResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(TagRouteKind), + APIVersion: "v1alpha1", + }, + Items: items, } } diff --git a/pkg/core/resource/apis/mesh/v1alpha1/zkconfig_types.go b/pkg/core/resource/apis/mesh/v1alpha1/zkconfig_types.go new file mode 100644 index 000000000..700f2883a --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/zkconfig_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ZKConfigKind coremodel.ResourceKind = "ZKConfig" + +func init() { + coremodel.RegisterResourceSchema(ZKConfigKind, NewZKConfigResource, NewZKConfigResourceList) +} + +type ZKConfigResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo ZKConfig resource. + Spec *meshproto.ZKConfig `json:"spec,omitempty"` + + // Status is the status of the Dubbo ZKConfig resource. + Status ZKConfigResourceStatus `json:"status,omitempty"` +} + +type ZKConfigResourceStatus struct { + // define resource-specific status here +} + +func (r *ZKConfigResource) ResourceKind() coremodel.ResourceKind { + return ZKConfigKind +} + +func (r *ZKConfigResource) ResourceMesh() string { + return r.Mesh +} + +func (r *ZKConfigResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *ZKConfigResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *ZKConfigResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *ZKConfigResource) DeepCopyObject() k8sruntime.Object { + out := &ZKConfigResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ZKConfig) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ZKConfigResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ZKConfigResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewZKConfigResourceWithAttributes(name string, mesh string) *ZKConfigResource { + return &ZKConfigResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKConfigKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.ZKConfig{}, + } +} + +func NewZKConfigResource() coremodel.Resource { + return &ZKConfigResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKConfigKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ZKConfig{}, + } +} + +type ZKConfigResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ZKConfigResource `json:"items"` +} + +func (r *ZKConfigResourceList) DeepCopyObject() k8sruntime.Object { + out := &ZKConfigResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ZKConfigResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ZKConfigResource) + } + return out +} + +func NewZKConfigResourceList() coremodel.ResourceList { + return &ZKConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKConfigKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ZKConfigResource, 0), + } +} + +func (r *ZKConfigResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ZKConfigResource, len(items)) + for i := range items { + res, ok := items[i].(*ZKConfigResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ZKConfigKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewZKConfigResourceListWithItems(items ...*ZKConfigResource) *ZKConfigResourceList { + return &ZKConfigResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKConfigKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/mesh/v1alpha1/zkmetadata_types.go b/pkg/core/resource/apis/mesh/v1alpha1/zkmetadata_types.go new file mode 100644 index 000000000..5190de16e --- /dev/null +++ b/pkg/core/resource/apis/mesh/v1alpha1/zkmetadata_types.go @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ZKMetadataKind coremodel.ResourceKind = "ZKMetadata" + +func init() { + coremodel.RegisterResourceSchema(ZKMetadataKind, NewZKMetadataResource, NewZKMetadataResourceList) +} + +type ZKMetadataResource struct { + metav1.TypeMeta `json:",inline"` + + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string `json:"mesh,omitempty"` + + // Spec is the specification of the Dubbo ZKMetadata resource. + Spec *meshproto.ZKMetadata `json:"spec,omitempty"` + + // Status is the status of the Dubbo ZKMetadata resource. + Status ZKMetadataResourceStatus `json:"status,omitempty"` +} + +type ZKMetadataResourceStatus struct { + // define resource-specific status here +} + +func (r *ZKMetadataResource) ResourceKind() coremodel.ResourceKind { + return ZKMetadataKind +} + +func (r *ZKMetadataResource) ResourceMesh() string { + return r.Mesh +} + +func (r *ZKMetadataResource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *ZKMetadataResource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *ZKMetadataResource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *ZKMetadataResource) DeepCopyObject() k8sruntime.Object { + out := &ZKMetadataResource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*meshproto.ZKMetadata) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *ZKMetadataResource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode ZKMetadataResource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func NewZKMetadataResourceWithAttributes(name string, mesh string) *ZKMetadataResource { + return &ZKMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKMetadataKind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.ZKMetadata{}, + } +} + +func NewZKMetadataResource() coremodel.Resource { + return &ZKMetadataResource{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKMetadataKind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.ZKMetadata{}, + } +} + +type ZKMetadataResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*ZKMetadataResource `json:"items"` +} + +func (r *ZKMetadataResourceList) DeepCopyObject() k8sruntime.Object { + out := &ZKMetadataResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*ZKMetadataResource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*ZKMetadataResource) + } + return out +} + +func NewZKMetadataResourceList() coremodel.ResourceList { + return &ZKMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKMetadataKind), + APIVersion: "v1alpha1", + }, + Items: make([]*ZKMetadataResource, 0), + } +} + +func (r *ZKMetadataResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*ZKMetadataResource, len(items)) + for i := range items { + res, ok := items[i].(*ZKMetadataResource) + if !ok { + logger.Errorf("unexpected resource type, expected: %s, get %s", ZKMetadataKind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func NewZKMetadataResourceListWithItems(items ...*ZKMetadataResource) *ZKMetadataResourceList { + return &ZKMetadataResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string(ZKMetadataKind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} diff --git a/pkg/core/resource/apis/system/v1alpha1/config_types.go b/pkg/core/resource/apis/system/v1alpha1/config_types.go deleted file mode 100644 index 2d6f2328e..000000000 --- a/pkg/core/resource/apis/system/v1alpha1/config_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - systemproto "github.com/apache/dubbo-admin/api/system/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - -const ConfigKind coremodel.ResourceKind = "Config" - -func init() { - coremodel.RegisterResourceKind(ConfigKind) -} - -type ConfigResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo Config resource. - // +kubebuilder:validation:Optional - Spec *systemproto.Config `json:"spec,omitempty"` - // Status is the status of the Dubbo Config resource. - Status ConfigResourceStatus `json:"status,omitempty"` -} - -type ConfigResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type ConfigResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ConfigResource `json:"items"` -} - -func (r *ConfigResource) ResourceKind() coremodel.ResourceKind { - return ConfigKind -} - -func (r *ConfigResource) MeshName() string { - return r.Mesh -} - -func (r *ConfigResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *ConfigResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *ConfigResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewConfigResource(name string, mesh string, apiVersion string) *ConfigResource { - return &ConfigResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(ConfigKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/pkg/core/resource/apis/system/v1alpha1/datasource_types.go b/pkg/core/resource/apis/system/v1alpha1/datasource_types.go deleted file mode 100644 index 5788de8b3..000000000 --- a/pkg/core/resource/apis/system/v1alpha1/datasource_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - systemproto "github.com/apache/dubbo-admin/api/system/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - -const DataSourceKind coremodel.ResourceKind = "DataSource" - -func init() { - coremodel.RegisterResourceKind(DataSourceKind) -} - -type DataSourceResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo DataSource resource. - // +kubebuilder:validation:Optional - Spec *systemproto.DataSource `json:"spec,omitempty"` - // Status is the status of the Dubbo DataSource resource. - Status DataSourceResourceStatus `json:"status,omitempty"` -} - -type DataSourceResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type DataSourceResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []DataSourceResource `json:"items"` -} - -func (r *DataSourceResource) ResourceKind() coremodel.ResourceKind { - return DataSourceKind -} - -func (r *DataSourceResource) MeshName() string { - return r.Mesh -} - -func (r *DataSourceResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *DataSourceResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *DataSourceResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewDataSourceResource(name string, mesh string, apiVersion string) *DataSourceResource { - return &DataSourceResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(DataSourceKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/pkg/core/resource/apis/system/v1alpha1/secret_types.go b/pkg/core/resource/apis/system/v1alpha1/secret_types.go deleted file mode 100644 index fc356a8fb..000000000 --- a/pkg/core/resource/apis/system/v1alpha1/secret_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - systemproto "github.com/apache/dubbo-admin/api/system/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - -const SecretKind coremodel.ResourceKind = "Secret" - -func init() { - coremodel.RegisterResourceKind(SecretKind) -} - -type SecretResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo Secret resource. - // +kubebuilder:validation:Optional - Spec *systemproto.Secret `json:"spec,omitempty"` - // Status is the status of the Dubbo Secret resource. - Status SecretResourceStatus `json:"status,omitempty"` -} - -type SecretResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type SecretResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []SecretResource `json:"items"` -} - -func (r *SecretResource) ResourceKind() coremodel.ResourceKind { - return SecretKind -} - -func (r *SecretResource) MeshName() string { - return r.Mesh -} - -func (r *SecretResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *SecretResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *SecretResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewSecretResource(name string, mesh string, apiVersion string) *SecretResource { - return &SecretResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(SecretKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/pkg/core/resource/apis/system/v1alpha1/zone_types.go b/pkg/core/resource/apis/system/v1alpha1/zone_types.go deleted file mode 100644 index d57d38f93..000000000 --- a/pkg/core/resource/apis/system/v1alpha1/zone_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - systemproto "github.com/apache/dubbo-admin/api/system/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - -const ZoneKind coremodel.ResourceKind = "Zone" - -func init() { - coremodel.RegisterResourceKind(ZoneKind) -} - -type ZoneResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo Zone resource. - // +kubebuilder:validation:Optional - Spec *systemproto.Zone `json:"spec,omitempty"` - // Status is the status of the Dubbo Zone resource. - Status ZoneResourceStatus `json:"status,omitempty"` -} - -type ZoneResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type ZoneResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ZoneResource `json:"items"` -} - -func (r *ZoneResource) ResourceKind() coremodel.ResourceKind { - return ZoneKind -} - -func (r *ZoneResource) MeshName() string { - return r.Mesh -} - -func (r *ZoneResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *ZoneResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *ZoneResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewZoneResource(name string, mesh string, apiVersion string) *ZoneResource { - return &ZoneResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(ZoneKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go b/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go deleted file mode 100644 index 6b21872a9..000000000 --- a/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - systemproto "github.com/apache/dubbo-admin/api/system/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// +kubebuilder:object:root=true -// +kubebuilder:resource:categories=dubbo,scope=Cluster - -const ZoneInsightKind coremodel.ResourceKind = "ZoneInsight" - -func init() { - coremodel.RegisterResourceKind(ZoneInsightKind) -} - -type ZoneInsightResource struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string `json:"mesh,omitempty"` - // Spec is the specification of the Dubbo ZoneInsight resource. - // +kubebuilder:validation:Optional - Spec *systemproto.ZoneInsight `json:"spec,omitempty"` - // Status is the status of the Dubbo ZoneInsight resource. - Status ZoneInsightResourceStatus `json:"status,omitempty"` -} - -type ZoneInsightResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced -type ZoneInsightResourceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ZoneInsightResource `json:"items"` -} - -func (r *ZoneInsightResource) ResourceKind() coremodel.ResourceKind { - return ZoneInsightKind -} - -func (r *ZoneInsightResource) MeshName() string { - return r.Mesh -} - -func (r *ZoneInsightResource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *ZoneInsightResource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *ZoneInsightResource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func NewZoneInsightResource(name string, mesh string, apiVersion string) *ZoneInsightResource { - return &ZoneInsightResource{ - TypeMeta: metav1.TypeMeta{ - Kind: string(ZoneInsightKind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} diff --git a/pkg/core/resource/model/page.go b/pkg/core/resource/model/page.go index f91ad797e..3b195ce86 100644 --- a/pkg/core/resource/model/page.go +++ b/pkg/core/resource/model/page.go @@ -1,15 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package model -type PageQuery struct { - PageSize uint32 - CurrentPage uint32 - Page bool +type PageReq struct { + PageOffset int `form:"pageOffset" json:"pageOffset"` + PageSize int `form:"pageSize" json:"pageSize"` } type Pagination struct { - PageSize uint32 - CurrentPage uint32 - Total uint32 - Page bool - NextOffset string + Total int `json:"total"` + PageSize int `json:"pageSize"` + PageOffset int `json:"pageOffset"` +} + +type PageData[T any] struct { + Pagination + Data []T `json:"data"` +} + +func NewPageData[T any](total, pageOffset, pageSize int, data []T) *PageData[T] { + return &PageData[T]{ + Pagination: Pagination{ + Total: total, + PageSize: pageSize, + PageOffset: pageOffset, + }, + Data: data, + } +} + +func (pd *PageData[T]) WithTotal(total int) *PageData[T] { + pd.Total = total + return pd +} + +func (pd *PageData[T]) WithCurPage(curPage int) *PageData[T] { + pd.PageOffset = curPage + return pd +} + +func (pd *PageData[T]) WithPageSize(pageSize int) *PageData[T] { + pd.PageSize = pageSize + return pd +} + +func (pd *PageData[T]) WithData(data []T) *PageData[T] { + pd.Data = data + return pd } diff --git a/pkg/core/resource/model/registry.go b/pkg/core/resource/model/registry.go index 8ed401c29..67883f4b3 100644 --- a/pkg/core/resource/model/registry.go +++ b/pkg/core/resource/model/registry.go @@ -1,25 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package model -import ds "github.com/duke-git/lancet/v2/datastructure/set" +import ( + "fmt" + + "github.com/duke-git/lancet/v2/maputil" +) -var global = newRegistry() +var registry = newRegistry() -func ResourceKindRegistry() Registry { - return global +func ResourceSchemaRegistry() Registry { + return registry } -func RegisterResourceKind(kind ResourceKind) { - global.Register(kind) +func RegisterResourceSchema(kind ResourceKind, newFunc NewResourceFunc, newListFunc NewResourceListFunc) { + registry.Register(kind, newFunc, newListFunc) } +type NewResourceFunc func() Resource + +type NewResourceListFunc func() ResourceList + type Registry interface { - // AllResourceKinds returns all registered resource kinds + // AllResourceKinds returns all registered resource resourceDir AllResourceKinds() []ResourceKind + // NewResourceFunc returns the new resource function for a resource kind + NewResourceFunc(kind ResourceKind) (NewResourceFunc, error) + // NewResourceListFunc returns the new resource list function for a resource kind + NewResourceListFunc(kind ResourceKind) (NewResourceListFunc, error) } type RegistryMutator interface { // Register registers a resource kind, if a resource kind has been registered before, it will be ignored - Register(kind ResourceKind) + Register(kind ResourceKind, newFunc NewResourceFunc, newListFunc NewResourceListFunc) } type MutableRegistry interface { @@ -27,22 +56,46 @@ type MutableRegistry interface { RegistryMutator } -var _ MutableRegistry = &resourceKindRegistry{} +var _ MutableRegistry = &resourceSchemaRegistry{} func newRegistry() MutableRegistry { - return &resourceKindRegistry{ - kinds: ds.New[ResourceKind](), + return &resourceSchemaRegistry{ + resourceDir: make(map[ResourceKind]resourceSchema), } } -type resourceKindRegistry struct { - kinds ds.Set[ResourceKind] +type resourceSchema struct { + rk ResourceKind + newFunc NewResourceFunc + newListFunc NewResourceListFunc } -func (r *resourceKindRegistry) AllResourceKinds() []ResourceKind { - return r.kinds.ToSlice() +type resourceSchemaRegistry struct { + resourceDir map[ResourceKind]resourceSchema } -func (r *resourceKindRegistry) Register(kind ResourceKind) { - r.kinds.Add(kind) +func (r *resourceSchemaRegistry) AllResourceKinds() []ResourceKind { + return maputil.Keys(r.resourceDir) +} + +func (r *resourceSchemaRegistry) Register(kind ResourceKind, newFunc NewResourceFunc, newListFunc NewResourceListFunc) { + r.resourceDir[kind] = resourceSchema{ + rk: kind, + newFunc: newFunc, + newListFunc: newListFunc, + } +} + +func (r *resourceSchemaRegistry) NewResourceFunc(kind ResourceKind) (NewResourceFunc, error) { + if rs, exists := r.resourceDir[kind]; exists { + return rs.newFunc, nil + } + return nil, fmt.Errorf("there is no new resource func for %s", kind) +} + +func (r *resourceSchemaRegistry) NewResourceListFunc(kind ResourceKind) (NewResourceListFunc, error) { + if rs, exists := r.resourceDir[kind]; exists { + return rs.newListFunc, nil + } + return nil, fmt.Errorf("there is no new resource list func for %s", kind) } diff --git a/pkg/core/resource/model/resource.go b/pkg/core/resource/model/resource.go index 8b47d7cde..1ff3485b8 100644 --- a/pkg/core/resource/model/resource.go +++ b/pkg/core/resource/model/resource.go @@ -18,29 +18,11 @@ package model import ( - "fmt" - "reflect" - + k8smeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - DefaultMesh = "default" - // NoMesh defines a marker that resource is not bound to a Mesh. - // Resources not bound to a mesh (ScopeGlobal) should have an empty string in Mesh field. - NoMesh = "" -) + k8sruntime "k8s.io/apimachinery/pkg/runtime" -const separator = "/" - -const ( - ExtensionsImageKey = "image" - ExtensionsPodPhaseKey = "podPhase" - ExtensionsPodStatusKey = "podStatus" - ExtensionsContainerStatusReasonKey = "containerStatus" - ExtensionApplicationNameKey = "applicationName" // For universial mode - ExtensionsWorkLoadKey = "workLoad" - ExtensionsNodeNameKey = "nodeName" + "github.com/apache/dubbo-admin/pkg/common/constants" ) type ResourceSpec interface{} @@ -53,23 +35,29 @@ func (rk ResourceKind) ToString() string { } type Resource interface { + k8sruntime.Object // ResourceKind returns the resource type, e.g. Application, Service etc. ResourceKind() ResourceKind // ResourceKey returns the unique resource key ResourceKey() string - // MeshName returns the mesh which the resource belongs to - MeshName() string + // ResourceMesh returns the mesh which the resource belongs to + ResourceMesh() string // ResourceMeta returns the resource metadata ResourceMeta() metav1.ObjectMeta // ResourceSpec returns the resource spec ResourceSpec() ResourceSpec + // String returns the string representation of the resource + String() string } -// BuildResourceKey build a unique identifier for a resource, usually is `mesh/kind/name` -func BuildResourceKey(mesh string, name string) string { - return mesh + separator + name +type ResourceList interface { + k8sruntime.Object + k8smeta.List + + SetItems(items []Resource) } -func ErrorInvalidItemType(expected, actual interface{}) error { - return fmt.Errorf("invalid argument type: expected=%q got=%q", reflect.TypeOf(expected), reflect.TypeOf(actual)) +// BuildResourceKey build a unique identifier for a resource, usually is `mesh/name` +func BuildResourceKey(mesh string, name string) string { + return mesh + constants.PathSeparator + name } diff --git a/pkg/core/runtime/builder.go b/pkg/core/runtime/builder.go index a4b6bbb04..191470b00 100644 --- a/pkg/core/runtime/builder.go +++ b/pkg/core/runtime/builder.go @@ -23,10 +23,10 @@ import ( "os" "time" + "github.com/google/uuid" "github.com/pkg/errors" "github.com/apache/dubbo-admin/pkg/config/app" - "github.com/apache/dubbo-admin/pkg/core" ) // BuilderContext provides access to Builder's interim state. @@ -59,7 +59,7 @@ func BuilderFor(appCtx context.Context, cfg app.AdminConfig) (*Builder, error) { if err != nil { return nil, errors.Wrap(err, "could not get hostname") } - suffix := core.NewUUID()[0:4] + suffix := uuid.NewString()[0:4] return &Builder{ cfg: cfg, appCtx: appCtx, @@ -67,8 +67,8 @@ func BuilderFor(appCtx context.Context, cfg app.AdminConfig) (*Builder, error) { instanceId: fmt.Sprintf("%s-%s", hostname, suffix), clusterId: fmt.Sprintf("%s-%s", hostname, suffix), startTime: time.Now(), - mode: cfg.Mode, }, + components: make(map[ComponentType]Component), }, nil } diff --git a/pkg/core/runtime/component.go b/pkg/core/runtime/component.go index 29f3ece39..ec90648f2 100644 --- a/pkg/core/runtime/component.go +++ b/pkg/core/runtime/component.go @@ -25,9 +25,11 @@ const ( ResourceStore ComponentType = "resource store" ResourceEngine ComponentType = "resource engine" ResourceDiscovery ComponentType = "resource discovery" + EventBus ComponentType = "event bus" + RuleGovernor ComponentType = "rule governor" ) -var CoreComponentTypes = []ComponentType{Console, ResourceManager, ResourceStore, ResourceEngine, ResourceDiscovery} +var CoreComponentTypes = []ComponentType{Console, ResourceManager, ResourceStore, ResourceEngine, ResourceDiscovery, RuleGovernor} type Lifecycle interface { // Init initializes the component @@ -41,7 +43,12 @@ type Attribute interface { // Type returns the type of the component Type() ComponentType // Order indicates the order of the component during bootstrap, the bigger will be started first + // Deprecated: Use RequiredDependencies() instead for explicit dependency management Order() int + // RequiredDependencies returns the component types that must be initialized before this component + // The system will ensure all required dependencies are initialized first, or fail with a clear error + // Return an empty slice if the component has no dependencies + RequiredDependencies() []ComponentType } // Component defines a process that will be run in the application diff --git a/pkg/core/runtime/dependency_graph.go b/pkg/core/runtime/dependency_graph.go new file mode 100644 index 000000000..bf42d3902 --- /dev/null +++ b/pkg/core/runtime/dependency_graph.go @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "fmt" + "sort" + "strings" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" +) + +// DependencyGraph represents the dependency relationships between components +// The adjacency list is stored in reverse: if A depends on B, we store B -> A +// This makes topological sort return components in initialization order +type DependencyGraph struct { + components map[ComponentType]Component + adjList map[ComponentType][]ComponentType // reverse adjacency list: dependent <- dependee +} + +// NewDependencyGraph creates a new dependency graph from components +func NewDependencyGraph(components []Component) *DependencyGraph { + dg := &DependencyGraph{ + components: make(map[ComponentType]Component), + adjList: make(map[ComponentType][]ComponentType), + } + + // Initialize adjacency list for all components + for _, comp := range components { + dg.components[comp.Type()] = comp + dg.adjList[comp.Type()] = []ComponentType{} + } + + // Build reverse adjacency list + // If component A depends on B, we create edge B -> A + // This way, the adjacency list represents "who depends on me" + for _, comp := range components { + for _, dependency := range comp.RequiredDependencies() { + // dependency -> comp.Type() + // Meaning: dependency is required by comp.Type() + dg.adjList[dependency] = append(dg.adjList[dependency], comp.Type()) + } + } + + return dg +} + +// TopologicalSort performs topological sort using Kahn's algorithm +// Returns components in initialization order (dependencies first) +func (dg *DependencyGraph) TopologicalSort() ([]Component, error) { + // 1. Validate all dependencies exist + if err := dg.validate(); err != nil { + return nil, err + } + + // 2. Calculate in-degree for each node + // In-degree = number of dependencies + indegree := make(map[ComponentType]int) + for _, comp := range dg.components { + indegree[comp.Type()] = len(comp.RequiredDependencies()) + } + + // 3. Find all nodes with in-degree 0 (no dependencies) + queue := []ComponentType{} + for typ, deg := range indegree { + if deg == 0 { + queue = append(queue, typ) + } + } + + // 4. Process nodes in topological order + result := []Component{} + visited := make(map[ComponentType]bool) + + for len(queue) > 0 { + // Sort queue alphabetically for deterministic ordering + sort.Strings(queue) + + // Pop the first element + current := queue[0] + queue = queue[1:] + + result = append(result, dg.components[current]) + visited[current] = true + + // Process all components that depend on current + for _, dependent := range dg.adjList[current] { + indegree[dependent]-- + if indegree[dependent] == 0 && !visited[dependent] { + queue = append(queue, dependent) + } + } + } + + // 5. Check for circular dependencies + if len(result) != len(dg.components) { + cycle := dg.findCycle() + return nil, newCircularDependencyError(cycle) + } + + return result, nil +} + +// validate checks that all declared dependencies exist +func (dg *DependencyGraph) validate() error { + for _, comp := range dg.components { + for _, dependency := range comp.RequiredDependencies() { + if _, exists := dg.components[dependency]; !exists { + return bizerror.Wrap( + fmt.Errorf("missing dependency %q", dependency), + bizerror.ConfigError, + fmt.Sprintf( + "component %q requires missing dependency %q. "+ + "Hint: Make sure %q is registered in ComponentRegistry()", + comp.Type(), dependency, dependency, + ), + ) + } + } + } + return nil +} + +// findCycle uses DFS to find a circular dependency +func (dg *DependencyGraph) findCycle() []ComponentType { + visited := make(map[ComponentType]bool) + recStack := make(map[ComponentType]bool) + var cycle []ComponentType + + var dfs func(ComponentType) bool + dfs = func(node ComponentType) bool { + visited[node] = true + recStack[node] = true + cycle = append(cycle, node) + + // Visit dependencies (not dependents) + for _, dependency := range dg.components[node].RequiredDependencies() { + if !visited[dependency] { + if dfs(dependency) { + return true + } + } else if recStack[dependency] { + // Found cycle, extract the cycle path + for i, typ := range cycle { + if typ == dependency { + cycle = cycle[i:] + return true + } + } + } + } + + recStack[node] = false + cycle = cycle[:len(cycle)-1] + return false + } + + for typ := range dg.components { + if !visited[typ] { + if dfs(typ) { + return cycle + } + } + } + + return nil +} + +// newCircularDependencyError creates a circular dependency error +func newCircularDependencyError(cycle []ComponentType) error { + if len(cycle) == 0 { + return bizerror.New(bizerror.ConfigError, "circular dependency detected") + } + + // Format cycle path: A -> B -> C -> A + path := make([]string, len(cycle)+1) + for i, typ := range cycle { + path[i] = string(typ) + } + path[len(cycle)] = string(cycle[0]) + cyclePath := strings.Join(path, " -> ") + + return bizerror.New( + bizerror.ConfigError, + fmt.Sprintf( + "circular dependency detected: %s. "+ + "Please check the RequiredDependencies() methods of these components and break the cycle", + cyclePath, + ), + ) +} diff --git a/pkg/core/runtime/dependency_graph_test.go b/pkg/core/runtime/dependency_graph_test.go new file mode 100644 index 000000000..ef8bbca40 --- /dev/null +++ b/pkg/core/runtime/dependency_graph_test.go @@ -0,0 +1,271 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// Mock component for testing +type mockComponent struct { + typ ComponentType + order int + deps []ComponentType +} + +func (m *mockComponent) Type() ComponentType { + return m.typ +} +func (m *mockComponent) Order() int { + return m.order +} +func (m *mockComponent) RequiredDependencies() []ComponentType { + return m.deps +} +func (m *mockComponent) Init(ctx BuilderContext) error { + return nil +} +func (m *mockComponent) Start(Runtime, <-chan struct{}) error { + return nil +} + +func TestDependencyGraph_SimpleLinearDependency(t *testing.T) { + // A -> B -> C + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"B"}}, + &mockComponent{typ: "B", order: 200, deps: []ComponentType{"C"}}, + &mockComponent{typ: "C", order: 300, deps: []ComponentType{}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 3, len(sorted)) + // C should be first, then B, then A + assert.Equal(t, ComponentType("C"), sorted[0].Type()) + assert.Equal(t, ComponentType("B"), sorted[1].Type()) + assert.Equal(t, ComponentType("A"), sorted[2].Type()) +} + +func TestDependencyGraph_DiamondDependency(t *testing.T) { + // A depends on B and C, both B and C depend on D + // A + // / \ + // B C + // \ / + // D + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"B", "C"}}, + &mockComponent{typ: "B", order: 200, deps: []ComponentType{"D"}}, + &mockComponent{typ: "C", order: 300, deps: []ComponentType{"D"}}, + &mockComponent{typ: "D", order: 400, deps: []ComponentType{}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 4, len(sorted)) + // D must be first + assert.Equal(t, ComponentType("D"), sorted[0].Type()) + // B and C can be in any order (alphabetically: B before C) + assert.Equal(t, ComponentType("B"), sorted[1].Type()) + assert.Equal(t, ComponentType("C"), sorted[2].Type()) + // A must be last + assert.Equal(t, ComponentType("A"), sorted[3].Type()) +} + +func TestDependencyGraph_CircularDependency_TwoNodes(t *testing.T) { + // A -> B -> A (circular) + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"B"}}, + &mockComponent{typ: "B", order: 200, deps: []ComponentType{"A"}}, + } + + graph := NewDependencyGraph(components) + _, err := graph.TopologicalSort() + + assert.Error(t, err) + assert.Contains(t, err.Error(), "circular dependency detected") + assert.Contains(t, err.Error(), "A") + assert.Contains(t, err.Error(), "B") +} + +func TestDependencyGraph_CircularDependency_ThreeNodes(t *testing.T) { + // A -> B -> C -> A (circular) + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"B"}}, + &mockComponent{typ: "B", order: 200, deps: []ComponentType{"C"}}, + &mockComponent{typ: "C", order: 300, deps: []ComponentType{"A"}}, + } + + graph := NewDependencyGraph(components) + _, err := graph.TopologicalSort() + + assert.Error(t, err) + assert.Contains(t, err.Error(), "circular dependency detected") + errMsg := err.Error() + assert.Contains(t, errMsg, "A") + assert.Contains(t, errMsg, "B") + assert.Contains(t, errMsg, "C") +} + +func TestDependencyGraph_MissingDependency(t *testing.T) { + // A depends on non-existent component "X" + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"X"}}, + } + + graph := NewDependencyGraph(components) + _, err := graph.TopologicalSort() + + assert.Error(t, err) + assert.Contains(t, err.Error(), "missing dependency") + assert.Contains(t, err.Error(), "X") +} + +func TestDependencyGraph_NoDependencies(t *testing.T) { + // All components independent, should sort alphabetically (deterministic) + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{}}, + &mockComponent{typ: "B", order: 300, deps: []ComponentType{}}, + &mockComponent{typ: "C", order: 200, deps: []ComponentType{}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 3, len(sorted)) + // With no dependencies, components are sorted alphabetically + assert.Equal(t, ComponentType("A"), sorted[0].Type()) + assert.Equal(t, ComponentType("B"), sorted[1].Type()) + assert.Equal(t, ComponentType("C"), sorted[2].Type()) +} + +func TestDependencyGraph_ComplexDependencies(t *testing.T) { + // Simulating real dubbo-admin components + // EventBus (no deps) + // Store -> EventBus + // Discovery -> EventBus, Store + // Engine -> EventBus, Store + // Manager -> Store + // Console -> Manager + components := []Component{ + &mockComponent{typ: "EventBus", order: 1000, deps: []ComponentType{}}, + &mockComponent{typ: "Store", order: 900, deps: []ComponentType{"EventBus"}}, + &mockComponent{typ: "Discovery", order: 800, deps: []ComponentType{"EventBus", "Store"}}, + &mockComponent{typ: "Engine", order: 700, deps: []ComponentType{"EventBus", "Store"}}, + &mockComponent{typ: "Manager", order: 600, deps: []ComponentType{"Store"}}, + &mockComponent{typ: "Console", order: 500, deps: []ComponentType{"Manager"}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 6, len(sorted)) + + // Create a map for easier verification + orderMap := make(map[ComponentType]int) + for i, comp := range sorted { + orderMap[comp.Type()] = i + } + + // Verify dependency constraints + assert.Less(t, orderMap["EventBus"], orderMap["Store"], "EventBus must initialize before Store") + assert.Less(t, orderMap["EventBus"], orderMap["Discovery"], "EventBus must initialize before Discovery") + assert.Less(t, orderMap["Store"], orderMap["Discovery"], "Store must initialize before Discovery") + assert.Less(t, orderMap["EventBus"], orderMap["Engine"], "EventBus must initialize before Engine") + assert.Less(t, orderMap["Store"], orderMap["Engine"], "Store must initialize before Engine") + assert.Less(t, orderMap["Store"], orderMap["Manager"], "Store must initialize before Manager") + assert.Less(t, orderMap["Manager"], orderMap["Console"], "Manager must initialize before Console") +} + +func TestDependencyGraph_SelfDependency(t *testing.T) { + // Component depends on itself (edge case) + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"A"}}, + } + + graph := NewDependencyGraph(components) + _, err := graph.TopologicalSort() + + assert.Error(t, err) + assert.Contains(t, err.Error(), "circular dependency detected") + assert.Contains(t, err.Error(), "A -> A") +} + +func TestDependencyGraph_MultipleDependenciesSameLevel(t *testing.T) { + // A depends on B, C, D (all at same level) + // B, C, D have no dependencies + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{"B", "C", "D"}}, + &mockComponent{typ: "B", order: 200, deps: []ComponentType{}}, + &mockComponent{typ: "C", order: 300, deps: []ComponentType{}}, + &mockComponent{typ: "D", order: 400, deps: []ComponentType{}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 4, len(sorted)) + + // Create a map for easier verification + orderMap := make(map[ComponentType]int) + for i, comp := range sorted { + orderMap[comp.Type()] = i + } + + // All dependencies must come before A + assert.Less(t, orderMap["B"], orderMap["A"]) + assert.Less(t, orderMap["C"], orderMap["A"]) + assert.Less(t, orderMap["D"], orderMap["A"]) + + // A must be last + assert.Equal(t, ComponentType("A"), sorted[3].Type()) +} + +func TestDependencyGraph_EmptyComponents(t *testing.T) { + // Empty component list + components := []Component{} + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 0, len(sorted)) +} + +func TestDependencyGraph_SingleComponent(t *testing.T) { + // Single component with no dependencies + components := []Component{ + &mockComponent{typ: "A", order: 100, deps: []ComponentType{}}, + } + + graph := NewDependencyGraph(components) + sorted, err := graph.TopologicalSort() + + assert.NoError(t, err) + assert.Equal(t, 1, len(sorted)) + assert.Equal(t, ComponentType("A"), sorted[0].Type()) +} diff --git a/pkg/core/runtime/registry.go b/pkg/core/runtime/registry.go index 28e2196f3..244301e7d 100644 --- a/pkg/core/runtime/registry.go +++ b/pkg/core/runtime/registry.go @@ -21,25 +21,27 @@ import ( "github.com/pkg/errors" ) -var global = NewRegistry() +var registry = NewRegistry() func ComponentRegistry() Registry { - return global + return registry } func RegisterComponent(component Component) { - if err := global.Register(component); err != nil { + if err := registry.Register(component); err != nil { panic(err) } } type Registry interface { Get(typ ComponentType) (Component, error) + EventBus() (Component, error) Console() (Component, error) ResourceStore() (Component, error) ResourceManager() (Component, error) ResourceDiscovery() (Component, error) ResourceEngine() (Component, error) + RuleGovernor() (Component, error) } type RegistryMutator interface { @@ -63,6 +65,10 @@ type componentRegistry struct { directory map[ComponentType]Component } +func (r *componentRegistry) EventBus() (Component, error) { + return r.Get(EventBus) +} + func (r *componentRegistry) Console() (Component, error) { return r.Get(Console) } @@ -83,6 +89,9 @@ func (r *componentRegistry) ResourceEngine() (Component, error) { return r.Get(ResourceEngine) } +func (r *componentRegistry) RuleGovernor() (Component, error) { + return r.Get(RuleGovernor) +} func (r *componentRegistry) Register(component Component) error { _, ok := r.directory[component.Type()] if ok { diff --git a/pkg/core/runtime/runtime.go b/pkg/core/runtime/runtime.go index 8f0acfb21..3c4c589c1 100644 --- a/pkg/core/runtime/runtime.go +++ b/pkg/core/runtime/runtime.go @@ -26,6 +26,7 @@ import ( "github.com/pkg/errors" "github.com/apache/dubbo-admin/pkg/config/app" + "github.com/apache/dubbo-admin/pkg/core/logger" "github.com/apache/dubbo-admin/pkg/config/mode" ) @@ -78,7 +79,6 @@ func (i *runtimeInfo) GetMode() mode.Mode { var _ RuntimeContext = &runtimeContext{} -// TODO add console type runtimeContext struct { cfg app.AdminConfig components map[ComponentType]Component @@ -116,13 +116,31 @@ func (rt *runtime) Add(components ...Component) { func (rt *runtime) Start(stop <-chan struct{}) error { components := maputil.Values(rt.components) slice.SortBy(components, func(a, b Component) bool { - return a.Order() < b.Order() + return a.Order() > b.Order() }) for _, com := range components { - err := com.Start(rt, stop) - if err != nil { - return err + go func() { + err := com.Start(rt, stop) + if err != nil { + // if a core component failed to start, panic + if slice.Contain(CoreComponentTypes, com.Type()) { + panic("core component " + com.Type() + " running failed with error: " + err.Error()) + } else { + logger.Errorf("component %s running failed with error: %s", com.Type(), err.Error()) + } + } else { + logger.Infof("component %s started successfully", com.Type()) + } + }() + } + logger.Info("Admin started successfully") + select { + case <-stop: + for _, com := range components { + if gc, ok := com.(GracefulComponent); ok { + gc.WaitForDone() + } } + return nil } - return nil } diff --git a/pkg/core/store/component.go b/pkg/core/store/component.go index 7bbfdff1e..2cae0097b 100644 --- a/pkg/core/store/component.go +++ b/pkg/core/store/component.go @@ -1,18 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package store import ( "fmt" "math" + "reflect" + + "gorm.io/gorm" + "github.com/apache/dubbo-admin/pkg/core/leader" coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" "github.com/apache/dubbo-admin/pkg/core/runtime" ) +func init() { + runtime.RegisterComponent(newStoreComponent()) +} + type Router interface { ResourceRoute(coremodel.Resource) (ResourceStore, error) ResourceKindRoute(k coremodel.ResourceKind) (ResourceStore, error) } +// poolProvider is an internal interface for stores that provide DB access +// This avoids circular imports by not referencing dbcommon directly +type poolProvider interface { + Pool() interface{} // Returns *ConnectionPool, but we don't type it to avoid import +} + // The Component interface is composed of both functional interfaces and lifecycle interfaces type Component interface { runtime.Component @@ -27,12 +58,27 @@ type storeComponent struct { stores map[coremodel.ResourceKind]ManagedResourceStore } +// Compile-time check that storeComponent implements leader.DBSource interface +var _ leader.DBSource = &storeComponent{} + +func (sc *storeComponent) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.EventBus, // Store may need EventBus for event emission + } +} + +func newStoreComponent() *storeComponent { + return &storeComponent{ + stores: make(map[coremodel.ResourceKind]ManagedResourceStore), + } +} + func (sc *storeComponent) Type() runtime.ComponentType { return runtime.ResourceStore } func (sc *storeComponent) Order() int { - return math.MaxInt + return math.MaxInt - 1 } func (sc *storeComponent) Init(ctx runtime.BuilderContext) error { @@ -43,7 +89,7 @@ func (sc *storeComponent) Init(ctx runtime.BuilderContext) error { return err } // 2. create store for each resource kind - for _, kind := range coremodel.ResourceKindRegistry().AllResourceKinds() { + for _, kind := range coremodel.ResourceSchemaRegistry().AllResourceKinds() { store, err := factory.New(kind, cfg) if err != nil { return err @@ -53,16 +99,6 @@ func (sc *storeComponent) Init(ctx runtime.BuilderContext) error { return err } } - // 3. add indexers for each kind of store - for kind, store := range sc.stores { - indexers := IndexersRegistry().Indexers(kind) - if indexers == nil { - continue - } - if err := store.AddIndexers(indexers); err != nil { - return err - } - } return nil } @@ -76,10 +112,7 @@ func (sc *storeComponent) Start(rt runtime.Runtime, ch <-chan struct{}) error { } func (sc *storeComponent) ResourceRoute(r coremodel.Resource) (ResourceStore, error) { - if store, exists := sc.stores[r.ResourceKind()]; exists { - return store, nil - } - return nil, fmt.Errorf("%s is not supported by store yet", r.ResourceKind()) + return sc.ResourceKindRoute(r.ResourceKind()) } func (sc *storeComponent) ResourceKindRoute(k coremodel.ResourceKind) (ResourceStore, error) { @@ -89,3 +122,32 @@ func (sc *storeComponent) ResourceKindRoute(k coremodel.ResourceKind) (ResourceS return nil, fmt.Errorf("%s is not supported by store yet", k) } + +// GetDB returns the shared DB connection if the underlying store is DB-backed +// Implements the leader.DBSource interface +func (sc *storeComponent) GetDB() (*gorm.DB, bool) { + // Try to get DB from any store that has a Pool() method (all GormStores share the same ConnectionPool) + for _, store := range sc.stores { + pp, ok := store.(poolProvider) + if !ok { + continue + } + pool := pp.Pool() + if pool == nil { + continue + } + // Use reflection to call GetDB() on the pool to avoid importing dbcommon + poolVal := reflect.ValueOf(pool) + getDBMethod := poolVal.MethodByName("GetDB") + if !getDBMethod.IsValid() { + continue + } + result := getDBMethod.Call(nil) + if len(result) > 0 { + if db, ok := result[0].Interface().(*gorm.DB); ok { + return db, true + } + } + } + return nil, false +} diff --git a/pkg/core/store/factory.go b/pkg/core/store/factory.go index 7e5aaad65..e0e9b79ec 100644 --- a/pkg/core/store/factory.go +++ b/pkg/core/store/factory.go @@ -1,9 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package store import ( "fmt" - "github.com/apache/dubbo-admin/pkg/config/store" + storecfg "github.com/apache/dubbo-admin/pkg/config/store" "github.com/apache/dubbo-admin/pkg/core/resource/model" ) @@ -20,17 +37,17 @@ func FactoryRegistry() Registry { // Factory is the interface for create a specific type of ManagedResourceStore type Factory interface { // Support returns true if the factory supports the given type in config - Support(store.Type) bool + Support(storecfg.Type) bool // New returns a new ManagedResourceStore for the model.ResourceKind using the given config - New(model.ResourceKind, *store.Config) (ManagedResourceStore, error) + New(model.ResourceKind, *storecfg.Config) (ManagedResourceStore, error) } type Registry interface { - GetStoreFactory(store.Type) (Factory, error) + GetStoreFactory(storecfg.Type) (Factory, error) } type RegistryMutator interface { - // RegisterFactory registers a resource store type and a func to new it + // Register registers a new factory Register(Factory) } type MutableRegistry interface { @@ -49,7 +66,7 @@ func newStoreFactoryRegistry() MutableRegistry { factories: make([]Factory, 0), } } -func (s *storeFactoryRegistry) GetStoreFactory(t store.Type) (Factory, error) { +func (s *storeFactoryRegistry) GetStoreFactory(t storecfg.Type) (Factory, error) { for _, factory := range s.factories { if factory.Support(t) { return factory, nil diff --git a/pkg/common/util/template/render.go b/pkg/core/store/index/common.go similarity index 54% rename from pkg/common/util/template/render.go rename to pkg/core/store/index/common.go index adae2f4b5..1312db0e5 100644 --- a/pkg/common/util/template/render.go +++ b/pkg/core/store/index/common.go @@ -15,40 +15,33 @@ * limitations under the License. */ -package template +package index import ( - "strings" + "reflect" - "github.com/hoisie/mustache" -) - -type contextMap map[string]interface{} + "github.com/duke-git/lancet/v2/slice" + "k8s.io/client-go/tools/cache" -func (cm contextMap) merge(other contextMap) { - for k, v := range other { - cm[k] = v - } -} + "github.com/apache/dubbo-admin/pkg/common/bizerror" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) -func newContextMap(key, value string) contextMap { - if !strings.Contains(key, ".") { - return map[string]interface{}{ - key: value, - } - } +const ByMeshIndex = "idx_mesh" - parts := strings.SplitAfterN(key, ".", 2) - return map[string]interface{}{ - parts[0][:len(parts[0])-1]: newContextMap(parts[1], value), - } +func init() { + rks := coremodel.ResourceSchemaRegistry().AllResourceKinds() + slice.ForEach(rks, func(_ int, rk coremodel.ResourceKind) { + RegisterIndexers(rk, map[string]cache.IndexFunc{ + ByMeshIndex: ByMesh, + }) + }) } -func Render(template string, values map[string]string) []byte { - ctx := contextMap{} - for k, v := range values { - ctx.merge(newContextMap(k, v)) +func ByMesh(obj interface{}) ([]string, error) { + r, ok := obj.(coremodel.Resource) + if !ok { + return nil, bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) } - data := mustache.Render(template, ctx) - return []byte(data) + return []string{r.ResourceMesh()}, nil } diff --git a/pkg/core/store/index/condition.go b/pkg/core/store/index/condition.go new file mode 100644 index 000000000..4bdcee2f7 --- /dev/null +++ b/pkg/core/store/index/condition.go @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package index + +// IndexOperator defines the comparison operator for index queries +type IndexOperator string + +const ( + // Equals performs exact match on the index value + Equals IndexOperator = "Equals" + // HasPrefix performs prefix match on the index value + HasPrefix IndexOperator = "HasPrefix" +) + +// IndexCondition represents a single index query condition +type IndexCondition struct { + // IndexName is the name of the index to query + IndexName string + // Value is the value to match against the index + Value string + // Operator is the comparison operator to use (Equals, HasPrefix, etc.) + Operator IndexOperator +} diff --git a/pkg/core/store/index/instance.go b/pkg/core/store/index/instance.go new file mode 100644 index 000000000..e7319daf3 --- /dev/null +++ b/pkg/core/store/index/instance.go @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package index + +import ( + "reflect" + + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) + +const ( + ByInstanceAppNameIndex = "idx_instance_app_name" + ByInstanceIpIndex = "idx_instance_ip" + ByInstanceNameIndex = "idx_instance_name" +) + +func init() { + RegisterIndexers(meshresource.InstanceKind, map[string]cache.IndexFunc{ + ByInstanceAppNameIndex: byInstanceAppName, + ByInstanceIpIndex: byInstanceIp, + ByInstanceNameIndex: byInstanceName, + }) +} + +func byInstanceAppName(obj interface{}) ([]string, error) { + instance, ok := obj.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.InstanceKind, reflect.TypeOf(obj).Name()) + } + if instance.Spec == nil || strutil.IsBlank(instance.Spec.AppName) { + return []string{}, nil + } + return []string{instance.Spec.AppName}, nil +} + +func byInstanceIp(obj interface{}) ([]string, error) { + instance, ok := obj.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.InstanceKind, reflect.TypeOf(obj).Name()) + } + if instance.Spec == nil || strutil.IsBlank(instance.Spec.Ip) { + return []string{}, nil + } + return []string{instance.Spec.Ip}, nil +} + +func byInstanceName(obj interface{}) ([]string, error) { + instance, ok := obj.(*meshresource.InstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.InstanceKind, reflect.TypeOf(obj).Name()) + } + if instance.Spec == nil || strutil.IsBlank(instance.Spec.Name) { + return []string{}, nil + } + return []string{instance.Spec.Name}, nil +} diff --git a/pkg/core/store/index/registry.go b/pkg/core/store/index/registry.go new file mode 100644 index 000000000..cef06ce63 --- /dev/null +++ b/pkg/core/store/index/registry.go @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package index + +import ( + "github.com/duke-git/lancet/v2/maputil" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +var indexRegistry = newIndexRegistry() + +func RegisterIndexers(rk model.ResourceKind, indexers cache.Indexers) { + indexRegistry.Register(rk, indexers) +} + +func IndexersRegistry() IndexerRegistry { + return indexRegistry +} + +type IndexerRegistry interface { + // Indexers returns the indexers for the given resource kind + // if no indexers are registered for the resource kind, an empty map is returned + Indexers(model.ResourceKind) cache.Indexers +} + +type IndexerRegistryMutator interface { + Register(model.ResourceKind, cache.Indexers) +} + +type MutableIndexerRegistry interface { + IndexerRegistry + IndexerRegistryMutator +} + +var _ IndexerRegistry = &indexerRegistry{} + +type indexerRegistry struct { + rIndexers map[model.ResourceKind]cache.Indexers +} + +func newIndexRegistry() MutableIndexerRegistry { + return &indexerRegistry{ + rIndexers: make(map[model.ResourceKind]cache.Indexers), + } +} + +func (i *indexerRegistry) Indexers(k model.ResourceKind) cache.Indexers { + if indexers, exists := i.rIndexers[k]; exists && indexers != nil { + return indexers + } + return make(cache.Indexers) +} + +func (i *indexerRegistry) Register(k model.ResourceKind, indexers cache.Indexers) { + if existedIndexers, exists := i.rIndexers[k]; !exists { + i.rIndexers[k] = indexers + } else { + i.rIndexers[k] = maputil.Merge(existedIndexers, indexers) + } +} diff --git a/pkg/core/events/interfaces.go b/pkg/core/store/index/rpc_instance.go similarity index 51% rename from pkg/core/events/interfaces.go rename to pkg/core/store/index/rpc_instance.go index 4dc549e52..86db39e26 100644 --- a/pkg/core/events/interfaces.go +++ b/pkg/core/store/index/rpc_instance.go @@ -15,64 +15,35 @@ * limitations under the License. */ -package events +package index import ( - "github.com/pkg/errors" -) + "reflect" -type Event interface{} + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" -type Op int + "github.com/apache/dubbo-admin/pkg/common/bizerror" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) const ( - Create Op = iota - Update - Delete + ByRPCInstanceAppName = "idx_rpc_instance_app_name" ) -type ResourceChangedEvent struct { - Operation Op - Kind string - Key string - TenantID string -} - -type TriggerInsightsComputationEvent struct { - TenantID string -} - -var ListenerStoppedErr = errors.New("listener closed") - -type Listener interface { - Recv() <-chan Event - Close() -} - -func NewNeverListener() Listener { - return &neverRecvListener{} -} - -type neverRecvListener struct{} - -func (*neverRecvListener) Recv() <-chan Event { - return nil -} - -func (*neverRecvListener) Close() { -} - -type Predicate = func(event Event) bool - -type Emitter interface { - Send(Event) -} - -type ListenerFactory interface { - Subscribe(...Predicate) Listener -} - -type EventBus interface { - Emitter - ListenerFactory +func init() { + RegisterIndexers(meshresource.RPCInstanceKind, map[string]cache.IndexFunc{ + ByRPCInstanceAppName: byRPCInstanceAppName, + }) +} + +func byRPCInstanceAppName(obj interface{}) ([]string, error) { + instance, ok := obj.(*meshresource.RPCInstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.RPCInstanceKind, reflect.TypeOf(obj).Name()) + } + if instance.Spec == nil || strutil.IsBlank(instance.Spec.AppName) { + return []string{}, nil + } + return []string{instance.Spec.AppName}, nil } diff --git a/api/generic/insights.go b/pkg/core/store/index/runtime_instance.go similarity index 50% rename from api/generic/insights.go rename to pkg/core/store/index/runtime_instance.go index f0f4609ff..745e81144 100644 --- a/api/generic/insights.go +++ b/pkg/core/store/index/runtime_instance.go @@ -15,43 +15,33 @@ * limitations under the License. */ -package generic +package index import ( - "time" + "reflect" - "google.golang.org/protobuf/proto" -) + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/tools/cache" -func AllSubscriptions[S Subscription, T interface{ GetSubscriptions() []S }](t T) []Subscription { - var subs []Subscription - for _, s := range t.GetSubscriptions() { - subs = append(subs, s) - } - return subs -} + "github.com/apache/dubbo-admin/pkg/common/bizerror" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) -func GetSubscription[S Subscription, T interface{ GetSubscriptions() []S }](t T, id string) Subscription { - for _, s := range t.GetSubscriptions() { - if s.GetId() == id { - return s - } - } - return nil -} +const ByRuntimeInstanceIPIndex = "idx_rt_instance_ip" -type Insight interface { - proto.Message - IsOnline() bool - GetSubscription(id string) Subscription - AllSubscriptions() []Subscription - UpdateSubscription(Subscription) error +func init() { + RegisterIndexers(meshresource.RuntimeInstanceKind, map[string]cache.IndexFunc{ + ByRuntimeInstanceIPIndex: byRuntimeInstanceIp, + }) } -type Subscription interface { - proto.Message - GetId() string - GetGeneration() uint32 - IsOnline() bool - SetDisconnectTime(time time.Time) +func byRuntimeInstanceIp(obj interface{}) ([]string, error) { + rtInstance, ok := obj.(*meshresource.RuntimeInstanceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.RuntimeInstanceKind, reflect.TypeOf(obj).Name()) + } + if rtInstance.Spec == nil || strutil.IsBlank(rtInstance.Spec.Ip) { + return []string{}, nil + } + return []string{rtInstance.Spec.Ip}, nil } diff --git a/pkg/common/util/xds/logger.go b/pkg/core/store/index/service.go similarity index 55% rename from pkg/common/util/xds/logger.go rename to pkg/core/store/index/service.go index b7cffeb1f..f02500faa 100644 --- a/pkg/common/util/xds/logger.go +++ b/pkg/core/store/index/service.go @@ -15,35 +15,32 @@ * limitations under the License. */ -package xds +package index import ( - "fmt" + "reflect" - envoy_log "github.com/envoyproxy/go-control-plane/pkg/log" - "github.com/go-logr/logr" -) - -func NewLogger(log logr.Logger) envoy_log.Logger { - return &logger{log: log} -} - -type logger struct { - log logr.Logger -} + "k8s.io/client-go/tools/cache" -func (l logger) Debugf(format string, args ...interface{}) { - l.log.V(1).Info(fmt.Sprintf(format, args...)) -} + "github.com/apache/dubbo-admin/pkg/common/bizerror" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) -func (l logger) Warnf(format string, args ...interface{}) { - l.log.V(1).Info(fmt.Sprintf(format, args...)) -} +const ByServiceName = "idx_service_name" -func (l logger) Infof(format string, args ...interface{}) { - l.log.V(1).Info(fmt.Sprintf(format, args...)) +func init() { + RegisterIndexers(meshresource.ServiceKind, map[string]cache.IndexFunc{ + ByServiceName: byServiceName, + }) } -func (l logger) Errorf(format string, args ...interface{}) { - l.log.Error(fmt.Errorf(format, args...), "") +func byServiceName(obj interface{}) ([]string, error) { + service, ok := obj.(*meshresource.ServiceResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceKind, reflect.TypeOf(obj).Name()) + } + if service.Spec == nil { + return []string{}, nil + } + return []string{service.Spec.Name}, nil } diff --git a/pkg/core/store/index/service_consumer_metadata.go b/pkg/core/store/index/service_consumer_metadata.go new file mode 100644 index 000000000..e249620ab --- /dev/null +++ b/pkg/core/store/index/service_consumer_metadata.go @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package index + +import ( + "reflect" + + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) + +const ( + ByServiceConsumerAppName = "idx_service_consumer_app_name" + ByServiceConsumerServiceKey = "idx_service_consumer_service_key" + ByServiceConsumerServiceName = "idx_service_consumer_service_name" +) + +func init() { + RegisterIndexers(meshresource.ServiceConsumerMetadataKind, map[string]cache.IndexFunc{ + ByServiceConsumerAppName: byServiceConsumerAppName, + ByServiceConsumerServiceKey: byServiceConsumerServiceKey, + ByServiceConsumerServiceName: byServiceConsumerServiceName, + }) +} + +func byServiceConsumerAppName(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceConsumerMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceConsumerMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata == nil { + return []string{}, nil + } + return []string{metadata.Spec.ConsumerAppName}, nil +} + +func byServiceConsumerServiceName(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceConsumerMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceConsumerMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata == nil { + return []string{}, nil + } + return []string{metadata.Spec.ServiceName}, nil +} + +func byServiceConsumerServiceKey(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceConsumerMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceConsumerMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata.Spec == nil { + return []string{}, nil + } + return []string{buildServiceConsumerServiceKey(metadata.Spec.ServiceName, metadata.Spec.Version, metadata.Spec.Group)}, nil +} + +func buildServiceConsumerServiceKey(serviceName, version, group string) string { + return serviceName + constants.ColonSeparator + version + constants.ColonSeparator + group +} diff --git a/pkg/core/store/index/service_provider_metadata.go b/pkg/core/store/index/service_provider_metadata.go new file mode 100644 index 000000000..9804e1326 --- /dev/null +++ b/pkg/core/store/index/service_provider_metadata.go @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package index + +import ( + "reflect" + + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) + +const ( + ByServiceProviderAppName = "idx_service_provider_app_name" + ByServiceProviderServiceKey = "idx_service_provider_service_key" + ByServiceProviderServiceName = "idx_service_provider_service_name" +) + +func init() { + RegisterIndexers(meshresource.ServiceProviderMetadataKind, map[string]cache.IndexFunc{ + ByServiceProviderAppName: byServiceProviderAppName, + ByServiceProviderServiceKey: byServiceProviderServiceKey, + ByServiceProviderServiceName: byServiceProviderServiceName, + }) +} + +func byServiceProviderAppName(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceProviderMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceProviderMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata.Spec == nil { + return []string{}, nil + } + return []string{metadata.Spec.ProviderAppName}, nil +} + +func byServiceProviderServiceName(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceProviderMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceProviderMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata.Spec == nil { + return []string{}, nil + } + return []string{metadata.Spec.ServiceName}, nil +} + +func byServiceProviderServiceKey(obj interface{}) ([]string, error) { + metadata, ok := obj.(*meshresource.ServiceProviderMetadataResource) + if !ok { + return nil, bizerror.NewAssertionError(meshresource.ServiceProviderMetadataKind, reflect.TypeOf(obj).Name()) + } + if metadata.Spec == nil { + return []string{}, nil + } + return []string{buildServiceProviderServiceKey(metadata.Spec.ServiceName, metadata.Spec.Version, metadata.Spec.Group)}, nil +} + +func buildServiceProviderServiceKey(serviceName, version, group string) string { + return serviceName + constants.ColonSeparator + version + constants.ColonSeparator + group +} diff --git a/pkg/core/store/indexer.go b/pkg/core/store/indexer.go deleted file mode 100644 index 4aeb65fe4..000000000 --- a/pkg/core/store/indexer.go +++ /dev/null @@ -1,60 +0,0 @@ -package store - -import ( - "github.com/apache/dubbo-admin/pkg/core/resource/model" - "k8s.io/client-go/tools/cache" -) - -var indexRegistry = newIndexRegistry() - -func RegisterIndexers(rk model.ResourceKind, indexers cache.Indexers) { - indexRegistry.Register(rk, indexers) -} - -func IndexersRegistry() IndexerRegistry { - return indexRegistry -} - -type IndexerRegistry interface { - Indexers(model.ResourceKind) cache.Indexers -} - -type IndexerRegistryMutator interface { - Register(model.ResourceKind, cache.Indexers) -} - -type MutableIndexerRegistry interface { - IndexerRegistry - IndexerRegistryMutator -} - -// ResourceIndexers defines the rIndexers belong to a specific model.Resource -type ResourceIndexers struct { - rk model.ResourceKind - indexers cache.Indexers -} - -var _ IndexerRegistry = &indexerRegistry{} - -type indexerRegistry struct { - rIndexers []ResourceIndexers -} - -func newIndexRegistry() MutableIndexerRegistry { - return &indexerRegistry{ - rIndexers: make([]ResourceIndexers, 0), - } -} - -func (i *indexerRegistry) Indexers(k model.ResourceKind) cache.Indexers { - for _, rIndexer := range i.rIndexers { - if rIndexer.rk == k { - return rIndexer.indexers - } - } - return nil -} - -func (i *indexerRegistry) Register(k model.ResourceKind, indexers cache.Indexers) { - i.rIndexers = append(i.rIndexers, ResourceIndexers{rk: k, indexers: indexers}) -} diff --git a/pkg/core/store/options.go b/pkg/core/store/options.go deleted file mode 100644 index 684853d83..000000000 --- a/pkg/core/store/options.go +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package store - -import ( - "fmt" - "strings" - "time" - - meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -const ( - PathLabel = "dubbo.io/path" -) - -type CreateOptions struct { - Name string - Mesh string - CreationTime time.Time - Owner coremodel.Resource - Labels map[string]string -} - -type CreateOptionsFunc func(*CreateOptions) - -func NewCreateOptions(fs ...CreateOptionsFunc) *CreateOptions { - opts := &CreateOptions{ - Labels: map[string]string{}, - } - for _, f := range fs { - f(opts) - } - return opts -} - -func CreateByApplication(app string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[meshproto.ApplicationLabel] = app - } -} - -func CreateByService(service string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[meshproto.ServiceLabel] = service - } -} - -func CreateByID(id string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[meshproto.IDLabel] = id - } -} - -func CreateByServiceVersion(serviceVersion string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[meshproto.ServiceVersionLabel] = serviceVersion - } -} - -func CreateByServiceGroup(serviceGroup string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[meshproto.ServiceGroupLabel] = serviceGroup - } -} - -func CreateByPath(path string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels[PathLabel] = path - } -} - -func CreateByKey(name, mesh string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Name = name - opts.Mesh = mesh - } -} - -func CreatedAt(creationTime time.Time) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.CreationTime = creationTime - } -} - -func CreateWithOwner(owner coremodel.Resource) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Owner = owner - } -} - -func CreateWithLabels(labels map[string]string) CreateOptionsFunc { - return func(opts *CreateOptions) { - opts.Labels = labels - } -} - -type UpdateOptions struct { - Name string - Mesh string - ModificationTime time.Time - Labels map[string]string -} - -func ModifiedAt(modificationTime time.Time) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.ModificationTime = modificationTime - } -} - -func UpdateByApplication(app string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[meshproto.ApplicationLabel] = app - } -} - -func UpdateByService(service string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[meshproto.ServiceLabel] = service - } -} - -func UpdateByID(id string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[meshproto.IDLabel] = id - } -} - -func UpdateByServiceVersion(serviceVersion string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[meshproto.ServiceVersionLabel] = serviceVersion - } -} - -func UpdateByServiceGroup(serviceGroup string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[meshproto.ServiceGroupLabel] = serviceGroup - } -} - -func UpdateByKey(name, mesh string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Name = name - opts.Mesh = mesh - } -} - -func UpdateWithPath(path string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels[PathLabel] = path - } -} - -func UpdateWithLabels(labels map[string]string) UpdateOptionsFunc { - return func(opts *UpdateOptions) { - opts.Labels = labels - } -} - -type UpdateOptionsFunc func(*UpdateOptions) - -func NewUpdateOptions(fs ...UpdateOptionsFunc) *UpdateOptions { - opts := &UpdateOptions{ - Labels: map[string]string{}, - } - for _, f := range fs { - f(opts) - } - return opts -} - -type DeleteOptions struct { - Name string - Mesh string - Labels map[string]string -} - -type DeleteOptionsFunc func(*DeleteOptions) - -func NewDeleteOptions(fs ...DeleteOptionsFunc) *DeleteOptions { - opts := &DeleteOptions{ - Labels: map[string]string{}, - } - for _, f := range fs { - f(opts) - } - return opts -} - -func DeleteByPath(path string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[PathLabel] = path - } -} - -func DeleteByApplication(app string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[meshproto.ApplicationLabel] = app - } -} - -func DeleteByService(service string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[meshproto.ServiceLabel] = service - } -} - -func DeleteByID(id string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[meshproto.IDLabel] = id - } -} - -func DeleteByServiceVersion(serviceVersion string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[meshproto.ServiceVersionLabel] = serviceVersion - } -} - -func DeleteByServiceGroup(serviceGroup string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Labels[meshproto.ServiceGroupLabel] = serviceGroup - } -} - -func DeleteByKey(name, mesh string) DeleteOptionsFunc { - return func(opts *DeleteOptions) { - opts.Name = name - opts.Mesh = mesh - } -} - -type DeleteAllOptions struct { - Mesh string -} - -type DeleteAllOptionsFunc func(*DeleteAllOptions) - -func DeleteAllByMesh(mesh string) DeleteAllOptionsFunc { - return func(opts *DeleteAllOptions) { - opts.Mesh = mesh - } -} - -func NewDeleteAllOptions(fs ...DeleteAllOptionsFunc) *DeleteAllOptions { - opts := &DeleteAllOptions{} - for _, f := range fs { - f(opts) - } - return opts -} - -type GetOptions struct { - Name string - Mesh string - Version string - Type string - Consistent bool - Labels map[string]string -} - -type GetOptionsFunc func(*GetOptions) - -func NewGetOptions(fs ...GetOptionsFunc) *GetOptions { - opts := &GetOptions{ - Labels: map[string]string{}, - } - for _, f := range fs { - f(opts) - } - return opts -} - -func (g *GetOptions) HashCode() string { - return fmt.Sprintf("%s:%s", g.Name, g.Mesh) -} - -func GetByPath(path string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[PathLabel] = path - } -} - -func GetByRevision(revision string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.RevisionLabel] = revision - } -} - -func GetByType(t string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Type = t - } -} - -func GetByApplication(app string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.ApplicationLabel] = app - } -} - -func GetByService(service string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.ServiceLabel] = service - } -} - -func GetByID(id string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.IDLabel] = id - } -} - -func GetByServiceVersion(serviceVersion string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.ServiceVersionLabel] = serviceVersion - } -} - -func GetByServiceGroup(serviceGroup string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Labels[meshproto.ServiceGroupLabel] = serviceGroup - } -} -func GetByKey(name, mesh string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Name = name - opts.Mesh = mesh - } -} - -func GetByVersion(version string) GetOptionsFunc { - return func(opts *GetOptions) { - opts.Version = version - } -} - -// GetConsistent forces consistency if storage provides eventual consistency like read replica for Postgres. -func GetConsistent() GetOptionsFunc { - return func(opts *GetOptions) { - opts.Consistent = true - } -} - -func (l *GetOptions) Predicate(r coremodel.Resource) bool { - if l.Mesh != "" && r.Mesh() != l.Mesh { - return false - } - - if l.Version != "" && r.Meta().ResourceVersion != l.Version { - return false - } - - if len(l.Labels) > 0 { - for k, v := range l.Labels { - if r.Meta().Labels[k] != v { - return false - } - } - } - - return true -} - -type ( - ListFilterFunc func(rs coremodel.Resource) bool -) - -type ListOptions struct { - Mesh string - Labels map[string]string - PageSize int - PageOffset string - FilterFunc ListFilterFunc - NameContains string - NameEquals string - ApplicationContains string - Ordered bool - ResourceKeys map[string]struct{} -} - -type ListOptionsFunc func(*ListOptions) - -func NewListOptions(fs ...ListOptionsFunc) *ListOptions { - opts := &ListOptions{ - Labels: map[string]string{}, - ResourceKeys: map[string]struct{}{}, - } - for _, f := range fs { - f(opts) - } - return opts -} - -// Filter returns true if the item passes the filtering criteria -func (l *ListOptions) Filter(rs coremodel.Resource) bool { - if l.FilterFunc == nil { - return true - } - - return l.FilterFunc(rs) -} - -func ListByPath(path string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.Labels[PathLabel] = path - } -} - -func ListByApplicationContains(app string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.ApplicationContains = app - } -} - -func ListByApplication(app string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.Labels[meshproto.ApplicationLabel] = app - } -} - -func ListByNameContains(name string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.NameContains = name - } -} - -func ListByNameEquals(name string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.NameEquals = name - } -} - -func ListByMesh(mesh string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.Mesh = mesh - } -} - -func ListByPage(size int, offset string) ListOptionsFunc { - return func(opts *ListOptions) { - opts.PageSize = size - opts.PageOffset = offset - } -} - -func ListByFilterFunc(filterFunc ListFilterFunc) ListOptionsFunc { - return func(opts *ListOptions) { - opts.FilterFunc = filterFunc - } -} - -func ListOrdered() ListOptionsFunc { - return func(opts *ListOptions) { - opts.Ordered = true - } -} - -func (l *ListOptions) IsCacheable() bool { - return l.FilterFunc == nil -} - -func (l *ListOptions) HashCode() string { - return fmt.Sprintf("%s:%t:%s:%d:%s", l.Mesh, l.Ordered, l.NameContains, l.PageSize, l.PageOffset) -} - -func (l *ListOptions) Predicate(r coremodel.Resource) bool { - if l.Mesh != "" && r.Mesh() != l.Mesh { - return false - } - if l.NameEquals != "" && r.Meta().Name != l.NameEquals { - return false - } - - if l.NameContains != "" && !strings.Contains(r.Meta().Name, l.NameContains) { - return false - } - - if l.ApplicationContains != "" && !strings.Contains(r.Meta().Labels[meshproto.ApplicationLabel], l.ApplicationContains) { - return false - } - - if len(l.Labels) > 0 { - for k, v := range l.Labels { - if r.Meta().Labels[k] != v { - return false - } - } - } - - return l.Filter(r) -} diff --git a/pkg/core/store/store.go b/pkg/core/store/store.go index dd3103cf7..8923f6577 100644 --- a/pkg/core/store/store.go +++ b/pkg/core/store/store.go @@ -23,17 +23,24 @@ import ( "reflect" "strings" - "github.com/apache/dubbo-admin/pkg/core/runtime" . "k8s.io/client-go/tools/cache" "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store/index" ) // ResourceStore defines the interface for the persistance of a resource // ResourceStore expanded the interface of cache.Indexer and cache.Store type ResourceStore interface { Indexer - ListPageByIndex(indexName string, indexValue interface{}, pq model.PageQuery) ([]interface{}, model.Pagination, error) + // GetByKeys get resources by keys, return list of resource. + // if a resource of specified key doesn't exist in the store, resource list will not include it + GetByKeys(keys []string) ([]model.Resource, error) + // ListByIndexes list resources by index conditions + ListByIndexes(indexes []index.IndexCondition) ([]model.Resource, error) + // PageListByIndexes list resources by index conditions pageable + PageListByIndexes(indexes []index.IndexCondition, pq model.PageReq) (*model.PageData[model.Resource], error) } // ManagedResourceStore includes both functional interfaces and lifecycle interfaces @@ -76,37 +83,6 @@ func IsResourceNotFound(err error) bool { return err != nil && strings.HasPrefix(err.Error(), "Resource not found") } -// AssertionError -type AssertionError struct { - msg string - err error -} - -func ErrorResourceAssertion(msg, rt, name, mesh string) error { - return &AssertionError{ - msg: fmt.Sprintf("%s: type=%q name=%q mesh=%q", msg, rt, name, mesh), - } -} - -func (e *AssertionError) Unwrap() error { - return e.err -} - -func (e *AssertionError) Error() string { - msg := "store assertion failed" - if e.msg != "" { - msg += " " + e.msg - } - if e.err != nil { - msg += fmt.Sprintf("error: %s", e.err) - } - return msg -} - -func (e *AssertionError) Is(err error) bool { - return reflect.TypeOf(e) == reflect.TypeOf(err) -} - type PreconditionError struct { Reason string } diff --git a/pkg/diagnostics/server.go b/pkg/diagnostics/server.go index 16d163f43..7749b9156 100644 --- a/pkg/diagnostics/server.go +++ b/pkg/diagnostics/server.go @@ -19,16 +19,15 @@ package diagnostics import ( "context" + "errors" "fmt" "math" "net/http" "net/http/pprof" "time" - "github.com/bakito/go-log-logr-adapter/adapter" - diagnosticsconfig "github.com/apache/dubbo-admin/pkg/config/diagnostics" - "github.com/apache/dubbo-admin/pkg/core" + "github.com/apache/dubbo-admin/pkg/core/logger" "github.com/apache/dubbo-admin/pkg/core/runtime" ) @@ -36,8 +35,6 @@ func init() { runtime.RegisterComponent(&diagnosticsServer{}) } -var diagnosticsServerLog = core.Log.WithName("diagnostics") - const DiagnosticsServer = "diagnostics server" type diagnosticsServer struct { @@ -48,12 +45,12 @@ var ( _ runtime.Component = &diagnosticsServer{} ) -func (s *diagnosticsServer) Type() runtime.ComponentType { - return DiagnosticsServer +func (s *diagnosticsServer) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{} // Diagnostics server has no dependencies } -func (s *diagnosticsServer) SubType() runtime.ComponentType { - return runtime.DefaultComponentSubType +func (s *diagnosticsServer) Type() runtime.ComponentType { + return DiagnosticsServer } func (s *diagnosticsServer) Order() int { @@ -83,31 +80,30 @@ func (s *diagnosticsServer) Start(_ runtime.Runtime, stop <-chan struct{}) error Addr: fmt.Sprintf(":%d", s.config.ServerPort), Handler: mux, ReadHeaderTimeout: time.Second, - ErrorLog: adapter.ToStd(diagnosticsServerLog), } - diagnosticsServerLog.Info("starting diagnostic server", "interface", "0.0.0.0", "port", s.config.ServerPort) + logger.Infof("starting diagnostic server, endpoint is 0.0.0.0: %d", s.config.ServerPort) errChan := make(chan error) go func() { defer close(errChan) var err error err = httpServer.ListenAndServe() if err != nil { - switch err { - case http.ErrServerClosed: - diagnosticsServerLog.Info("shutting down server") + switch { + case errors.Is(err, http.ErrServerClosed): + logger.Info("shutting down diagnostics server") default: - diagnosticsServerLog.Error(err, "could not start HTTP Server") + logger.Error("could not start diagnostics http server, unknown err: %s", err) errChan <- err } return } - diagnosticsServerLog.Info("terminated normally") + logger.Info("terminated normally") }() select { case <-stop: - diagnosticsServerLog.Info("stopping") + logger.Info("received stop signal, stopping diagnostics server ...") return httpServer.Shutdown(context.Background()) case err := <-errChan: return err diff --git a/pkg/common/util/k8s/name_converter.go b/pkg/discovery/mock/factory.go similarity index 56% rename from pkg/common/util/k8s/name_converter.go rename to pkg/discovery/mock/factory.go index 04060a3fe..87c1ada28 100644 --- a/pkg/common/util/k8s/name_converter.go +++ b/pkg/discovery/mock/factory.go @@ -15,28 +15,26 @@ * limitations under the License. */ -package k8s +package mock import ( - "fmt" - "strings" - - "github.com/pkg/errors" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/discovery" ) -func CoreNameToK8sName(coreName string) (string, string, error) { - idx := strings.LastIndex(coreName, ".") - if idx == -1 { - return "", "", errors.Errorf(`name %q must include namespace after the dot, ex. "name.namespace"`, coreName) - } - // namespace cannot contain "." therefore it's always the last part - namespace := coreName[idx+1:] - if namespace == "" { - return "", "", errors.New("namespace must be non-empty") - } - return coreName[:idx], namespace, nil +func init() { + discovery.RegisterListWatcherFactory(&mockListerWaterFactory{}) +} + +type mockListerWaterFactory struct{} + +var _ discovery.Factory = &mockListerWaterFactory{} + +func (l *mockListerWaterFactory) Support(d discoverycfg.Type) bool { + return d == discoverycfg.Mock } -func K8sNamespacedNameToCoreName(name, namespace string) string { - return fmt.Sprintf("%s.%s", name, namespace) +func (l *mockListerWaterFactory) NewListWatchers(_ *discoverycfg.Config) ([]controller.ResourceListerWatcher, error) { + return make([]controller.ResourceListerWatcher, 0), nil } diff --git a/pkg/discovery/nacos2/factory.go b/pkg/discovery/nacos2/factory.go new file mode 100644 index 000000000..65d391a56 --- /dev/null +++ b/pkg/discovery/nacos2/factory.go @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nacos2 + +import ( + "fmt" + + dubbogocom "dubbo.apache.org/dubbo-go/v3/common" + dubbogoconstant "dubbo.apache.org/dubbo-go/v3/common/constant" + dubbogonacos "dubbo.apache.org/dubbo-go/v3/remoting/nacos" + nacosconfigclient "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" + nacosnamingclient "github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/discovery/nacos2/listerwatcher" +) + +func init() { + discovery.RegisterListWatcherFactory(&Factory{ + subscribers: make([]events.Subscriber, 0), + }) +} + +type Factory struct { + subscribers []events.Subscriber +} + +func (f *Factory) Support(d discoverycfg.Type) bool { + return d == discoverycfg.Nacos2 +} + +func (f *Factory) NewListWatchers( + cfg *discoverycfg.Config) ([]controller.ResourceListerWatcher, error) { + nacosConfigClient, nacosNamingClient, err := f.initNacosClients(cfg) + listerWatchers, err := f.initListerWatchers(cfg, nacosConfigClient, nacosNamingClient) + if err != nil { + return nil, err + } + return listerWatchers, nil +} + +func (f *Factory) initNacosClients( + cfg *discoverycfg.Config, +) (nacosconfigclient.IConfigClient, nacosnamingclient.INamingClient, error) { + cfgCenterUrl, err := dubbogocom.NewURL(cfg.Address.ConfigCenter) + if err != nil { + return nil, nil, err + } + cfgCenterUrl.AddParam(dubbogoconstant.ClientNameKey, cfg.ID) + nacosConfigClient, err := dubbogonacos.NewNacosConfigClientByUrl(cfgCenterUrl) + if err != nil { + return nil, nil, bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("cannot create nacos config client for %s %s", cfg.ID, cfg.Address)) + } + registryUrl, err := dubbogocom.NewURL(cfg.Address.Registry) + if err != nil { + return nil, nil, err + } + registryUrl.AddParam(dubbogoconstant.ClientNameKey, cfg.ID) + namingClient, err := dubbogonacos.NewNacosClientByURL(registryUrl) + if err != nil { + return nil, nil, bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("cannot create nacos naming client for %s %s", cfg.ID, cfg.Address)) + } + return nacosConfigClient.Client(), namingClient.Client(), nil +} + +func (f *Factory) initListerWatchers( + cfg *discoverycfg.Config, + nacosConfigClient nacosconfigclient.IConfigClient, + namingClient nacosnamingclient.INamingClient) ([]controller.ResourceListerWatcher, error) { + nacosServiceLW := listerwatcher.NewNacosServiceListerWatcher(cfg, namingClient) + dynamicConfigLW, err := listerwatcher.NewConfigListerWatcher( + meshresource.DynamicConfigKind, + cfg, + nacosConfigClient, + meshresource.ToDynamicConfigResource, + true, + constants.WildcardCharacter+constants.ConfiguratorRuleDotSuffix, + constants.NacosConfigGroup, + ) + if err != nil { + return nil, err + } + conditionRouteLW, err := listerwatcher.NewConfigListerWatcher( + meshresource.ConditionRouteKind, + cfg, + nacosConfigClient, + meshresource.ToConditionRouteResource, + true, + constants.WildcardCharacter+constants.ConditionRuleDotSuffix, + constants.NacosConfigGroup, + ) + if err != nil { + return nil, err + } + tagRouteLW, err := listerwatcher.NewConfigListerWatcher( + meshresource.TagRouteKind, + cfg, + nacosConfigClient, + meshresource.ToTagRouteResource, + true, + constants.WildcardCharacter+constants.TagRuleDotSuffix, // "*.tag-router" + constants.NacosConfigGroup, + ) + if err != nil { + return nil, err + } + serviceProviderMetadataLW, err := listerwatcher.NewConfigListerWatcher( + meshresource.ServiceProviderMetadataKind, + cfg, + nacosConfigClient, + meshresource.ToServiceProviderMetadataResource, + true, + constants.ServiceProviderNacosKey, + constants.NacosConfigGroup, + ) + if err != nil { + return nil, err + } + serviceProviderMappingLW, err := listerwatcher.NewConfigListerWatcher( + meshresource.ServiceProviderMappingKind, + cfg, + nacosConfigClient, + meshresource.ToServiceProviderMappingResource, + false, + "", + constants.NacosMappingGroup, + ) + if err != nil { + return nil, err + } + return []controller.ResourceListerWatcher{ + nacosServiceLW, + dynamicConfigLW, + conditionRouteLW, + tagRouteLW, + serviceProviderMetadataLW, + serviceProviderMappingLW, + }, nil +} diff --git a/pkg/discovery/nacos2/listerwatcher/nacos_config.go b/pkg/discovery/nacos2/listerwatcher/nacos_config.go new file mode 100644 index 000000000..d764b9fd7 --- /dev/null +++ b/pkg/discovery/nacos2/listerwatcher/nacos_config.go @@ -0,0 +1,292 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package listerwatcher + +import ( + "fmt" + "time" + + "github.com/duke-git/lancet/v2/convertor" + "github.com/go-co-op/gocron" + nacosconfigclient "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" + nacosmodel "github.com/nacos-group/nacos-sdk-go/v2/model" + nacosvo "github.com/nacos-group/nacos-sdk-go/v2/vo" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +type ConfigListerWatcher[T coremodel.Resource] struct { + rk coremodel.ResourceKind + cfg *discoverycfg.Config + configClient nacosconfigclient.IConfigClient + resultChan chan watch.Event + // watchingCfg is used to record the configs that are currently being watched + // key-> dataId, value-> true if it is watched in current list turn + watchingCfg map[string]bool + scheduler *gocron.Scheduler + newResListFunc coremodel.NewResourceListFunc + toResourceFunc meshresource.ToRuleResourceFunc + blurSearch bool + searchExpr string + nacosGroup string + stopWatch bool +} + +func NewConfigListerWatcher( + rk coremodel.ResourceKind, + cfg *discoverycfg.Config, + configClient nacosconfigclient.IConfigClient, + toResourceFunc meshresource.ToRuleResourceFunc, + blurSearch bool, + searchExpr string, + nacosGroup string, +) (*ConfigListerWatcher[coremodel.Resource], error) { + listFunc, err := coremodel.ResourceSchemaRegistry().NewResourceListFunc(rk) + if err != nil { + return nil, bizerror.Wrap(err, bizerror.UnknownError, + fmt.Sprintf("get resource schema failed, cause: %s", err.Error())) + } + return &ConfigListerWatcher[coremodel.Resource]{ + rk: rk, + cfg: cfg, + configClient: configClient, + resultChan: make(chan watch.Event), + watchingCfg: make(map[string]bool), + scheduler: gocron.NewScheduler(time.UTC), + newResListFunc: listFunc, + toResourceFunc: toResourceFunc, + blurSearch: blurSearch, + searchExpr: searchExpr, + nacosGroup: nacosGroup, + stopWatch: false, + }, nil +} + +func (lw *ConfigListerWatcher[T]) List(_ metav1.ListOptions) (k8sruntime.Object, error) { + resList := lw.newResListFunc() + configs, err := lw.fetchAllConfigs() + if err != nil { + return nil, err + } + resList.SetItems(configs) + return resList, nil +} + +func (lw *ConfigListerWatcher[T]) Watch(_ metav1.ListOptions) (watch.Interface, error) { + _, err := lw.scheduler.Every(lw.cfg.Properties.ConfigWatchPeriod).Seconds().Do(func() { + if lw.stopWatch { + logger.Debugf("stop watching %s in nacos %s", lw.rk, lw.nacosAddress()) + lw.scheduler.Stop() + } + startTime := time.Now() + logger.Debugf("start fetching and processing all %s in nacos %s at %s", lw.rk, lw.nacosAddress(), startTime) + err := lw.fetchAndProcessConfigs() + if err != nil { + logger.Errorf("fetchAndProcessConfigs %s in nacos %s failed, cause: %s", lw.rk, lw.nacosAddress(), err.Error()) + return + } + costs := time.Now().UnixMilli() - startTime.UnixMilli() + logger.Debugf("fetchAndProcessConfigs succeed %s in nacos %s, costs %dms", lw.rk, lw.nacosAddress(), costs) + + }) + if err != nil { + return nil, bizerror.Wrap(err, bizerror.UnknownError, + fmt.Sprintf("fetch all metadata of nacos %s in a schedule occurs error", lw.nacosAddress())) + } + lw.scheduler.StartAsync() + return lw, nil +} + +func (lw *ConfigListerWatcher[T]) fetchAllConfigs() ([]coremodel.Resource, error) { + configList := make([]coremodel.Resource, 0) + pageNum := 1 + pageSize := 100 + // list all configs by page search + for { + configPage, err := lw.listPage(pageNum, pageSize) + if err != nil { + return nil, err + } + for _, item := range configPage.PageItems { + r := lw.toResourceFunc(lw.mesh(), item.DataId, item.Content) + if r == nil { + logger.Warnf("config %s convert to %s failed in %s, raw content: %s", item.DataId, lw.rk, lw.nacosAddress(), item.Content) + continue + } + configList = append(configList, r) + } + if configPage.TotalCount <= pageNum*pageSize { + break + } + pageNum++ + } + return configList, nil +} + +func (lw *ConfigListerWatcher[T]) fetchAndProcessConfigs() error { + pageNum := 1 + pageSize := 50 + // list all configs by page search + for { + configPage, err := lw.listPage(pageNum, pageSize) + if err != nil { + return err + } + for _, item := range configPage.PageItems { + lw.processConfig(item) + } + if configPage.TotalCount <= pageNum*pageSize { + break + } + pageNum++ + } + // remove listeners for configs that are not watched in current turn + for dataId, watched := range lw.watchingCfg { + if watched { + lw.watchingCfg[dataId] = false + continue + } + err := lw.unsubscribeConfig(dataId, lw.nacosGroup) + if err != nil { + logger.Errorf("unsubscribe failed, cause: %s", err) + continue + } + // only one go routine, thread safe + delete(lw.watchingCfg, dataId) + } + return nil +} + +func (lw *ConfigListerWatcher[T]) subscribeConfig(configKey string, group string) error { + logger.Infof("subscribe config %s in nacos %s", configKey, lw.nacosAddress()) + err := lw.configClient.ListenConfig(nacosvo.ConfigParam{ + DataId: configKey, + Group: group, + OnChange: func(namespace string, group string, dataId string, content string) { + lw.resultChan <- watch.Event{ + Type: watch.Modified, + Object: lw.toResourceFunc(lw.mesh(), dataId, content), + } + }, + }) + if err != nil { + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("subscribe config %s failed in nacos %s", configKey, lw.nacosAddress())) + } + return nil +} + +func (lw *ConfigListerWatcher[T]) unsubscribeConfig(configKey string, group string) error { + logger.Infof("unsubscribe config %s in nacos %s", configKey, lw.nacosAddress()) + err := lw.configClient.CancelListenConfig(nacosvo.ConfigParam{ + DataId: configKey, + Group: group, + }) + lw.resultChan <- watch.Event{ + Type: watch.Deleted, + Object: lw.toResourceFunc(lw.mesh(), configKey, ""), + } + if err != nil { + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("unsubscribe config %s failed in nacos %s", configKey, lw.nacosAddress())) + } + return nil +} + +func (lw *ConfigListerWatcher[T]) listPage(pageNum int, pageSize int) (*nacosmodel.ConfigPage, error) { + var searchOp string + if lw.blurSearch { + searchOp = "blur" + } else { + searchOp = "accurate" + } + configPage, err := lw.configClient.SearchConfig(nacosvo.SearchConfigParam{ + Search: searchOp, + DataId: lw.searchExpr, + Group: lw.nacosGroup, + PageNo: pageNum, + PageSize: pageSize, + }) + if err != nil { + errMsg := fmt.Sprintf("cannot do page list of config, page size %d, page num %d, nacos address %s", + pageSize, pageNum, lw.nacosAddress()) + return nil, bizerror.Wrap(err, bizerror.NacosError, errMsg) + } + logger.Debugf("list config page, page size %d, page num %d, nacos address %s, total count %d, items %s", + pageSize, pageNum, lw.nacosAddress(), configPage.TotalCount, convertor.ToString(configPage.PageItems)) + return configPage, nil +} + +func (lw *ConfigListerWatcher[T]) processConfig(item nacosmodel.ConfigItem) { + // convert to resource + res := lw.toResourceFunc(lw.mesh(), item.DataId, item.Content) + // if resource is nil, skip the event emitting and other operations + if res == nil { + logger.Warnf("config %s to resource failed, raw content: %s", item.DataId, item.Content) + return + } + // emit event + lw.resultChan <- watch.Event{ + Type: watch.Modified, + Object: res, + } + // subscribe config if not watched + if _, exists := lw.watchingCfg[item.DataId]; exists { + lw.watchingCfg[item.DataId] = true + return + } + err := lw.subscribeConfig(item.DataId, item.Group) + if err != nil { + logger.Errorf("subscribe config %s failed in nacos %s, cause: %v", item.DataId, lw.nacosAddress(), err) + return + } + lw.watchingCfg[item.DataId] = true +} + +func (lw *ConfigListerWatcher[T]) ResourceKind() coremodel.ResourceKind { + return lw.rk +} + +func (lw *ConfigListerWatcher[T]) Stop() { + lw.configClient.CloseClient() + lw.stopWatch = true +} + +func (lw *ConfigListerWatcher[T]) ResultChan() <-chan watch.Event { + return lw.resultChan +} + +func (lw *ConfigListerWatcher[T]) TransformFunc() cache.TransformFunc { + return nil +} + +func (lw *ConfigListerWatcher[T]) nacosAddress() string { + return lw.cfg.Address.ConfigCenter +} + +func (lw *ConfigListerWatcher[T]) mesh() string { + return lw.cfg.ID +} diff --git a/pkg/discovery/nacos2/listerwatcher/nacos_service.go b/pkg/discovery/nacos2/listerwatcher/nacos_service.go new file mode 100644 index 000000000..53d486fe9 --- /dev/null +++ b/pkg/discovery/nacos2/listerwatcher/nacos_service.go @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package listerwatcher + +import ( + "fmt" + "time" + + "github.com/duke-git/lancet/v2/slice" + "github.com/go-co-op/gocron" + nacosnamingclient "github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client" + nacosmodel "github.com/nacos-group/nacos-sdk-go/v2/model" + nacosvo "github.com/nacos-group/nacos-sdk-go/v2/vo" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +type NacosServiceListerWatcher struct { + cfg *discoverycfg.Config + namingClient nacosnamingclient.INamingClient + // watchingServices is used to record the services that are currently being watched + // key -> nacos service name, value -> true if it is watched in current list turn + watchingServices map[string]bool + scheduler *gocron.Scheduler + resultChan chan watch.Event + stopWatch bool +} + +func NewNacosServiceListerWatcher(cfg *discoverycfg.Config, namingClient nacosnamingclient.INamingClient) *NacosServiceListerWatcher { + return &NacosServiceListerWatcher{ + cfg: cfg, + namingClient: namingClient, + resultChan: make(chan watch.Event), + watchingServices: make(map[string]bool), + scheduler: gocron.NewScheduler(time.UTC), + stopWatch: false, + } +} + +func (lw *NacosServiceListerWatcher) List(_ metav1.ListOptions) (k8sruntime.Object, error) { + serviceNames, err := lw.fetchAllServiceNames() + if err != nil { + return nil, err + } + nacosServiceList := meshresource.NewNacosServiceResourceListWithItems() + resList := make([]*meshresource.NacosServiceResource, 0) + for _, serviceName := range serviceNames { + service, err := lw.namingClient.GetService(nacosvo.GetServiceParam{ + ServiceName: serviceName, + }) + if err != nil { + logger.Errorf("get instances of service %s failed in nacos %s, cause: %v", serviceName, lw.nacosAddress(), err) + continue + } + resList = append(resList, lw.toNacosServiceResource(serviceName, service.Hosts)) + } + nacosServiceList.Items = resList + return nacosServiceList, nil +} + +func (lw *NacosServiceListerWatcher) Watch(_ metav1.ListOptions) (watch.Interface, error) { + _, err := lw.scheduler.Every(lw.cfg.Properties.ServiceWatchPeriod).Seconds().Do(func() { + if lw.stopWatch { + logger.Debugf("stop watch all services of nacos %s", lw.mesh()) + lw.scheduler.Stop() + return + } + startTime := time.Now() + err := lw.fetchAndProcessService() + if err != nil { + logger.Errorf("fetch all service failed in nacos %s, cause: %v", lw.nacosAddress(), err) + return + } + costs := time.Now().UnixMilli() - startTime.UnixMilli() + logger.Debugf("finish fetching and processing all services in nacos %s, costs %dms", lw.nacosAddress(), costs) + }) + if err != nil { + return nil, bizerror.Wrap(err, bizerror.UnknownError, + fmt.Sprintf("watch all services of nacos %s in a schedule occurs error", lw.mesh())) + } + lw.scheduler.StartAsync() + return lw, nil +} + +func (lw *NacosServiceListerWatcher) fetchAllServiceNames() ([]string, error) { + serviceNameList := make([]string, 0) + var pageNum uint32 = 1 + var pageSize uint32 = 100 + // If the number of serviceInfos is less than the page size, it means that the last page has been reached + for { + serviceNames, err := lw.listPage(pageNum, pageSize) + if err != nil { + return nil, err + } + serviceNameList = append(serviceNameList, serviceNames...) + if len(serviceNames) < int(pageSize) { + break + } + pageNum++ + } + return serviceNameList, nil +} + +func (lw *NacosServiceListerWatcher) fetchAndProcessService() error { + var pageNum uint32 = 1 + var pageSize uint32 = 100 + // list all services by page search and subscribe it + for { + serviceNames, err := lw.listPage(pageNum, pageSize) + if err != nil { + return err + } + slice.ForEach(serviceNames, func(index int, item string) { + lw.processNacosService(item) + }) + if len(serviceNames) < int(pageSize) { + break + } + pageNum++ + } + // remove subscribers for services that are no longer being watched + for serviceName, watched := range lw.watchingServices { + if watched { + lw.watchingServices[serviceName] = false + continue + } + err := lw.unsubscribeService(serviceName) + if err != nil { + logger.Errorf("unsubscribe service %s failed in nacos %s, cause: %v", serviceName, lw.nacosAddress(), err) + continue + } + // delete service from watchingServices, only one go routine, thread safe + delete(lw.watchingServices, serviceName) + } + return nil +} + +func (lw *NacosServiceListerWatcher) processNacosService(serviceName string) { + if _, exists := lw.watchingServices[serviceName]; exists { + lw.watchingServices[serviceName] = true + return + } + err := lw.subscribeService(serviceName) + if err != nil { + logger.Errorf("subscribe service %s failed in nacos %s, cause: %v", serviceName, lw.nacosAddress(), err) + return + } + lw.watchingServices[serviceName] = true +} + +func (lw *NacosServiceListerWatcher) listPage(pageNo, pageSize uint32) ([]string, error) { + serviceNames := make([]string, 0, pageSize) + serviceInfos, err := lw.namingClient.GetAllServicesInfo(nacosvo.GetAllServiceInfoParam{ + PageSize: pageSize, + PageNo: pageNo, + }) + + if err != nil { + return nil, bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("get service names failed in nacos %s failed, page size: %d, page num: %d", lw.nacosAddress(), pageSize, pageNo)) + } + serviceNames = append(serviceNames, serviceInfos.Doms...) + + return serviceNames, nil +} + +func (lw *NacosServiceListerWatcher) subscribeService(serviceName string) error { + logger.Infof("subscribe service %s in nacos %s", serviceName, lw.mesh()) + err := lw.namingClient.Subscribe(&nacosvo.SubscribeParam{ + ServiceName: serviceName, + SubscribeCallback: func(instances []nacosmodel.Instance, err error) { + if err != nil { + logger.Errorf("subscribe service %s failed in nacos %s, cause: %v", serviceName, lw.nacosAddress(), err) + return + } + lw.resultChan <- watch.Event{ + Type: watch.Modified, + Object: lw.toNacosServiceResource(serviceName, instances), + } + }, + }) + if err != nil { + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("subscribe service %s failed in nacos %s", serviceName, lw.mesh())) + } + return nil +} + +func (lw *NacosServiceListerWatcher) unsubscribeService(serviceName string) error { + logger.Infof("unsubscribe service %s in nacos %s", serviceName, lw.mesh()) + lw.resultChan <- watch.Event{ + Type: watch.Deleted, + Object: lw.toNacosServiceResource(serviceName, []nacosmodel.Instance{}), + } + return lw.namingClient.Unsubscribe(&nacosvo.SubscribeParam{ + ServiceName: serviceName, + GroupName: "DEFAULT_GROUP", + SubscribeCallback: func(instances []nacosmodel.Instance, err error) { + if err != nil { + logger.Errorf("unsubscribe service %s failed in nacos %s, cause: %v", serviceName, lw.nacosAddress(), err) + return + } + lw.resultChan <- watch.Event{ + Type: watch.Deleted, + Object: lw.toNacosServiceResource(serviceName, instances), + } + }, + }) +} + +func (lw *NacosServiceListerWatcher) toNacosServiceResource(serviceName string, instances []nacosmodel.Instance) *meshresource.NacosServiceResource { + resource := meshresource.NewNacosServiceResourceWithAttributes(serviceName, lw.mesh()) + nacosInstances := slice.Map(instances, func(index int, item nacosmodel.Instance) *meshproto.NacosInstance { + return &meshproto.NacosInstance{ + Ip: item.Ip, + Port: int64(item.Port), + Metadata: item.Metadata, + } + }) + resource.Spec = &meshproto.NacosService{ + ServiceKey: serviceName, + Instances: nacosInstances, + } + return resource +} + +func (lw *NacosServiceListerWatcher) ResourceKind() coremodel.ResourceKind { + return meshresource.NacosServiceKind +} + +func (lw *NacosServiceListerWatcher) TransformFunc() cache.TransformFunc { + return nil +} + +func (lw *NacosServiceListerWatcher) Stop() { + lw.namingClient.CloseClient() + lw.stopWatch = true +} + +func (lw *NacosServiceListerWatcher) ResultChan() <-chan watch.Event { + return lw.resultChan +} + +func (lw *NacosServiceListerWatcher) nacosAddress() string { + return lw.cfg.Address.Registry +} + +func (lw *NacosServiceListerWatcher) mesh() string { + return lw.cfg.ID +} diff --git a/pkg/discovery/zk/factory.go b/pkg/discovery/zk/factory.go new file mode 100644 index 000000000..7518af8f0 --- /dev/null +++ b/pkg/discovery/zk/factory.go @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package zk + +import ( + "encoding/json" + "strconv" + "strings" + + "github.com/duke-git/lancet/v2/strutil" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/discovery" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/discovery/zk/listerwatcher" +) + +func init() { + discovery.RegisterListWatcherFactory(&Factory{}) +} + +type Factory struct { +} + +func (f *Factory) Support(typ discoverycfg.Type) bool { + return discoverycfg.Zookeeper == typ +} + +func (f *Factory) NewListWatchers(config *discoverycfg.Config) ([]controller.ResourceListerWatcher, error) { + mappingLw, err := listerwatcher.NewListerWatcher( + meshresource.ServiceProviderMappingKind, + toUpsertMappingResource, + toDeleteMappingResource, + "/dubbo/mapping", + config, + ) + if err != nil { + return nil, err + } + rpcInstanceLW, err := listerwatcher.NewListerWatcher( + meshresource.RPCInstanceKind, + toUpsertRPCInstanceResource, + toDeleteRPCInstanceResource, + "/services", + config, + ) + if err != nil { + return nil, err + } + configLW, err := listerwatcher.NewListerWatcher( + meshresource.ZKConfigKind, + toUpsertZKConfigResource, + toDeleteZKConfigResource, + "/dubbo/config", + config, + ) + if err != nil { + return nil, err + } + metadataLW, err := listerwatcher.NewListerWatcher( + meshresource.ZKMetadataKind, + toUpsertZKMetadataResource, + toDeleteZKMetadataResource, + "/dubbo/metadata", + config, + ) + if err != nil { + return nil, err + } + + return []controller.ResourceListerWatcher{ + mappingLw, + rpcInstanceLW, + configLW, + metadataLW, + }, nil +} + +func toUpsertMappingResource(mesh, nodePath, nodeData string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) != 4 { + return nil + } + serviceName := paths[3] + return meshresource.ToServiceProviderMappingResource(mesh, serviceName, nodeData) +} + +func toDeleteMappingResource(mesh, nodePath string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) != 4 { + return nil + } + serviceName := paths[3] + res := meshresource.NewServiceProviderMappingResourceWithAttributes(serviceName, mesh) + return res +} + +func toUpsertZKConfigResource(mesh, nodePath, nodeData string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) != 4 { + return nil + } + configName := paths[3] + res := meshresource.NewZKConfigResourceWithAttributes(configName, mesh) + res.Spec = &meshproto.ZKConfig{ + NodeName: configName, + NodeData: nodeData, + } + return res +} + +func toDeleteZKConfigResource(mesh, nodePath string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) != 4 { + return nil + } + configName := paths[3] + res := meshresource.NewZKConfigResourceWithAttributes(configName, mesh) + res.Spec = &meshproto.ZKConfig{ + NodeName: configName, + } + return res +} + +func toUpsertZKMetadataResource(mesh, nodePath, nodeData string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) < 5 { + return nil + } + res := meshresource.NewZKMetadataResourceWithAttributes(nodePath, mesh) + res.Spec = &meshproto.ZKMetadata{ + NodePath: nodePath, + NodeData: nodeData, + } + return res +} + +func toDeleteZKMetadataResource(mesh, nodePath string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) < 5 { + return nil + } + return meshresource.NewZKMetadataResourceWithAttributes(nodePath, mesh) +} + +type ZooKeeperInstance struct { + Name string `json:"name"` + ID string `json:"id"` + Address string `json:"address"` + Port int64 `json:"port"` + SSLPort *int `json:"sslPort,omitempty"` + Payload *ZookeeperInstancePayload `json:"payload"` + RegistrationTimeUTC int64 `json:"registrationTimeUTC"` + ServiceType string `json:"serviceType"` + UriSpec *string `json:"uriSpec,omitempty"` +} + +type ZookeeperInstancePayload struct { + Class string `json:"@class"` + ID string `json:"id"` + Name string `json:"name"` + Metadata map[string]string `json:"metadata"` +} + +func toUpsertRPCInstanceResource(mesh, _, nodeData string) coremodel.Resource { + zkInstance := &ZooKeeperInstance{} + err := json.Unmarshal([]byte(nodeData), zkInstance) + if err != nil { + logger.Warnf("parse instance from zookeeper failed, cause: %v, raw content: %s ", err, nodeData) + return nil + } + if strutil.IsBlank(zkInstance.Name) { + logger.Errorf("invalid content for rpc instance, need app name, raw content: %s", nodeData) + return nil + } + if strutil.IsBlank(zkInstance.Address) { + logger.Errorf("invalid content for rpc instance, need ip, raw content: %s", nodeData) + return nil + } + if zkInstance.Port <= 0 { + logger.Errorf("invalid content for rpc instance, need port, raw content: %s", nodeData) + return nil + } + if zkInstance.Payload == nil { + logger.Errorf("invalid content for rpc instance, need payload, raw content: %s", nodeData) + return nil + } + metadata := zkInstance.Payload.Metadata + if metadata == nil { + logger.Errorf("invalid content for rpc instance, need metadata, raw content: %s", nodeData) + return nil + } + return meshresource.ToRPCInstance(mesh, zkInstance.Name, zkInstance.Address, zkInstance.Port, metadata) +} + +func toDeleteRPCInstanceResource(mesh, nodePath string) coremodel.Resource { + paths := strings.Split(nodePath, constants.PathSeparator) + if len(paths) < 4 { + return nil + } + endpoint := paths[3] + appName := paths[2] + splits := strings.Split(endpoint, constants.ColonSeparator) + ip := splits[0] + port, err := strconv.ParseInt(splits[1], 10, 64) + if err != nil { + logger.Errorf("parse port failed, cause: %v, paths: %s", err, paths) + return nil + } + resName := meshresource.BuildInstanceResName(appName, ip, port) + return meshresource.NewRPCInstanceResourceWithAttributes(resName, mesh) +} diff --git a/pkg/discovery/zk/listerwatcher/listerwatcher.go b/pkg/discovery/zk/listerwatcher/listerwatcher.go new file mode 100644 index 000000000..61b0f1581 --- /dev/null +++ b/pkg/discovery/zk/listerwatcher/listerwatcher.go @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package listerwatcher + +import ( + "fmt" + + "github.com/dubbogo/go-zookeeper/zk" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/clients" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/discovery/zk/zkwatcher" +) + +type ToUpsertResourceFunc func(mesh, nodePath, nodeData string) coremodel.Resource + +type ToDeleteResourceFunc func(mesh, nodePath string) coremodel.Resource + +type ListerWatcher[T coremodel.Resource] struct { + basePath string + rk coremodel.ResourceKind + conn *zk.Conn + cfg *discoverycfg.Config + toUpsertResourceFunc ToUpsertResourceFunc + toDeleteResourceFunc ToDeleteResourceFunc + newResourceFunc coremodel.NewResourceFunc + newResListFunc coremodel.NewResourceListFunc + watcher *zkwatcher.RecursiveWatcher + resultChan chan watch.Event + stopChan chan struct{} +} + +func NewListerWatcher( + rk coremodel.ResourceKind, + toResourceFunc ToUpsertResourceFunc, + toDeleteResourceFunc ToDeleteResourceFunc, + basePath string, + cfg *discoverycfg.Config) (*ListerWatcher[coremodel.Resource], error) { + newResourceFunc, err := coremodel.ResourceSchemaRegistry().NewResourceFunc(rk) + if err != nil { + return nil, err + } + newResListFunc, err := coremodel.ResourceSchemaRegistry().NewResourceListFunc(rk) + if err != nil { + return nil, err + } + conn, err := clients.NewZKConnection(cfg.Address.Registry) + if err != nil { + return nil, err + } + return &ListerWatcher[coremodel.Resource]{ + rk: rk, + toUpsertResourceFunc: toResourceFunc, + toDeleteResourceFunc: toDeleteResourceFunc, + basePath: basePath, + conn: conn, + cfg: cfg, + newResourceFunc: newResourceFunc, + newResListFunc: newResListFunc, + resultChan: make(chan watch.Event, 1000), + stopChan: make(chan struct{}), + }, nil +} + +func (lw *ListerWatcher[T]) List(_ metav1.ListOptions) (k8sruntime.Object, error) { + resList, err := lw.listRecursively(lw.basePath) + if err != nil { + logger.Errorf("list all %s under path %s in zk %s failed, cause: %v", lw.rk, lw.basePath, lw.zkAddr(), err) + return nil, err + } + resListObj := lw.newResListFunc() + resListObj.SetItems(resList) + return resListObj, nil +} + +func (lw *ListerWatcher[T]) listRecursively(path string) ([]coremodel.Resource, error) { + resList := make([]coremodel.Resource, 0) + nodeData, _, err := lw.conn.Get(path) + if err != nil { + errStr := fmt.Sprintf("get %s from zk failed, path: %s, addr: %s, cause: %v", lw.rk, path, lw.zkAddr(), err) + logger.Errorf(errStr) + return nil, bizerror.Wrap(err, bizerror.ZKError, errStr) + } + res := lw.toUpsertResourceFunc(lw.mesh(), path, string(nodeData)) + if res != nil { + resList = append(resList, res) + } + children, _, err := lw.conn.Children(path) + if err != nil { + errStr := fmt.Sprintf("list %s from zk failed, path: %s, addr: %s, cause: %v", lw.rk, path, lw.zkAddr(), err) + logger.Errorf(errStr) + return nil, bizerror.Wrap(err, bizerror.ZKError, errStr) + } + if len(children) == 0 { + return resList, nil + } + for _, childPath := range children { + resources, err := lw.listRecursively(path + constants.PathSeparator + childPath) + if err != nil { + return nil, err + } + resList = append(resList, resources...) + } + return resList, nil +} + +func (lw *ListerWatcher[T]) Watch(_ metav1.ListOptions) (watch.Interface, error) { + watcher := zkwatcher.NewRecursiveWatcher(lw.conn, lw.basePath) + go func() { + for { + select { + case event, ok := <-watcher.EventChan(): + if !ok { + logger.Warnf("zookeeper watcher stopped, path: %s, addr: %s", lw.basePath, lw.zkAddr()) + return + } + lw.handleEvent(event) + case <-lw.stopChan: + logger.Warnf("stop watching %s in %s,", lw.basePath, lw.zkAddr()) + return + } + + } + }() + err := watcher.StartAsync() + lw.watcher = watcher + if err != nil { + lw.Stop() + return nil, err + } + return lw, nil +} + +func (lw *ListerWatcher[T]) handleEvent(event zkwatcher.ZookeeperEvent) { + switch event.Type { + case zkwatcher.NodeCreated: + res := lw.toUpsertResourceFunc(lw.mesh(), event.Path, event.Data) + if res == nil { + logger.Warnf("skip creating resource, parse zookeeper node data to %s failed, path: %s, zk: %s, event: %v", + lw.rk, event.Path, lw.zkAddr(), event) + return + } + logger.Infof("%s added, rsKey: %s", lw.rk, res.ResourceKey()) + lw.resultChan <- watch.Event{ + Type: watch.Added, + Object: res, + } + case zkwatcher.NodeChanged: + res := lw.toUpsertResourceFunc(lw.mesh(), event.Path, event.Data) + if res == nil { + logger.Warnf("skip updating resource, parse zookeeper node data to %s failed, path: %s, zk: %s, event: %v", + lw.rk, event.Path, lw.zkAddr(), event) + return + } + logger.Infof("%s modified, rsKey: %s", lw.rk, res.ResourceKey()) + lw.resultChan <- watch.Event{ + Type: watch.Modified, + Object: res, + } + case zkwatcher.NodeDeleted: + res := lw.toDeleteResourceFunc(lw.mesh(), event.Path) + if res == nil { + logger.Warnf("skip deleting resource, parse zookeeper node data to %s failed, path: %s, zk: %s, event: %v", + lw.rk, event.Path, lw.zkAddr(), event) + return + } + logger.Infof("%s deleted, rsKey: %s", lw.rk, res.ResourceKey()) + lw.resultChan <- watch.Event{ + Type: watch.Deleted, + Object: res, + } + default: + logger.Warnf("unknown event type, event: %v", event) + } +} + +func (lw *ListerWatcher[T]) zkAddr() string { + return lw.cfg.Address.Registry +} + +func (lw *ListerWatcher[T]) mesh() string { + return lw.cfg.ID +} + +func (lw *ListerWatcher[T]) ResourceKind() coremodel.ResourceKind { + return lw.rk +} + +func (lw *ListerWatcher[T]) TransformFunc() cache.TransformFunc { + return nil +} + +func (lw *ListerWatcher[T]) Stop() { + if lw.watcher != nil { + lw.watcher.Stop() + } + close(lw.stopChan) + close(lw.resultChan) + lw.conn.Close() +} + +func (lw *ListerWatcher[T]) ResultChan() <-chan watch.Event { + return lw.resultChan +} diff --git a/pkg/discovery/zk/zkwatcher/watcher.go b/pkg/discovery/zk/zkwatcher/watcher.go new file mode 100644 index 000000000..2b7c08c20 --- /dev/null +++ b/pkg/discovery/zk/zkwatcher/watcher.go @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package zkwatcher + +import ( + "sync" + "time" + + "github.com/dubbogo/go-zookeeper/zk" + set "github.com/duke-git/lancet/v2/datastructure/set" + + "github.com/apache/dubbo-admin/pkg/core/logger" +) + +type EventType string + +const ( + NodeCreated EventType = "NodeCreated" + NodeDeleted EventType = "NodeDeleted" + NodeChanged EventType = "NodeChanged" +) + +// ZookeeperEvent represents a zookeeper event +type ZookeeperEvent struct { + Type EventType + // node path + Path string + // node data + Data string + // whether it is a leaf node + LeafNode bool +} + +// RecursiveWatcher recursive watcher +type RecursiveWatcher struct { + conn *zk.Conn + basePath string + eventChan chan ZookeeperEvent + stopChan chan struct{} + mu sync.Mutex +} + +// NewRecursiveWatcher create a new recursive watcher +func NewRecursiveWatcher(conn *zk.Conn, basePath string) *RecursiveWatcher { + return &RecursiveWatcher{ + conn: conn, + basePath: basePath, + eventChan: make(chan ZookeeperEvent, 1000), + stopChan: make(chan struct{}), + } +} + +// StartAsync begin watching +func (rw *RecursiveWatcher) StartAsync() error { + logger.Infof("Start watching path: %s", rw.basePath) + // Recursively watch the initial path + return rw.watchPathRecursively(rw.basePath) +} + +// Stop watching +func (rw *RecursiveWatcher) Stop() { + logger.Infof("Stop watching path: %s", rw.basePath) + close(rw.stopChan) + close(rw.eventChan) +} + +// EventChan return event channel +func (rw *RecursiveWatcher) EventChan() <-chan ZookeeperEvent { + return rw.eventChan +} + +// watchPathRecursively watch path recursively +func (rw *RecursiveWatcher) watchPathRecursively(path string) error { + // Watch data changes for the current path + go rw.watchDataChanges(path) + + // Get children of current path and watch + children, _, err := rw.conn.Children(path) + if err != nil { + logger.Errorf("Failed to get children of path: %s, cause: %v", path, err) + return err + } + // Watch children list changes + go rw.watchChildrenChanges(path) + + // Recursively watch child nodes + for _, child := range children { + childPath := path + "/" + child + if err := rw.watchPathRecursively(childPath); err != nil { + logger.Errorf("Failed to watch subpath %s: %v", childPath, err) + } + } + return nil +} + +// watchDataChanges watch node data changes +func (rw *RecursiveWatcher) watchDataChanges(path string) { + logger.Debugf("Watching data changes for path: %s", path) + for { + + select { + case <-rw.stopChan: + return + default: + } + + // Get data and set up watch + data, stat, watcher, err := rw.conn.GetW(path) + if err != nil { + logger.Errorf("Failed to watch data changes for path %s, cause: %v", path, err) + time.Sleep(time.Second) + continue + } + rw.eventChan <- ZookeeperEvent{ + Type: NodeCreated, + Path: path, + Data: string(data), + LeafNode: stat.NumChildren == 0, + } + + select { + case event := <-watcher.EvtCh: + if event.Type == zk.EventNodeDataChanged { + logger.Debugf("node data changed: %s", path) + + // Re-watch data changes + go rw.watchDataChanges(path) + return + } else if event.Type == zk.EventNodeDeleted { + // Node deleted, stop watching + logger.Debugf("node deleted: %s", path) + rw.eventChan <- ZookeeperEvent{ + Type: NodeDeleted, + Path: path, + LeafNode: stat.NumChildren == 0, + } + return + } + case <-rw.stopChan: + return + } + + // If node exists but no changes, continue watching + if stat != nil { + continue + } + } +} + +// watchChildrenChanges watch child node changes +func (rw *RecursiveWatcher) watchChildrenChanges(path string) { + logger.Debugf("Watching child node changes for path: %s", path) + for { + // Check if stopped + select { + case <-rw.stopChan: + return + default: + } + + // Get child nodes and set up watch + children, stat, watcher, err := rw.conn.ChildrenW(path) + if err != nil { + logger.Errorf("Failed to watch child node changes for path %s: %v", path, err) + time.Sleep(time.Second) + continue + } + + select { + case event := <-watcher.EvtCh: + if event.Type == zk.EventNodeChildrenChanged { + logger.Debugf("Child node list changed: %s", path) + + // Get current child nodes + newChildren, _, err := rw.conn.Children(path) + if err != nil { + logger.Debugf("Failed to get new child nodes: %v", err) + continue + } + // Calculate added and deleted child nodes + newChildSet := set.FromSlice(newChildren) + oldChildSet := set.FromSlice(children) + addedChildren := newChildSet.Minus(oldChildSet) + deletedChildren := oldChildSet.Minus(newChildSet) + + // watch newly added child nodes + for _, c := range addedChildren.ToSlice() { + childPath := path + "/" + c + logger.Debugf("New child node added: %s", childPath) + // Recursively watch new node + go func() { + err := rw.watchPathRecursively(childPath) + if err != nil { + logger.Errorf("Failed to watch subpath %s: %v", childPath, err) + } + }() + } + + // Check for deleted child nodes + for _, c := range deletedChildren.ToSlice() { + logger.Debugf("child node %s of %s deleted", c, path) + } + + // Re-watch child node changes + go rw.watchChildrenChanges(path) + return + } else if event.Type == zk.EventNodeDeleted { + // Parent node deleted, stop watching + logger.Debugf("parent node %s deleted, stop watching children changes", path) + return + } + case <-rw.stopChan: + return + } + + // If node exists but no changes, continue watching + if stat != nil { + continue + } + } +} diff --git a/pkg/engine/kubernetes/factory.go b/pkg/engine/kubernetes/factory.go new file mode 100644 index 000000000..f1fa79170 --- /dev/null +++ b/pkg/engine/kubernetes/factory.go @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kubernetes + +import ( + "fmt" + + "github.com/duke-git/lancet/v2/strutil" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/engine" + "github.com/apache/dubbo-admin/pkg/engine/kubernetes/listerwatcher" +) + +func init() { + engine.RegisterFactory(NewKubernetesEngineFactory()) +} + +var _ engine.Factory = &EngineFactory{} + +type EngineFactory struct{} + +func NewKubernetesEngineFactory() *EngineFactory { + return &EngineFactory{} +} + +func (e *EngineFactory) Support(typ enginecfg.Type) bool { + return enginecfg.Kubernetes == typ +} + +func (e *EngineFactory) NewListWatchers(cfg *enginecfg.Config) ([]controller.ResourceListerWatcher, error) { + kubeconfigPath := cfg.Properties.KubeConfigPath + + var config *rest.Config + var err error + if !strutil.IsBlank(kubeconfigPath) { + config, err = clientcmd.BuildConfigFromFlags("", kubeconfigPath) + } else { + config, err = rest.InClusterConfig() + } + if err != nil { + return nil, fmt.Errorf("failed to init kubeconfig in kubernetes engine, %w", err) + } + + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, fmt.Errorf("failed to init clientset in kubernetes engine, %w", err) + } + + lwList := make([]controller.ResourceListerWatcher, 0) + podListerWatcher, err := listerwatcher.NewPodListWatcher(clientset, cfg) + if err != nil { + return nil, fmt.Errorf("failed to init PodListerWatcher in kubernetes engine, %w", err) + } + lwList = append(lwList, podListerWatcher) + return lwList, nil +} diff --git a/pkg/engine/kubernetes/listerwatcher/runtime_instance.go b/pkg/engine/kubernetes/listerwatcher/runtime_instance.go new file mode 100644 index 000000000..bc35f3fb9 --- /dev/null +++ b/pkg/engine/kubernetes/listerwatcher/runtime_instance.go @@ -0,0 +1,374 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package listerwatcher + +import ( + "fmt" + "reflect" + "strconv" + + "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/v2/strutil" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + + meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1" + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +type PodListerWatcher struct { + cfg *enginecfg.Config + lw cache.ListerWatcher +} + +var _ controller.ResourceListerWatcher = &PodListerWatcher{} +var _ controller.ResourceKeyProvider = &PodListerWatcher{} + +func NewPodListWatcher(clientset *kubernetes.Clientset, cfg *enginecfg.Config) (*PodListerWatcher, error) { + var selector fields.Selector + s := cfg.Properties.PodWatchSelector + if strutil.IsBlank(s) { + selector = fields.Everything() + } + selector, err := fields.ParseSelector(s) + if err != nil { + return nil, fmt.Errorf("parse selector %s failed: %v", s, err) + } + lw := cache.NewListWatchFromClient( + clientset.CoreV1().RESTClient(), + "pods", + metav1.NamespaceAll, + selector, + ) + return &PodListerWatcher{ + cfg: cfg, + lw: lw, + }, nil +} + +func (p *PodListerWatcher) List(options metav1.ListOptions) (k8sruntime.Object, error) { + return p.lw.List(options) +} + +func (p *PodListerWatcher) Watch(options metav1.ListOptions) (watch.Interface, error) { + return p.lw.Watch(options) +} + +func (p *PodListerWatcher) ResourceKind() coremodel.ResourceKind { + return meshresource.RuntimeInstanceKind +} + +func (p *PodListerWatcher) TransformFunc() cache.TransformFunc { + return func(obj interface{}) (interface{}, error) { + pod, ok := obj.(*v1.Pod) + if !ok { + objType := reflect.TypeOf(obj).Name() + logger.Errorf("cannot transform %s to Pod", objType) + return nil, bizerror.NewAssertionError("Pod", objType) + } + mainContainer := p.getMainContainer(pod) + appName := p.getDubboAppName(pod) + rpcPort := p.getDubboRPCPort(pod) + var startTime string + if pod.Status.StartTime != nil { + startTime = pod.Status.StartTime.Format(constants.TimeFormatStr) + } + createTime := pod.CreationTimestamp.Format(constants.TimeFormatStr) + readyTime := "" + slice.ForEach(pod.Status.Conditions, func(_ int, c v1.PodCondition) { + if c.Type == v1.PodReady && c.Status == v1.ConditionTrue { + readyTime = c.LastTransitionTime.Format(constants.TimeFormatStr) + } + }) + phase := derivePodPhase(pod) + var workloadName string + var workloadType string + if len(pod.GetOwnerReferences()) > 0 { + workloadName = pod.GetOwnerReferences()[0].Name + workloadType = pod.GetOwnerReferences()[0].Kind + } + conditions := slice.Map(pod.Status.Conditions, func(_ int, c v1.PodCondition) *meshproto.Condition { + return &meshproto.Condition{ + Type: string(c.Type), + Status: string(c.Status), + LastTransitionTime: c.LastTransitionTime.Format(constants.TimeFormatStr), + Reason: c.Reason, + Message: c.Message, + } + }) + var image string + probes := make([]*meshproto.Probe, 0) + if mainContainer != nil { + image = mainContainer.Image + if mainContainer.LivenessProbe != nil { + port := p.getProbePort(mainContainer.LivenessProbe) + probes = append(probes, &meshproto.Probe{ + Type: meshproto.LivenessProbe, + Port: port, + }) + } + if mainContainer.ReadinessProbe != nil { + port := p.getProbePort(mainContainer.ReadinessProbe) + probes = append(probes, &meshproto.Probe{ + Type: meshproto.ReadinessProbe, + Port: port, + }) + } + if mainContainer.StartupProbe != nil { + port := p.getProbePort(mainContainer.StartupProbe) + probes = append(probes, &meshproto.Probe{ + Type: meshproto.StartupProbe, + Port: port, + }) + } + } + res := meshresource.NewRuntimeInstanceResourceWithAttributes(pod.Name, p.getDubboMesh(pod)) + res.Spec = &meshproto.RuntimeInstance{ + Name: pod.Name, + Ip: pod.Status.PodIP, + RpcPort: rpcPort, + Image: image, + AppName: appName, + CreateTime: createTime, + StartTime: startTime, + ReadyTime: readyTime, + Phase: phase, + WorkloadName: workloadName, + WorkloadType: workloadType, + Node: pod.Spec.NodeName, + Probes: probes, + Conditions: conditions, + SourceEngine: p.cfg.ID, + SourceEngineType: string(p.cfg.Type), + } + return res, nil + } +} + +func (p *PodListerWatcher) KeyFunc() cache.KeyFunc { + return p.resourceKeyFromObject +} + +func (p *PodListerWatcher) resourceKeyFromObject(obj interface{}) (string, error) { + for { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + break + } + obj = tombstone.Obj + } + switch o := obj.(type) { + case *v1.Pod: + return p.resourceKeyFromPod(o), nil + case *meshresource.RuntimeInstanceResource: + return o.ResourceKey(), nil + default: + if obj == nil { + return "", bizerror.NewAssertionError("Pod", "nil") + } + return "", bizerror.NewAssertionError("Pod", reflect.TypeOf(obj).Name()) + } +} + +func (p *PodListerWatcher) resourceKeyFromPod(pod *v1.Pod) string { + return coremodel.BuildResourceKey(p.getDubboMesh(pod), pod.Name) +} + +func derivePodPhase(pod *v1.Pod) string { + if pod == nil { + return "Unknown" + } + if pod.DeletionTimestamp != nil { + return meshproto.InstanceTerminating + } + if hasCrashingContainerStatus(pod.Status.InitContainerStatuses) || hasCrashingContainerStatus(pod.Status.ContainerStatuses) { + return meshproto.InstanceCrashing + } + switch pod.Status.Phase { + case v1.PodPending: + if hasStartingContainerStatus(pod.Status.InitContainerStatuses) || hasStartingContainerStatus(pod.Status.ContainerStatuses) { + return meshproto.InstanceStarting + } + return string(v1.PodPending) + case v1.PodRunning: + if !isPodReady(pod.Status.Conditions) { + return meshproto.InstanceStarting + } + return string(v1.PodRunning) + case v1.PodFailed: + return string(v1.PodFailed) + case v1.PodSucceeded: + return string(v1.PodSucceeded) + case v1.PodUnknown: + return string(v1.PodUnknown) + default: + return string(pod.Status.Phase) + } +} + +func isPodReady(conditions []v1.PodCondition) bool { + for _, condition := range conditions { + if condition.Type == v1.PodReady { + return condition.Status == v1.ConditionTrue + } + } + return false +} + +func hasStartingContainerStatus(statuses []v1.ContainerStatus) bool { + for _, status := range statuses { + if status.State.Waiting == nil { + continue + } + switch status.State.Waiting.Reason { + case "ContainerCreating", "PodInitializing": + return true + } + } + return false +} + +func hasCrashingContainerStatus(statuses []v1.ContainerStatus) bool { + for _, status := range statuses { + if status.State.Waiting != nil { + switch status.State.Waiting.Reason { + case "CrashLoopBackOff", "ImagePullBackOff", "ErrImagePull", "RunContainerError", + "CreateContainerConfigError", "CreateContainerError", "StartError": + return true + } + } + if status.State.Terminated != nil && status.State.Terminated.ExitCode != 0 { + return true + } + } + return false +} + +func (p *PodListerWatcher) getMainContainer(pod *v1.Pod) *v1.Container { + containers := pod.Spec.Containers + strategy := p.cfg.Properties.MainContainerChooseStrategy + switch strategy.Type { + case enginecfg.ChooseByLast: + return &containers[len(containers)-1] + case enginecfg.ChooseByIndex: + return &containers[strategy.Index] + case enginecfg.ChooseByName: + c, ok := slice.FindBy[v1.Container](containers, func(_ int, c v1.Container) bool { + return c.Name == strategy.Name + }) + if !ok { + logger.Warnf("pod %s has no container named %s, cannot retrieve the correct main container", + pod.Name, strategy.Name) + return nil + } + return &c + case enginecfg.ChooseByAnnotation: + value, exists := pod.Annotations[strategy.AnnotationKey] + if !exists { + logger.Warnf("pod %s has no annotation %s, cannot retrieve the correct main container", + pod.Name, strategy.AnnotationKey) + return nil + } + c, ok := slice.FindBy[v1.Container](containers, func(_ int, c v1.Container) bool { + return c.Name == value + }) + if !ok { + logger.Warnf("pod %s has no container named %s, cannot retrieve the correct main container", + pod.Name, value) + return nil + } + return &c + } + return nil +} + +func (p *PodListerWatcher) getDubboAppName(pod *v1.Pod) string { + identifier := p.cfg.Properties.DubboAppIdentifier + if identifier == nil { + return "" + } + switch identifier.Type { + case enginecfg.IdentifyByAnnotation: + return pod.Annotations[identifier.AnnotationKey] + case enginecfg.IdentifyByLabel: + return pod.Labels[identifier.LabelKey] + default: + return "" + } +} + +func (p *PodListerWatcher) getDubboRPCPort(pod *v1.Pod) int64 { + identifier := p.cfg.Properties.DubboRPCPortIdentifier + if identifier == nil { + return 0 + } + var rpcPort int64 + var err error + switch identifier.Type { + case enginecfg.IdentifyByAnnotation: + rpcPort, err = strconv.ParseInt(pod.Annotations[identifier.AnnotationKey], 10, 64) + case enginecfg.IdentifyByLabel: + rpcPort, err = strconv.ParseInt(pod.Labels[identifier.LabelKey], 10, 64) + default: + rpcPort = 0 + } + if err != nil { + logger.Warnf("failed to parse dubbo rpc port %s, cannot retrieve the correct dubbo rpc port", + pod.Annotations[identifier.AnnotationKey]) + } + return rpcPort +} + +func (p *PodListerWatcher) getDubboMesh(pod *v1.Pod) string { + identifier := p.cfg.Properties.DubboDiscoveryIdentifier + if identifier == nil { + return constants.DefaultMesh + } + var mesh string + switch identifier.Type { + case enginecfg.IdentifyByAnnotation: + mesh = pod.Annotations[identifier.AnnotationKey] + case enginecfg.IdentifyByLabel: + mesh = pod.Labels[identifier.LabelKey] + default: + mesh = constants.DefaultMesh + } + return mesh +} + +func (p *PodListerWatcher) getProbePort(probe *v1.Probe) int32 { + if probe.TCPSocket != nil { + return probe.TCPSocket.Port.IntVal + } else if probe.HTTPGet != nil { + return probe.HTTPGet.Port.IntVal + } else if probe.GRPC != nil { + return probe.GRPC.Port + } + return 0 +} diff --git a/pkg/engine/mock/factory.go b/pkg/engine/mock/factory.go new file mode 100644 index 000000000..39e676749 --- /dev/null +++ b/pkg/engine/mock/factory.go @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mock + +import ( + enginecfg "github.com/apache/dubbo-admin/pkg/config/engine" + "github.com/apache/dubbo-admin/pkg/core/controller" + "github.com/apache/dubbo-admin/pkg/core/engine" +) + +func init() { + engine.RegisterFactory(&EngineFactory{}) +} + +var _ engine.Factory = &EngineFactory{} + +type EngineFactory struct{} + +func (e *EngineFactory) Support(typ enginecfg.Type) bool { + return enginecfg.Mock == typ +} + +func (e *EngineFactory) NewListWatchers(cfg *enginecfg.Config) ([]controller.ResourceListerWatcher, error) { + return make([]controller.ResourceListerWatcher, 0), nil +} diff --git a/pkg/governor/mock/factory.go b/pkg/governor/mock/factory.go new file mode 100644 index 000000000..4c7b282dd --- /dev/null +++ b/pkg/governor/mock/factory.go @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mock + +import ( + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/governor" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +func init() { + governor.RegisterFactory(&mockGovernorFactory{}) +} + +type mockGovernorFactory struct{} + +var _ governor.Factory = &mockGovernorFactory{} + +func (f *mockGovernorFactory) Support(t discoverycfg.Type) bool { + return t == discoverycfg.Mock +} + +func (f *mockGovernorFactory) New(_ string, _ *discoverycfg.Config, _ store.Router, _ events.Emitter) (governor.RuleGovernor, error) { + return &mockGovernor{}, nil +} + +type mockGovernor struct{} + +var _ governor.RuleGovernor = &mockGovernor{} + +func (g *mockGovernor) CreateRule(_ coremodel.Resource) error { return nil } +func (g *mockGovernor) UpdateRule(_ coremodel.Resource) error { return nil } +func (g *mockGovernor) DeleteRule(_ coremodel.Resource) error { return nil } diff --git a/pkg/common/util/files/files.go b/pkg/governor/nacos2/factory.go similarity index 58% rename from pkg/common/util/files/files.go rename to pkg/governor/nacos2/factory.go index 6fdc5018f..3b82b1616 100644 --- a/pkg/common/util/files/files.go +++ b/pkg/governor/nacos2/factory.go @@ -15,34 +15,25 @@ * limitations under the License. */ -package files +package nacos2 import ( - "io/fs" - "os" - "path/filepath" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/governor" + "github.com/apache/dubbo-admin/pkg/core/store" ) -func FileExists(path string) bool { - _, err := os.Stat(path) - return err == nil +func init() { + governor.RegisterFactory(&Factory{}) } -func FileEmpty(path string) (bool, error) { - file, err := os.Stat(path) - if err != nil { - return true, err - } - return file.Size() == 0, nil +type Factory struct{} + +func (f *Factory) Support(t discoverycfg.Type) bool { + return t == discoverycfg.Nacos2 } -// IsDirWriteable checks if dir is writable by writing and removing a file -// to dir. It returns nil if dir is writable. -func IsDirWriteable(dir string) error { - f := filepath.Join(dir, ".touch") - perm := 0o600 - if err := os.WriteFile(f, []byte(""), fs.FileMode(perm)); err != nil { - return err - } - return os.Remove(f) +func (f *Factory) New(mesh string, config *discoverycfg.Config, router store.Router, emitter events.Emitter) (governor.RuleGovernor, error) { + return NewNacos2Governor(config, router, emitter) } diff --git a/pkg/governor/nacos2/governor.go b/pkg/governor/nacos2/governor.go new file mode 100644 index 000000000..626f665f4 --- /dev/null +++ b/pkg/governor/nacos2/governor.go @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nacos2 + +import ( + "fmt" + "reflect" + "time" + + nacosconfigclient "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" + nacosnamingclient "github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client" + nacosvo "github.com/nacos-group/nacos-sdk-go/v2/vo" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/yaml" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/clients" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +type RuleGovernor struct { + cfg *discoverycfg.Config + storeRouter store.Router + emitter events.Emitter + configClient nacosconfigclient.IConfigClient + namingClient nacosnamingclient.INamingClient +} + +func NewNacos2Governor( + cfg *discoverycfg.Config, + storeRouter store.Router, + emitter events.Emitter) (*RuleGovernor, error) { + configClient, namingClient, err := clients.CreateNacosClients(cfg.Address.ConfigCenter) + if err != nil { + return nil, err + } + return &RuleGovernor{ + cfg: cfg, + storeRouter: storeRouter, + emitter: emitter, + configClient: configClient, + namingClient: namingClient, + }, nil +} + +func (g *RuleGovernor) CreateRule(r coremodel.Resource) error { + rawContent, err := yaml.Marshal(r.ResourceSpec()) + if err != nil { + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("failed to marshal resource spec, res: %s", r.String())) + } + ok, err := g.configClient.PublishConfig(nacosvo.ConfigParam{ + DataId: r.ResourceMeta().Name, + Group: constants.NacosConfigGroup, + Content: string(rawContent), + }) + if err != nil || !ok { + logger.Errorf("failed to publish config in %s, res: %s", r.String(), r.ResourceMesh()) + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("failed to publish config, res: %s", r.String())) + } + // wait for the config to be published indeed + <-time.After(2 * time.Second) + g.GetConfigAndUpdateStore(r) + return nil +} + +func (g *RuleGovernor) UpdateRule(r coremodel.Resource) error { + return g.CreateRule(r) +} + +func (g *RuleGovernor) DeleteRule(r coremodel.Resource) error { + ok, err := g.configClient.DeleteConfig(nacosvo.ConfigParam{ + DataId: r.ResourceMeta().Name, + Group: constants.NacosConfigGroup, + }) + if err != nil || !ok { + logger.Errorf("failed to delete config in %s, res: %s", r.String(), r.ResourceMesh()) + return bizerror.Wrap(err, bizerror.NacosError, + fmt.Sprintf("failed to delete config, res: %s", r.String())) + } + // delete resource in store, if delete failed, just log an error message + // the lister-watcher will sync the deleted event finally + st, err := g.storeRouter.ResourceKindRoute(r.ResourceKind()) + if err != nil { + logger.Errorf("failed to get store in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return nil + } + // wait for the config to be deleted indeed + <-time.After(2 * time.Second) + if err := st.Delete(r); err != nil { + logger.Errorf("failed to delete resource in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return nil + } + return nil +} + +// GetConfigAndUpdateStore get resource from nacos, and update resource in store, if failed, just log an error message, +// the lister-watcher will sync the event finally +func (g *RuleGovernor) GetConfigAndUpdateStore(r coremodel.Resource) { + content, err := g.configClient.GetConfig(nacosvo.ConfigParam{ + DataId: r.ResourceMeta().Name, + Group: constants.NacosConfigGroup, + }) + if err != nil { + logger.Errorf("failed to get config in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return + } + st, err := g.storeRouter.ResourceKindRoute(r.ResourceKind()) + if err != nil { + logger.Errorf("failed to get store in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return + } + var res coremodel.Resource + switch r.ResourceKind() { + case meshresource.DynamicConfigKind: + res = meshresource.ToDynamicConfigResource(r.ResourceMesh(), r.ResourceMeta().Name, content) + case meshresource.ConditionRouteKind: + res = meshresource.ToConditionRouteResource(r.ResourceMesh(), r.ResourceMeta().Name, content) + case meshresource.TagRouteKind: + res = meshresource.ToTagRouteResource(r.ResourceMesh(), r.ResourceMeta().Name, content) + } + obj, exists, err := st.GetByKey(r.ResourceKey()) + if err != nil { + logger.Errorf("failed to get resource in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return + } + // if exists in store, update it + if exists { + if err := st.Update(res); err != nil { + logger.Errorf("failed to update resource in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return + } + oldRes, ok := obj.(coremodel.Resource) + if !ok { + logger.Errorf("type assertion failed in nacos2 discovery %s, expected Resource, got %s", + g.mesh(), reflect.TypeOf(obj).Name()) + } + g.emitter.Send(events.NewResourceChangedEvent(cache.Updated, oldRes, res)) + return + } + + // otherwise add it + err = st.Add(res) + if err != nil { + logger.Errorf("failed to add resource in %s, res: %s, cause: %s", r.String(), r.ResourceMesh(), err) + return + } + g.emitter.Send(events.NewResourceChangedEvent(cache.Added, nil, res)) +} + +func (g *RuleGovernor) mesh() string { + return g.cfg.ID +} diff --git a/pkg/governor/zk/factory.go b/pkg/governor/zk/factory.go new file mode 100644 index 000000000..1d6819d41 --- /dev/null +++ b/pkg/governor/zk/factory.go @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package zk + +import ( + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/governor" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +func init() { + governor.RegisterFactory(&Factory{}) +} + +type Factory struct{} + +func (f *Factory) Support(t discoverycfg.Type) bool { + return t == discoverycfg.Zookeeper +} + +func (f *Factory) New(_ string, config *discoverycfg.Config, router store.Router, emitter events.Emitter) (governor.RuleGovernor, error) { + return NewZKRuleGovernor(config, router, emitter) +} diff --git a/pkg/governor/zk/governor.go b/pkg/governor/zk/governor.go new file mode 100644 index 000000000..a811557b2 --- /dev/null +++ b/pkg/governor/zk/governor.go @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package zk + +import ( + "fmt" + + "github.com/dubbogo/go-zookeeper/zk" + "sigs.k8s.io/yaml" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + discoverycfg "github.com/apache/dubbo-admin/pkg/config/discovery" + "github.com/apache/dubbo-admin/pkg/core/clients" + "github.com/apache/dubbo-admin/pkg/core/events" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" +) + +type RuleGovernor struct { + cfg *discoverycfg.Config + storeRouter store.Router + emitter events.Emitter + conn *zk.Conn +} + +func NewZKRuleGovernor(cfg *discoverycfg.Config, router store.Router, emitter events.Emitter) (*RuleGovernor, error) { + address := cfg.Address.Registry + conn, err := clients.NewZKConnection(address) + if err != nil { + return nil, err + } + return &RuleGovernor{ + cfg: cfg, + storeRouter: router, + emitter: emitter, + conn: conn, + }, nil +} + +func (g *RuleGovernor) CreateRule(r coremodel.Resource) error { + path := "/dubbo/config/" + r.ResourceMeta().Name + content, err := yaml.Marshal(r.ResourceSpec()) + if err != nil { + return bizerror.Wrap(err, bizerror.YamlError, + fmt.Sprintf("failed to marshal resource spec, res: %s", r.String())) + } + _, err = g.conn.Create(path, content, 0, zk.WorldACL(zk.PermAll)) + if err != nil { + return bizerror.Wrap(err, bizerror.ZKError, + fmt.Sprintf("failed to create zk node, path: %s", path)) + } + // save to store once znode is created in zk to insure local store is consistent to zk timely. + // if save to store failed, the discovery will watch and update the store finally. + st, err := g.storeRouter.ResourceRoute(r) + if err != nil { + logger.Warnf("cannot find store for rk: %s, cause: %v", r.ResourceKind(), err) + return nil + } + err = st.Add(r) + if err != nil { + logger.Warnf("add resource to store failed, res: %s, cause: %v", r.String(), err) + return nil + } + return nil +} + +func (g *RuleGovernor) UpdateRule(r coremodel.Resource) error { + path := "/dubbo/config/" + r.ResourceMeta().Name + content, err := yaml.Marshal(r.ResourceSpec()) + if err != nil { + return bizerror.Wrap(err, bizerror.YamlError, + fmt.Sprintf("failed to marshal resource spec, res: %s", r.String())) + } + _, err = g.conn.Set(path, content, -1) + if err != nil { + return bizerror.Wrap(err, bizerror.ZKError, + fmt.Sprintf("failed to update zk node, path: %s", path)) + } + st, err := g.storeRouter.ResourceRoute(r) + if err != nil { + logger.Warnf("cannot find store for rk: %s, cause: %v", r.ResourceKind(), err) + return nil + } + err = st.Update(r) + if err != nil { + logger.Warnf("update resource in store failed, res: %s, cause: %v", r.String(), err) + } + return nil +} + +func (g *RuleGovernor) DeleteRule(r coremodel.Resource) error { + path := "/dubbo/config/" + r.ResourceMeta().Name + err := g.conn.Delete(path, -1) + if err != nil { + return bizerror.Wrap(err, bizerror.ZKError, + fmt.Sprintf("failed to delete zk node, path: %s", path)) + } + st, err := g.storeRouter.ResourceRoute(r) + if err != nil { + logger.Warnf("cannot find store for rk: %s, cause: %v", r.ResourceKind(), err) + } + err = st.Delete(r) + if err != nil { + logger.Warnf("delete resource from store failed, res: %s, cause: %v", r.String(), err) + } + return nil +} diff --git a/pkg/lock/gorm/factory.go b/pkg/lock/gorm/factory.go new file mode 100644 index 000000000..ff9f81bd1 --- /dev/null +++ b/pkg/lock/gorm/factory.go @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package gorm + +import ( + "fmt" + + "github.com/apache/dubbo-admin/pkg/core/lock" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/store/dbcommon" +) + +func init() { + lock.RegisterLockFactory(&gormLockFactory{}) +} + +type gormLockFactory struct{} + +// Support checks if GORM-based lock is supported based on store configuration +func (f *gormLockFactory) Support(ctx runtime.BuilderContext) bool { + cfg := ctx.Config().Store + // GORM lock is supported for database-backed stores (mysql, postgres) + return cfg.Type == "mysql" || cfg.Type == "postgres" +} + +// NewLock creates a GORM Lock instance by obtaining DB from dbcommon package +func (f *gormLockFactory) NewLock(ctx runtime.BuilderContext) (lock.Lock, error) { + cfg := ctx.Config().Store + + // Get the database connection from dbcommon's global connection pool + // This reuses the existing connection pool created by the store + // but accesses it through the dbcommon package instead of StoreComponent + db := dbcommon.GetGlobalDB(cfg.Type) + if db == nil { + return nil, fmt.Errorf("no database connection found for store type: %s", cfg.Type) + } + + // Auto-migrate lock table + if err := db.AutoMigrate(&LockRecord{}); err != nil { + return nil, fmt.Errorf("failed to migrate lock table: %w", err) + } + + logger.Info("Creating GORM-based distributed lock using existing database connection") + return NewGormLockFromDB(db), nil +} diff --git a/pkg/lock/gorm/lock.go b/pkg/lock/gorm/lock.go new file mode 100644 index 000000000..83e1e658d --- /dev/null +++ b/pkg/lock/gorm/lock.go @@ -0,0 +1,278 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package gorm + +import ( + "context" + "fmt" + "time" + + "github.com/google/uuid" + "gorm.io/gorm" + "gorm.io/gorm/clause" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/common/constants" + "github.com/apache/dubbo-admin/pkg/core/lock" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/store/dbcommon" +) + +// Ensure GormLock implements Lock interface +var _ lock.Lock = (*GormLock)(nil) + +// GormLock provides distributed locking using database as backend +// It uses GORM for database operations and supports MySQL, PostgreSQL, etc. +type GormLock struct { + pool *dbcommon.ConnectionPool + db *gorm.DB // Direct DB reference to avoid circular dependency + owner string // Unique identifier for this lock instance +} + +// NewGormLock creates a new GORM-based distributed lock instance +// Deprecated: Use NewGormLockFromDB to avoid circular dependencies +func NewGormLock(pool *dbcommon.ConnectionPool) lock.Lock { + return &GormLock{ + pool: pool, + db: pool.GetDB(), + owner: uuid.New().String(), + } +} + +// NewGormLockFromDB creates a new GORM-based distributed lock instance from a DB connection +// This is the preferred constructor to avoid circular dependencies +func NewGormLockFromDB(db *gorm.DB) lock.Lock { + return &GormLock{ + db: db, + owner: uuid.New().String(), + } +} + +// getDB returns the database instance, to prefer direct DB to pool +func (g *GormLock) getDB() *gorm.DB { + if g.db != nil { + return g.db + } + if g.pool != nil { + return g.pool.GetDB() + } + return nil +} + +// Lock acquires a lock with the specified key and TTL +// It blocks until the lock is acquired or context is cancelled +func (g *GormLock) Lock(ctx context.Context, key string, ttl time.Duration) error { + ticker := time.NewTicker(constants.DefaultLockRetryInterval) + defer ticker.Stop() + + for { + acquired, err := g.TryLock(ctx, key, ttl) + if err != nil { + return fmt.Errorf("failed to try lock: %w", err) + } + if acquired { + return nil + } + + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + } + } +} + +// TryLock attempts to acquire a lock without blocking +// Returns true if lock was acquired, false otherwise +func (g *GormLock) TryLock(ctx context.Context, key string, ttl time.Duration) (bool, error) { + db := g.getDB().WithContext(ctx) + expireAt := time.Now().Add(ttl) + + var acquired bool + err := db.Transaction(func(tx *gorm.DB) error { + // Clean up only this key's expired lock to improve performance + now := time.Now() + if err := tx.Where("lock_key = ? AND expire_at < ?", key, now). + Delete(&LockRecord{}).Error; err != nil { + return fmt.Errorf("failed to clean expired lock for key %s: %w", key, err) + } + + // Try to acquire lock using INSERT ... ON CONFLICT + lock := &LockRecord{ + LockKey: key, + Owner: g.owner, + ExpireAt: expireAt, + } + + // Try to insert the lock record + result := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "lock_key"}}, + DoNothing: true, // If conflict, do nothing + }).Create(lock) + + if result.Error != nil { + return fmt.Errorf("failed to insert lock record: %w", result.Error) + } + + // Check if the insertion was successful + if result.RowsAffected == 0 { + // The lock already exists + acquired = false + return nil + } + + // New row inserted successfully, lock acquired successfully + acquired = true + return nil + }) + + if err != nil { + return false, err + } + + return acquired, nil +} + +// Unlock releases a lock held by this instance +func (g *GormLock) Unlock(ctx context.Context, key string) error { + db := g.getDB().WithContext(ctx) + + result := db.Where("lock_key = ? AND owner = ?", key, g.owner). + Delete(&LockRecord{}) + + if result.Error != nil { + return fmt.Errorf("failed to release lock: %w", result.Error) + } + + if result.RowsAffected == 0 { + return bizerror.New(bizerror.LockNotHeld, "lock not held by this owner") + } + + return nil +} + +// Renew extends the TTL of a lock held by this instance +func (g *GormLock) Renew(ctx context.Context, key string, ttl time.Duration) error { + db := g.getDB().WithContext(ctx) + newExpireAt := time.Now().Add(ttl) + + result := db.Model(&LockRecord{}). + Where("lock_key = ? AND owner = ?", key, g.owner). + Update("expire_at", newExpireAt) + + if result.Error != nil { + return fmt.Errorf("failed to renew lock: %w", result.Error) + } + + if result.RowsAffected == 0 { + return bizerror.New(bizerror.LockNotHeld, "lock not held by this owner") + } + + return nil +} + +// IsLocked checks if a lock is currently held (by anyone) +func (g *GormLock) IsLocked(ctx context.Context, key string) (bool, error) { + db := g.getDB().WithContext(ctx) + + var count int64 + err := db.Model(&LockRecord{}). + Where("lock_key = ? AND expire_at > ?", key, time.Now()). + Count(&count).Error + + if err != nil { + return false, fmt.Errorf("failed to check lock status: %w", err) + } + + return count > 0, nil +} + +// WithLock executes a function while holding a lock +func (g *GormLock) WithLock(ctx context.Context, key string, ttl time.Duration, fn func() error) error { + // Acquire lock + if err := g.Lock(ctx, key, ttl); err != nil { + return fmt.Errorf("failed to acquire lock: %w", err) + } + + // Ensure lock is released + defer func() { + // Use background context for unlock to ensure it completes even if ctx is cancelled + unlockCtx, cancel := context.WithTimeout(context.Background(), constants.DefaultUnlockTimeout) + defer cancel() + + if err := g.Unlock(unlockCtx, key); err != nil { + logger.Errorf("Failed to release lock %s: %v", key, err) + } + }() + + // Start auto-renewal if TTL is long enough + var renewDone chan struct{} + if ttl > constants.DefaultAutoRenewThreshold { + renewDone = make(chan struct{}) + go g.autoRenew(ctx, key, ttl, renewDone) + defer close(renewDone) + } + + // Execute the function + return fn() +} + +// autoRenew periodically renews the lock until done channel is closed +func (g *GormLock) autoRenew(ctx context.Context, key string, ttl time.Duration, done <-chan struct{}) { + // Renew at 1/3 of TTL to ensure lock doesn't expire + renewInterval := ttl / 3 + ticker := time.NewTicker(renewInterval) + defer ticker.Stop() + + for { + select { + case <-done: + return + case <-ctx.Done(): + return + case <-ticker.C: + // Double-check done channel before renewing to avoid unnecessary renewal + select { + case <-done: + return + default: + } + + renewCtx, cancel := context.WithTimeout(context.Background(), constants.DefaultRenewTimeout) + if err := g.Renew(renewCtx, key, ttl); err != nil { + logger.Warnf("Failed to renew lock %s: %v", key, err) + cancel() + return + } + cancel() + } + } +} + +// CleanupExpiredLocks removes all expired locks from the database +// This should be called periodically as a maintenance task +func (g *GormLock) CleanupExpiredLocks(ctx context.Context) error { + db := g.getDB().WithContext(ctx) + + result := db.Where("expire_at < ?", time.Now()).Delete(&LockRecord{}) + if result.Error != nil { + return fmt.Errorf("failed to cleanup expired locks: %w", result.Error) + } + + return nil +} diff --git a/pkg/lock/gorm/lock_test.go b/pkg/lock/gorm/lock_test.go new file mode 100644 index 000000000..480579945 --- /dev/null +++ b/pkg/lock/gorm/lock_test.go @@ -0,0 +1,364 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package gorm_test + +import ( + "context" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + gormlock "github.com/apache/dubbo-admin/pkg/lock/gorm" +) + +func setupTestDB(t *testing.T) *gorm.DB { + db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{ + PrepareStmt: false, + }) + require.NoError(t, err, "failed to create test database") + + sqlDB, err := db.DB() + require.NoError(t, err) + + sqlDB.SetMaxOpenConns(1) + + err = db.Exec("PRAGMA journal_mode=WAL;").Error + require.NoError(t, err, "failed to set WAL mode") + + err = db.Exec("PRAGMA busy_timeout=5000;").Error + require.NoError(t, err, "failed to set busy timeout") + + err = db.AutoMigrate(&gormlock.LockRecord{}) + require.NoError(t, err, "failed to migrate lock table") + + return db +} + +func TestBasicLockUnlock(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err := lockInstance.Lock(ctx, "test-key", 5*time.Second) + assert.NoError(t, err, "should acquire lock successfully") + + isLocked, err := lockInstance.IsLocked(ctx, "test-key") + assert.NoError(t, err) + assert.True(t, isLocked, "lock should be held") + + err = lockInstance.Unlock(ctx, "test-key") + assert.NoError(t, err, "should release lock successfully") + + isLocked, err = lockInstance.IsLocked(ctx, "test-key") + assert.NoError(t, err) + assert.False(t, isLocked, "lock should be released") +} + +func TestTryLock(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + acquired, err := lock1.TryLock(ctx, "test-key", 5*time.Second) + assert.NoError(t, err) + assert.True(t, acquired, "first lock should be acquired") + + acquired, err = lock2.TryLock(ctx, "test-key", 5*time.Second) + assert.NoError(t, err) + assert.False(t, acquired, "second lock should not be acquired") + + err = lock1.Unlock(ctx, "test-key") + assert.NoError(t, err) + + acquired, err = lock2.TryLock(ctx, "test-key", 5*time.Second) + assert.NoError(t, err) + assert.True(t, acquired, "second lock should be acquired after first is released") + + _ = lock2.Unlock(ctx, "test-key") +} + +func TestConcurrentLockAttempts(t *testing.T) { + db := setupTestDB(t) + ctx := context.Background() + + const numGoroutines = 10 + var successCount atomic.Int32 + var wg sync.WaitGroup + wg.Add(numGoroutines) + + for i := 0; i < numGoroutines; i++ { + go func() { + defer wg.Done() + lockInstance := gormlock.NewGormLockFromDB(db) + acquired, err := lockInstance.TryLock(ctx, "concurrent-key", 1*time.Second) + if err == nil && acquired { + successCount.Add(1) + time.Sleep(100 * time.Millisecond) // Hold lock briefly + _ = lockInstance.Unlock(ctx, "concurrent-key") + } + }() + } + + wg.Wait() + + assert.Equal(t, int32(1), successCount.Load(), "only one goroutine should acquire the lock") +} + +func TestLockExpiration(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + acquired, err := lock1.TryLock(ctx, "expire-key", 100*time.Millisecond) + assert.NoError(t, err) + assert.True(t, acquired) + + acquired, err = lock2.TryLock(ctx, "expire-key", 1*time.Second) + assert.NoError(t, err) + assert.False(t, acquired, "lock should still be held") + + time.Sleep(200 * time.Millisecond) + + acquired, err = lock2.TryLock(ctx, "expire-key", 1*time.Second) + assert.NoError(t, err) + assert.True(t, acquired, "lock should be acquired after expiration") + + _ = lock2.Unlock(ctx, "expire-key") +} + +func TestLockRenewal(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err := lockInstance.Lock(ctx, "renew-key", 1*time.Second) + require.NoError(t, err) + + time.Sleep(500 * time.Millisecond) + + err = lockInstance.Renew(ctx, "renew-key", 2*time.Second) + assert.NoError(t, err, "should renew lock successfully") + + isLocked, err := lockInstance.IsLocked(ctx, "renew-key") + assert.NoError(t, err) + assert.True(t, isLocked, "lock should still be held after renewal") + + _ = lockInstance.Unlock(ctx, "renew-key") +} + +func TestUnlockNotHeld(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err := lock1.Lock(ctx, "test-key", 5*time.Second) + require.NoError(t, err) + + err = lock2.Unlock(ctx, "test-key") + assert.Error(t, err, "should return error") + + // 检查错误类型和错误码 + var bizErr bizerror.Error + if assert.ErrorAs(t, err, &bizErr) { + assert.Equal(t, bizerror.LockNotHeld, bizErr.Code(), "should return LockNotHeld error code") + } + + _ = lock1.Unlock(ctx, "test-key") +} + +func TestRenewNotHeld(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err := lock1.Lock(ctx, "test-key", 5*time.Second) + require.NoError(t, err) + + err = lock2.Renew(ctx, "test-key", 10*time.Second) + assert.Error(t, err, "should return error") + + var bizErr bizerror.Error + if assert.ErrorAs(t, err, &bizErr) { + assert.Equal(t, bizerror.LockNotHeld, bizErr.Code(), "should return LockNotHeld error code") + } + + _ = lock1.Unlock(ctx, "test-key") +} + +func TestWithLock(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + executed := false + err := lockInstance.WithLock(ctx, "with-lock-key", 2*time.Second, func() error { + executed = true + isLocked, err := lockInstance.IsLocked(ctx, "with-lock-key") + assert.NoError(t, err) + assert.True(t, isLocked) + return nil + }) + + assert.NoError(t, err) + assert.True(t, executed, "function should be executed") + + time.Sleep(100 * time.Millisecond) + isLocked, err := lockInstance.IsLocked(ctx, "with-lock-key") + assert.NoError(t, err) + assert.False(t, isLocked, "lock should be released after WithLock") +} + +func TestWithLockAutoRenewal(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + executed := false + err := lockInstance.WithLock(ctx, "auto-renew-key", 15*time.Second, func() error { + time.Sleep(6 * time.Second) + executed = true + return nil + }) + + assert.NoError(t, err) + assert.True(t, executed, "function should be executed") + + time.Sleep(100 * time.Millisecond) + isLocked, err := lockInstance.IsLocked(ctx, "auto-renew-key") + assert.NoError(t, err) + assert.False(t, isLocked, "lock should be released after WithLock") +} + +func TestWithLockContextCancellation(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + + ctx, cancel := context.WithCancel(context.Background()) + + started := make(chan struct{}) + err := lockInstance.WithLock(ctx, "cancel-key", 5*time.Second, func() error { + close(started) + cancel() + time.Sleep(100 * time.Millisecond) + return nil + }) + + <-started + + assert.NoError(t, err, "function should complete even if context is cancelled during execution") + + time.Sleep(100 * time.Millisecond) + isLocked, err := lockInstance.IsLocked(context.Background(), "cancel-key") + assert.NoError(t, err) + assert.False(t, isLocked, "lock should be released even after context cancellation") +} + +func TestCleanupExpiredLocks(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + _, _ = lock1.TryLock(ctx, "cleanup-key-1", 100*time.Millisecond) + _, _ = lock2.TryLock(ctx, "cleanup-key-2", 100*time.Millisecond) + + time.Sleep(200 * time.Millisecond) + + err := lock1.CleanupExpiredLocks(ctx) + assert.NoError(t, err) + + var count int64 + db.Model(&gormlock.LockRecord{}).Count(&count) + assert.Equal(t, int64(0), count, "all expired locks should be cleaned up") +} + +func TestMultipleDifferentLocks(t *testing.T) { + db := setupTestDB(t) + lockInstance := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err1 := lockInstance.Lock(ctx, "key-1", 5*time.Second) + err2 := lockInstance.Lock(ctx, "key-2", 5*time.Second) + err3 := lockInstance.Lock(ctx, "key-3", 5*time.Second) + + assert.NoError(t, err1) + assert.NoError(t, err2) + assert.NoError(t, err3) + + isLocked1, _ := lockInstance.IsLocked(ctx, "key-1") + isLocked2, _ := lockInstance.IsLocked(ctx, "key-2") + isLocked3, _ := lockInstance.IsLocked(ctx, "key-3") + + assert.True(t, isLocked1) + assert.True(t, isLocked2) + assert.True(t, isLocked3) + + _ = lockInstance.Unlock(ctx, "key-1") + _ = lockInstance.Unlock(ctx, "key-2") + _ = lockInstance.Unlock(ctx, "key-3") +} + +func TestLockBlockingBehavior(t *testing.T) { + db := setupTestDB(t) + lock1 := gormlock.NewGormLockFromDB(db) + lock2 := gormlock.NewGormLockFromDB(db) + ctx := context.Background() + + err := lock1.Lock(ctx, "blocking-key", 10*time.Second) + require.NoError(t, err) + + isLocked, err := lock1.IsLocked(ctx, "blocking-key") + require.NoError(t, err) + require.True(t, isLocked) + + acquiredTime := time.Now() + done := make(chan time.Time) + + go func() { + _ = lock2.Lock(ctx, "blocking-key", 10*time.Second) + done <- time.Now() + }() + + time.Sleep(500 * time.Millisecond) + + unlockErr := lock1.Unlock(ctx, "blocking-key") + require.NoError(t, unlockErr, "unlock should succeed") + + isLocked, err = lock1.IsLocked(ctx, "blocking-key") + require.NoError(t, err) + + lock2AcquiredTime := <-done + + duration := lock2AcquiredTime.Sub(acquiredTime) + + assert.GreaterOrEqual(t, duration, 500*time.Millisecond, "lock2 should acquire after lock1 releases") + assert.Less(t, duration, 1500*time.Millisecond, "lock2 should acquire shortly after lock1 releases") + + _ = lock2.Unlock(ctx, "blocking-key") +} diff --git a/pkg/lock/gorm/model.go b/pkg/lock/gorm/model.go new file mode 100644 index 000000000..0becabb8f --- /dev/null +++ b/pkg/lock/gorm/model.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package gorm + +import ( + "time" +) + +// LockRecord represents a distributed lock record in the database +type LockRecord struct { + ID uint `gorm:"primarykey"` + LockKey string `gorm:"uniqueIndex;size:255;not null"` // Unique lock identifier + Owner string `gorm:"size:255;not null"` // UUID of the lock holder + ExpireAt time.Time `gorm:"index;not null"` // Lock expiration time + CreatedAt time.Time `gorm:"autoCreateTime"` // Lock creation time + UpdatedAt time.Time `gorm:"autoUpdateTime"` // Last renewal time +} + +// TableName returns the table name for LockRecord +func (LockRecord) TableName() string { + return "distributed_locks" +} diff --git a/pkg/mcp/component.go b/pkg/mcp/component.go new file mode 100644 index 000000000..e643d2dd6 --- /dev/null +++ b/pkg/mcp/component.go @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mcp + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/config/app" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/tools" + "github.com/apache/dubbo-admin/pkg/mcp/transport/http" +) + +const ( + // ComponentType MCP组件类型 + ComponentType = runtime.ComponentType("mcp") +) + +// Component MCP组件,集成到admin服务中 +type Component struct { + server *core.Server + consoleCtx consolectx.Context + cfg *app.MCPConfig +} + +func init() { + runtime.RegisterComponent(&Component{}) +} + +// Type 返回组件类型 +func (c *Component) Type() runtime.ComponentType { + return ComponentType +} + +// Order 返回组件启动顺序 +func (c *Component) Order() int { + return 999 // 在Console之后启动 +} + +// RequiredDependencies 返回依赖的组件 +func (c *Component) RequiredDependencies() []runtime.ComponentType { + return []runtime.ComponentType{ + runtime.Console, // 依赖Console(需要runtime) + } +} + +// Init 初始化MCP组件 +func (c *Component) Init(ctx runtime.BuilderContext) error { + cfg := ctx.Config() + + // 从admin配置中获取MCP配置 + if cfg.MCP == nil { + // MCP未配置,使用默认配置(禁用) + c.cfg = &app.MCPConfig{ + Enabled: false, + Path: "/api/mcp", + } + return nil + } + + c.cfg = cfg.MCP + + // 如果未启用,直接返回 + if !c.cfg.Enabled { + return nil + } + + return nil +} + +// Start 启动MCP组件 +func (c *Component) Start(coreRt runtime.Runtime, stop <-chan struct{}) error { + // 如果未启用,直接返回 + if c.cfg == nil || !c.cfg.Enabled { + <-stop + return nil + } + + // 获取console context(由Console组件创建) + c.consoleCtx = consolectx.NewConsoleContext(coreRt) + + // 创建MCP服务器 + c.server = core.NewServer("dubbo-admin", "1.0.0") + c.server.SetConsoleContext(c.consoleCtx) + + // 注册所有工具 + reg := c.server.GetRegistry() + reg.RegisterRegistrar(&tools.MetricsRegistrar{}) + reg.RegisterRegistrar(&tools.ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&tools.ServiceRegistrar{}) + reg.RegisterRegistrar(&tools.DetailRegistrar{}) + reg.RegisterAll() + + // 获取console的HTTP引擎并注册MCP路由 + consoleComp, err := coreRt.GetComponent(runtime.Console) + if err != nil { + // Console未启动,无法注册MCP路由 + <-stop + return nil + } + + // 通过runtime获取gin.Engine + // 这里需要一种方式来访问console组件的gin.Engine + // 暂时使用全局注册方式 + RegisterMCPRoutes(c.server, c.cfg.Path) + + _ = consoleComp // 暂时忽略,实际使用时需要访问console的gin.Engine + + // 等待停止信号 + <-stop + + return nil +} + +// RegisterMCPRoutes 注册MCP路由到gin引擎 +// 这个函数应该在console路由初始化后调用 +// 注意:由于这个函数使用gin.Default(),它创建了一个新的引擎实例 +// 在实际使用中,应该由console组件调用并注册到它自己的引擎上 +func RegisterMCPRoutes(server *core.Server, path string) { + if path == "" { + path = "/api/mcp" + } + + handler := http.NewHandler(server) + + // 注册MCP端点(不需要认证) + // 注意:这只是示例代码,实际注册应该在console组件中完成 + _ = handler // 避免未使用警告 + _ = path // 避免未使用警告 +} + +// GetServer 获取MCP服务器实例 +func (c *Component) GetServer() *core.Server { + return c.server +} diff --git a/pkg/mcp/core/builder.go b/pkg/mcp/core/builder.go new file mode 100644 index 000000000..56f4bd8a7 --- /dev/null +++ b/pkg/mcp/core/builder.go @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package core + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" +) + +// ServerBuilder 服务器构建器 +type ServerBuilder struct { + name string + version string + consoleContext consolectx.Context +} + +// NewServerBuilder 创建服务器构建器 +func NewServerBuilder() *ServerBuilder { + return &ServerBuilder{ + name: "mcp-server", + version: "1.0.0", + } +} + +// WithName 设置服务器名称 +func (b *ServerBuilder) WithName(name string) *ServerBuilder { + b.name = name + return b +} + +// WithVersion 设置服务器版本 +func (b *ServerBuilder) WithVersion(version string) *ServerBuilder { + b.version = version + return b +} + +// WithConsoleContext 设置 console context +func (b *ServerBuilder) WithConsoleContext(ctx consolectx.Context) *ServerBuilder { + b.consoleContext = ctx + return b +} + +// Build 构建服务器 +func (b *ServerBuilder) Build() *Server { + server := NewServer(b.name, b.version) + if b.consoleContext != nil { + server.SetConsoleContext(b.consoleContext) + } + return server +} diff --git a/pkg/mcp/core/constants.go b/pkg/mcp/core/constants.go new file mode 100644 index 000000000..b66c98ee9 --- /dev/null +++ b/pkg/mcp/core/constants.go @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package core + +const ( + // JSONRPCVersion JSON-RPC 协议版本 + JSONRPCVersion = "2.0" + + // ProtocolVersion MCP 协议版本 + ProtocolVersion = "2024-11-05" + + // MethodInitialize 初始化方法 + MethodInitialize = "initialize" + // MethodToolsList 工具列表方法 + MethodToolsList = "tools/list" + // MethodToolsCall 工具调用方法 + MethodToolsCall = "tools/call" + + // ContentTypeText 文本内容类型 + ContentTypeText = "text" +) + +// JSONRPC 错误码 +const ( + ErrCodeParseError = -32700 + ErrCodeInvalidRequest = -32600 + ErrCodeMethodNotFound = -32601 + ErrCodeInvalidParams = -32602 + ErrCodeInternalError = -32603 +) diff --git a/pkg/mcp/core/server.go b/pkg/mcp/core/server.go new file mode 100644 index 000000000..d113059e6 --- /dev/null +++ b/pkg/mcp/core/server.go @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package core + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/registry" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/gin-gonic/gin" +) + +// Server MCP 服务器 +type Server struct { + name string + version string + registry *registry.Registry + consoleContext consolectx.Context +} + +// NewServer 创建 MCP 服务器 +func NewServer(name, version string) *Server { + return &Server{ + name: name, + version: version, + registry: registry.NewRegistry(), + } +} + +// NewServerWithRegistry 使用指定 Registry 创建 MCP 服务器 +func NewServerWithRegistry(name, version string, reg *registry.Registry) *Server { + return &Server{ + name: name, + version: version, + registry: reg, + } +} + +// GetRegistry 获取工具注册表 +func (s *Server) GetRegistry() *registry.Registry { + return s.registry +} + +// SetConsoleContext 设置 console context +func (s *Server) SetConsoleContext(ctx consolectx.Context) { + s.consoleContext = ctx +} + +// GetConsoleContext 获取 console context +func (s *Server) GetConsoleContext() consolectx.Context { + return s.consoleContext +} + +// ==================== 请求处理 ==================== + +// HandleRequest 处理 JSON-RPC 请求(公开方法,供 transport 层使用) +func (s *Server) HandleRequest(req *JSONRPCRequest) *JSONRPCResponse { + return s.handleRequest(req) +} + +// HandleHTTP 处理 HTTP 请求 +func (s *Server) HandleHTTP(c *gin.Context) { + body, err := io.ReadAll(c.Request.Body) + if err != nil { + s.respondWithError(c, nil, ErrCodeParseError, "Parse error") + return + } + + var req JSONRPCRequest + if err := json.NewDecoder(bytes.NewReader(body)).Decode(&req); err != nil { + s.respondWithError(c, nil, ErrCodeParseError, "Parse error") + return + } + + c.JSON(http.StatusOK, s.handleRequest(&req)) +} + +// respondWithError 返回错误响应 +func (s *Server) respondWithError(c *gin.Context, id interface{}, code int, message string) { + c.JSON(http.StatusBadRequest, JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + Error: &JSONRPCError{ + Code: code, + Message: message, + }, + }) +} + +// handleRequest 处理 JSON-RPC 请求 +func (s *Server) handleRequest(req *JSONRPCRequest) *JSONRPCResponse { + switch req.Method { + case MethodInitialize: + return s.handleInitialize(req) + case MethodToolsList: + return s.handleToolsList(req) + case MethodToolsCall: + return s.handleToolsCall(req) + default: + return s.methodNotFoundResponse(req) + } +} + +// methodNotFoundResponse 方法未找到响应 +func (s *Server) methodNotFoundResponse(req *JSONRPCRequest) *JSONRPCResponse { + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: req.ID, + Error: &JSONRPCError{ + Code: ErrCodeMethodNotFound, + Message: fmt.Sprintf("Method not found: %s", req.Method), + }, + } +} + +// newErrorResponse 创建错误响应 +func (s *Server) newErrorResponse(id interface{}, code int, message string) *JSONRPCResponse { + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: id, + Error: &JSONRPCError{ + Code: code, + Message: message, + }, + } +} + +// handleInitialize 处理 initialize 请求 +func (s *Server) handleInitialize(req *JSONRPCRequest) *JSONRPCResponse { + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: req.ID, + Result: InitializeResult{ + ProtocolVersion: ProtocolVersion, + ServerInfo: ServerInfo{ + Name: s.name, + Version: s.version, + }, + Capabilities: ServerCapabilities{ + Tools: &ToolsCapability{}, + }, + }, + } +} + +// handleToolsList 处理 tools/list 请求 +func (s *Server) handleToolsList(req *JSONRPCRequest) *JSONRPCResponse { + toolDefs := s.registry.List() + tools := make([]Tool, 0, len(toolDefs)) + for _, def := range toolDefs { + tools = append(tools, Tool{ + Name: def.Name, + Description: def.Description, + InputSchema: def.InputSchema, + }) + } + + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: req.ID, + Result: ToolListResult{Tools: tools}, + } +} + +// handleToolsCall 处理 tools/call 请求 +func (s *Server) handleToolsCall(req *JSONRPCRequest) *JSONRPCResponse { + params, ok := req.Params.(map[string]any) + if !ok { + return s.newErrorResponse(req.ID, ErrCodeInvalidParams, "Invalid params") + } + + name, ok := params["name"].(string) + if !ok { + return s.newErrorResponse(req.ID, ErrCodeInvalidParams, "Tool name is required") + } + + tool, ok := s.registry.Get(name) + if !ok { + return s.newErrorResponse(req.ID, ErrCodeMethodNotFound, "Tool not found: "+name) + } + + arguments, _ := params["arguments"].(map[string]any) + + // 验证必需参数 + if err := ValidateRequired(tool.InputSchema, arguments); err != nil { + return s.newErrorResponse(req.ID, ErrCodeInvalidParams, err.Error()) + } + + result, err := tool.Handler(s.consoleContext, arguments) + if err != nil { + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: req.ID, + Result: CallToolResult{ + Content: []types.Content{{Type: ContentTypeText, Text: err.Error()}}, + IsError: true, + }, + } + } + + return &JSONRPCResponse{ + JSONRPC: JSONRPCVersion, + ID: req.ID, + Result: s.convertToCallToolResult(result), + } +} + +// convertToCallToolResult 转换 ToolResult 到 CallToolResult +func (s *Server) convertToCallToolResult(result *ToolResult) CallToolResult { + content := make([]types.Content, len(result.Content)) + for i, c := range result.Content { + content[i] = types.Content{Type: c.Type, Text: c.Text} + } + return CallToolResult{ + Content: content, + IsError: result.IsError, + } +} diff --git a/pkg/mcp/core/server_test.go b/pkg/mcp/core/server_test.go new file mode 100644 index 000000000..834759766 --- /dev/null +++ b/pkg/mcp/core/server_test.go @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package core + +import ( + "testing" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/registry" + "github.com/apache/dubbo-admin/pkg/mcp/types" +) + +func TestServer_NewServer(t *testing.T) { + server := NewServer("test", "1.0.0") + + if server.name != "test" { + t.Errorf("expected name 'test', got '%s'", server.name) + } + + if server.version != "1.0.0" { + t.Errorf("expected version '1.0.0', got '%s'", server.version) + } + + if server.registry == nil { + t.Error("expected registry to be initialized") + } +} + +func TestServer_NewServerWithRegistry(t *testing.T) { + reg := registry.NewRegistry() + server := NewServerWithRegistry("test", "1.0.0", reg) + + if server.registry != reg { + t.Error("expected server to use provided registry") + } +} + +func TestServer_GetRegistry(t *testing.T) { + server := NewServer("test", "1.0.0") + + reg := server.GetRegistry() + if reg == nil { + t.Error("expected registry to be returned") + } + + if reg != server.registry { + t.Error("expected returned registry to be the same as server's registry") + } +} + +func TestRegistry_Register(t *testing.T) { + reg := registry.NewRegistry() + + tool := types.ToolDef{ + Name: "test_tool", + Description: "A test tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + } + + err := reg.Register(tool) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + if !reg.Has("test_tool") { + t.Error("expected tool to be registered") + } + + if reg.Count() != 1 { + t.Errorf("expected 1 tool, got %d", reg.Count()) + } +} + +func TestRegistry_Unregister(t *testing.T) { + reg := registry.NewRegistry() + + tool := types.ToolDef{ + Name: "test_tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + } + + reg.Register(tool) + removed := reg.Unregister("test_tool") + + if !removed { + t.Error("expected tool to be removed") + } + + if reg.Has("test_tool") { + t.Error("expected tool to be unregistered") + } + + // 再次移除应该返回 false + removed = reg.Unregister("test_tool") + if removed { + t.Error("expected second removal to return false") + } +} + +func TestRegistry_Clear(t *testing.T) { + reg := registry.NewRegistry() + + tool := types.ToolDef{ + Name: "test_tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + } + + reg.Register(tool) + reg.Clear() + + if reg.Count() != 0 { + t.Errorf("expected 0 tools after clear, got %d", reg.Count()) + } +} + +func TestServerBuilder(t *testing.T) { + server := NewServerBuilder(). + WithName("custom-server"). + WithVersion("2.0.0"). + Build() + + if server.name != "custom-server" { + t.Errorf("expected name 'custom-server', got '%s'", server.name) + } + + if server.version != "2.0.0" { + t.Errorf("expected version '2.0.0', got '%s'", server.version) + } +} diff --git a/pkg/common/util/maps/sorted_keys_test.go b/pkg/mcp/core/tool.go similarity index 59% rename from pkg/common/util/maps/sorted_keys_test.go rename to pkg/mcp/core/tool.go index 730c759a5..7dd07cfb7 100644 --- a/pkg/common/util/maps/sorted_keys_test.go +++ b/pkg/mcp/core/tool.go @@ -15,28 +15,29 @@ * limitations under the License. */ -package maps_test +package core -import ( - . "github.com/onsi/ginkgo/v2" +import "github.com/apache/dubbo-admin/pkg/mcp/types" - "github.com/apache/dubbo-admin/pkg/common/util/maps" - . "github.com/onsi/gomega" +// 类型别名,保持向后兼容 +type ( + ToolDef = types.ToolDef + InputSchema = types.InputSchema + PropertyDef = types.PropertyDef + ToolHandler = types.ToolHandler + ToolResult = types.ToolResult + Content = types.Content ) -var _ = Describe("SortedKeys", func() { - It("should return sorted keys", func() { - // given - m := map[string]string{ - "c": "x", - "b": "y", - "a": "z", - } - - // when - keys := maps.SortedKeys(m) +// 工具结果构造函数 +var ( + NewToolResult = types.NewToolResult + NewTextResult = types.NewTextResult + NewErrorResult = types.NewErrorResult +) - // then - Expect(keys).To(Equal([]string{"a", "b", "c"})) - }) -}) +// 验证函数 +var ( + ValidateRequired = types.ValidateRequired + IsEmpty = types.IsEmpty +) diff --git a/pkg/mcp/core/types.go b/pkg/mcp/core/types.go new file mode 100644 index 000000000..0f8531a5c --- /dev/null +++ b/pkg/mcp/core/types.go @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package core + +import "github.com/apache/dubbo-admin/pkg/mcp/types" + +// JSONRPCRequest JSON-RPC 2.0 请求 +type JSONRPCRequest struct { + JSONRPC string `json:"jsonrpc"` + ID interface{} `json:"id"` + Method string `json:"method"` + Params interface{} `json:"params"` +} + +// JSONRPCResponse JSON-RPC 2.0 响应 +type JSONRPCResponse struct { + JSONRPC string `json:"jsonrpc"` + ID interface{} `json:"id"` + Result interface{} `json:"result,omitempty"` + Error *JSONRPCError `json:"error,omitempty"` +} + +// JSONRPCError JSON-RPC 2.0 错误 +type JSONRPCError struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data,omitempty"` +} + +// InitializeResult 初始化结果 +type InitializeResult struct { + ProtocolVersion string `json:"protocolVersion"` + ServerInfo ServerInfo `json:"serverInfo"` + Capabilities ServerCapabilities `json:"capabilities"` +} + +// ServerInfo 服务器信息 +type ServerInfo struct { + Name string `json:"name"` + Version string `json:"version"` +} + +// ServerCapabilities 服务器能力 +type ServerCapabilities struct { + Tools *ToolsCapability `json:"tools,omitempty"` +} + +// ToolsCapability 工具能力 +type ToolsCapability struct { + ListChanged bool `json:"listChanged"` +} + +// ToolListResult 工具列表结果 +type ToolListResult struct { + Tools []Tool `json:"tools"` +} + +// Tool 工具定义(用于响应) +type Tool struct { + Name string `json:"name"` + Description string `json:"description"` + InputSchema types.InputSchema `json:"inputSchema"` +} + +// CallToolResult 调用工具结果 +type CallToolResult struct { + Content []types.Content `json:"content"` + IsError bool `json:"isError,omitempty"` +} diff --git a/pkg/mcp/mcp.go b/pkg/mcp/mcp.go new file mode 100644 index 000000000..af0173b78 --- /dev/null +++ b/pkg/mcp/mcp.go @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Package mcp 提供 MCP (Model Context Protocol) 服务器实现。 +// +// # 包结构 +// +// - core: MCP 服务器核心功能(Server、类型定义、常量) +// - registry: 工具注册表和注册器接口 +// - tools: 内置工具实现(cluster、search、service) +// +// # 快速开始 +// +// server := mcp.NewServer("dubbo-admin", "1.0.0") +// mcp.RegisterDefaultTools(server) +// +// # 使用构建器 +// +// server := mcp.NewServerBuilder(). +// WithName("custom-server"). +// WithVersion("2.0.0"). +// Build() +// mcp.RegisterDefaultTools(server) +package mcp + +import ( + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/registry" + "github.com/apache/dubbo-admin/pkg/mcp/tools" +) + +// 类型别名,方便外部使用 +type ( + Server = core.Server + ServerBuilder = core.ServerBuilder + ToolDef = core.ToolDef + ToolResult = core.ToolResult + ToolHandler = core.ToolHandler + InputSchema = core.InputSchema + PropertyDef = core.PropertyDef + JSONRPCRequest = core.JSONRPCRequest + JSONRPCResponse = core.JSONRPCResponse + ToolRegistrar = registry.ToolRegistrar + Registry = registry.Registry +) + +// NewServer 创建 MCP 服务器 +func NewServer(name, version string) *core.Server { + return core.NewServer(name, version) +} + +// NewServerBuilder 创建服务器构建器 +func NewServerBuilder() *core.ServerBuilder { + return core.NewServerBuilder() +} + +// NewRegistry 创建空的工具注册表 +func NewRegistry() *registry.Registry { + return registry.NewRegistry() +} + +// RegisterDefaultTools 注册所有默认工具到注册表 +func RegisterDefaultTools(reg *registry.Registry) { + reg.RegisterRegistrar(&tools.MetricsRegistrar{}) + reg.RegisterRegistrar(&tools.ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&tools.ServiceRegistrar{}) + reg.RegisterAll() +} + +// DefaultRegistry 创建包含所有内置工具的注册表 +func DefaultRegistry() *registry.Registry { + reg := registry.NewRegistry() + RegisterDefaultTools(reg) + return reg +} + +// 常量导出 +const ( + JSONRPCVersion = core.JSONRPCVersion + ProtocolVersion = core.ProtocolVersion + MethodInitialize = core.MethodInitialize + MethodToolsList = core.MethodToolsList + MethodToolsCall = core.MethodToolsCall + ContentTypeText = core.ContentTypeText + ErrCodeParseError = core.ErrCodeParseError + ErrCodeInvalidRequest = core.ErrCodeInvalidRequest + ErrCodeMethodNotFound = core.ErrCodeMethodNotFound + ErrCodeInvalidParams = core.ErrCodeInvalidParams +) + +// 工具结果构造函数 +var ( + NewToolResult = core.NewToolResult + NewTextResult = core.NewTextResult + NewErrorResult = core.NewErrorResult +) diff --git a/pkg/mcp/registry/registry.go b/pkg/mcp/registry/registry.go new file mode 100644 index 000000000..9f3e91995 --- /dev/null +++ b/pkg/mcp/registry/registry.go @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package registry + +import ( + "fmt" + + "github.com/apache/dubbo-admin/pkg/mcp/types" +) + +// ToolRegistrar 工具注册器接口 +type ToolRegistrar interface { + RegisterTools(registry *Registry) +} + +// Registry 工具注册表 +type Registry struct { + tools map[string]types.ToolDef + registrars []ToolRegistrar +} + +// NewRegistry 创建工具注册表 +func NewRegistry() *Registry { + return &Registry{ + tools: make(map[string]types.ToolDef), + registrars: make([]ToolRegistrar, 0), + } +} + +// ==================== Tool CRUD 操作 ==================== + +// Register 注册单个工具 +func (r *Registry) Register(tool types.ToolDef) error { + if tool.Name == "" { + return fmt.Errorf("tool name cannot be empty") + } + r.tools[tool.Name] = tool + return nil +} + +// Unregister 注销工具 +func (r *Registry) Unregister(name string) bool { + if _, exists := r.tools[name]; !exists { + return false + } + delete(r.tools, name) + return true +} + +// Get 获取指定工具 +func (r *Registry) Get(name string) (types.ToolDef, bool) { + tool, exists := r.tools[name] + return tool, exists +} + +// Has 检查工具是否存在 +func (r *Registry) Has(name string) bool { + _, exists := r.tools[name] + return exists +} + +// List 列出所有工具 +func (r *Registry) List() []types.ToolDef { + result := make([]types.ToolDef, 0, len(r.tools)) + for _, tool := range r.tools { + result = append(result, tool) + } + return result +} + +// Count 获取工具数量 +func (r *Registry) Count() int { + return len(r.tools) +} + +// Clear 清空所有工具 +func (r *Registry) Clear() { + r.tools = make(map[string]types.ToolDef) +} + +// ==================== Registrar 管理 ==================== + +// RegisterRegistrar 注册注册器 +func (r *Registry) RegisterRegistrar(registrar ToolRegistrar) { + r.registrars = append(r.registrars, registrar) +} + +// RegisterAll 注册所有注册器的工具 +func (r *Registry) RegisterAll() { + for _, registrar := range r.registrars { + registrar.RegisterTools(r) + } +} + +// RegistrarsCount 返回注册器数量 +func (r *Registry) RegistrarsCount() int { + return len(r.registrars) +} + +// ClearRegistrars 清空注册器 +func (r *Registry) ClearRegistrars() { + r.registrars = make([]ToolRegistrar, 0) +} diff --git a/pkg/mcp/registry/registry_test.go b/pkg/mcp/registry/registry_test.go new file mode 100644 index 000000000..3a761ad1e --- /dev/null +++ b/pkg/mcp/registry/registry_test.go @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package registry + +import ( + "testing" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/types" +) + +// mockRegistrar 模拟注册器 +type mockRegistrar struct { + registered bool +} + +func (m *mockRegistrar) RegisterTools(reg *Registry) { + m.registered = true + reg.Register(types.ToolDef{ + Name: "mock_tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("mock", false), nil + }, + }) +} + +func TestRegistry_RegisterAll(t *testing.T) { + reg := NewRegistry() + + mock := &mockRegistrar{} + reg.RegisterRegistrar(mock) + + reg.RegisterAll() + + if !mock.registered { + t.Error("expected registrar to be called") + } + + if !reg.Has("mock_tool") { + t.Error("expected tool to be registered") + } +} + +func TestRegistry_RegistrarsCount(t *testing.T) { + reg := NewRegistry() + + if reg.RegistrarsCount() != 0 { + t.Errorf("expected 0 registrars, got %d", reg.RegistrarsCount()) + } + + reg.RegisterRegistrar(&mockRegistrar{}) + reg.RegisterRegistrar(&mockRegistrar{}) + + if reg.RegistrarsCount() != 2 { + t.Errorf("expected 2 registrars, got %d", reg.RegistrarsCount()) + } +} + +func TestRegistry_ClearRegistrars(t *testing.T) { + reg := NewRegistry() + reg.RegisterRegistrar(&mockRegistrar{}) + reg.RegisterRegistrar(&mockRegistrar{}) + + reg.ClearRegistrars() + + if reg.RegistrarsCount() != 0 { + t.Errorf("expected 0 registrars after clear, got %d", reg.RegistrarsCount()) + } +} + +func TestRegistry_RegisterAndGet(t *testing.T) { + reg := NewRegistry() + + tool := types.ToolDef{ + Name: "test_tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + } + + reg.Register(tool) + + // 测试 Get + retrieved, ok := reg.Get("test_tool") + if !ok { + t.Error("expected tool to be found") + } + + if retrieved.Name != "test_tool" { + t.Errorf("expected tool name 'test_tool', got '%s'", retrieved.Name) + } + + // 测试获取不存在的工具 + _, ok = reg.Get("non_existent") + if ok { + t.Error("expected non-existent tool to not be found") + } +} + +func TestRegistry_List(t *testing.T) { + reg := NewRegistry() + + reg.Register(types.ToolDef{ + Name: "tool1", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + }) + + reg.Register(types.ToolDef{ + Name: "tool2", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + }) + + tools := reg.List() + if len(tools) != 2 { + t.Errorf("expected 2 tools, got %d", len(tools)) + } +} + +func TestRegistry_RegisterEmptyName(t *testing.T) { + reg := NewRegistry() + + err := reg.Register(types.ToolDef{ + Name: "", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("test", false), nil + }, + }) + + if err == nil { + t.Error("expected error when registering tool with empty name") + } +} + diff --git a/pkg/mcp/tools/detail_tools.go b/pkg/mcp/tools/detail_tools.go new file mode 100644 index 000000000..0ffca99ef --- /dev/null +++ b/pkg/mcp/tools/detail_tools.go @@ -0,0 +1,493 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + "fmt" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/console/service" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/apache/dubbo-admin/pkg/mcp/registry" +) + +// DetailRegistrar 详情查询工具注册器 +type DetailRegistrar struct{} + +// RegisterTools 实现 ToolRegistrar 接口 +func (r *DetailRegistrar) RegisterTools(reg *registry.Registry) { + // 获取服务的实例列表 + reg.Register(types.ToolDef{ + Name: "get_service_instances", + Description: "获取指定服务的所有实例列表", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"serviceName"}, + Properties: map[string]types.PropertyDef{ + "serviceName": { + Type: "string", + Description: "服务名称(完整服务名)", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码", + Default: DefaultPageNumber, + }, + }, + }, + Handler: GetServiceInstances, + }) + + // 获取实例详情 + reg.Register(types.ToolDef{ + Name: "get_instance_detail", + Description: "获取实例的详细信息", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"instanceName"}, + Properties: map[string]types.PropertyDef{ + "instanceName": { + Type: "string", + Description: "实例名称", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + }, + }, + Handler: GetInstanceDetail, + }) + + // 获取实例指标 + reg.Register(types.ToolDef{ + Name: "get_instance_metrics", + Description: "获取实例的监控指标(qps、rt、成功率等)", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"instanceName"}, + Properties: map[string]types.PropertyDef{ + "instanceName": { + Type: "string", + Description: "实例名称", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + }, + }, + Handler: GetInstanceMetrics, + }) + + // 获取应用详情 + reg.Register(types.ToolDef{ + Name: "get_application_detail", + Description: "获取应用的详细信息(端口、版本、协议等)", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"appName"}, + Properties: map[string]types.PropertyDef{ + "appName": { + Type: "string", + Description: "应用名称", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + }, + }, + Handler: GetApplicationDetail, + }) + + // 获取应用的实例列表 + reg.Register(types.ToolDef{ + Name: "get_application_instances", + Description: "获取应用的所有实例", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"appName"}, + Properties: map[string]types.PropertyDef{ + "appName": { + Type: "string", + Description: "应用名称", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码", + Default: DefaultPageNumber, + }, + }, + }, + Handler: GetApplicationInstances, + }) + + // 获取应用的服务列表 + reg.Register(types.ToolDef{ + Name: "get_application_services", + Description: "获取应用提供的所有服务", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"appName"}, + Properties: map[string]types.PropertyDef{ + "appName": { + Type: "string", + Description: "应用名称", + }, + "side": { + Type: "string", + Description: "服务端类型: provider/consumer", + Default: string(ServiceSideProvider), + Enum: []string{string(ServiceSideProvider), string(ServiceSideConsumer)}, + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码", + Default: DefaultPageNumber, + }, + }, + }, + Handler: GetApplicationServices, + }) + + // 搜索实例 + reg.Register(types.ToolDef{ + Name: "search_instances", + Description: "按应用名或关键字搜索实例", + InputSchema: types.InputSchema{ + Type: "object", + Properties: map[string]types.PropertyDef{ + "appName": { + Type: "string", + Description: "按应用名搜索", + }, + "keywords": { + Type: "string", + Description: "按关键字搜索实例名或IP", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码", + Default: DefaultPageNumber, + }, + }, + }, + Handler: SearchInstances, + }) +} + +// GetServiceInstances 获取服务的实例列表 +func GetServiceInstances(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + serviceName, ok := helper.GetRequiredString("serviceName") + if !ok || serviceName == "" { + return ErrorResult(fmt.Errorf("required parameter 'serviceName' is missing")), nil + } + + mesh := GetMeshArg(ctx, args) + pageSize := helper.GetInt("pageSize", DefaultPageSize) + pageNumber := helper.GetInt("pageNumber", DefaultPageNumber) + + // 使用 SearchInstances 按服务名搜索实例 + req := &model.SearchInstanceReq{ + Keywords: serviceName, // 用服务名作为关键字搜索 + Mesh: mesh, + PageReq: BuildPageReq(pageNumber, pageSize), + } + + result, err := service.SearchInstances(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + instances, totalCount := extractSearchInstances(result) + return JsonResult(map[string]any{ + "serviceName": serviceName, + "mesh": mesh, + "instances": instances, + "totalCount": totalCount, + }) +} + +// GetInstanceDetail 获取实例详情 +func GetInstanceDetail(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + instanceName, ok := helper.GetRequiredString("instanceName") + if !ok || instanceName == "" { + return ErrorResult(fmt.Errorf("required parameter 'instanceName' is missing")), nil + } + + req := &model.InstanceDetailReq{ + InstanceName: instanceName, + Mesh: GetMeshArg(ctx, args), + } + + detail, err := service.GetInstanceDetail(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + return JsonResult(detail) +} + +// GetInstanceMetrics 获取实例指标 +func GetInstanceMetrics(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + instanceName, ok := helper.GetRequiredString("instanceName") + if !ok || instanceName == "" { + return ErrorResult(fmt.Errorf("required parameter 'instanceName' is missing")), nil + } + + req := &model.MetricsReq{ + InstanceName: instanceName, + Mesh: GetMeshArg(ctx, args), + } + + metrics, err := service.GetInstanceMetrics(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + if len(metrics) == 0 { + return JsonResult(map[string]any{ + "instanceName": instanceName, + "metrics": []any{}, + "message": "No metrics available", + }) + } + + return JsonResult(metrics[0]) +} + +// GetApplicationDetail 获取应用详情 +func GetApplicationDetail(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + appName, ok := helper.GetRequiredString("appName") + if !ok || appName == "" { + return ErrorResult(fmt.Errorf("required parameter 'appName' is missing")), nil + } + + req := &model.ApplicationDetailReq{ + AppName: appName, + Mesh: GetMeshArg(ctx, args), + } + + detail, err := service.GetApplicationDetail(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + return JsonResult(detail) +} + +// GetApplicationInstances 获取应用的实例列表 +func GetApplicationInstances(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + appName, ok := helper.GetRequiredString("appName") + if !ok || appName == "" { + return ErrorResult(fmt.Errorf("required parameter 'appName' is missing")), nil + } + + req := &model.ApplicationTabInstanceInfoReq{ + AppName: appName, + Mesh: GetMeshArg(ctx, args), + PageReq: BuildPageReq( + helper.GetInt("pageNumber", DefaultPageNumber), + helper.GetInt("pageSize", DefaultPageSize), + ), + } + + result, err := service.GetAppInstanceInfo(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + instances := extractAppInstances(result) + return JsonResult(map[string]any{ + "appName": appName, + "instances": instances, + "totalCount": int(result.PageInfo.Total), + }) +} + +// GetApplicationServices 获取应用的服务列表 +func GetApplicationServices(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + appName, ok := helper.GetRequiredString("appName") + if !ok || appName == "" { + return ErrorResult(fmt.Errorf("required parameter 'appName' is missing")), nil + } + + req := &model.ApplicationServiceFormReq{ + AppName: appName, + Side: helper.GetString("side", string(ServiceSideProvider)), + Mesh: GetMeshArg(ctx, args), + PageReq: BuildPageReq( + helper.GetInt("pageNumber", DefaultPageNumber), + helper.GetInt("pageSize", DefaultPageSize), + ), + } + + result, err := service.GetAppServiceInfo(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + services, _ := extractServicesFromResult(result) + return JsonResult(map[string]any{ + "appName": appName, + "side": req.Side, + "services": services, + "totalCount": int(result.PageInfo.Total), + }) +} + +// SearchInstances 搜索实例 +func SearchInstances(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + appName := helper.GetString("appName", "") + keywords := helper.GetString("keywords", "") + + if appName == "" && keywords == "" { + return ErrorResult(fmt.Errorf("at least one of 'appName' or 'keywords' is required")), nil + } + + req := &model.SearchInstanceReq{ + AppName: appName, + Keywords: keywords, + Mesh: GetMeshArg(ctx, args), + PageReq: BuildPageReq( + helper.GetInt("pageNumber", DefaultPageNumber), + helper.GetInt("pageSize", DefaultPageSize), + ), + } + + result, err := service.SearchInstances(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + instances, totalCount := extractSearchInstances(result) + return JsonResult(map[string]any{ + "appName": appName, + "keywords": keywords, + "instances": instances, + "totalCount": totalCount, + }) +} + +// extractAppInstances 从应用实例结果中提取实例列表 +func extractAppInstances(result *model.SearchPaginationResult) []any { + if result == nil || result.List == nil { + return []any{} + } + + instances, ok := result.List.([]*model.AppInstanceInfoResp) + if !ok { + return []any{} + } + + resultSlice := make([]any, 0, len(instances)) + for _, inst := range instances { + if inst != nil { + resultSlice = append(resultSlice, map[string]any{ + "name": inst.Name, + "ip": inst.IP, + "appName": inst.AppName, + "deployState": inst.DeployState, + "registerState": inst.RegisterState, + "workloadName": inst.WorkloadName, + "createTime": inst.CreateTime, + "registerTime": inst.RegisterTime, + }) + } + } + return resultSlice +} + +// extractSearchInstances 从搜索结果中提取实例列表 +func extractSearchInstances(result *model.SearchPaginationResult) ([]any, int) { + if result == nil || result.List == nil { + return []any{}, 0 + } + + instances, ok := result.List.([]*model.SearchInstanceResp) + if !ok { + return []any{}, 0 + } + + resultSlice := make([]any, 0, len(instances)) + for _, inst := range instances { + if inst != nil { + resultSlice = append(resultSlice, map[string]any{ + "name": inst.Name, + "appName": inst.AppName, + "ip": inst.Ip, + "workloadName": inst.WorkloadName, + "deployState": inst.DeployState, + "deployCluster": inst.DeployCluster, + "registerState": inst.RegisterState, + "registerClusters": inst.RegisterClusters, + "createTime": inst.CreateTime, + "registerTime": inst.RegisterTime, + }) + } + } + return resultSlice, int(result.PageInfo.Total) +} + +// Ensure DetailRegistrar implements ToolRegistrar +var _ registry.ToolRegistrar = (*DetailRegistrar)(nil) diff --git a/pkg/mcp/tools/integration_test.go b/pkg/mcp/tools/integration_test.go new file mode 100644 index 000000000..2dd8d8651 --- /dev/null +++ b/pkg/mcp/tools/integration_test.go @@ -0,0 +1,429 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + "encoding/json" + "testing" + + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/registry" + "github.com/apache/dubbo-admin/pkg/mcp/transport/stdio" + "github.com/apache/dubbo-admin/pkg/mcp/types" + appcfg "github.com/apache/dubbo-admin/pkg/config/app" + ctx "context" +) + +// TestTools_E2E 通过 MCP Server 端到端测试工具 +// 这展示了如何在实际场景中测试 MCP 工具 +func TestTools_E2E(t *testing.T) { + // 创建 MCP 服务器 + server := core.NewServer("dubbo-admin-test", "1.0.0") + + // 注册所有默认工具 + reg := server.GetRegistry() + reg.RegisterRegistrar(&MetricsRegistrar{}) + reg.RegisterRegistrar(&ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&ServiceRegistrar{}) + reg.RegisterAll() + + // 验证工具已注册 + tools := reg.List() + t.Logf("Registered %d tools:", len(tools)) + for _, tool := range tools { + t.Logf(" - %s: %s", tool.Name, tool.Description) + } + + // 测试获取工具列表 + t.Run("ToolsList", func(t *testing.T) { + req := &core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: 1, + Method: core.MethodToolsList, + } + + resp := server.HandleRequest(req) + if resp.Error != nil { + t.Fatalf("Tools list failed: %s", resp.Error.Message) + } + + // 将响应序列化为 JSON 以验证格式 + respData, err := json.MarshalIndent(resp, "", " ") + if err != nil { + t.Fatalf("Failed to marshal response: %v", err) + } + t.Logf("Tools list response:\n%s", string(respData)) + + // Result 是 ToolListResult,通过 JSON 反序列化来验证 + var result map[string]any + err = json.Unmarshal(respData, &result) + if err != nil { + t.Fatalf("Failed to unmarshal response: %v", err) + } + + tools := result["result"].(map[string]any)["tools"].([]any) + + // 验证核心工具存在 + toolNames := make(map[string]bool) + for _, t := range tools { + tool := t.(map[string]any) + toolNames[tool["name"].(string)] = true + } + + expectedTools := []string{ + "get_cluster_info", + "global_search", + "search_services", + "get_service_detail", + } + + for _, name := range expectedTools { + if !toolNames[name] { + t.Errorf("Expected tool '%s' not found", name) + } + } + + t.Logf("Found %d tools in tools/list response", len(tools)) + }) + + // 测试工具定义可以正确转换为 JSON + t.Run("ToolSchemaSerialization", func(t *testing.T) { + tools := reg.List() + + for _, tool := range tools { + // 创建不包含 Handler 的工具定义用于序列化 + toolForMarshal := struct { + Name string `json:"name"` + Description string `json:"description"` + InputSchema types.InputSchema `json:"inputSchema"` + }{ + Name: tool.Name, + Description: tool.Description, + InputSchema: tool.InputSchema, + } + + // 尝试序列化为 JSON + data, err := json.Marshal(toolForMarshal) + if err != nil { + t.Errorf("Failed to marshal tool %s: %v", tool.Name, err) + continue + } + + // 验证可以反序列化 + var unmarshaled map[string]any + err = json.Unmarshal(data, &unmarshaled) + if err != nil { + t.Errorf("Failed to unmarshal tool %s: %v", tool.Name, err) + } + } + }) + + // 测试工具 schema 验证 + t.Run("ToolSchemaValidation", func(t *testing.T) { + tools := reg.List() + + for _, tool := range tools { + t.Run(tool.Name, func(t *testing.T) { + // 验证必需参数可以正确检测 + if len(tool.InputSchema.Required) > 0 { + // 缺少必需参数 + invalidArgs := map[string]any{} + + err := core.ValidateRequired(tool.InputSchema, invalidArgs) + if err == nil { + t.Errorf("Tool %s: expected validation error for missing required params", tool.Name) + } + } + + // 空参数应该通过(如果无必需参数) + if len(tool.InputSchema.Required) == 0 { + validArgs := map[string]any{} + err := core.ValidateRequired(tool.InputSchema, validArgs) + if err != nil { + t.Errorf("Tool %s: unexpected validation error: %v", tool.Name, err) + } + } + }) + } + }) +} + +// TestTools_Manual 手动测试示例 +// 这展示了如何在需要时手动调用工具 handler +func TestTools_Manual(t *testing.T) { + t.Skip("跳过手动测试示例 - 需要真实的服务依赖") + + // 示例:如何直接调用 GetClusterInfo + // 注意:这需要真实的 CounterManager + /* + ctx := setupRealContext() + args := map[string]any{ + "mesh": "test-mesh", + } + + result, err := GetClusterInfo(ctx, args) + if err != nil { + t.Fatalf("GetClusterInfo failed: %v", err) + } + + t.Logf("Result: %s", result.Content[0].Text) + */ +} + +// MockContext 用于测试的 mock context +type MockContext struct { + meshName string + config *appcfg.AdminConfig +} + +func NewMockContext(meshName string) *MockContext { + return &MockContext{ + meshName: meshName, + config: &appcfg.AdminConfig{ + // 设置必要的配置 + }, + } +} + +func (m *MockContext) Config() appcfg.AdminConfig { + if m.config == nil { + m.config = &appcfg.AdminConfig{} + } + return *m.config +} + +func (m *MockContext) CounterManager() interface{} { + // 返回 mock CounterManager + return nil +} + +func (m *MockContext) AppContext() ctx.Context { + return ctx.Background() +} + +// TestGetClusterInfoSchema 测试 get_cluster_info 的 schema +func TestGetClusterInfoSchema(t *testing.T) { + reg := registry.NewRegistry() + registrar := &MetricsRegistrar{} + registrar.RegisterTools(reg) + + tool, ok := reg.Get("get_cluster_info") + if !ok { + t.Fatal("Tool get_cluster_info not registered") + } + + // 验证 schema + t.Run("Schema", func(t *testing.T) { + if tool.Name != "get_cluster_info" { + t.Errorf("Expected name 'get_cluster_info', got '%s'", tool.Name) + } + + if tool.InputSchema.Type != "object" { + t.Errorf("Expected type 'object', got '%s'", tool.InputSchema.Type) + } + + // 验证可选参数 + if _, ok := tool.InputSchema.Properties["mesh"]; !ok { + t.Error("Missing 'mesh' property") + } + }) + + t.Run("Arguments", func(t *testing.T) { + // 无参数调用(使用默认 mesh) + args := map[string]any{} + err := core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Validation failed for empty args: %v", err) + } + + // 指定 mesh 参数 + args = map[string]any{"mesh": "custom-mesh"} + err = core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Validation failed for mesh arg: %v", err) + } + }) +} + +// TestGlobalSearchSchema 测试 global_search 的 schema +func TestGlobalSearchSchema(t *testing.T) { + reg := registry.NewRegistry() + registrar := &ResourceSearchRegistrar{} + registrar.RegisterTools(reg) + + tool, ok := reg.Get("global_search") + if !ok { + t.Fatal("Tool global_search not registered") + } + + t.Run("RequiredParameters", func(t *testing.T) { + // keyword 现在是可选的,空关键字返回所有数据 + if len(tool.InputSchema.Required) != 0 { + t.Errorf("Expected 0 required parameters (keyword is optional), got %d", len(tool.InputSchema.Required)) + } + }) + + t.Run("Validation", func(t *testing.T) { + // 所有参数都是可选的,不应有验证错误 + args := map[string]any{} + err := core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Expected no validation error for empty args: %v", err) + } + + // 空字符串也是有效的(返回所有数据) + args = map[string]any{"keyword": ""} + err = core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Expected no validation error for empty keyword: %v", err) + } + + // 有效参数 + args = map[string]any{"keyword": "test-service"} + err = core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Validation failed for valid args: %v", err) + } + }) + + t.Run("OptionalParameters", func(t *testing.T) { + // 验证所有可选参数存在 + expectedProps := []string{"keyword", "searchType", "mesh", "pageSize", "pageNumber"} + for _, prop := range expectedProps { + if _, ok := tool.InputSchema.Properties[prop]; !ok { + t.Errorf("Missing property '%s'", prop) + } + } + }) +} + +// TestServiceToolsSchema 测试服务工具的 schema +func TestServiceToolsSchema(t *testing.T) { + reg := registry.NewRegistry() + registrar := &ServiceRegistrar{} + registrar.RegisterTools(reg) + + t.Run("SearchServices", func(t *testing.T) { + tool, ok := reg.Get("search_services") + if !ok { + t.Fatal("Tool search_services not registered") + } + + // 无必需参数 + if len(tool.InputSchema.Required) != 0 { + t.Errorf("Expected no required parameters, got %v", tool.InputSchema.Required) + } + + // 测试验证 + args := map[string]any{} + err := core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Validation failed unexpectedly: %v", err) + } + }) + + t.Run("GetServiceDetail", func(t *testing.T) { + tool, ok := reg.Get("get_service_detail") + if !ok { + t.Fatal("Tool get_service_detail not registered") + } + + // serviceName 是必需的 + if len(tool.InputSchema.Required) != 1 { + t.Errorf("Expected 1 required parameter, got %d", len(tool.InputSchema.Required)) + } + + // 测试验证 + args := map[string]any{} + err := core.ValidateRequired(tool.InputSchema, args) + if err == nil { + t.Error("Expected validation error for missing 'serviceName'") + } + + args = map[string]any{"serviceName": "com.example.Service"} + err = core.ValidateRequired(tool.InputSchema, args) + if err != nil { + t.Errorf("Validation failed for valid args: %v", err) + } + + // 测试 side 参数枚举 + sideProp := tool.InputSchema.Properties["side"] + actualEnum := sideProp.Enum + if len(actualEnum) != 2 { + t.Errorf("Expected enum with 2 values, got %d", len(actualEnum)) + } + }) +} + +// Example_testUsage 演示如何通过 stdio transport 使用工具 +func Example_testUsage() { + // 创建服务器 + server := core.NewServer("dubbo-admin", "1.0.0") + reg := server.GetRegistry() + + // 注册工具 + reg.RegisterRegistrar(&MetricsRegistrar{}) + reg.RegisterRegistrar(&ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&ServiceRegistrar{}) + reg.RegisterAll() + + // 创建 stdio transport + transport := stdio.NewTransport(server) + + // 在实际使用中,你会这样启动: + // transport.Serve(context.Background()) + + // 或者使用自定义 io 进行测试 + // transport := stdio.NewTransportWithIO(server, stdin, stdout) + + _ = transport +} + +// TestDefaultRegistry 测试默认注册表 +func TestDefaultRegistry(t *testing.T) { + // 使用 DefaultRegistry 创建包含所有工具的注册表 + reg := registry.NewRegistry() + + // 注册所有默认工具 + reg.RegisterRegistrar(&MetricsRegistrar{}) + reg.RegisterRegistrar(&ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&ServiceRegistrar{}) + reg.RegisterAll() + + tools := reg.List() + t.Logf("DefaultRegistry has %d tools", len(tools)) + + // 验证核心工具存在 + expectedTools := []string{ + "get_cluster_info", + "global_search", + "search_services", + "get_service_detail", + } + + toolNames := make(map[string]bool) + for _, tool := range tools { + toolNames[tool.Name] = true + } + + for _, name := range expectedTools { + if !toolNames[name] { + t.Errorf("Expected tool '%s' not found in default registry", name) + } + } +} diff --git a/pkg/mcp/tools/live_test.go b/pkg/mcp/tools/live_test.go new file mode 100644 index 000000000..a96177bca --- /dev/null +++ b/pkg/mcp/tools/live_test.go @@ -0,0 +1,365 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "log" + "os" + "time" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/core" +) + +// LiveTestOptions 真实测试选项 +type LiveTestOptions struct { + ConfigPath string + Mesh string + Keyword string + ServiceName string +} + +// LiveTester 真实数据测试器 +type LiveTester struct { + ctx context.Context + consoleCtx consolectx.Context + server *core.Server + options *LiveTestOptions +} + +// NewLiveTester 创建真实数据测试器 +func NewLiveTester(configPath string) (*LiveTester, error) { + // 这里需要导入 bootstrap 包来初始化真实的 runtime + // 但为了避免循环导入,我们通过依赖注入的方式接收 context + + return &LiveTester{ + ctx: context.Background(), + options: &LiveTestOptions{ConfigPath: configPath}, + }, nil +} + +// SetConsoleContext 设置 console context(由外部初始化后传入) +func (t *LiveTester) SetConsoleContext(ctx consolectx.Context) { + t.consoleCtx = ctx +} + +// InitServer 初始化 MCP 服务器 +func (t *LiveTester) InitServer() { + t.server = core.NewServer("dubbo-admin-live-test", "1.0.0") + reg := t.server.GetRegistry() + + // 注册所有工具 + reg.RegisterRegistrar(&MetricsRegistrar{}) + reg.RegisterRegistrar(&ResourceSearchRegistrar{}) + reg.RegisterRegistrar(&ServiceRegistrar{}) + reg.RegisterAll() + + // 设置 console context + t.server.SetConsoleContext(t.consoleCtx) +} + +// TestClusterInfo 测试获取集群信息 +func (t *LiveTester) TestClusterInfo(mesh string) (string, error) { + t.options.Mesh = mesh + + args := map[string]any{ + "mesh": mesh, + } + + result, err := GetClusterInfo(t.consoleCtx, args) + if err != nil { + return "", fmt.Errorf("GetClusterInfo failed: %w", err) + } + + return result.Content[0].Text, nil +} + +// TestGlobalSearch 测试全局搜索 +func (t *LiveTester) TestGlobalSearch(keyword, searchType, mesh string) (string, error) { + args := map[string]any{ + "keyword": keyword, + "searchType": searchType, + "mesh": mesh, + "pageSize": 10, + "pageNumber": 1, + } + + result, err := GlobalSearch(t.consoleCtx, args) + if err != nil { + return "", fmt.Errorf("GlobalSearch failed: %w", err) + } + + return result.Content[0].Text, nil +} + +// TestSearchServices 测试搜索服务 +func (t *LiveTester) TestSearchServices(keywords, mesh string) (string, error) { + args := map[string]any{ + "keywords": keywords, + "mesh": mesh, + "pageSize": 10, + "pageNumber": 1, + } + + result, err := SearchServices(t.consoleCtx, args) + if err != nil { + return "", fmt.Errorf("SearchServices failed: %w", err) + } + + return result.Content[0].Text, nil +} + +// TestGetServiceDetail 测试获取服务详情 +func (t *LiveTester) TestGetServiceDetail(serviceName, group, version, side, mesh string) (string, error) { + args := map[string]any{ + "serviceName": serviceName, + "group": group, + "version": version, + "side": side, + "mesh": mesh, + } + + result, err := GetServiceDetail(t.consoleCtx, args) + if err != nil { + return "", fmt.Errorf("GetServiceDetail failed: %w", err) + } + + return result.Content[0].Text, nil +} + +// TestToolViaServer 通过服务器测试工具调用 +func (t *LiveTester) TestToolViaServer(toolName string, args map[string]any) (*core.JSONRPCResponse, error) { + req := &core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: 1, + Method: core.MethodToolsCall, + Params: map[string]any{ + "name": toolName, + "arguments": args, + }, + } + + resp := t.server.HandleRequest(req) + if resp.Error != nil { + return nil, fmt.Errorf("tool call failed: %s", resp.Error.Message) + } + + return resp, nil +} + +// PrintResult 打印结果 +func (t *LiveTester) PrintResult(name string, result string) { + fmt.Printf("\n=== %s ===\n", name) + fmt.Printf("Result:\n%s\n", result) + fmt.Printf("==================\n\n") +} + +// RunAllTests 运行所有测试 +func (t *LiveTester) RunAllTests(mesh, keyword, serviceName string) error { + fmt.Println("🧪 Starting live MCP tools tests...") + + // 1. 测试集群信息 + fmt.Println("1️⃣ Testing GetClusterInfo...") + clusterInfo, err := t.TestClusterInfo(mesh) + if err != nil { + log.Printf("❌ GetClusterInfo failed: %v", err) + } else { + t.PrintResult("Cluster Info", clusterInfo) + } + + // 2. 测试全局搜索 + fmt.Println("2️⃣ Testing GlobalSearch...") + searchResult, err := t.TestGlobalSearch(keyword, "serviceName", mesh) + if err != nil { + log.Printf("❌ GlobalSearch failed: %v", err) + } else { + t.PrintResult("Global Search", searchResult) + } + + // 3. 测试服务搜索 + fmt.Println("3️⃣ Testing SearchServices...") + servicesResult, err := t.TestSearchServices(keyword, mesh) + if err != nil { + log.Printf("❌ SearchServices failed: %v", err) + } else { + t.PrintResult("Search Services", servicesResult) + } + + // 4. 测试服务详情(如果有服务名) + if serviceName != "" { + fmt.Println("4️⃣ Testing GetServiceDetail...") + detailResult, err := t.TestGetServiceDetail(serviceName, "", "", "provider", mesh) + if err != nil { + log.Printf("❌ GetServiceDetail failed: %v", err) + } else { + t.PrintResult("Service Detail", detailResult) + } + } + + fmt.Println("✅ All tests completed!") + return nil +} + +// RunViaJSONRPC 通过 JSON-RPC 接口测试 +func (t *LiveTester) RunViaJSONRPC(mesh, keyword, serviceName string) error { + fmt.Println("🧪 Testing via JSON-RPC interface...") + + // 测试 tools/list + fmt.Println("\n1️⃣ Testing tools/list...") + listReq := &core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: 1, + Method: core.MethodToolsList, + } + listResp := t.server.HandleRequest(listReq) + listData, _ := json.MarshalIndent(listResp, "", " ") + fmt.Printf("Tools list:\n%s\n", string(listData)) + + // 测试 get_cluster_info + fmt.Println("\n2️⃣ Testing get_cluster_info via JSON-RPC...") + clusterResp, err := t.TestToolViaServer("get_cluster_info", map[string]any{"mesh": mesh}) + if err != nil { + return err + } + clusterData, _ := json.MarshalIndent(clusterResp, "", " ") + fmt.Printf("Cluster info response:\n%s\n", string(clusterData)) + + // 测试 global_search + fmt.Println("\n3️⃣ Testing global_search via JSON-RPC...") + searchResp, err := t.TestToolViaServer("global_search", map[string]any{ + "keyword": keyword, + "mesh": mesh, + }) + if err != nil { + return err + } + searchData, _ := json.MarshalIndent(searchResp, "", " ") + fmt.Printf("Search response:\n%s\n", string(searchData)) + + return nil +} + +// exampleLiveTest 示例:如何在其他地方使用 LiveTester +func exampleLiveTest() { + // 注意:这只是一个示例,实际使用时需要从外部获取 consoleCtx + /* + // 1. 初始化 runtime 和 console context + cfg := app.DefaultAdminConfig() + config.Load("dubbo-admin.yaml", &cfg) + rt, _ := bootstrap.Bootstrap(context.Background(), cfg) + consoleCtx := context.NewConsoleContext(rt) + + // 2. 创建测试器 + tester, _ := NewLiveTester("dubbo-admin.yaml") + tester.SetConsoleContext(consoleCtx) + tester.InitServer() + + // 3. 运行测试 + tester.RunAllTests("default", "demo", "com.example.Service") + */ +} + +// main 函数可以作为独立的测试工具运行 +func main() { + configPath := flag.String("config", "./dubbo-admin.yaml", "配置文件路径") + mesh := flag.String("mesh", "default", "Mesh 名称") + keyword := flag.String("keyword", "", "搜索关键字") + serviceName := flag.String("service", "", "服务名称") + flag.Parse() + + if *configPath == "" { + fmt.Println("请提供配置文件路径: -config ") + os.Exit(1) + } + + fmt.Printf("📋 配置: %s\n", *configPath) + fmt.Printf("🔍 Mesh: %s\n", *mesh) + if *keyword != "" { + fmt.Printf("🔑 关键字: %s\n", *keyword) + } + if *serviceName != "" { + fmt.Printf("🛠️ 服务: %s\n", *serviceName) + } + + // 注意:这里需要真实的 console context + // 实际使用时需要从外部注入 + fmt.Println("\n⚠️ 注意:此测试工具需要真实的 console context") + fmt.Println("⚠️ 请通过代码方式调用,在初始化 runtime 后传入 context") + fmt.Println("\n示例代码:") + fmt.Println(` + rt, _ := bootstrap.Bootstrap(context.Background(), cfg) + consoleCtx := context.NewConsoleContext(rt) + + tester := &LiveTester{} + tester.SetConsoleContext(consoleCtx) + tester.InitServer() + tester.RunAllTests("default", "demo", "com.example.Service") + `) + + // 如果有环境变量指定了真实模式,则尝试运行 + if os.Getenv("MCP_LIVE_TEST") == "true" { + fmt.Println("\n🚀 Running in live test mode...") + // 这里需要实际的初始化代码 + // 由于循环导入问题,需要在实际使用的地方实现 + } +} + +// LiveTestHelper 辅助函数,用于在已有 context 的地方进行测试 +func LiveTestHelper(consoleCtx consolectx.Context, mesh, keyword, serviceName string) { + tester := &LiveTester{ + ctx: context.Background(), + consoleCtx: consoleCtx, + options: &LiveTestOptions{}, + } + tester.InitServer() + + // 设置超时 + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + // 运行测试 + done := make(chan error) + go func() { + done <- tester.RunAllTests(mesh, keyword, serviceName) + }() + + select { + case err := <-done: + if err != nil { + log.Printf("Test failed: %v", err) + } + case <-ctx.Done(): + log.Println("Test timeout!") + } +} + +// LiveTestViaJSONRPCHelper 通过 JSON-RPC 测试的辅助函数 +func LiveTestViaJSONRPCHelper(consoleCtx consolectx.Context, mesh, keyword string) error { + tester := &LiveTester{ + ctx: context.Background(), + consoleCtx: consoleCtx, + options: &LiveTestOptions{}, + } + tester.InitServer() + + return tester.RunViaJSONRPC(mesh, keyword, "") +} diff --git a/pkg/mcp/tools/metrics.go b/pkg/mcp/tools/metrics.go new file mode 100644 index 000000000..25e01df32 --- /dev/null +++ b/pkg/mcp/tools/metrics.go @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/counter" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/apache/dubbo-admin/pkg/mcp/registry" + meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1" +) + +// MetricsRegistrar 集群工具注册器 +type MetricsRegistrar struct{} + +// RegisterTools 实现 ToolRegistrar 接口 +func (r *MetricsRegistrar) RegisterTools(reg *registry.Registry) { + reg.Register(types.ToolDef{ + Name: "get_cluster_info", + Description: "获取 Dubbo 集群基本信息,包括应用数、服务数、实例数等统计信息", + InputSchema: types.InputSchema{ + Type: "object", + Properties: map[string]types.PropertyDef{ + "mesh": { + Type: "string", + Description: "Mesh 名称,默认使用配置中的默认 mesh", + }, + }, + }, + Handler: GetClusterInfo, + }) +} + +// GetClusterInfo 获取集群基本信息 +func GetClusterInfo(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + mesh := GetMeshArg(ctx, args) + info := collectClusterInfo(ctx, mesh) + return JsonResult(info) +} + +// collectClusterInfo 收集集群信息 +func collectClusterInfo(ctx consolectx.Context, mesh string) map[string]any { + counterMgr := ctx.CounterManager() + if counterMgr == nil { + return map[string]any{ + "mesh": mesh, + "appCount": 0, + "serviceCount": 0, + "instanceCount": 0, + "protocols": map[string]int{}, + "releases": map[string]int{}, + "discoveries": map[string]int{}, + "error": "Counter manager not available", + } + } + + return map[string]any{ + "mesh": mesh, + "appCount": counterMgr.CountByMesh(meshresource.ApplicationKind, mesh), + "serviceCount": counterMgr.CountByMesh(meshresource.ServiceProviderMetadataKind, mesh), + "instanceCount": counterMgr.CountByMesh(meshresource.InstanceKind, mesh), + "protocols": counterMgr.DistributionByMesh(counter.ProtocolCounter, mesh), + "releases": counterMgr.DistributionByMesh(counter.ReleaseCounter, mesh), + "discoveries": counterMgr.DistributionByMesh(counter.DiscoveryCounter, mesh), + } +} + +// Ensure MetricsRegistrar implements ToolRegistrar +var _ registry.ToolRegistrar = (*MetricsRegistrar)(nil) diff --git a/pkg/mcp/tools/resource_search.go b/pkg/mcp/tools/resource_search.go new file mode 100644 index 000000000..8943fdd3f --- /dev/null +++ b/pkg/mcp/tools/resource_search.go @@ -0,0 +1,291 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/console/service" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/apache/dubbo-admin/pkg/mcp/registry" +) + +// ResourceSearchRegistrar 搜索工具注册器 +type ResourceSearchRegistrar struct{} + +// searchExecutor 搜索执行器接口 +type searchExecutor interface { + execute(ctx consolectx.Context, keyword, mesh string, pageNumber, pageSize int) (*model.SearchPaginationResult, error) + buildResult(pagedResult *model.SearchPaginationResult, keyword string, pageSize, pageNumber int) map[string]any +} + +// RegisterTools 实现 ToolRegistrar 接口 +func (r *ResourceSearchRegistrar) RegisterTools(reg *registry.Registry) { + reg.Register(types.ToolDef{ + Name: "global_search", + Description: "全局搜索,支持搜索服务、实例、应用等资源。不传 keyword 返回所有数据", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{}, // keyword 改为可选,空值返回所有数据 + Properties: map[string]types.PropertyDef{ + "keyword": { + Type: "string", + Description: "搜索关键字,为空时返回所有数据", + }, + "searchType": { + Type: "string", + Description: "搜索类型: ip(按IP搜索实例), instanceName(按实例名搜索), appName(按应用名搜索), serviceName(按服务名搜索)", + Default: string(SearchTypeName), + Enum: []string{string(SearchTypeIP), string(SearchTypeInstanceName), string(SearchTypeAppName), string(SearchTypeName)}, + }, + "mesh": { + Type: "string", + Description: "Mesh 名称,默认使用配置中的默认 mesh", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码,从 1 开始", + Default: DefaultPageNumber, + }, + }, + }, + Handler: GlobalSearch, + }) +} + +// GlobalSearch 全局搜索 +func GlobalSearch(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + keyword := helper.GetString("keyword", "") + + searchType := SearchType(helper.GetString("searchType", string(SearchTypeName))) + mesh := GetMeshArg(ctx, args) + pageSize := helper.GetInt("pageSize", DefaultPageSize) + pageNumber := helper.GetInt("pageNumber", DefaultPageNumber) + + executor := getSearchExecutor(searchType) + result, err := executor.execute(ctx, keyword, mesh, pageNumber, pageSize) + if err != nil { + return ErrorResult(err), nil + } + + searchResult := executor.buildResult(result, keyword, pageSize, pageNumber) + searchResult["searchType"] = string(searchType) + + return JsonResult(searchResult) +} + +// getSearchExecutor 根据搜索类型获取对应的执行器 +func getSearchExecutor(searchType SearchType) searchExecutor { + executors := map[SearchType]searchExecutor{ + SearchTypeIP: &ipSearchExecutor{}, + SearchTypeInstanceName: &instanceNameSearchExecutor{}, + SearchTypeAppName: &appNameSearchExecutor{}, + SearchTypeName: &serviceNameSearchExecutor{}, + } + + if executor, ok := executors[searchType]; ok { + return executor + } + return &serviceNameSearchExecutor{} +} + +// ipSearchExecutor IP 搜索执行器 +type ipSearchExecutor struct{} + +func (e *ipSearchExecutor) execute(ctx consolectx.Context, keyword, mesh string, pageNumber, pageSize int) (*model.SearchPaginationResult, error) { + req := buildSearchReq(keyword, mesh, pageNumber, pageSize) + return service.SearchInstanceByIp(ctx, req) +} + +func (e *ipSearchExecutor) buildResult(pagedResult *model.SearchPaginationResult, keyword string, pageSize, pageNumber int) map[string]any { + instances, totalCount := extractInstances(pagedResult) + return map[string]any{ + "keyword": keyword, + "pageSize": pageSize, + "pageNumber": pageNumber, + "instances": instances, + "totalCount": totalCount, + } +} + +// instanceNameSearchExecutor 实例名搜索执行器 +type instanceNameSearchExecutor struct{} + +func (e *instanceNameSearchExecutor) execute(ctx consolectx.Context, keyword, mesh string, pageNumber, pageSize int) (*model.SearchPaginationResult, error) { + req := buildSearchReq(keyword, mesh, pageNumber, pageSize) + return service.SearchInstanceByName(ctx, req) +} + +func (e *instanceNameSearchExecutor) buildResult(pagedResult *model.SearchPaginationResult, keyword string, pageSize, pageNumber int) map[string]any { + instances, totalCount := extractInstances(pagedResult) + return map[string]any{ + "keyword": keyword, + "pageSize": pageSize, + "pageNumber": pageNumber, + "instances": instances, + "totalCount": totalCount, + } +} + +// appNameSearchExecutor 应用名搜索执行器 +type appNameSearchExecutor struct{} + +func (e *appNameSearchExecutor) execute(ctx consolectx.Context, keyword, mesh string, pageNumber, pageSize int) (*model.SearchPaginationResult, error) { + // 使用 SearchApplications 而不是 SearchApplicationsByKeywords + // SearchApplications 会正确处理空 keyword 的情况(返回所有应用的分页列表) + req := &model.ApplicationSearchReq{ + Keywords: keyword, + Mesh: mesh, + PageReq: BuildPageReq(pageNumber, pageSize), + } + return service.SearchApplications(ctx, req) +} + +func (e *appNameSearchExecutor) buildResult(pagedResult *model.SearchPaginationResult, keyword string, pageSize, pageNumber int) map[string]any { + apps := extractApplicationsFromResult(pagedResult) + return map[string]any{ + "keyword": keyword, + "pageSize": pageSize, + "pageNumber": pageNumber, + "applications": apps, + "totalCount": len(apps), + } +} + +// serviceNameSearchExecutor 服务名搜索执行器 +type serviceNameSearchExecutor struct{} + +func (e *serviceNameSearchExecutor) execute(ctx consolectx.Context, keyword, mesh string, pageNumber, pageSize int) (*model.SearchPaginationResult, error) { + req := &model.ServiceSearchReq{ + ServiceName: "", + Keywords: keyword, + Mesh: mesh, + PageReq: BuildPageReq(pageNumber, pageSize), + } + // 空关键字时调用 SearchServices 获取所有服务,否则精确匹配 + if keyword == "" { + return service.SearchServices(ctx, req) + } + return service.SearchServicesByKeywords(ctx, req) +} + +func (e *serviceNameSearchExecutor) buildResult(pagedResult *model.SearchPaginationResult, keyword string, pageSize, pageNumber int) map[string]any { + services, totalCount := extractServicesFromResult(pagedResult) + return map[string]any{ + "keyword": keyword, + "pageSize": pageSize, + "pageNumber": pageNumber, + "services": services, + "totalCount": totalCount, + } +} + +// buildSearchReq 构建搜索请求 +func buildSearchReq(keyword, mesh string, pageNumber, pageSize int) *model.SearchReq { + req := model.NewSearchReq() + req.Keywords = keyword + req.Mesh = mesh + req.PageReq = BuildPageReq(pageNumber, pageSize) + return req +} + +// extractInstances 从分页结果中提取实例列表 +func extractInstances(pagedResult *model.SearchPaginationResult) ([]any, int) { + if pagedResult == nil || pagedResult.List == nil { + return []any{}, 0 + } + + instances, ok := pagedResult.List.([]*model.SearchInstanceResp) + if !ok { + return []any{}, 0 + } + + result := make([]any, 0, len(instances)) + for _, ins := range instances { + result = append(result, map[string]any{ + "name": ins.Name, + "appName": ins.AppName, + "ip": ins.Ip, + "workloadName": ins.WorkloadName, + "deployState": ins.DeployState, + "deployCluster": ins.DeployCluster, + "registerState": ins.RegisterState, + "registerClusters": ins.RegisterClusters, + "createTime": ins.CreateTime, + "registerTime": ins.RegisterTime, + "labels": ins.Labels, + }) + } + return result, int(pagedResult.PageInfo.Total) +} + +// extractApplicationsFromResult 从分页结果中提取应用列表 +func extractApplicationsFromResult(pagedResult *model.SearchPaginationResult) []any { + if pagedResult == nil || pagedResult.List == nil { + return []any{} + } + + apps, ok := pagedResult.List.([]*model.ApplicationSearchResp) + if !ok { + return []any{} + } + + result := make([]any, 0, len(apps)) + for _, app := range apps { + result = append(result, map[string]any{ + "appName": app.AppName, + "instanceCount": app.InstanceCount, + "deployClusters": app.DeployClusters, + "registryClusters": app.RegistryClusters, + }) + } + return result +} + +// extractServicesFromResult 从分页结果中提取服务列表 +func extractServicesFromResult(pagedResult *model.SearchPaginationResult) ([]any, int) { + if pagedResult == nil || pagedResult.List == nil { + return []any{}, 0 + } + + services, ok := pagedResult.List.([]*model.ServiceSearchResp) + if !ok { + return []any{}, 0 + } + + result := make([]any, 0, len(services)) + for _, svc := range services { + result = append(result, map[string]any{ + "serviceName": svc.ServiceName, + "version": svc.Version, + "group": svc.Group, + "providerAppName": svc.ProviderAppName, + "consumerAppName": svc.ConsumerAppName, + }) + } + return result, int(pagedResult.PageInfo.Total) +} + +// Ensure ResourceSearchRegistrar implements ToolRegistrar +var _ registry.ToolRegistrar = (*ResourceSearchRegistrar)(nil) diff --git a/pkg/mcp/tools/service_discovery.go b/pkg/mcp/tools/service_discovery.go new file mode 100644 index 000000000..0b4ff2894 --- /dev/null +++ b/pkg/mcp/tools/service_discovery.go @@ -0,0 +1,243 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/console/model" + "github.com/apache/dubbo-admin/pkg/console/service" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/apache/dubbo-admin/pkg/mcp/registry" +) + +// ServiceRegistrar 服务工具注册器 +type ServiceRegistrar struct{} + +// RegisterTools 实现 ToolRegistrar 接口 +func (r *ServiceRegistrar) RegisterTools(reg *registry.Registry) { + reg.Register(types.ToolDef{ + Name: "search_services", + Description: "搜索 Dubbo 服务,支持按服务名过滤和分页", + InputSchema: types.InputSchema{ + Type: "object", + Properties: map[string]types.PropertyDef{ + "keywords": { + Type: "string", + Description: "服务名搜索关键字,支持模糊匹配", + }, + "mesh": { + Type: "string", + Description: "Mesh 名称,默认使用配置中的默认 mesh", + }, + "pageSize": { + Type: "integer", + Description: "每页数量", + Default: DefaultPageSize, + }, + "pageNumber": { + Type: "integer", + Description: "页码,从 1 开始", + Default: DefaultPageNumber, + }, + }, + }, + Handler: SearchServices, + }) + + reg.Register(types.ToolDef{ + Name: "get_service_detail", + Description: "获取服务详情,包括服务分布和实例信息", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"serviceName"}, + Properties: map[string]types.PropertyDef{ + "serviceName": { + Type: "string", + Description: "服务名称", + }, + "group": { + Type: "string", + Description: "服务分组", + Default: "", + }, + "version": { + Type: "string", + Description: "服务版本", + Default: "", + }, + "side": { + Type: "string", + Description: "服务端或消费者 (provider/consumer)", + Default: string(ServiceSideProvider), + Enum: []string{string(ServiceSideProvider), string(ServiceSideConsumer)}, + }, + "mesh": { + Type: "string", + Description: "Mesh 名称,默认使用配置中的默认 mesh", + }, + }, + }, + Handler: GetServiceDetail, + }) +} + +// SearchServices 搜索服务 +func SearchServices(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + keywords := helper.GetString("keywords", "") + mesh := GetMeshArg(ctx, args) + pageSize := helper.GetInt("pageSize", DefaultPageSize) + pageNumber := helper.GetInt("pageNumber", DefaultPageNumber) + + req := &model.ServiceSearchReq{ + Keywords: keywords, + Mesh: mesh, + PageReq: BuildPageReq(pageNumber, pageSize), + } + + result, err := service.SearchServices(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + return buildServiceSearchResult(result, keywords, mesh, pageSize, pageNumber) +} + +// GetServiceDetail 获取服务详情 +func GetServiceDetail(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + helper := NewArgsHelper(args) + serviceName := helper.GetString("serviceName", "") + + params := serviceDetailParams{ + serviceName: serviceName, + group: helper.GetString("group", ""), + version: helper.GetString("version", ""), + mesh: GetMeshArg(ctx, args), + } + + side := ServiceSide(helper.GetString("side", string(ServiceSideProvider))) + + return fetchServiceDistribution(ctx, params, side) +} + +// serviceDetailParams 服务详情参数 +type serviceDetailParams struct { + serviceName string + group string + version string + mesh string +} + +// fetchServiceDistribution 获取服务分布信息 +func fetchServiceDistribution(ctx consolectx.Context, params serviceDetailParams, side ServiceSide) (*types.ToolResult, error) { + targetSide := string(ServiceSideConsumer) + if side == ServiceSideConsumer { + targetSide = string(ServiceSideProvider) + } + + req := &model.ServiceTabDistributionReq{ + ServiceName: params.serviceName, + Group: params.group, + Version: params.version, + Side: targetSide, + Mesh: params.mesh, + PageReq: BuildPageReq(1, MaxDistributionLimit), + } + + distribution, err := service.GetServiceTabDistribution(ctx, req) + if err != nil { + return ErrorResult(err), nil + } + + apps := extractApplications(distribution) + return JsonResult(map[string]any{ + "serviceName": params.serviceName, + "group": params.group, + "version": params.version, + "side": string(side), + "mesh": params.mesh, + "distribution": apps, + "totalApps": len(apps), + }) +} + +// extractApplications 从分页结果中提取应用列表 +func extractApplications(result *model.SearchPaginationResult) []any { + if result == nil || result.List == nil { + return []any{} + } + + apps, ok := result.List.([]*model.ApplicationSearchResp) + if !ok { + return []any{} + } + + resultSlice := make([]any, 0, len(apps)) + for _, app := range apps { + if app != nil { + resultSlice = append(resultSlice, map[string]any{ + "appName": app.AppName, + "instanceCount": app.InstanceCount, + "deployClusters": app.DeployClusters, + "registryClusters": app.RegistryClusters, + }) + } + } + return resultSlice +} + +// buildServiceSearchResult 构建服务搜索结果 +func buildServiceSearchResult(result *model.SearchPaginationResult, keywords, mesh string, pageSize, pageNumber int) (*types.ToolResult, error) { + services, totalCount := extractServices(result) + + return JsonResult(map[string]any{ + "keywords": keywords, + "mesh": mesh, + "pageSize": pageSize, + "pageNumber": pageNumber, + "services": services, + "totalCount": totalCount, + }) +} + +// extractServices 从分页结果中提取服务列表 +func extractServices(result *model.SearchPaginationResult) ([]any, int) { + if result == nil || result.List == nil { + return []any{}, 0 + } + + services, ok := result.List.([]*model.ServiceSearchResp) + if !ok { + return []any{result.List}, int(result.PageInfo.Total) + } + + resultSlice := make([]any, 0, len(services)) + for _, svc := range services { + resultSlice = append(resultSlice, map[string]any{ + "serviceName": svc.ServiceName, + "version": svc.Version, + "group": svc.Group, + "providerAppName": svc.ProviderAppName, + "consumerAppName": svc.ConsumerAppName, + }) + } + return resultSlice, int(result.PageInfo.Total) +} + +// Ensure ServiceRegistrar implements ToolRegistrar +var _ registry.ToolRegistrar = (*ServiceRegistrar)(nil) diff --git a/pkg/mcp/tools/tools_test.go b/pkg/mcp/tools/tools_test.go new file mode 100644 index 000000000..2a1297c2f --- /dev/null +++ b/pkg/mcp/tools/tools_test.go @@ -0,0 +1,485 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + "errors" + "testing" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/types" + "github.com/apache/dubbo-admin/pkg/mcp/registry" +) + +// TestArgsHelper 测试参数辅助器 +func TestArgsHelper(t *testing.T) { + t.Run("GetString", func(t *testing.T) { + args := map[string]any{ + "name": "test", + "empty": "", + } + helper := NewArgsHelper(args) + + if v := helper.GetString("name", "default"); v != "test" { + t.Errorf("Expected 'test', got '%s'", v) + } + + if v := helper.GetString("empty", "default"); v != "" { + t.Errorf("Expected '', got '%s'", v) + } + + if v := helper.GetString("notexist", "default"); v != "default" { + t.Errorf("Expected 'default', got '%s'", v) + } + }) + + t.Run("GetInt", func(t *testing.T) { + args := map[string]any{ + "intVal": 42, + "floatVal": 3.14, + } + helper := NewArgsHelper(args) + + if v := helper.GetInt("intVal", 0); v != 42 { + t.Errorf("Expected 42, got %d", v) + } + + if v := helper.GetInt("floatVal", 0); v != 3 { + t.Errorf("Expected 3, got %d", v) + } + + if v := helper.GetInt("notexist", 10); v != 10 { + t.Errorf("Expected 10, got %d", v) + } + }) + + t.Run("GetBool", func(t *testing.T) { + args := map[string]any{ + "true": true, + "false": false, + } + helper := NewArgsHelper(args) + + if v := helper.GetBool("true", false); !v { + t.Error("Expected true") + } + + if v := helper.GetBool("false", true); v { + t.Error("Expected false") + } + + if v := helper.GetBool("notexist", true); !v { + t.Error("Expected default true") + } + }) + + t.Run("GetRequiredString", func(t *testing.T) { + args := map[string]any{ + "valid": "value", + "empty": "", + } + helper := NewArgsHelper(args) + + if v, ok := helper.GetRequiredString("valid"); !ok || v != "value" { + t.Errorf("Expected 'value', got '%s', ok=%v", v, ok) + } + + if v, ok := helper.GetRequiredString("empty"); ok || v != "" { + t.Errorf("Expected empty and false, got '%s', ok=%v", v, ok) + } + + if v, ok := helper.GetRequiredString("notexist"); ok || v != "" { + t.Errorf("Expected empty and false, got '%s', ok=%v", v, ok) + } + }) +} + +// TestBuildPageReq 测试分页请求构建 +func TestBuildPageReq(t *testing.T) { + tests := []struct { + name string + pageNumber int + pageSize int + wantOffset int + wantSize int + }{ + {"正常分页", 2, 10, 10, 10}, + {"第一页", 1, 20, 0, 20}, + {"无效页码", 0, 10, 0, 10}, + {"无效大小", 1, 0, 0, 10}, + {"负数页码", -1, 10, 0, 10}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := BuildPageReq(tt.pageNumber, tt.pageSize) + if req.PageOffset != tt.wantOffset { + t.Errorf("Expected offset %d, got %d", tt.wantOffset, req.PageOffset) + } + if req.PageSize != tt.wantSize { + t.Errorf("Expected size %d, got %d", tt.wantSize, req.PageSize) + } + }) + } +} + +// TestJsonResult 测试 JSON 结果创建 +func TestJsonResult(t *testing.T) { + data := map[string]any{ + "key": "value", + "count": 42, + } + + result, err := JsonResult(data) + if err != nil { + t.Fatalf("JsonResult failed: %v", err) + } + + if result.IsError { + t.Error("Expected non-error result") + } + + if len(result.Content) != 1 { + t.Fatalf("Expected 1 content item, got %d", len(result.Content)) + } + + // 验证包含 expected 内容 + text := result.Content[0].Text + if text == "" { + t.Error("Expected non-empty content text") + } +} + +// TestErrorResult 测试错误结果创建 +func TestErrorResult(t *testing.T) { + err := errors.New("test error") + result := ErrorResult(err) + + if !result.IsError { + t.Error("Expected error result") + } + + if len(result.Content) != 1 { + t.Fatalf("Expected 1 content item, got %d", len(result.Content)) + } + + if result.Content[0].Text != "test error" { + t.Errorf("Expected 'test error', got '%s'", result.Content[0].Text) + } +} + +// TestToolValidation 测试工具参数验证 +func TestToolValidation(t *testing.T) { + // 创建测试工具 + testTool := types.ToolDef{ + Name: "test_tool", + Description: "Test tool for validation", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"name"}, + Properties: map[string]types.PropertyDef{ + "name": { + Type: "string", + Description: "Name parameter", + }, + "age": { + Type: "integer", + Description: "Age parameter", + }, + }, + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("ok", false), nil + }, + } + + t.Run("ValidArguments", func(t *testing.T) { + args := map[string]any{ + "name": "test", + "age": 25, + } + + err := types.ValidateRequired(testTool.InputSchema, args) + if err != nil { + t.Errorf("Expected no error, got: %v", err) + } + }) + + t.Run("MissingRequired", func(t *testing.T) { + args := map[string]any{ + "age": 25, + } + + err := types.ValidateRequired(testTool.InputSchema, args) + if err == nil { + t.Error("Expected validation error") + } + }) + + t.Run("EmptyString", func(t *testing.T) { + args := map[string]any{ + "name": "", + } + + err := types.ValidateRequired(testTool.InputSchema, args) + if err == nil { + t.Error("Expected validation error for empty string") + } + }) +} + +// TestMetricsRegistrar 测试集群信息工具注册 +func TestMetricsRegistrar(t *testing.T) { + registrar := &MetricsRegistrar{} + reg := registry.NewRegistry() + + registrar.RegisterTools(reg) + + // 验证工具已注册 + tool, ok := reg.Get("get_cluster_info") + if !ok { + t.Fatal("Tool 'get_cluster_info' not registered") + } + + if tool.Name != "get_cluster_info" { + t.Errorf("Expected name 'get_cluster_info', got '%s'", tool.Name) + } + + if len(tool.InputSchema.Required) != 0 { + t.Errorf("Expected no required params, got %v", tool.InputSchema.Required) + } +} + +// TestResourceSearchRegistrar 测试搜索工具注册 +func TestResourceSearchRegistrar(t *testing.T) { + registrar := &ResourceSearchRegistrar{} + reg := registry.NewRegistry() + + registrar.RegisterTools(reg) + + // 验证工具已注册 + tool, ok := reg.Get("global_search") + if !ok { + t.Fatal("Tool 'global_search' not registered") + } + + // 验证必需参数(keyword 现在是可选的) + if len(tool.InputSchema.Required) != 0 { + t.Errorf("Expected required=[], got %v", tool.InputSchema.Required) + } + + // 验证所有属性定义 + expectedProps := []string{"keyword", "searchType", "mesh", "pageSize", "pageNumber"} + for _, prop := range expectedProps { + if _, ok := tool.InputSchema.Properties[prop]; !ok { + t.Errorf("Missing property: %s", prop) + } + } +} + +// TestServiceRegistrar 测试服务发现工具注册 +func TestServiceRegistrar(t *testing.T) { + registrar := &ServiceRegistrar{} + reg := registry.NewRegistry() + + registrar.RegisterTools(reg) + + // 验证工具已注册 + tools := reg.List() + if len(tools) != 2 { + t.Errorf("Expected 2 tools, got %d", len(tools)) + } + + expectedTools := []string{"search_services", "get_service_detail"} + for _, name := range expectedTools { + if _, ok := reg.Get(name); !ok { + t.Errorf("Tool '%s' not registered", name) + } + } +} + +// TestRegistryList 测试注册表列表功能 +func TestRegistryList(t *testing.T) { + reg := registry.NewRegistry() + + // 注册一个测试工具 + reg.Register(types.ToolDef{ + Name: "test1", + Description: "Test tool 1", + InputSchema: types.InputSchema{Type: "object"}, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { return nil, nil }, + }) + + reg.Register(types.ToolDef{ + Name: "test2", + Description: "Test tool 2", + InputSchema: types.InputSchema{Type: "object"}, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { return nil, nil }, + }) + + tools := reg.List() + if len(tools) != 2 { + t.Errorf("Expected 2 tools, got %d", len(tools)) + } +} + +// TestRegistryUnregister 测试工具注销 +func TestRegistryUnregister(t *testing.T) { + reg := registry.NewRegistry() + + reg.Register(types.ToolDef{ + Name: "test", + Description: "Test tool", + InputSchema: types.InputSchema{Type: "object"}, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { return nil, nil }, + }) + + if _, ok := reg.Get("test"); !ok { + t.Error("Tool not registered") + } + + reg.Unregister("test") + + if _, ok := reg.Get("test"); ok { + t.Error("Tool still exists after unregister") + } +} + +// TestDefaultPageValues 测试默认分页值 +func TestDefaultPageValues(t *testing.T) { + if DefaultPageSize != 10 { + t.Errorf("Expected DefaultPageSize=10, got %d", DefaultPageSize) + } + + if DefaultPageNumber != 1 { + t.Errorf("Expected DefaultPageNumber=1, got %d", DefaultPageNumber) + } +} + +// TestToolHandlerExecution 测试工具处理器执行 +func TestToolHandlerExecution(t *testing.T) { + // 创建简单的测试工具 + var called bool + var receivedArgs map[string]any + + testTool := types.ToolDef{ + Name: "echo", + Description: "Echo tool", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"message"}, + Properties: map[string]types.PropertyDef{ + "message": {Type: "string", Description: "Message"}, + }, + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + called = true + receivedArgs = args + msg := args["message"].(string) + return types.NewTextResult("echo: "+msg, false), nil + }, + } + + t.Run("成功调用", func(t *testing.T) { + called = false + receivedArgs = nil + + args := map[string]any{ + "message": "hello", + } + + result, err := testTool.Handler(nil, args) + if err != nil { + t.Fatalf("Handler failed: %v", err) + } + + if !called { + t.Error("Handler was not called") + } + + if msg, ok := receivedArgs["message"].(string); !ok || msg != "hello" { + t.Errorf("Handler did not receive correct args, got %+v", receivedArgs) + } + + if result.IsError { + t.Error("Expected non-error result") + } + + if result.Content[0].Text != "echo: hello" { + t.Errorf("Expected 'echo: hello', got '%s'", result.Content[0].Text) + } + }) +} + +// TestSearchType 测试搜索类型 +func TestSearchType(t *testing.T) { + types := map[SearchType]string{ + SearchTypeIP: "ip", + SearchTypeInstanceName: "instanceName", + SearchTypeAppName: "appName", + SearchTypeName: "serviceName", + } + + for k, v := range types { + if string(k) != v { + t.Errorf("Expected '%s', got '%s'", v, string(k)) + } + } +} + +// TestServiceSide 测试服务端类型 +func TestServiceSide(t *testing.T) { + types := map[ServiceSide]string{ + ServiceSideProvider: "provider", + ServiceSideConsumer: "consumer", + } + + for k, v := range types { + if string(k) != v { + t.Errorf("Expected '%s', got '%s'", v, string(k)) + } + } +} + +// TestIsEmpty 测试空值判断 +func TestIsEmpty(t *testing.T) { + tests := []struct { + name string + value any + expected bool + }{ + {"空字符串", "", true}, + {"非空字符串", "hello", false}, + {"nil", nil, true}, + {"空数组", []any{}, true}, + {"非空数组", []any{1, 2}, false}, + {"空map", map[string]any{}, true}, + {"非空map", map[string]any{"key": "value"}, false}, + {"数字", 42, false}, + {"布尔", true, false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := types.IsEmpty(tt.value) + if result != tt.expected { + t.Errorf("IsEmpty(%v) = %v, want %v", tt.value, result, tt.expected) + } + }) + } +} diff --git a/pkg/mcp/tools/utils.go b/pkg/mcp/tools/utils.go new file mode 100644 index 000000000..84eb23fe5 --- /dev/null +++ b/pkg/mcp/tools/utils.go @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools + +import ( + "encoding/json" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/core" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +const ( + // DefaultPageSize 默认分页大小 + DefaultPageSize = 10 + // DefaultPageNumber 默认页码 + DefaultPageNumber = 1 + // MaxDistributionLimit 服务分布查询的最大数量 + MaxDistributionLimit = 100 +) + +// SearchType 搜索类型枚举 +type SearchType string + +const ( + SearchTypeIP SearchType = "ip" + SearchTypeInstanceName SearchType = "instanceName" + SearchTypeAppName SearchType = "appName" + SearchTypeName SearchType = "serviceName" +) + +// ServiceSide 服务端类型 +type ServiceSide string + +const ( + ServiceSideProvider ServiceSide = "provider" + ServiceSideConsumer ServiceSide = "consumer" +) + +// ArgsHelper 参数辅助器 +type ArgsHelper struct { + args map[string]any +} + +// NewArgsHelper 创建参数辅助器 +func NewArgsHelper(args map[string]any) *ArgsHelper { + return &ArgsHelper{args: args} +} + +// GetString 获取字符串参数 +func (h *ArgsHelper) GetString(key, defaultValue string) string { + if v, ok := h.args[key].(string); ok { + return v + } + return defaultValue +} + +// GetInt 获取整数参数 +func (h *ArgsHelper) GetInt(key string, defaultValue int) int { + switch v := h.args[key].(type) { + case int: + return v + case float64: + return int(v) + } + return defaultValue +} + +// GetBool 获取布尔参数 +func (h *ArgsHelper) GetBool(key string, defaultValue bool) bool { + if v, ok := h.args[key].(bool); ok { + return v + } + return defaultValue +} + +// GetRequiredString 获取必需的字符串参数 +func (h *ArgsHelper) GetRequiredString(key string) (string, bool) { + v, ok := h.args[key].(string) + if !ok || v == "" { + return "", false + } + return v, true +} + +// BuildPageReq 构建分页请求参数 +func BuildPageReq(pageNumber, pageSize int) coremodel.PageReq { + if pageSize <= 0 { + pageSize = DefaultPageSize + } + if pageNumber <= 0 { + pageNumber = DefaultPageNumber + } + return coremodel.PageReq{ + PageOffset: (pageNumber - 1) * pageSize, + PageSize: pageSize, + } +} + +// FormatJSON 格式化 JSON +func FormatJSON(data any) (string, error) { + bytes, err := json.Marshal(data) + if err != nil { + return "", err + } + return string(bytes), nil +} + +// JsonResult 创建 JSON 结果 +func JsonResult(data any) (*core.ToolResult, error) { + jsonData, err := FormatJSON(data) + if err != nil { + return nil, err + } + return core.NewTextResult(jsonData, false), nil +} + +// ErrorResult 创建错误结果 +func ErrorResult(err error) *core.ToolResult { + return core.NewErrorResult(err) +} + +// GetMeshArg 获取 mesh 参数,默认使用配置中的 discovery id 作为 mesh +func GetMeshArg(ctx consolectx.Context, args map[string]any) string { + helper := NewArgsHelper(args) + if mesh := helper.GetString("mesh", ""); mesh != "" { + return mesh + } + // 默认使用第一个 discovery 配置的 id 作为 mesh 名称 + if len(ctx.Config().Discovery) > 0 { + return ctx.Config().Discovery[0].ID + } + // fallback 到 engine name + return ctx.Config().Engine.Name +} diff --git a/pkg/mcp/transport/http/handler.go b/pkg/mcp/transport/http/handler.go new file mode 100644 index 000000000..88b3f6553 --- /dev/null +++ b/pkg/mcp/transport/http/handler.go @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package http + +import ( + "encoding/json" + "io" + "net/http" + + "github.com/apache/dubbo-admin/pkg/mcp/core" +) + +// Handler HTTP请求处理器 +type Handler struct { + server *core.Server +} + +// NewHandler 创建HTTP处理器 +func NewHandler(server *core.Server) *Handler { + return &Handler{ + server: server, + } +} + +// ServeHTTP 实现http.Handler接口 +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // 设置CORS headers + h.setCORSHeaders(w) + + // 处理OPTIONS请求(CORS preflight) + if r.Method == http.MethodOptions { + w.WriteHeader(http.StatusOK) + return + } + + // 只接受POST请求 + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + // 读取请求体 + body, err := io.ReadAll(r.Body) + if err != nil { + h.sendError(w, nil, core.ErrCodeParseError, "Failed to read request body") + return + } + + // 解析JSON-RPC请求 + var req core.JSONRPCRequest + if err := json.Unmarshal(body, &req); err != nil { + h.sendError(w, nil, core.ErrCodeParseError, "Invalid JSON") + return + } + + // 处理请求并获取响应 + resp := h.server.HandleRequest(&req) + + // 发送响应 + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(resp) +} + +// setCORSHeaders 设置CORS headers +func (h *Handler) setCORSHeaders(w http.ResponseWriter) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type") + w.Header().Set("Access-Control-Max-Age", "86400") +} + +// sendError 发送错误响应 +func (h *Handler) sendError(w http.ResponseWriter, id interface{}, code int, message string) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusBadRequest) + + resp := core.JSONRPCResponse{ + JSONRPC: core.JSONRPCVersion, + ID: id, + Error: &core.JSONRPCError{ + Code: code, + Message: message, + }, + } + json.NewEncoder(w).Encode(resp) +} + +// HandleMCPRequest 处理MCP请求(公开方法) +func (h *Handler) HandleMCPRequest(w http.ResponseWriter, req *core.JSONRPCRequest) { + resp := h.server.HandleRequest(req) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) +} diff --git a/pkg/mcp/transport/http/http.go b/pkg/mcp/transport/http/http.go new file mode 100644 index 000000000..182de6287 --- /dev/null +++ b/pkg/mcp/transport/http/http.go @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package http + +import ( + "context" + "fmt" + "net/http" + "sync" + "time" + + "github.com/apache/dubbo-admin/pkg/mcp/core" +) + +// Transport HTTP传输层 +type Transport struct { + server *core.Server + httpServer *http.Server + handler *Handler + mu sync.RWMutex + started bool +} + +// Config HTTP传输配置 +type Config struct { + Host string + Port int + ReadTimeout time.Duration + WriteTimeout time.Duration + ShutdownTimeout time.Duration +} + +// DefaultConfig 返回默认配置 +func DefaultConfig() *Config { + return &Config{ + Host: "0.0.0.0", + Port: 8080, + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + ShutdownTimeout: 10 * time.Second, + } +} + +// NewTransport 创建HTTP传输层 +func NewTransport(server *core.Server) *Transport { + return NewTransportWithConfig(server, DefaultConfig()) +} + +// NewTransportWithConfig 使用指定配置创建HTTP传输层 +func NewTransportWithConfig(server *core.Server, cfg *Config) *Transport { + handler := NewHandler(server) + + addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) + httpServer := &http.Server{ + Addr: addr, + Handler: handler, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + } + + return &Transport{ + server: server, + httpServer: httpServer, + handler: handler, + } +} + +// Start 启动HTTP服务器(阻塞运行) +func (t *Transport) Start(ctx context.Context) error { + t.mu.Lock() + if t.started { + t.mu.Unlock() + return fmt.Errorf("transport already started") + } + t.started = true + t.mu.Unlock() + + // 启动服务器 + errCh := make(chan error, 1) + go func() { + if err := t.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + errCh <- err + } + }() + + // 等待上下文取消或错误 + select { + case <-ctx.Done(): + return t.Shutdown() + case err := <-errCh: + return err + } +} + +// StartAsync 异步启动HTTP服务器 +func (t *Transport) StartAsync(ctx context.Context) error { + t.mu.Lock() + if t.started { + t.mu.Unlock() + return fmt.Errorf("transport already started") + } + t.started = true + t.mu.Unlock() + + go func() { + if err := t.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + // 记录错误但不退出 + fmt.Printf("HTTP server error: %v\n", err) + } + }() + + return nil +} + +// Shutdown 关闭HTTP服务器 +func (t *Transport) Shutdown() error { + t.mu.Lock() + defer t.mu.Unlock() + + if !t.started { + return nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + if err := t.httpServer.Shutdown(ctx); err != nil { + return fmt.Errorf("shutdown failed: %w", err) + } + + t.started = false + return nil +} + +// Close 关闭传输层 +func (t *Transport) Close() error { + return t.Shutdown() +} + +// Addr 返回监听地址 +func (t *Transport) Addr() string { + return t.httpServer.Addr +} + +// GetServer 获取HTTP服务器(用于自定义路由) +func (t *Transport) GetServer() *http.Server { + return t.httpServer +} + +// GetHandler 获取HTTP处理器(用于自定义路由) +func (t *Transport) GetHandler() *Handler { + return t.handler +} diff --git a/pkg/mcp/transport/http/http_test.go b/pkg/mcp/transport/http/http_test.go new file mode 100644 index 000000000..c735d7fb0 --- /dev/null +++ b/pkg/mcp/transport/http/http_test.go @@ -0,0 +1,272 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package http + +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/registry" +) + +// TestHTTPTransport 测试HTTP传输 +func TestHTTPTransport(t *testing.T) { + // 创建测试服务器 + server := core.NewServer("test-server", "1.0.0") + + // 注册测试工具 + reg := server.GetRegistry() + reg.Register(core.ToolDef{ + Name: "test_tool", + Description: "A test tool", + InputSchema: core.InputSchema{ + Type: "object", + Properties: map[string]core.PropertyDef{ + "message": { + Type: "string", + Description: "Test message", + }, + }, + }, + Handler: func(ctx interface{}, args map[string]any) (*core.ToolResult, error) { + msg, _ := args["message"].(string) + return core.NewTextResult("Echo: " + msg), nil + }, + }) + reg.RegisterAll() + + // 创建HTTP传输层 + transport := NewTransportWithConfig(server, &Config{ + Host: "127.0.0.1", + Port: 0, // 随机端口 + ReadTimeout: 5 * time.Second, + WriteTimeout: 5 * time.Second, + }) + + // 异步启动 + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if err := transport.StartAsync(ctx); err != nil { + t.Fatalf("Failed to start transport: %v", err) + } + + // 等待服务器启动 + time.Sleep(100 * time.Millisecond) + + // 测试initialize请求 + t.Run("Initialize", func(t *testing.T) { + req := core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: "1", + Method: core.MethodInitialize, + } + + resp := makeRequest(t, transport, req) + if resp.Error != nil { + t.Fatalf("Initialize failed: %v", resp.Error) + } + + result, ok := resp.Result.(map[string]any) + if !ok { + t.Fatal("Invalid result type") + } + + serverInfo := result["serverInfo"].(map[string]any) + if serverInfo["name"] != "test-server" { + t.Errorf("Expected server name 'test-server', got '%v'", serverInfo["name"]) + } + }) + + // 测试tools/list请求 + t.Run("ToolsList", func(t *testing.T) { + req := core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: "2", + Method: core.MethodToolsList, + } + + resp := makeRequest(t, transport, req) + if resp.Error != nil { + t.Fatalf("Tools list failed: %v", resp.Error) + } + + result, ok := resp.Result.(map[string]any) + if !ok { + t.Fatal("Invalid result type") + } + + tools := result["tools"].([]any) + if len(tools) != 1 { + t.Errorf("Expected 1 tool, got %d", len(tools)) + } + }) + + // 测试tools/call请求 + t.Run("ToolsCall", func(t *testing.T) { + req := core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: "3", + Method: core.MethodToolsCall, + Params: map[string]any{ + "name": "test_tool", + "arguments": map[string]any{ + "message": "Hello, MCP!", + }, + }, + } + + resp := makeRequest(t, transport, req) + if resp.Error != nil { + t.Fatalf("Tools call failed: %v", resp.Error) + } + + result, ok := resp.Result.(map[string]any) + if !ok { + t.Fatal("Invalid result type") + } + + content := result["content"].([]any) + if len(content) == 0 { + t.Fatal("Empty content") + } + + firstContent := content[0].(map[string]any) + text := firstContent["text"].(string) + if text != "Echo: Hello, MCP!" { + t.Errorf("Expected 'Echo: Hello, MCP!', got '%s'", text) + } + }) + + // 关闭传输层 + if err := transport.Shutdown(); err != nil { + t.Fatalf("Failed to shutdown transport: %v", err) + } +} + +// makeRequest 发送请求到HTTP传输层 +func makeRequest(t *testing.T, transport *Transport, req core.JSONRPCRequest) core.JSONRPCResponse { + t.Helper() + + // 使用httptest直接测试handler + handler := transport.GetHandler() + body, _ := json.Marshal(req) + + httpReq := httptest.NewRequest("POST", "/mcp", bytes.NewReader(body)) + httpReq.Header.Set("Content-Type", "application/json") + + w := httptest.NewRecorder() + handler.ServeHTTP(w, httpReq) + + var resp core.JSONRPCResponse + if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { + t.Fatalf("Failed to decode response: %v", err) + } + + return resp +} + +// TestHandlerCORS 测试CORS支持 +func TestHandlerCORS(t *testing.T) { + server := core.NewServer("test", "1.0.0") + handler := NewHandler(server) + + req := httptest.NewRequest("OPTIONS", "/mcp", nil) + req.Header.Set("Origin", "https://example.com") + + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("Expected status 200, got %d", w.Code) + } + + corsHeader := w.Header().Get("Access-Control-Allow-Origin") + if corsHeader != "*" { + t.Errorf("Expected CORS origin '*', got '%s'", corsHeader) + } +} + +// TestConcurrentRequests 测试并发请求 +func TestConcurrentRequests(t *testing.T) { + server := core.NewServer("test", "1.0.0") + transport := NewTransportWithConfig(server, &Config{ + Host: "127.0.0.1", + Port: 0, + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if err := transport.StartAsync(ctx); err != nil { + t.Fatalf("Failed to start transport: %v", err) + } + defer transport.Shutdown() + + time.Sleep(100 * time.Millisecond) + + // 并发发送10个请求 + const numRequests = 10 + errCh := make(chan error, numRequests) + + for i := 0; i < numRequests; i++ { + go func(id int) { + req := core.JSONRPCRequest{ + JSONRPC: core.JSONRPCVersion, + ID: fmt.Sprintf("req-%d", id), + Method: core.MethodInitialize, + } + _ = makeRequest(t, transport, req) + errCh <- nil + }(i) + } + + // 等待所有请求完成 + for i := 0; i < numRequests; i++ { + if err := <-errCh; err != nil { + t.Errorf("Request failed: %v", err) + } + } +} + +// TestSSETransport 测试SSE传输 +func TestSSETransport(t *testing.T) { + server := core.NewServer("test", "1.0.0") + sseTransport := NewSSETransport(server) + + // 测试SSE连接 + t.Run("SSEConnection", func(t *testing.T) { + req := httptest.NewRequest("GET", "/sse", nil) + w := httptest.NewRecorder() + + // SSE需要flusher支持,httptest.NewRecorder实现了Flusher接口 + sseTransport.HandleSSE(w, req) + + // 验证响应headers + contentType := w.Header().Get("Content-Type") + if contentType != "text/event-stream" { + t.Errorf("Expected content type 'text/event-stream', got '%s'", contentType) + } + }) +} diff --git a/pkg/mcp/transport/http/sse.go b/pkg/mcp/transport/http/sse.go new file mode 100644 index 000000000..de3c07d23 --- /dev/null +++ b/pkg/mcp/transport/http/sse.go @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package http + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "sync" + + "github.com/apache/dubbo-admin/pkg/mcp/core" +) + +// SSETransport Server-Sent Events传输层 +type SSETransport struct { + server *core.Server + clients map[*SSEClient]bool + mu sync.RWMutex + broadcast chan []byte +} + +// SSEClient SSE客户端连接 +type SSEClient struct { + id string + ch chan []byte + ctx context.Context + done context.CancelFunc +} + +// NewSSEClient 创建SSE客户端 +func NewSSEClient(id string) *SSEClient { + ctx, cancel := context.WithCancel(context.Background()) + return &SSEClient{ + id: id, + ch: make(chan []byte, 256), + ctx: ctx, + done: cancel, + } +} + +// NewSSETransport 创建SSE传输层 +func NewSSETransport(server *core.Server) *SSETransport { + return &SSETransport{ + server: server, + clients: make(map[*SSEClient]bool), + broadcast: make(chan []byte, 256), + } +} + +// HandleSSE 处理SSE连接 +func (t *SSETransport) HandleSSE(w http.ResponseWriter, r *http.Request) { + // 设置SSE headers + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Access-Control-Allow-Origin", "*") + + // 创建客户端 + client := NewSSEClient(r.RemoteAddr) + + t.mu.Lock() + t.clients[client] = true + t.mu.Unlock() + + // 发送连接成功消息 + t.sendToClient(client, t.sseEvent("connected", "SSE connection established")) + + // 等待断开连接 + <-client.ctx.Done() + + t.mu.Lock() + delete(t.clients, client) + close(client.ch) + t.mu.Unlock() +} + +// HandleRPCWithSSE 处理带有SSE的RPC请求(支持异步响应流) +func (t *SSETransport) HandleRPCWithSSE(w http.ResponseWriter, r *http.Request) { + // 设置SSE headers + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Access-Control-Allow-Origin", "*") + + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "SSE not supported", http.StatusInternalServerError) + return + } + + // 读取请求 + decoder := json.NewDecoder(r.Body) + var req core.JSONRPCRequest + if err := decoder.Decode(&req); err != nil { + t.sendSSE(w, "error", err.Error()) + return + } + + // 发送处理中状态 + t.sendSSE(w, "processing", "Processing request...") + + // 处理请求 + resp := t.server.HandleRequest(&req) + + // 发送响应 + respData, _ := json.Marshal(resp) + t.sendSSE(w, "result", string(respData)) + + // 发送完成事件 + t.sendSSE(w, "done", "") + flusher.Flush() +} + +// BroadcastEvent 广播事件到所有客户端 +func (t *SSETransport) BroadcastEvent(eventType string, data interface{}) { + event := t.sseEvent(eventType, data) + select { + case t.broadcast <- event: + default: + // broadcast channel满,丢弃事件 + } +} + +// StartBroadcasting 启动广播协程 +func (t *SSETransport) StartBroadcasting(ctx context.Context) { + go func() { + for { + select { + case <-ctx.Done(): + return + case msg := <-t.broadcast: + t.mu.RLock() + for client := range t.clients { + select { + case client.ch <- msg: + default: + // client channel满,关闭客户端 + client.done() + } + } + t.mu.RUnlock() + } + } + }() +} + +// sendToClient 发送消息到指定客户端 +func (t *SSETransport) sendToClient(client *SSEClient, msg []byte) { + select { + case client.ch <- msg: + default: + client.done() + } +} + +// sseEvent 创建SSE事件格式 +func (t *SSETransport) sseEvent(eventType string, data interface{}) []byte { + var dataStr string + switch v := data.(type) { + case string: + dataStr = v + case []byte: + dataStr = string(v) + default: + bytes, _ := json.Marshal(data) + dataStr = string(bytes) + } + return []byte(fmt.Sprintf("event: %s\ndata: %s\n\n", eventType, dataStr)) +} + +// sendSSE 发送SSE事件到ResponseWriter +func (t *SSETransport) sendSSE(w http.ResponseWriter, eventType, data string) { + event := t.sseEvent(eventType, data) + w.Write(event) +} diff --git a/pkg/mcp/transport/stdio/stdio.go b/pkg/mcp/transport/stdio/stdio.go new file mode 100644 index 000000000..f920d00a8 --- /dev/null +++ b/pkg/mcp/transport/stdio/stdio.go @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stdio + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "os" + "sync" + + "github.com/apache/dubbo-admin/pkg/mcp/core" +) + +// Transport stdio 传输层 +type Transport struct { + server *core.Server + reader io.Reader + writer io.Writer + mu sync.Mutex + closed bool +} + +// NewTransport 创建 stdio 传输层(使用 stdin/stdout) +func NewTransport(server *core.Server) *Transport { + return &Transport{ + server: server, + reader: os.Stdin, + writer: os.Stdout, + } +} + +// NewTransportWithIO 创建使用指定 reader/writer 的传输层(用于测试) +func NewTransportWithIO(server *core.Server, reader io.Reader, writer io.Writer) *Transport { + return &Transport{ + server: server, + reader: reader, + writer: writer, + } +} + +// Serve 启动 stdio 服务,阻塞运行直到发生错误或上下文取消 +func (t *Transport) Serve(ctx context.Context) error { + // 从 reader 读取请求,写入 writer 响应 + reader := bufio.NewReader(t.reader) + writer := bufio.NewWriter(t.writer) + + // 确保输出缓冲区刷新 + defer writer.Flush() + + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + // 读取一行 JSON 请求 + line, err := reader.ReadString('\n') + if err != nil { + if err == io.EOF { + return nil // 正常结束 + } + return fmt.Errorf("read stdin: %w", err) + } + + if len(line) == 0 || line == "\n" { + continue + } + + // 解析 JSON-RPC 请求 + var req core.JSONRPCRequest + if err := json.Unmarshal([]byte(line), &req); err != nil { + // 发送错误响应 + t.sendError(writer, nil, core.ErrCodeParseError, "Parse error") + if err := writer.Flush(); err != nil { + return fmt.Errorf("flush error: %w", err) + } + continue + } + + // 处理请求并获取响应 + resp := t.server.HandleRequest(&req) + + // 发送响应 + respData, err := json.Marshal(resp) + if err != nil { + t.sendError(writer, req.ID, core.ErrCodeInternalError, "Failed to marshal response") + } else { + writer.Write(respData) + writer.WriteByte('\n') + } + + if err := writer.Flush(); err != nil { + return fmt.Errorf("flush stdout: %w", err) + } + } +} + +// sendError 发送错误响应 +func (t *Transport) sendError(writer *bufio.Writer, id interface{}, code int, message string) { + resp := core.JSONRPCResponse{ + JSONRPC: core.JSONRPCVersion, + ID: id, + Error: &core.JSONRPCError{ + Code: code, + Message: message, + }, + } + data, _ := json.Marshal(resp) + writer.Write(data) + writer.WriteByte('\n') +} + +// Close 关闭传输层 +func (t *Transport) Close() error { + t.mu.Lock() + defer t.mu.Unlock() + if t.closed { + return nil + } + t.closed = true + return nil +} + +// ServeOnce 处理单个请求(用于测试) +func (t *Transport) ServeOnce(input string) (string, error) { + var req core.JSONRPCRequest + if err := json.Unmarshal([]byte(input), &req); err != nil { + return "", fmt.Errorf("parse request: %w", err) + } + + resp := t.server.HandleRequest(&req) + respData, err := json.Marshal(resp) + if err != nil { + return "", fmt.Errorf("marshal response: %w", err) + } + + return string(respData) + "\n", nil +} diff --git a/pkg/mcp/transport/stdio/stdio_integration_test.go b/pkg/mcp/transport/stdio/stdio_integration_test.go new file mode 100644 index 000000000..cbc8ddeef --- /dev/null +++ b/pkg/mcp/transport/stdio/stdio_integration_test.go @@ -0,0 +1,407 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stdio + +import ( + "bufio" + "context" + "encoding/json" + "io" + "sync" + "testing" + "time" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/types" +) + +// TestTransport_Integration_EndToEnd 端到端集成测试 +func TestTransport_Integration_EndToEnd(t *testing.T) { + // 创建服务器并注册工具 + server := core.NewServer("test-server", "1.0.0") + reg := server.GetRegistry() + + // 注册一个测试工具 + reg.Register(types.ToolDef{ + Name: "echo", + Description: "Echo back the input message", + InputSchema: types.InputSchema{ + Type: "object", + Required: []string{"message"}, + Properties: map[string]types.PropertyDef{ + "message": { + Type: "string", + Description: "Message to echo", + }, + }, + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + msg, _ := args["message"].(string) + return types.NewTextResult("echo: "+msg, false), nil + }, + }) + + // 创建管道对 + serverR, clientW := io.Pipe() + clientR, serverW := io.Pipe() + defer func() { + clientW.Close() + serverW.Close() + }() + + // 创建使用管道的 transport + transport := NewTransportWithIO(server, serverR, serverW) + + // 启动服务器(在后台) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + serverErr := make(chan error, 1) + go func() { + serverErr <- transport.Serve(ctx) + }() + + // 给服务器一点时间启动 + time.Sleep(100 * time.Millisecond) + + // 客户端发送请求 + client := newMCPClient(clientR, clientW) + + // 1. 测试 initialize + t.Run("Initialize", func(t *testing.T) { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": map[string]any{}, + }) + + if resp.Error != nil { + t.Fatalf("Initialize failed: %s", resp.Error.Message) + } + + result := resp.Result.(map[string]any) + serverInfo := result["serverInfo"].(map[string]any) + if serverInfo["name"] != "test-server" { + t.Errorf("Expected name 'test-server', got '%v'", serverInfo["name"]) + } + }) + + // 2. 测试 tools/list + t.Run("ToolsList", func(t *testing.T) { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/list", + }) + + if resp.Error != nil { + t.Fatalf("Tools list failed: %s", resp.Error.Message) + } + + result := resp.Result.(map[string]any) + tools := result["tools"].([]any) + if len(tools) != 1 { + t.Fatalf("Expected 1 tool, got %d", len(tools)) + } + + tool := tools[0].(map[string]any) + if tool["name"] != "echo" { + t.Errorf("Expected tool name 'echo', got '%v'", tool["name"]) + } + }) + + // 3. 测试 tools/call - 成功调用 + t.Run("ToolCall_Success", func(t *testing.T) { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "id": 3, + "method": "tools/call", + "params": map[string]any{ + "name": "echo", + "arguments": map[string]any{ + "message": "hello world", + }, + }, + }) + + if resp.Error != nil { + t.Fatalf("Tool call failed: %s", resp.Error.Message) + } + + result := resp.Result.(map[string]any) + content := result["content"].([]any) + if len(content) != 1 { + t.Fatalf("Expected 1 content item, got %d", len(content)) + } + + firstContent := content[0].(map[string]any) + if firstContent["text"] != "echo: hello world" { + t.Errorf("Expected 'echo: hello world', got '%v'", firstContent["text"]) + } + }) + + // 4. 测试 tools/call - 缺少必需参数 + t.Run("ToolCall_MissingRequired", func(t *testing.T) { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "id": 4, + "method": "tools/call", + "params": map[string]any{ + "name": "echo", + "arguments": map[string]any{}, + }, + }) + + if resp.Error == nil { + t.Fatal("Expected error for missing required parameter") + } + + if resp.Error.Code != core.ErrCodeInvalidParams { + t.Errorf("Expected invalid params code, got %d", resp.Error.Code) + } + }) + + // 5. 测试 tools/call - 工具不存在 + t.Run("ToolCall_NotFound", func(t *testing.T) { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "id": 5, + "method": "tools/call", + "params": map[string]any{ + "name": "nonexistent", + "arguments": map[string]any{}, + }, + }) + + if resp.Error == nil { + t.Fatal("Expected error for nonexistent tool") + } + + if resp.Error.Code != core.ErrCodeMethodNotFound { + t.Errorf("Expected method not found code, got %d", resp.Error.Code) + } + }) + + // 取消服务器上下文并关闭管道 + cancel() + clientW.Close() // 关闭客户端写入端,让服务器 ReadString 返回 EOF + + // 等待服务器退出 + select { + case err := <-serverErr: + if err != nil && err != context.Canceled { + t.Logf("Server exited with error: %v", err) + } + case <-time.After(2 * time.Second): + t.Error("Server did not exit in time") + } +} + +// mcpClient 简单的 MCP 客户端 +type mcpClient struct { + r *bufio.Reader + w io.Writer + wMutex sync.Mutex + reqID int +} + +func newMCPClient(r io.Reader, w io.WriteCloser) *mcpClient { + return &mcpClient{ + r: bufio.NewReader(r), + w: w, + reqID: 0, + } +} + +func (c *mcpClient) call(req map[string]any) *jsonRPCResponse { + c.wMutex.Lock() + defer c.wMutex.Unlock() + + c.reqID++ + req["id"] = c.reqID + + // 发送请求 + reqData, _ := json.Marshal(req) + c.w.Write(reqData) + c.w.Write([]byte("\n")) + + // 读取响应 + line, err := c.r.ReadString('\n') + if err != nil { + return &jsonRPCResponse{ + Error: &core.JSONRPCError{ + Code: -1, + Message: err.Error(), + }, + } + } + + var resp jsonRPCResponse + if err := json.Unmarshal([]byte(line), &resp); err != nil { + return &jsonRPCResponse{ + Error: &core.JSONRPCError{ + Code: -1, + Message: "Failed to parse response: " + err.Error(), + }, + } + } + + return &resp +} + +type jsonRPCResponse struct { + JSONRPC string `json:"jsonrpc"` + ID any `json:"id"` + Result any `json:"result,omitempty"` + Error *core.JSONRPCError `json:"error,omitempty"` +} + +// TestTransport_RealIO 使用真实 io 操作的测试 +func TestTransport_RealIO(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + reg := server.GetRegistry() + + reg.Register(types.ToolDef{ + Name: "ping", + Description: "Ping tool", + InputSchema: types.InputSchema{Type: "object"}, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("pong", false), nil + }, + }) + + // 创建管道对 + serverR, clientW := io.Pipe() + clientR, serverW := io.Pipe() + + transport := NewTransportWithIO(server, serverR, serverW) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + // 启动服务器 + serverErr := make(chan error, 1) + go func() { + serverErr <- transport.Serve(ctx) + }() + + time.Sleep(100 * time.Millisecond) + + // 客户端发送多个请求 + client := newMCPClient(clientR, clientW) + + responses := make([]*jsonRPCResponse, 0, 3) + for i := 0; i < 3; i++ { + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "method": "tools/call", + "params": map[string]any{ + "name": "ping", + "arguments": map[string]any{}, + }, + }) + responses = append(responses, resp) + } + + // 验证所有响应 + for i, resp := range responses { + if resp.Error != nil { + t.Errorf("Request %d failed: %s", i, resp.Error.Message) + } + } + + cancel() + <-serverErr +} + +// TestTransport_ConcurrentRequests 并发请求测试 +func TestTransport_ConcurrentRequests(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + reg := server.GetRegistry() + + reg.Register(types.ToolDef{ + Name: "counter", + Description: "Counting tool", + InputSchema: types.InputSchema{Type: "object"}, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("count", false), nil + }, + }) + + serverR, clientW := io.Pipe() + clientR, serverW := io.Pipe() + + transport := NewTransportWithIO(server, serverR, serverW) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + serverErr := make(chan error, 1) + go func() { + serverErr <- transport.Serve(ctx) + }() + + time.Sleep(100 * time.Millisecond) + + // 并发发送多个请求 + // 使用共享客户端(内部有锁保护写操作) + client := newMCPClient(clientR, clientW) + const numRequests = 10 + results := make(chan *jsonRPCResponse, numRequests) + var wg sync.WaitGroup + + for i := 0; i < numRequests; i++ { + wg.Add(1) + go func() { + defer wg.Done() + resp := client.call(map[string]any{ + "jsonrpc": "2.0", + "method": "tools/call", + "params": map[string]any{ + "name": "counter", + "arguments": map[string]any{}, + }, + }) + results <- resp + }() + } + + // 等待所有请求完成 + go func() { + wg.Wait() + close(results) + }() + + // 收集结果 + successCount := 0 + for resp := range results { + if resp.Error == nil { + successCount++ + } + } + + if successCount != numRequests { + t.Errorf("Expected %d successful requests, got %d", numRequests, successCount) + } + + cancel() + clientW.Close() + <-serverErr +} diff --git a/pkg/mcp/transport/stdio/stdio_test.go b/pkg/mcp/transport/stdio/stdio_test.go new file mode 100644 index 000000000..b1f70bd07 --- /dev/null +++ b/pkg/mcp/transport/stdio/stdio_test.go @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stdio + +import ( + "encoding/json" + "testing" + + consolectx "github.com/apache/dubbo-admin/pkg/console/context" + "github.com/apache/dubbo-admin/pkg/mcp/core" + "github.com/apache/dubbo-admin/pkg/mcp/types" +) + +func TestTransport_ServeOnce_Initialize(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + transport := NewTransport(server) + + // 测试 initialize 请求 + req := map[string]any{ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": map[string]any{}, + } + reqJSON, _ := json.Marshal(req) + + resp, err := transport.ServeOnce(string(reqJSON) + "\n") + if err != nil { + t.Fatalf("ServeOnce failed: %v", err) + } + + var jsonResp core.JSONRPCResponse + if err := json.Unmarshal([]byte(resp), &jsonResp); err != nil { + t.Fatalf("Failed to parse response: %v", err) + } + + if jsonResp.Error != nil { + t.Fatalf("Response error: %s", jsonResp.Error.Message) + } + + result, ok := jsonResp.Result.(map[string]any) + if !ok { + t.Fatal("Result is not a map") + } + + serverInfo, ok := result["serverInfo"].(map[string]any) + if !ok { + t.Fatal("serverInfo not found") + } + + if serverInfo["name"] != "test-server" { + t.Errorf("Expected name 'test-server', got '%v'", serverInfo["name"]) + } +} + +func TestTransport_ServeOnce_ToolsList(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + transport := NewTransport(server) + + // 注册一个测试工具 + reg := server.GetRegistry() + reg.Register(types.ToolDef{ + Name: "test_tool", + Description: "A test tool", + InputSchema: types.InputSchema{ + Type: "object", + }, + Handler: func(ctx consolectx.Context, args map[string]any) (*types.ToolResult, error) { + return types.NewTextResult("ok", false), nil + }, + }) + + // 测试 tools/list 请求 + req := map[string]any{ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/list", + } + reqJSON, _ := json.Marshal(req) + + resp, err := transport.ServeOnce(string(reqJSON) + "\n") + if err != nil { + t.Fatalf("ServeOnce failed: %v", err) + } + + var jsonResp core.JSONRPCResponse + if err := json.Unmarshal([]byte(resp), &jsonResp); err != nil { + t.Fatalf("Failed to parse response: %v", err) + } + + if jsonResp.Error != nil { + t.Fatalf("Response error: %s", jsonResp.Error.Message) + } + + result, ok := jsonResp.Result.(map[string]any) + if !ok { + t.Fatal("Result is not a map") + } + + tools, ok := result["tools"].([]any) + if !ok { + t.Fatal("tools not found") + } + + if len(tools) != 1 { + t.Errorf("Expected 1 tool, got %d", len(tools)) + } +} + +func TestTransport_ServeOnce_ParseError(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + transport := NewTransport(server) + + // 测试无效 JSON - ServeOnce 在解析失败时返回错误 + _, err := transport.ServeOnce("invalid json\n") + if err == nil { + t.Fatal("Expected error for invalid JSON") + } + + // 测试无效方法名 - 这会返回 JSON 错误响应 + req := map[string]any{ + "jsonrpc": "2.0", + "id": 1, + "method": "invalid_method", + } + reqJSON, _ := json.Marshal(req) + + resp, err := transport.ServeOnce(string(reqJSON) + "\n") + if err != nil { + t.Fatalf("ServeOnce failed: %v", err) + } + + var jsonResp core.JSONRPCResponse + if err := json.Unmarshal([]byte(resp), &jsonResp); err != nil { + t.Fatalf("Failed to parse response: %v", err) + } + + if jsonResp.Error == nil { + t.Fatal("Expected error response") + } + + if jsonResp.Error.Code != core.ErrCodeMethodNotFound { + t.Errorf("Expected method not found code, got %d", jsonResp.Error.Code) + } +} + +func TestTransport_Close(t *testing.T) { + server := core.NewServer("test-server", "1.0.0") + transport := NewTransport(server) + + if err := transport.Close(); err != nil { + t.Fatalf("Close failed: %v", err) + } + + // 再次关闭应该成功 + if err := transport.Close(); err != nil { + t.Fatalf("Second Close failed: %v", err) + } +} diff --git a/pkg/mcp/types/tool.go b/pkg/mcp/types/tool.go new file mode 100644 index 000000000..71ac83235 --- /dev/null +++ b/pkg/mcp/types/tool.go @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package types + +import ( + consolectx "github.com/apache/dubbo-admin/pkg/console/context" +) + +// ToolDef 工具定义 +type ToolDef struct { + Name string + Description string + InputSchema InputSchema + Handler ToolHandler +} + +// InputSchema 输入参数 schema +type InputSchema struct { + Type string `json:"type"` + Properties map[string]PropertyDef `json:"properties,omitempty"` + Required []string `json:"required,omitempty"` +} + +// PropertyDef 属性定义 +type PropertyDef struct { + Type string `json:"type"` + Description string `json:"description,omitempty"` + Default any `json:"default,omitempty"` + Enum []string `json:"enum,omitempty"` +} + +// ToolHandler 工具处理器类型 +type ToolHandler func(ctx consolectx.Context, args map[string]any) (*ToolResult, error) + +// ToolResult 工具执行结果 +type ToolResult struct { + Content []Content `json:"content"` + IsError bool `json:"isError,omitempty"` +} + +// Content 内容块 +type Content struct { + Type string `json:"type"` + Text string `json:"text"` +} + +// NewToolResult 创建工具结果 +func NewToolResult(content []Content, isError bool) *ToolResult { + return &ToolResult{ + Content: content, + IsError: isError, + } +} + +// NewTextResult 创建文本结果 +func NewTextResult(text string, isError bool) *ToolResult { + return &ToolResult{ + Content: []Content{{Type: "text", Text: text}}, + IsError: isError, + } +} + +// NewErrorResult 创建错误结果 +func NewErrorResult(err error) *ToolResult { + return &ToolResult{ + Content: []Content{{Type: "text", Text: err.Error()}}, + IsError: true, + } +} diff --git a/pkg/mcp/types/validation.go b/pkg/mcp/types/validation.go new file mode 100644 index 000000000..25c38005d --- /dev/null +++ b/pkg/mcp/types/validation.go @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package types + +import "fmt" + +// ValidateRequired 验证必需参数是否存在且非空 +func ValidateRequired(schema InputSchema, args map[string]any) error { + if args == nil { + args = make(map[string]any) + } + + for _, required := range schema.Required { + val, exists := args[required] + if !exists { + return fmt.Errorf("missing required parameter: %s", required) + } + + if IsEmpty(val) { + return fmt.Errorf("required parameter %s cannot be empty", required) + } + } + return nil +} + +// IsEmpty 判断值是否为空 +func IsEmpty(val any) bool { + switch v := val.(type) { + case string: + return v == "" + case []any: + return len(v) == 0 + case map[string]any: + return len(v) == 0 + case nil: + return true + default: + return false + } +} diff --git a/pkg/store/db/mysql.go b/pkg/store/db/mysql.go deleted file mode 100644 index 4a3d25601..000000000 --- a/pkg/store/db/mysql.go +++ /dev/null @@ -1,3 +0,0 @@ -package db - -// TODO implement memory resource store, refer to GORM https://gorm.io/docs/ diff --git a/pkg/store/dbcommon/connection_pool.go b/pkg/store/dbcommon/connection_pool.go new file mode 100644 index 000000000..5a866262f --- /dev/null +++ b/pkg/store/dbcommon/connection_pool.go @@ -0,0 +1,244 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbcommon + +import ( + "database/sql" + "fmt" + "sync" + "time" + + "gorm.io/gorm" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/logger" +) + +var ( + // pools stores all connection pools indexed by a unique key (storeType:address) + pools = make(map[string]*ConnectionPool) + // poolsMutex protects concurrent access to the pools map + poolsMutex sync.RWMutex +) + +// ConnectionPoolConfig defines connection pool configuration +type ConnectionPoolConfig struct { + MaxIdleConns int // Maximum number of idle connections + MaxOpenConns int // Maximum number of open connections + ConnMaxLifetime time.Duration // Maximum lifetime of a connection + ConnMaxIdleTime time.Duration // Maximum idle time of a connection +} + +// ConnectionPool manages database connections with connection pooling +type ConnectionPool struct { + db *gorm.DB + sqlDB *sql.DB + address string + storeType storecfg.Type + mu sync.RWMutex + refCount int // Reference counter for the number of stores using this pool + closeOnce sync.Once // Ensure Close is called only once + closed bool // Track if the pool is closed +} + +// GetOrCreatePool returns or creates a connection pool for the given store type and address +// It implements a singleton pattern with reference counting to allow pool reuse across multiple stores +// If a pool already exists for the same storeType and address, it increments the reference count and returns the existing pool +// Otherwise, it creates a new pool with the provided dialector +func GetOrCreatePool(dialector gorm.Dialector, storeType storecfg.Type, address string, config *ConnectionPoolConfig) (*ConnectionPool, error) { + if storeType == storecfg.Memory { + return nil, fmt.Errorf("memory pool store is no need to create connection pool") + } + + poolKey := fmt.Sprintf("%s:%s", storeType, address) + + poolsMutex.Lock() + defer poolsMutex.Unlock() + + // Check if pool already exists + if existingPool, exists := pools[poolKey]; exists { + // Increment reference count when reusing existing pool + existingPool.refCount++ + logger.Infof("Reusing %s connection pool: address=%s, refCount=%d", storeType, address, existingPool.refCount) + return existingPool, nil + } + + // Create new pool + if config == nil { + config = DefaultConnectionPoolConfig() + } + + pool, err := NewConnectionPool(dialector, storeType, address, config) + if err != nil { + return nil, err + } + + // Store the pool + pools[poolKey] = pool + logger.Infof("%s connection pool created successfully: address=%s, maxIdleConns=%d, maxOpenConns=%d", + storeType, address, config.MaxIdleConns, config.MaxOpenConns) + + return pool, nil +} + +// RemovePool removes a pool from the global registry +// This should only be called when the pool's reference count reaches zero +func RemovePool(storeType storecfg.Type, address string) { + poolKey := fmt.Sprintf("%s:%s", storeType, address) + + poolsMutex.Lock() + defer poolsMutex.Unlock() + + delete(pools, poolKey) + logger.Infof("Removed %s connection pool from registry: address=%s", storeType, address) +} + +// DefaultConnectionPoolConfig returns default connection pool configuration +func DefaultConnectionPoolConfig() *ConnectionPoolConfig { + return &ConnectionPoolConfig{ + MaxIdleConns: 10, // Default: 10 idle connections + MaxOpenConns: 100, // Default: 100 max open connections + ConnMaxLifetime: time.Hour, // Default: 1 hour max lifetime + ConnMaxIdleTime: 10 * time.Minute, // Default: 10 minutes max idle time + } +} + +// NewConnectionPool creates a new connection pool +func NewConnectionPool(dialector gorm.Dialector, storeType storecfg.Type, address string, config *ConnectionPoolConfig) (*ConnectionPool, error) { + db, err := gorm.Open(dialector, &gorm.Config{}) + if err != nil { + return nil, fmt.Errorf("failed to connect to %s: %w", storeType, err) + } + + sqlDB, err := db.DB() + if err != nil { + return nil, fmt.Errorf("failed to get underlying sql.DB: %w", err) + } + + // Configure connection pool + sqlDB.SetMaxIdleConns(config.MaxIdleConns) + sqlDB.SetMaxOpenConns(config.MaxOpenConns) + sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime) + sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime) + + return &ConnectionPool{ + db: db, + sqlDB: sqlDB, + address: address, + storeType: storeType, + refCount: 1, // Initial reference count + }, nil +} + +// GetDB returns the gorm.DB instance +func (p *ConnectionPool) GetDB() *gorm.DB { + p.mu.RLock() + defer p.mu.RUnlock() + return p.db +} + +// Address returns the connection address +func (p *ConnectionPool) Address() string { + p.mu.RLock() + defer p.mu.RUnlock() + return p.address +} + +// RefCount returns the current reference count +func (p *ConnectionPool) RefCount() int { + p.mu.RLock() + defer p.mu.RUnlock() + return p.refCount +} + +// IncrementRef increments the reference count +func (p *ConnectionPool) IncrementRef() { + p.mu.Lock() + defer p.mu.Unlock() + p.refCount++ +} + +// Close closes the connection pool gracefully with reference counting +// The pool is only actually closed when refCount reaches 0 +func (p *ConnectionPool) Close() error { + p.mu.Lock() + defer p.mu.Unlock() + + if p.closed { + return nil // Already closed + } + + p.refCount-- + logger.Infof("Decremented %s connection pool refCount: address=%s, refCount=%d", p.storeType, p.address, p.refCount) + + // Only close the pool when no stores are using it + if p.refCount <= 0 { + var closeErr error + p.closeOnce.Do(func() { + if p.sqlDB != nil { + logger.Infof("Closing %s connection pool: address=%s", p.storeType, p.address) + closeErr = p.sqlDB.Close() + p.closed = true + } + RemovePool(p.storeType, p.address) + }) + return closeErr + } + + return nil +} + +// Ping checks if the database connection is alive +func (p *ConnectionPool) Ping() error { + p.mu.RLock() + defer p.mu.RUnlock() + + if p.sqlDB != nil { + return p.sqlDB.Ping() + } + return fmt.Errorf("connection pool not initialized") +} + +// Stats returns database connection pool statistics +func (p *ConnectionPool) Stats() sql.DBStats { + p.mu.RLock() + defer p.mu.RUnlock() + + if p.sqlDB != nil { + return p.sqlDB.Stats() + } + return sql.DBStats{} +} + +// GetGlobalDB returns the first available gorm.DB instance from the global pool registry +// This is used by components that need database access without going through StoreComponent +// Returns nil if no database connection is available +func GetGlobalDB(storeType storecfg.Type) *gorm.DB { + poolsMutex.RLock() + defer poolsMutex.RUnlock() + + // Find the first pool matching the store type + prefix := string(storeType) + ":" + for key, pool := range pools { + if len(key) >= len(prefix) && key[:len(prefix)] == prefix { + return pool.GetDB() + } + } + + return nil +} diff --git a/pkg/store/dbcommon/connection_pool_test.go b/pkg/store/dbcommon/connection_pool_test.go new file mode 100644 index 000000000..a9e5c71d4 --- /dev/null +++ b/pkg/store/dbcommon/connection_pool_test.go @@ -0,0 +1,502 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbcommon + +import ( + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gorm.io/driver/sqlite" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" +) + +func TestDefaultConnectionPoolConfig(t *testing.T) { + config := DefaultConnectionPoolConfig() + + assert.NotNil(t, config) + assert.Equal(t, 10, config.MaxIdleConns) + assert.Equal(t, 100, config.MaxOpenConns) + assert.Equal(t, time.Hour, config.ConnMaxLifetime) + assert.Equal(t, 10*time.Minute, config.ConnMaxIdleTime) +} + +func TestNewConnectionPool(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + config := DefaultConnectionPoolConfig() + + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", config) + + assert.NoError(t, err) + assert.NotNil(t, pool) + assert.NotNil(t, pool.db) + assert.NotNil(t, pool.sqlDB) + assert.Equal(t, "test-address", pool.address) + assert.Equal(t, storecfg.MySQL, pool.storeType) + assert.Equal(t, 1, pool.refCount) + assert.False(t, pool.closed) + + // Cleanup + if err := pool.Close(); err != nil { + return + } +} + +func TestConnectionPool_GetDB(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + db := pool.GetDB() + assert.NotNil(t, db) +} + +func TestConnectionPool_Address(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address-123", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + assert.Equal(t, "test-address-123", pool.Address()) +} + +func TestConnectionPool_RefCount(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + // Initial ref count should be 1 + assert.Equal(t, 1, pool.RefCount()) + + // Increment ref count + pool.IncrementRef() + assert.Equal(t, 2, pool.RefCount()) + + pool.IncrementRef() + assert.Equal(t, 3, pool.RefCount()) +} + +func TestConnectionPool_IncrementRef(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + initialRefCount := pool.RefCount() + pool.IncrementRef() + assert.Equal(t, initialRefCount+1, pool.RefCount()) +} + +func TestConnectionPool_Close(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // First close should decrement ref count + err = pool.Close() + assert.NoError(t, err) + assert.Equal(t, 0, pool.refCount) + assert.True(t, pool.closed) + + // Second close should be a no-op + err = pool.Close() + assert.NoError(t, err) + assert.Equal(t, 0, pool.refCount) +} + +func TestConnectionPool_CloseWithMultipleReferences(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Increment ref count + pool.IncrementRef() + pool.IncrementRef() + assert.Equal(t, 3, pool.RefCount()) + + // First close should just decrement + err = pool.Close() + assert.NoError(t, err) + assert.Equal(t, 2, pool.RefCount()) + assert.False(t, pool.closed) + + // Second close should just decrement + err = pool.Close() + assert.NoError(t, err) + assert.Equal(t, 1, pool.RefCount()) + assert.False(t, pool.closed) + + // Third close should actually close + err = pool.Close() + assert.NoError(t, err) + assert.Equal(t, 0, pool.RefCount()) + assert.True(t, pool.closed) +} + +func TestConnectionPool_Ping(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + err = pool.Ping() + assert.NoError(t, err) +} + +func TestConnectionPool_Stats(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + config := &ConnectionPoolConfig{ + MaxIdleConns: 5, + MaxOpenConns: 10, + ConnMaxLifetime: time.Hour, + ConnMaxIdleTime: 10 * time.Minute, + } + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", config) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + stats := pool.Stats() + assert.NotNil(t, stats) + // The max values should match configuration + assert.Equal(t, 10, stats.MaxOpenConnections) +} + +func TestGetOrCreatePool_CreateNew(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := GetOrCreatePool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + + assert.NoError(t, err) + assert.NotNil(t, pool) + assert.Equal(t, 1, pool.RefCount()) + + // Cleanup + if err := pool.Close(); err != nil { + return + } +} + +func TestGetOrCreatePool_ReuseExisting(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector := sqlite.Open("file::memory:?cache=shared") + + // Create first pool + pool1, err := GetOrCreatePool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + assert.Equal(t, 1, pool1.RefCount()) + + // Get same pool again + pool2, err := GetOrCreatePool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Should be the same pool with incremented ref count + assert.Equal(t, pool1, pool2) + assert.Equal(t, 2, pool1.RefCount()) + + // Cleanup + pool1.Close() + pool2.Close() +} + +func TestGetOrCreatePool_DifferentAddresses(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector1 := sqlite.Open("file::memory:?cache=shared") + dialector2 := sqlite.Open("file::memory:?cache=shared") + + // Create pool for address 1 + pool1, err := GetOrCreatePool(dialector1, storecfg.MySQL, "address-1", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Create pool for address 2 + pool2, err := GetOrCreatePool(dialector2, storecfg.MySQL, "address-2", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Should be different pools + assert.NotEqual(t, pool1, pool2) + assert.Equal(t, "address-1", pool1.Address()) + assert.Equal(t, "address-2", pool2.Address()) + + // Cleanup + pool1.Close() + pool2.Close() +} + +func TestGetOrCreatePool_DifferentStoreTypes(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector1 := sqlite.Open("file::memory:?cache=shared") + dialector2 := sqlite.Open("file::memory:?cache=shared") + + // Create MySQL pool + pool1, err := GetOrCreatePool(dialector1, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Create Postgres pool with same address + pool2, err := GetOrCreatePool(dialector2, storecfg.Postgres, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Should be different pools (different store types) + assert.NotEqual(t, pool1, pool2) + assert.Equal(t, storecfg.MySQL, pool1.storeType) + assert.Equal(t, storecfg.Postgres, pool2.storeType) + + // Cleanup + pool1.Close() + pool2.Close() +} + +func TestGetOrCreatePool_MemoryStoreError(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + + pool, err := GetOrCreatePool(dialector, storecfg.Memory, "test-address", DefaultConnectionPoolConfig()) + + assert.Error(t, err) + assert.Nil(t, pool) + assert.Contains(t, err.Error(), "memory pool store is no need to create connection pool") +} + +func TestRemovePool(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := GetOrCreatePool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Verify pool exists in registry + poolKey := "mysql:test-address" + poolsMutex.RLock() + _, exists := pools[poolKey] + poolsMutex.RUnlock() + assert.True(t, exists, "Pool should exist in registry after creation") + + // Close pool (which should call RemovePool internally) + err = pool.Close() + require.NoError(t, err) + + // Verify pool was removed from registry + poolsMutex.RLock() + _, exists = pools[poolKey] + poolsMutex.RUnlock() + assert.False(t, exists, "Pool should be removed from registry after close") +} + +func TestConnectionPool_ConcurrentAccess(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer pool.Close() + + const numGoroutines = 10 + var wg sync.WaitGroup + wg.Add(numGoroutines) + + // Concurrently access pool methods + for i := 0; i < numGoroutines; i++ { + go func() { + defer wg.Done() + + // Test concurrent reads + _ = pool.GetDB() + _ = pool.Address() + _ = pool.RefCount() + _ = pool.Stats() + + // Test concurrent ping + _ = pool.Ping() + }() + } + + wg.Wait() +} + +func TestConnectionPool_ConcurrentIncrement(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + const numGoroutines = 100 + var wg sync.WaitGroup + wg.Add(numGoroutines) + + // Concurrently increment ref count + for i := 0; i < numGoroutines; i++ { + go func() { + defer wg.Done() + pool.IncrementRef() + }() + } + + wg.Wait() + + // Verify ref count (initial 1 + 100 increments) + assert.Equal(t, 101, pool.RefCount()) + + // Cleanup + for i := 0; i <= numGoroutines; i++ { + pool.Close() + } +} + +func TestGetOrCreatePool_ConcurrentCreation(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + const numGoroutines = 10 + var wg sync.WaitGroup + wg.Add(numGoroutines) + + createdPools := make([]*ConnectionPool, numGoroutines) + + // Concurrently try to create/get the same pool + for i := 0; i < numGoroutines; i++ { + go func(index int) { + defer wg.Done() + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := GetOrCreatePool(dialector, storecfg.MySQL, "concurrent-address", DefaultConnectionPoolConfig()) + assert.NoError(t, err) + createdPools[index] = pool + }(i) + } + + wg.Wait() + + // All goroutines should get the same pool + firstPool := createdPools[0] + for i := 1; i < numGoroutines; i++ { + assert.Equal(t, firstPool, createdPools[i]) + } + + // Ref count should be numGoroutines + assert.Equal(t, numGoroutines, firstPool.RefCount()) + + // Cleanup + for i := 0; i < numGoroutines; i++ { + firstPool.Close() + } +} + +func TestConnectionPool_CustomConfig(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + config := &ConnectionPoolConfig{ + MaxIdleConns: 5, + MaxOpenConns: 20, + ConnMaxLifetime: 30 * time.Minute, + ConnMaxIdleTime: 5 * time.Minute, + } + + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", config) + require.NoError(t, err) + defer pool.Close() + + stats := pool.Stats() + assert.Equal(t, 20, stats.MaxOpenConnections) +} + +func TestConnectionPool_NilConfig(t *testing.T) { + // Clear the pools map for isolated test + poolsMutex.Lock() + pools = make(map[string]*ConnectionPool) + poolsMutex.Unlock() + + dialector := sqlite.Open("file::memory:?cache=shared") + + // Pass nil config - should use default + pool, err := GetOrCreatePool(dialector, storecfg.MySQL, "test-address", nil) + require.NoError(t, err) + defer pool.Close() + + assert.NotNil(t, pool) + stats := pool.Stats() + // Should have default max open connections (100) + assert.Equal(t, 100, stats.MaxOpenConnections) +} + +func TestConnectionPool_MultipleCloseIdempotent(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Close multiple times + err = pool.Close() + assert.NoError(t, err) + + err = pool.Close() + assert.NoError(t, err) + + err = pool.Close() + assert.NoError(t, err) + + // Should still be closed + assert.True(t, pool.closed) + assert.Equal(t, 0, pool.refCount) +} diff --git a/pkg/store/dbcommon/gorm_store.go b/pkg/store/dbcommon/gorm_store.go new file mode 100644 index 000000000..cedc20144 --- /dev/null +++ b/pkg/store/dbcommon/gorm_store.go @@ -0,0 +1,766 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbcommon + +import ( + "errors" + "fmt" + "reflect" + "sort" + "sync" + + "gorm.io/gorm" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + "github.com/apache/dubbo-admin/pkg/core/logger" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +// GormStore is a GORM-backed store implementation for Dubbo resources +// It uses GORM for database operations and persists all indices to the resource_indices table +// This implementation is database-agnostic and works with any GORM-supported database +type GormStore struct { + pool *ConnectionPool // Shared connection pool with reference counting + kind model.ResourceKind + address string + indexers cache.Indexers // Index functions for creating indices + mu sync.RWMutex // Protects indexers + stopCh chan struct{} +} + +var _ store.ManagedResourceStore = &GormStore{} + +// NewGormStore creates a new GORM store for the specified resource kind +func NewGormStore(kind model.ResourceKind, address string, pool *ConnectionPool) *GormStore { + return &GormStore{ + kind: kind, + address: address, + pool: pool, + indexers: make(cache.Indexers), + stopCh: make(chan struct{}), + } +} + +// Init initializes the GORM store by migrating the schema and registering indexers +func (gs *GormStore) Init(_ runtime.BuilderContext) error { + // Perform table migration + db := gs.pool.GetDB() + // Use Scopes to set the table name dynamically for migration + if err := db.Scopes(TableScope(gs.kind.ToString())).AutoMigrate(&ResourceModel{}); err != nil { + return fmt.Errorf("failed to migrate schema for %s: %w", gs.kind.ToString(), err) + } + + // Migrate resource_indices table (shared across all resource kinds) + if err := db.AutoMigrate(&ResourceIndexModel{}); err != nil { + return fmt.Errorf("failed to migrate resource_indices: %w", err) + } + + // Register indexers for the resource kind + indexers := index.IndexersRegistry().Indexers(gs.kind) + if err := gs.AddIndexers(indexers); err != nil { + return err + } + + // Backfill resource_indices from existing ResourceModel rows so that + // ListByIndexes/HasPrefix work correctly after restarts or upgrades. + if err := gs.backfillIndices(); err != nil { + return fmt.Errorf("failed to backfill indices for %s: %w", gs.kind.ToString(), err) + } + + logger.Infof("GORM store initialized for resource kind: %s", gs.kind.ToString()) + return nil +} + +// Start starts the GORM store and monitors for shutdown signal +func (gs *GormStore) Start(_ runtime.Runtime, stopCh <-chan struct{}) error { + logger.Infof("GORM store started for resource kind: %s", gs.kind.ToString()) + + // Monitor stop channel for graceful shutdown in a goroutine + go func() { + <-stopCh + logger.Infof("GORM store for %s received stop signal, initiating graceful shutdown", gs.kind.ToString()) + + // Close the internal stop channel to signal any ongoing operations + close(gs.stopCh) + + // Decrement the reference count and potentially close the connection pool + if gs.pool != nil { + if err := gs.pool.Close(); err != nil { + logger.Errorf("Failed to close connection pool for %s: %v", gs.kind.ToString(), err) + } else { + logger.Infof("GORM store for %s shutdown completed", gs.kind.ToString()) + } + } + }() + + return nil +} + +// Add inserts a new resource into the database +func (gs *GormStore) Add(obj interface{}) error { + resource, ok := obj.(model.Resource) + if !ok { + return bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + + if resource.ResourceKind() != gs.kind { + return fmt.Errorf("resource kind mismatch: expected %s, got %s", gs.kind, resource.ResourceKind()) + } + + var count int64 + db := gs.pool.GetDB() + err := db.Scopes(TableScope(gs.kind.ToString())).Model(&ResourceModel{}). + Where("resource_key = ?", resource.ResourceKey()). + Count(&count).Error + if err != nil { + return err + } + if count > 0 { + return store.ErrorResourceAlreadyExists( + resource.ResourceKind().ToString(), + resource.ResourceMeta().Name, + resource.ResourceMesh(), + ) + } + + m, err := FromResource(resource) + if err != nil { + return err + } + + return db.Transaction(func(tx *gorm.DB) error { + if err := tx.Scopes(TableScope(gs.kind.ToString())).Create(m).Error; err != nil { + return err + } + if err := gs.persistIndexEntriesTx(tx, resource, nil); err != nil { + return fmt.Errorf("failed to persist index entries for %s: %w", resource.ResourceKey(), err) + } + return nil + }) +} + +// Update modifies an existing resource in the database +func (gs *GormStore) Update(obj interface{}) error { + resource, ok := obj.(model.Resource) + if !ok { + return bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + + if resource.ResourceKind() != gs.kind { + return fmt.Errorf("resource kind mismatch: expected %s, got %s", gs.kind, resource.ResourceKind()) + } + + // Get old resource for index update + oldResource, exists, err := gs.GetByKey(resource.ResourceKey()) + if err != nil { + return err + } + if !exists { + return store.ErrorResourceNotFound( + resource.ResourceKind().ToString(), + resource.ResourceMeta().Name, + resource.ResourceMesh(), + ) + } + + m, err := FromResource(resource) + if err != nil { + return err + } + + db := gs.pool.GetDB() + return db.Transaction(func(tx *gorm.DB) error { + result := tx.Scopes(TableScope(gs.kind.ToString())).Model(&ResourceModel{}). + Where("resource_key = ?", resource.ResourceKey()). + Updates(map[string]interface{}{ + "name": m.Name, + "mesh": m.Mesh, + "data": m.Data, + }) + + if result.Error != nil { + return result.Error + } + + if result.RowsAffected == 0 { + return store.ErrorResourceNotFound( + resource.ResourceKind().ToString(), + resource.ResourceMeta().Name, + resource.ResourceMesh(), + ) + } + + if err := gs.persistIndexEntriesTx(tx, resource, oldResource.(model.Resource)); err != nil { + return fmt.Errorf("failed to persist index entries for %s: %w", resource.ResourceKey(), err) + } + return nil + }) +} + +// Delete removes a resource from the database +func (gs *GormStore) Delete(obj interface{}) error { + resource, ok := obj.(model.Resource) + if !ok { + return bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + + db := gs.pool.GetDB() + return db.Transaction(func(tx *gorm.DB) error { + result := tx.Scopes(TableScope(gs.kind.ToString())). + Where("resource_key = ?", resource.ResourceKey()). + Delete(&ResourceModel{}) + + if result.Error != nil { + return result.Error + } + + if result.RowsAffected == 0 { + return store.ErrorResourceNotFound( + resource.ResourceKind().ToString(), + resource.ResourceMeta().Name, + resource.ResourceMesh(), + ) + } + + return tx.Where("resource_kind = ? AND resource_key = ?", gs.kind.ToString(), resource.ResourceKey()). + Delete(&ResourceIndexModel{}).Error + }) +} + +// List returns all resources of the configured kind from the database +func (gs *GormStore) List() []interface{} { + var models []ResourceModel + db := gs.pool.GetDB() + if err := db.Scopes(TableScope(gs.kind.ToString())).Model(&ResourceModel{}).Find(&models).Error; err != nil { + logger.Errorf("failed to list resources: %v", err) + return []interface{}{} + } + + result := make([]interface{}, 0, len(models)) + for _, m := range models { + resource, err := m.ToResource() + if err != nil { + logger.Errorf("failed to deserialize resource: %v", err) + continue + } + result = append(result, resource) + } + return result +} + +// ListKeys returns all resource keys of the configured kind from the database +func (gs *GormStore) ListKeys() []string { + var keys []string + db := gs.pool.GetDB() + if err := db.Scopes(TableScope(gs.kind.ToString())).Model(&ResourceModel{}).Pluck("resource_key", &keys).Error; err != nil { + logger.Errorf("failed to list keys: %v", err) + return []string{} + } + return keys +} + +// Get retrieves a resource by its object reference +func (gs *GormStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + resource, ok := obj.(model.Resource) + if !ok { + return nil, false, bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + return gs.GetByKey(resource.ResourceKey()) +} + +// GetByKey retrieves a resource by its unique key +func (gs *GormStore) GetByKey(key string) (item interface{}, exists bool, err error) { + var m ResourceModel + db := gs.pool.GetDB() + result := db.Scopes(TableScope(gs.kind.ToString())). + Where("resource_key = ?", key). + First(&m) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, false, nil + } + return nil, false, result.Error + } + + resource, err := m.ToResource() + if err != nil { + return nil, false, err + } + + return resource, true, nil +} + +// Replace atomically replaces all resources in the database with the provided list +func (gs *GormStore) Replace(list []interface{}, _ string) error { + db := gs.pool.GetDB() + return db.Transaction(func(tx *gorm.DB) error { + // Delete all existing records for this resource kind + if err := tx.Scopes(TableScope(gs.kind.ToString())). + Delete(&ResourceModel{}, "1=1").Error; err != nil { + return err + } + + // Delete all index entries for this resource kind + if err := tx.Where("resource_kind = ?", gs.kind.ToString()). + Delete(&ResourceIndexModel{}).Error; err != nil { + return err + } + + // Return early if list is empty + if len(list) == 0 { + return nil + } + + // Convert all resources to ResourceModel + models := make([]*ResourceModel, 0, len(list)) + resources := make([]model.Resource, 0, len(list)) + for _, obj := range list { + resource, ok := obj.(model.Resource) + if !ok { + return bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + + m, err := FromResource(resource) + if err != nil { + return err + } + models = append(models, m) + resources = append(resources, resource) + } + + // Batch insert all models at once + if err := tx.Scopes(TableScope(gs.kind.ToString())).CreateInBatches(models, 100).Error; err != nil { + return err + } + + // Persist all index entries in bulk + var indexEntries []ResourceIndexModel + indexers := gs.GetIndexers() + for _, resource := range resources { + for indexName, indexFunc := range indexers { + values, err := indexFunc(resource) + if err != nil { + continue + } + for _, v := range values { + indexEntries = append(indexEntries, ResourceIndexModel{ + ResourceKind: gs.kind.ToString(), + IndexName: indexName, + IndexValue: v, + ResourceKey: resource.ResourceKey(), + Operator: string(index.Equals), + }) + } + } + } + + if len(indexEntries) > 0 { + if err := tx.CreateInBatches(&indexEntries, 100).Error; err != nil { + return fmt.Errorf("failed to persist index entries during replace: %w", err) + } + } + + return nil + }) +} + +func (gs *GormStore) Resync() error { + return nil +} + +func (gs *GormStore) Index(indexName string, obj interface{}) ([]interface{}, error) { + if !gs.IndexExists(indexName) { + return nil, fmt.Errorf("index %s does not exist", indexName) + } + + indexers := gs.GetIndexers() + indexFunc := indexers[indexName] + indexValues, err := indexFunc(obj) + if err != nil { + return nil, err + } + + if len(indexValues) == 0 { + return []interface{}{}, nil + } + + return gs.findByIndex(indexName, indexValues[0]) +} + +func (gs *GormStore) IndexKeys(indexName, indexedValue string) ([]string, error) { + if !gs.IndexExists(indexName) { + return nil, fmt.Errorf("index %s does not exist", indexName) + } + + resources, err := gs.findByIndex(indexName, indexedValue) + if err != nil { + return nil, err + } + + keys := make([]string, 0, len(resources)) + for _, obj := range resources { + if resource, ok := obj.(model.Resource); ok { + keys = append(keys, resource.ResourceKey()) + } + } + + return keys, nil +} + +func (gs *GormStore) ListIndexFuncValues(indexName string) []string { + if !gs.IndexExists(indexName) { + return []string{} + } + + var values []string + db := gs.pool.GetDB() + if err := db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND index_name = ?", gs.kind.ToString(), indexName). + Distinct("index_value"). + Pluck("index_value", &values).Error; err != nil { + logger.Errorf("failed to list index func values for %s: %v", indexName, err) + return []string{} + } + return values +} + +func (gs *GormStore) ByIndex(indexName, indexedValue string) ([]interface{}, error) { + if !gs.IndexExists(indexName) { + return nil, fmt.Errorf("index %s does not exist", indexName) + } + + return gs.findByIndex(indexName, indexedValue) +} + +func (gs *GormStore) GetIndexers() cache.Indexers { + gs.mu.RLock() + defer gs.mu.RUnlock() + + result := make(cache.Indexers, len(gs.indexers)) + for k, v := range gs.indexers { + result[k] = v + } + return result +} + +func (gs *GormStore) AddIndexers(newIndexers cache.Indexers) error { + gs.mu.Lock() + defer gs.mu.Unlock() + + for name, indexFunc := range newIndexers { + if _, exists := gs.indexers[name]; exists { + return fmt.Errorf("indexer %s already exists", name) + } + gs.indexers[name] = indexFunc + } + + return nil +} + +func (gs *GormStore) GetByKeys(keys []string) ([]model.Resource, error) { + if len(keys) == 0 { + return []model.Resource{}, nil + } + + var models []ResourceModel + db := gs.pool.GetDB() + err := db.Scopes(TableScope(gs.kind.ToString())).Model(&ResourceModel{}). + Where("resource_key IN ?", keys). + Find(&models).Error + if err != nil { + return nil, err + } + + resources := make([]model.Resource, 0, len(models)) + for _, m := range models { + resource, err := m.ToResource() + if err != nil { + return nil, err + } + resources = append(resources, resource) + } + + return resources, nil +} + +func (gs *GormStore) ListByIndexes(indexes []index.IndexCondition) ([]model.Resource, error) { + keys, err := gs.getKeysByIndexes(indexes) + if err != nil { + return nil, err + } + + resources, err := gs.GetByKeys(keys) + if err != nil { + return nil, err + } + + sort.Slice(resources, func(i, j int) bool { + return resources[i].ResourceKey() < resources[j].ResourceKey() + }) + + return resources, nil +} + +func (gs *GormStore) PageListByIndexes(indexes []index.IndexCondition, pq model.PageReq) (*model.PageData[model.Resource], error) { + keys, err := gs.getKeysByIndexes(indexes) + if err != nil { + return nil, err + } + + sort.Strings(keys) + total := len(keys) + + if pq.PageOffset >= total { + return model.NewPageData(total, pq.PageOffset, pq.PageSize, []model.Resource{}), nil + } + + end := pq.PageOffset + pq.PageSize + if end > total { + end = total + } + + pageKeys := keys[pq.PageOffset:end] + resources, err := gs.GetByKeys(pageKeys) + if err != nil { + return nil, err + } + + return model.NewPageData(total, pq.PageOffset, pq.PageSize, resources), nil +} + +func (gs *GormStore) findByIndex(indexName, indexedValue string) ([]interface{}, error) { + if !gs.IndexExists(indexName) { + return nil, fmt.Errorf("index %s does not exist", indexName) + } + + // Get resource keys from database index + db := gs.pool.GetDB() + var entries []ResourceIndexModel + err := db.Where("resource_kind = ? AND index_name = ? AND index_value = ?", + gs.kind.ToString(), indexName, indexedValue). + Find(&entries).Error + if err != nil { + return nil, err + } + + if len(entries) == 0 { + return []interface{}{}, nil + } + + // Collect unique resource keys + keys := make([]string, 0, len(entries)) + seen := make(map[string]struct{}) + for _, e := range entries { + if _, ok := seen[e.ResourceKey]; !ok { + keys = append(keys, e.ResourceKey) + seen[e.ResourceKey] = struct{}{} + } + } + + // Fetch resources from DB by keys + resources, err := gs.GetByKeys(keys) + if err != nil { + return nil, err + } + + // Convert to []interface{} + result := make([]interface{}, len(resources)) + for i, resource := range resources { + result[i] = resource + } + + return result, nil +} + +func (gs *GormStore) getKeysByIndexes(indexes []index.IndexCondition) ([]string, error) { + if len(indexes) == 0 { + return gs.ListKeys(), nil + } + + var keySet map[string]struct{} + first := true + + for _, condition := range indexes { + var keys []string + var err error + switch condition.Operator { + case index.Equals: + keys, err = gs.IndexKeys(condition.IndexName, condition.Value) + case index.HasPrefix: + keys, err = gs.getKeysByPrefixFromDB(condition.IndexName, condition.Value) + default: + return nil, bizerror.New(bizerror.InvalidArgument, "operator not yet supported: "+string(condition.Operator)) + } + if err != nil { + return nil, err + } + + if first { + keySet = make(map[string]struct{}, len(keys)) + for _, key := range keys { + keySet[key] = struct{}{} + } + first = false + } else { + nextSet := make(map[string]struct{}, len(keys)) + for _, key := range keys { + if _, exists := keySet[key]; exists { + nextSet[key] = struct{}{} + } + } + keySet = nextSet + } + } + + result := make([]string, 0, len(keySet)) + for key := range keySet { + result = append(result, key) + } + + return result, nil +} + +// persistIndexEntriesTx writes index entries for a resource within an existing transaction. +// If oldResource is not nil, first deletes its old entries scoped by resource_kind. +func (gs *GormStore) persistIndexEntriesTx(tx *gorm.DB, resource model.Resource, oldResource model.Resource) error { + if oldResource != nil { + if err := tx.Where("resource_kind = ? AND resource_key = ?", gs.kind.ToString(), oldResource.ResourceKey()). + Delete(&ResourceIndexModel{}).Error; err != nil { + return err + } + } + + indexers := gs.GetIndexers() + var entries []ResourceIndexModel + for indexName, indexFunc := range indexers { + values, err := indexFunc(resource) + if err != nil { + continue + } + for _, v := range values { + entries = append(entries, ResourceIndexModel{ + ResourceKind: gs.kind.ToString(), + IndexName: indexName, + IndexValue: v, + ResourceKey: resource.ResourceKey(), + Operator: string(index.Equals), + }) + } + } + + if len(entries) == 0 { + return nil + } + + return tx.Create(&entries).Error +} + +// backfillIndices rebuilds resource_indices from existing ResourceModel rows. +// Called at Init time so that ListByIndexes works correctly after restarts or upgrades. +func (gs *GormStore) backfillIndices() error { + db := gs.pool.GetDB() + + // Load all existing resources for this kind + var models []ResourceModel + if err := db.Scopes(TableScope(gs.kind.ToString())).Find(&models).Error; err != nil { + return err + } + if len(models) == 0 { + return nil + } + + return db.Transaction(func(tx *gorm.DB) error { + // Drop stale index rows for this kind and rebuild from scratch + if err := tx.Where("resource_kind = ?", gs.kind.ToString()). + Delete(&ResourceIndexModel{}).Error; err != nil { + return err + } + + indexers := gs.GetIndexers() + var entries []ResourceIndexModel + for _, m := range models { + resource, err := m.ToResource() + if err != nil { + logger.Warnf("backfillIndices: failed to deserialize resource %s: %v", m.ResourceKey, err) + continue + } + for indexName, indexFunc := range indexers { + values, err := indexFunc(resource) + if err != nil { + continue + } + for _, v := range values { + entries = append(entries, ResourceIndexModel{ + ResourceKind: gs.kind.ToString(), + IndexName: indexName, + IndexValue: v, + ResourceKey: resource.ResourceKey(), + Operator: string(index.Equals), + }) + } + } + } + + if len(entries) == 0 { + return nil + } + return tx.CreateInBatches(&entries, 100).Error + }) +} + +// getKeysByPrefixFromDB retrieves resource keys matching a prefix from the database +func (gs *GormStore) getKeysByPrefixFromDB(indexName, prefix string) ([]string, error) { + db := gs.pool.GetDB() + var entries []ResourceIndexModel + err := db.Where("resource_kind = ? AND index_name = ? AND index_value LIKE ?", + gs.kind.ToString(), indexName, prefix+"%"). + Find(&entries).Error + if err != nil { + return nil, err + } + + keys := make([]string, 0, len(entries)) + seen := make(map[string]struct{}) + for _, e := range entries { + if _, ok := seen[e.ResourceKey]; !ok { + keys = append(keys, e.ResourceKey) + seen[e.ResourceKey] = struct{}{} + } + } + return keys, nil +} + +// IndexExists checks if an indexer with the given name exists +func (gs *GormStore) IndexExists(indexName string) bool { + gs.mu.RLock() + defer gs.mu.RUnlock() + _, exists := gs.indexers[indexName] + return exists +} + +// Pool returns the connection pool for this store +// Used by other components (e.g., leader election) that need direct DB access +// Returns interface{} to satisfy the poolProvider interface in pkg/core/store +func (gs *GormStore) Pool() interface{} { + return gs.pool +} diff --git a/pkg/store/dbcommon/gorm_store_test.go b/pkg/store/dbcommon/gorm_store_test.go new file mode 100644 index 000000000..b1dd1b8c6 --- /dev/null +++ b/pkg/store/dbcommon/gorm_store_test.go @@ -0,0 +1,1692 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbcommon + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gorm.io/driver/sqlite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +// mockResource is a mock implementation of model.Resource for testing +type mockResource struct { + Kind model.ResourceKind `json:"kind"` + Key string `json:"key"` + Mesh string `json:"mesh"` + Meta metav1.ObjectMeta `json:"meta"` + Spec model.ResourceSpec `json:"spec"` + ObjectRef runtime.Object `json:"-"` +} + +func (mr *mockResource) GetObjectKind() schema.ObjectKind { + return schema.EmptyObjectKind +} + +func (mr *mockResource) DeepCopyObject() runtime.Object { + return mr.ObjectRef +} + +func (mr *mockResource) ResourceKind() model.ResourceKind { + return mr.Kind +} + +func (mr *mockResource) ResourceKey() string { + return mr.Key +} + +func (mr *mockResource) MeshName() string { + return mr.Mesh +} + +func (mr *mockResource) ResourceMeta() metav1.ObjectMeta { + return mr.Meta +} + +func (mr *mockResource) ResourceSpec() model.ResourceSpec { + return mr.Spec +} + +func (mr *mockResource) ResourceMesh() string { + return mr.Mesh +} + +func (mr *mockResource) String() string { + b, err := json.Marshal(mr) + if err != nil { + return "" + } + return string(b) +} + +type mockResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []*mockResource `json:"items"` +} + +func (m mockResourceList) DeepCopyObject() runtime.Object { + out := &mockResourceList{ + TypeMeta: m.TypeMeta, + } + m.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(m.Items) == 0 { + return out + } + out.Items = make([]*mockResource, len(m.Items)) + for i := range m.Items { + out.Items[i] = m.Items[i].DeepCopyObject().(*mockResource) + } + return out +} + +func (m mockResourceList) SetItems(items []model.Resource) { + m.Items = make([]*mockResource, len(items)) + for i := range items { + m.Items[i] = items[i].(*mockResource) + } +} + +// setupTestStore creates a new GormStore with an in-memory SQLite database for testing +func setupTestStore(t *testing.T) (*GormStore, func()) { + // Create temporary SQLite database file for better isolation and reliability + tmpFile, err := os.CreateTemp("", fmt.Sprintf("test-db-%s-*.db", t.Name())) + require.NoError(t, err) + dbPath := tmpFile.Name() + tmpFile.Close() + + dialector := sqlite.Open(dbPath) + pool, err := NewConnectionPool(dialector, storecfg.MySQL, t.Name(), DefaultConnectionPoolConfig()) + require.NoError(t, err) + + // Register the mock resource type (only once) + kind := model.ResourceKind("TestResource") + if _, err := model.ResourceSchemaRegistry().NewResourceFunc(kind); err != nil { + model.RegisterResourceSchema(kind, func() model.Resource { + return &mockResource{Kind: kind} + }, func() model.ResourceList { + return &mockResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: kind.ToString(), + }, + Items: []*mockResource{}, + } + }) + } + + store := NewGormStore(kind, t.Name(), pool) + + // Cleanup function + cleanup := func() { + pool.Close() + os.Remove(dbPath) + } + + return store, cleanup +} + +func TestNewGormStore(t *testing.T) { + dialector := sqlite.Open("file::memory:?cache=shared") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer func(pool *ConnectionPool) { + err := pool.Close() + if err != nil { + return + } + }(pool) + + kind := model.ResourceKind("TestResource") + store := NewGormStore(kind, "test-address", pool) + + assert.NotNil(t, store) + assert.Equal(t, kind, store.kind) + assert.Equal(t, "test-address", store.address) + assert.NotNil(t, store.pool) + assert.NotNil(t, store.indexers) + assert.NotNil(t, store.stopCh) +} + +func TestGormStore_Init(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + assert.NoError(t, err) + + // Verify table was created by attempting to add a resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "init-test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "init-test"}, + } + err = store.Add(mockRes) + assert.NoError(t, err, "Should be able to add resource after Init") +} + +func TestGormStore_AddAndGet(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + assert.NoError(t, err) + + // Get the resource + item, exists, err := store.Get(mockRes) + assert.NoError(t, err) + assert.True(t, exists) + assert.NotNil(t, item) + + // Verify the resource content + retrieved := item.(*mockResource) + assert.Equal(t, mockRes.ResourceKey(), retrieved.ResourceKey()) + assert.Equal(t, mockRes.MeshName(), retrieved.MeshName()) + assert.Equal(t, mockRes.ResourceMeta().Name, retrieved.ResourceMeta().Name) + + // Get by key + item, exists, err = store.GetByKey("test-key") + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, mockRes.ResourceKey(), item.(model.Resource).ResourceKey()) +} + +func TestGormStore_AddDuplicate(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + assert.NoError(t, err) + + // Try to add the same resource again + err = store.Add(mockRes) + assert.Error(t, err) + assert.Contains(t, err.Error(), "already exists") +} + +func TestGormStore_AddWrongKind(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create a resource with different kind + mockRes := &mockResource{ + Kind: "DifferentKind", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + }, + } + + err = store.Add(mockRes) + assert.Error(t, err) + assert.Contains(t, err.Error(), "resource kind mismatch") +} + +func TestGormStore_Update(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + require.NoError(t, err) + + // Update the resource + updatedRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "updated-resource", + Namespace: "default", + }, + } + + err = store.Update(updatedRes) + assert.NoError(t, err) + + // Get the updated resource + item, exists, err := store.Get(updatedRes) + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, "updated-resource", item.(*mockResource).ResourceMeta().Name) +} + +func TestGormStore_UpdateNonExistent(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + mockRes := &mockResource{ + Kind: "TestResource", + Key: "non-existent-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + }, + } + + err = store.Update(mockRes) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestGormStore_Delete(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + require.NoError(t, err) + + // Delete the resource + err = store.Delete(mockRes) + assert.NoError(t, err) + + // Try to get the deleted resource + _, exists, err := store.Get(mockRes) + assert.NoError(t, err) + assert.False(t, exists) +} + +func TestGormStore_DeleteNonExistent(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + mockRes := &mockResource{ + Kind: "TestResource", + Key: "non-existent-key", + Mesh: "default", + Meta: metav1.ObjectMeta{ + Name: "test-resource", + }, + } + + err = store.Delete(mockRes) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestGormStore_List(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + + // List resources + list := store.List() + assert.Len(t, list, 2) + + // Verify resource keys are present + keys := make([]string, len(list)) + for i, item := range list { + keys[i] = item.(model.Resource).ResourceKey() + } + assert.Contains(t, keys, "test-key-1") + assert.Contains(t, keys, "test-key-2") +} + +func TestGormStore_ListKeys(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + + // List keys + keys := store.ListKeys() + assert.Len(t, keys, 2) + assert.Contains(t, keys, "test-key-1") + assert.Contains(t, keys, "test-key-2") +} + +func TestGormStore_Replace(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create initial mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add initial resource + err = store.Add(mockRes1) + require.NoError(t, err) + + // Replace with new set of resources + newResources := []interface{}{mockRes2} + err = store.Replace(newResources, "version-1") + assert.NoError(t, err) + + // Check that only the new resource exists + keys := store.ListKeys() + assert.Len(t, keys, 1) + assert.Contains(t, keys, "test-key-2") + assert.NotContains(t, keys, "test-key-1") +} + +func TestGormStore_ReplaceEmpty(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add a resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Replace with empty list + err = store.Replace([]interface{}{}, "version-1") + assert.NoError(t, err) + + // Check that all resources are removed + keys := store.ListKeys() + assert.Len(t, keys, 0) +} + +func TestGormStore_GetByKeys(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + + // Get by multiple keys + keys := []string{"test-key-1", "test-key-2", "test-key-3"} + resources, err := store.GetByKeys(keys) + assert.NoError(t, err) + assert.Len(t, resources, 2) + + // Verify resource keys + resKeys := make([]string, len(resources)) + for i, res := range resources { + resKeys[i] = res.ResourceKey() + } + assert.Contains(t, resKeys, "test-key-1") + assert.Contains(t, resKeys, "test-key-2") +} + +func TestGormStore_GetByKeysEmpty(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + resources, err := store.GetByKeys([]string{}) + assert.NoError(t, err) + assert.Len(t, resources, 0) +} + +func TestGormStore_AddIndexers(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Verify indexers were added + storedIndexers := store.GetIndexers() + assert.Len(t, storedIndexers, 1) + assert.Contains(t, storedIndexers, "by-mesh") +} + +func TestGormStore_IndexKeys(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-2", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "mesh2/test-key-3", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "test-resource-3"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + err = store.Add(mockRes3) + require.NoError(t, err) + + // Test IndexKeys method + keys, err := store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.Len(t, keys, 2) + assert.Contains(t, keys, "mesh1/test-key-1") + assert.Contains(t, keys, "mesh1/test-key-2") + + keys, err = store.IndexKeys("by-mesh", "mesh2") + assert.NoError(t, err) + assert.Len(t, keys, 1) + assert.Contains(t, keys, "mesh2/test-key-3") +} + +func TestGormStore_ByIndex(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-name": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMeta().Name}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-a"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-b"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + + // Test ByIndex method + items, err := store.ByIndex("by-name", "resource-a") + assert.NoError(t, err) + assert.Len(t, items, 1) + assert.Equal(t, "test-key-1", items[0].(model.Resource).ResourceKey()) + + items, err = store.ByIndex("by-name", "resource-b") + assert.NoError(t, err) + assert.Len(t, items, 1) + assert.Equal(t, "test-key-2", items[0].(model.Resource).ResourceKey()) +} + +func TestGormStore_ListByIndexes(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-2", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "mesh2/test-key-3", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "test-resource-3"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + err = store.Add(mockRes3) + require.NoError(t, err) + + // List by indexes + indexes := []index.IndexCondition{{IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}} + resources, err := store.ListByIndexes(indexes) + assert.NoError(t, err) + assert.Len(t, resources, 2) + // Should be sorted by ResourceKey + assert.Equal(t, "mesh1/test-key-1", resources[0].ResourceKey()) + assert.Equal(t, "mesh1/test-key-2", resources[1].ResourceKey()) +} + +func TestGormStore_ListByIndexesEmpty(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add some resources + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // List with empty indexes should return all resources + resources, err := store.ListByIndexes([]index.IndexCondition{}) + assert.NoError(t, err) + assert.Len(t, resources, 1) +} + +func TestGormStore_PageListByIndexes(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-2", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/test-key-3", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-3"}, + } + + // Add resources + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + err = store.Add(mockRes3) + require.NoError(t, err) + + // Page list by indexes + indexes := []index.IndexCondition{{IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}} + pageReq := model.PageReq{ + PageOffset: 0, + PageSize: 2, + } + pageData, err := store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + // Total 3 resources + assert.Equal(t, 3, pageData.Total) + // Page offset 0 + assert.Equal(t, 0, pageData.PageOffset) + // Page size 2 + assert.Equal(t, 2, pageData.PageSize) + // 2 items in this page + assert.Len(t, pageData.Data, 2) + // Sorted by key + assert.Equal(t, "mesh1/test-key-1", pageData.Data[0].ResourceKey()) + assert.Equal(t, "mesh1/test-key-2", pageData.Data[1].ResourceKey()) + + // Second page + pageReq.PageOffset = 2 + pageData, err = store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + // Total still 3 + assert.Equal(t, 3, pageData.Total) + // Page offset 2 + assert.Equal(t, 2, pageData.PageOffset) + // Page size 2 + assert.Equal(t, 2, pageData.PageSize) + // Only 1 item left + assert.Len(t, pageData.Data, 1) + // Last item + assert.Equal(t, "mesh1/test-key-3", pageData.Data[0].ResourceKey()) +} + +func TestGormStore_PageListByIndexesOffsetBeyondTotal(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Add one resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Request page beyond total + indexes := []index.IndexCondition{{IndexName: "by-mesh", Value: "default", Operator: index.Equals}} + pageReq := model.PageReq{ + PageOffset: 10, + PageSize: 2, + } + pageData, err := store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + assert.Equal(t, 1, pageData.Total) + assert.Len(t, pageData.Data, 0) +} + +func TestGormStore_MultipleIndexes(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexers for multiple fields + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + "by-namespace": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMeta().Namespace}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/default/app1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{ + Name: "app1", + Namespace: "default", + }, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/default/app2", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{ + Name: "app2", + Namespace: "default", + }, + } + + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/custom/app3", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{ + Name: "app3", + Namespace: "custom", + }, + } + + mockRes4 := &mockResource{ + Kind: "TestResource", + Key: "mesh2/default/app4", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{ + Name: "app4", + Namespace: "default", + }, + } + + // Add resources + resources := []model.Resource{mockRes1, mockRes2, mockRes3, mockRes4} + for _, res := range resources { + err = store.Add(res) + require.NoError(t, err) + } + + // Test multiple indexes - get all resources in mesh1 and default namespace + indexes := []index.IndexCondition{ + {IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}, + {IndexName: "by-namespace", Value: "default", Operator: index.Equals}, + } + result, err := store.ListByIndexes(indexes) + assert.NoError(t, err) + assert.Len(t, result, 2) + + // Should contain app1 and app2 + keys := make([]string, len(result)) + for i, res := range result { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "mesh1/default/app1") + assert.Contains(t, keys, "mesh1/default/app2") +} + +func TestGormStore_ListIndexFuncValues(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create mock resources with different meshes + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/resource1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "resource1"}, + } + + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "mesh2/resource2", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "resource2"}, + } + + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "mesh1/resource3", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "resource3"}, + } + + // Add resources + resources := []model.Resource{mockRes1, mockRes2, mockRes3} + for _, res := range resources { + err = store.Add(res) + require.NoError(t, err) + } + + // Test ListIndexFuncValues method + values := store.ListIndexFuncValues("by-mesh") + assert.Len(t, values, 2) + assert.Contains(t, values, "mesh1") + assert.Contains(t, values, "mesh2") +} + +func TestGormStore_IndexNonExistent(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + + // Try to use non-existent index + _, err = store.IndexKeys("non-existent-index", "value") + assert.Error(t, err) + assert.Contains(t, err.Error(), "does not exist") + + _, err = store.ByIndex("non-existent-index", "value") + assert.Error(t, err) + assert.Contains(t, err.Error(), "does not exist") + + _, err = store.Index("non-existent-index", mockRes) + assert.Error(t, err) + assert.Contains(t, err.Error(), "does not exist") +} + +func TestGormStore_UpdateIndices(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create and add initial resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Verify initial index + keys, err := store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.Contains(t, keys, "test-key") + + // Update resource with different mesh + updatedRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Update(updatedRes) + require.NoError(t, err) + + // Verify index was updated + keys, err = store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.NotContains(t, keys, "test-key") + + keys, err = store.IndexKeys("by-mesh", "mesh2") + assert.NoError(t, err) + assert.Contains(t, keys, "test-key") +} + +func TestGormStore_DeleteFromIndices(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create and add resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Verify initial index + keys, err := store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.Contains(t, keys, "test-key") + + // Delete resource + err = store.Delete(mockRes) + require.NoError(t, err) + + // Verify index was updated + keys, err = store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.NotContains(t, keys, "test-key") +} + +func TestGormStore_ReplaceIndices(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Add initial resources + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + err = store.Add(mockRes1) + require.NoError(t, err) + + // Replace with new resources + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "test-key-2", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + err = store.Replace([]interface{}{mockRes2}, "version-1") + require.NoError(t, err) + + // Verify indices were cleared and rebuilt + keys, err := store.IndexKeys("by-mesh", "mesh1") + assert.NoError(t, err) + assert.Len(t, keys, 0) + + keys, err = store.IndexKeys("by-mesh", "mesh2") + assert.NoError(t, err) + assert.Contains(t, keys, "test-key-2") +} + +func TestGormStore_Resync(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Resync should return nil (no-op for database stores) + err = store.Resync() + assert.NoError(t, err) +} + +func TestGormStore_TransactionRollback(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add initial resource + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "test-key-1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + err = store.Add(mockRes1) + require.NoError(t, err) + + // Try to replace with invalid resource (wrong type) + // This should cause transaction rollback + invalidList := []interface{}{"not-a-resource"} + err = store.Replace(invalidList, "version-1") + assert.Error(t, err) + + // Verify original resource still exists (transaction was rolled back) + keys := store.ListKeys() + assert.Len(t, keys, 1) + assert.Contains(t, keys, "test-key-1") +} + +func TestGormStore_ConcurrentOperations(t *testing.T) { + // Use WAL mode for better concurrent write support in SQLite + dialector := sqlite.Open("file::memory:?cache=shared&_journal_mode=WAL") + pool, err := NewConnectionPool(dialector, storecfg.MySQL, "test-address", DefaultConnectionPoolConfig()) + require.NoError(t, err) + defer pool.Close() + + // Register the mock resource type + kind := model.ResourceKind("TestResource") + model.RegisterResourceSchema(kind, func() model.Resource { + return &mockResource{Kind: kind} + }, func() model.ResourceList { + return &mockResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: kind.ToString(), + }, + Items: []*mockResource{}, + } + }) + + store := NewGormStore(kind, "test-address", pool) + err = store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Perform concurrent Add operations with less concurrency for SQLite + const numGoroutines = 5 + done := make(chan error, numGoroutines) + + for i := 0; i < numGoroutines; i++ { + go func(index int) { + mockRes := &mockResource{ + Kind: "TestResource", + Key: string(rune('a' + index)), + Mesh: "default", + Meta: metav1.ObjectMeta{Name: string(rune('a' + index))}, + } + done <- store.Add(mockRes) + }(i) + } + + // Wait for all goroutines to complete and check for errors + successCount := 0 + for i := 0; i < numGoroutines; i++ { + if err := <-done; err == nil { + successCount++ + } + } + + // Due to SQLite concurrency limitations, at least some operations should succeed + assert.Greater(t, successCount, 0, "At least some concurrent operations should succeed") + + // Verify resources were added + keys := store.ListKeys() + assert.Greater(t, len(keys), 0, "Should have added some resources") + assert.LessOrEqual(t, len(keys), numGoroutines, "Should not have more resources than goroutines") +} + +func TestGormStore_GetNonExistent(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + mockRes := &mockResource{ + Kind: "TestResource", + Key: "non-existent-key", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "non-existent"}, + } + + item, exists, err := store.Get(mockRes) + assert.NoError(t, err) + assert.False(t, exists) + assert.Nil(t, item) +} + +func TestGormStore_GetByKeyNonExistent(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + item, exists, err := store.GetByKey("non-existent-key") + assert.NoError(t, err) + assert.False(t, exists) + assert.Nil(t, item) +} + +func TestGormStore_InvalidResourceType(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Try to add invalid type + err = store.Add("not-a-resource") + assert.Error(t, err) + + // Try to update invalid type + err = store.Update("not-a-resource") + assert.Error(t, err) + + // Try to delete invalid type + err = store.Delete("not-a-resource") + assert.Error(t, err) + + // Try to get invalid type + _, _, err = store.Get("not-a-resource") + assert.Error(t, err) +} + +func TestGormStore_IndexPersistence(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer for IP addresses + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + // Simulate an IP address from the resource key + return []string{resource.ResourceKey()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create and add resources with IP-like keys + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "192.168.1.1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-1"}, + } + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "192.168.1.2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-2"}, + } + + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + + // Verify indices are persisted to resource_indices table + db := store.pool.GetDB() + var count int64 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND index_name = ?", "TestResource", "by-ip"). + Count(&count).Error + assert.NoError(t, err) + assert.Equal(t, int64(2), count, "Both index entries should be persisted to resource_indices table") + + // Verify operator field is set to "Equals" + var entries []ResourceIndexModel + err = db.Where("resource_kind = ? AND index_name = ?", "TestResource", "by-ip"). + Find(&entries).Error + assert.NoError(t, err) + for _, entry := range entries { + assert.Equal(t, "Equals", entry.Operator, "Operator field should be set to Equals") + } +} + +func TestGormStore_ListByIndexes_HasPrefix(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer for IP addresses + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceKey()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create resources with IP-like keys + mockRes1 := &mockResource{ + Kind: "TestResource", + Key: "192.168.1.1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-1"}, + } + mockRes2 := &mockResource{ + Kind: "TestResource", + Key: "192.168.1.2", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-2"}, + } + mockRes3 := &mockResource{ + Kind: "TestResource", + Key: "10.0.0.1", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "resource-3"}, + } + + err = store.Add(mockRes1) + require.NoError(t, err) + err = store.Add(mockRes2) + require.NoError(t, err) + err = store.Add(mockRes3) + require.NoError(t, err) + + // Query with HasPrefix operator + indexes := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168", Operator: index.HasPrefix}, + } + resources, err := store.ListByIndexes(indexes) + assert.NoError(t, err) + assert.Len(t, resources, 2) + + // Verify the correct resources were returned + keys := make([]string, len(resources)) + for i, res := range resources { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "192.168.1.1") + assert.Contains(t, keys, "192.168.1.2") + assert.NotContains(t, keys, "10.0.0.1") +} + +func TestGormStore_PageListByIndexes_HasPrefix(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer for IP addresses + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceKey()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create resources with IP-like keys + for i := 1; i <= 5; i++ { + mockRes := &mockResource{ + Kind: "TestResource", + Key: fmt.Sprintf("192.168.1.%d", i), + Mesh: "default", + Meta: metav1.ObjectMeta{Name: fmt.Sprintf("resource-%d", i)}, + } + err = store.Add(mockRes) + require.NoError(t, err) + } + + // Query with HasPrefix operator and pagination + indexes := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168", Operator: index.HasPrefix}, + } + pageReq := model.PageReq{ + PageOffset: 0, + PageSize: 2, + } + pageData, err := store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + assert.Equal(t, 5, pageData.Total) + assert.Len(t, pageData.Data, 2) + + // Verify second page + pageReq.PageOffset = 2 + pageData, err = store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + assert.Equal(t, 5, pageData.Total) + assert.Len(t, pageData.Data, 2) + + // Verify last page + pageReq.PageOffset = 4 + pageData, err = store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + assert.Equal(t, 5, pageData.Total) + assert.Len(t, pageData.Data, 1) +} + +func TestGormStore_DeleteIndex_RemovesFromDB(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-name": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMeta().Name}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create and add resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "default", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Verify index entry exists in DB + db := store.pool.GetDB() + var count int64 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND resource_key = ?", "TestResource", "test-key"). + Count(&count).Error + assert.NoError(t, err) + assert.Greater(t, count, int64(0), "Index entry should exist after Add") + + // Delete the resource + err = store.Delete(mockRes) + require.NoError(t, err) + + // Verify index entry is removed from DB + count = 0 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND resource_key = ?", "TestResource", "test-key"). + Count(&count).Error + assert.NoError(t, err) + assert.Equal(t, int64(0), count, "Index entry should be removed after Delete") +} + +func TestGormStore_UpdateIndex_UpdatesInDB(t *testing.T) { + store, cleanup := setupTestStore(t) + defer cleanup() + + err := store.Init(nil) + require.NoError(t, err) + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + require.NoError(t, err) + + // Create and add resource + mockRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "mesh1", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Add(mockRes) + require.NoError(t, err) + + // Verify initial index entry in DB + db := store.pool.GetDB() + var count int64 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND resource_key = ? AND index_value = ?", "TestResource", "test-key", "mesh1"). + Count(&count).Error + assert.NoError(t, err) + assert.Equal(t, int64(1), count, "Initial index entry should exist") + + // Update resource with different mesh + updatedRes := &mockResource{ + Kind: "TestResource", + Key: "test-key", + Mesh: "mesh2", + Meta: metav1.ObjectMeta{Name: "test-resource"}, + } + err = store.Update(updatedRes) + require.NoError(t, err) + + // Verify old index entry is removed + count = 0 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND resource_key = ? AND index_value = ?", "TestResource", "test-key", "mesh1"). + Count(&count).Error + assert.NoError(t, err) + assert.Equal(t, int64(0), count, "Old index entry should be removed") + + // Verify new index entry exists + count = 0 + err = db.Model(&ResourceIndexModel{}). + Where("resource_kind = ? AND resource_key = ? AND index_value = ?", "TestResource", "test-key", "mesh2"). + Count(&count).Error + assert.NoError(t, err) + assert.Equal(t, int64(1), count, "New index entry should exist") +} diff --git a/pkg/store/dbcommon/model.go b/pkg/store/dbcommon/model.go new file mode 100644 index 000000000..4bdecc137 --- /dev/null +++ b/pkg/store/dbcommon/model.go @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbcommon + +import ( + "encoding/json" + "strings" + "time" + "unicode" + + "gorm.io/gorm" + + "github.com/apache/dubbo-admin/pkg/core/resource/model" +) + +// ResourceModel is the database model for storing Dubbo resources +// It uses dynamic table naming based on ResourceKind to improve query performance +// Note: TableName() method is intentionally removed as GORM caches it. +// Use TableScope() instead for dynamic table names. +type ResourceModel struct { + ID uint `gorm:"primarykey"` // Auto-incrementing primary key + ResourceKey string `gorm:"type:varchar(255);uniqueIndex;not null"` // Unique identifier for the resource + ResourceKind string `gorm:"not null"` // Type of resource (e.g., "Application", "ServiceProviderMapping") + Name string `gorm:"index;not null"` // Resource name, indexed for fast lookups + Mesh string `gorm:"index;not null"` // Mesh identifier, indexed for filtering by mesh + Data []byte `gorm:"type:text;not null"` // JSON-encoded resource data + CreatedAt time.Time `gorm:"autoCreateTime"` // Automatically set on creation + UpdatedAt time.Time `gorm:"autoUpdateTime"` // Automatically updated on modification +} + +// TableNameForKind returns the table name for a given ResourceKind +// Uses dynamic table naming: each ResourceKind gets its own table +// e.g., "Application" -> "resources_application", "ServiceProviderMapping" -> "resources_service_provider_mapping" +func TableNameForKind(kind string) string { + if kind == "" { + return "resources" + } + // Convert ResourceKind to snake_case table name with "resources_" prefix + return "resources_" + toSnakeCase(kind) +} + +// TableScope returns a GORM scope function that sets the table name dynamically +// This is the recommended approach for dynamic table names as TableName() is cached by GORM +// Usage: db.Scopes(TableScope(kind)).Find(&models) +func TableScope(kind string) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Table(TableNameForKind(kind)) + } +} + +// toSnakeCase converts a string to snake_case +// e.g., "ServiceProviderMapping" -> "service_provider_mapping", "RPCInstance" -> "rpc_instance" +func toSnakeCase(s string) string { + var result strings.Builder + runes := []rune(s) + + for i := 0; i < len(runes); i++ { + r := runes[i] + + if unicode.IsUpper(r) { + // Add underscore before uppercase letter if: + // 1. Not at the beginning + // 2. Previous char is lowercase or + // 3. Next char exists and is lowercase (for handling acronyms like "RPCInstance") + if i > 0 { + prevIsLower := unicode.IsLower(runes[i-1]) + nextIsLower := i+1 < len(runes) && unicode.IsLower(runes[i+1]) + + if prevIsLower || nextIsLower { + result.WriteRune('_') + } + } + result.WriteRune(unicode.ToLower(r)) + } else { + result.WriteRune(r) + } + } + return result.String() +} + +// ToResource converts the database model back to a Resource object +// Unmarshals the JSON data and returns the typed resource +func (rm *ResourceModel) ToResource() (model.Resource, error) { + newFunc, err := model.ResourceSchemaRegistry().NewResourceFunc(model.ResourceKind(rm.ResourceKind)) + if err != nil { + return nil, err + } + resource := newFunc() + if err := json.Unmarshal(rm.Data, resource); err != nil { + return nil, err + } + return resource, nil +} + +// FromResource converts a Resource object to a database model +// Marshals the resource to JSON and populates the model fields +func FromResource(resource model.Resource) (*ResourceModel, error) { + data, err := json.Marshal(resource) + if err != nil { + return nil, err + } + + return &ResourceModel{ + ResourceKey: resource.ResourceKey(), + ResourceKind: resource.ResourceKind().ToString(), + Name: resource.ResourceMeta().Name, + Mesh: resource.ResourceMesh(), + Data: data, + }, nil +} + +// ResourceIndexModel represents a persisted index entry in the database +// This table stores index mappings to enable prefix queries and provide index persistence +// across multiple replicas in distributed deployments +// Table: resource_indices (shared across all resource kinds) +type ResourceIndexModel struct { + ID uint `gorm:"primarykey"` // Auto-incrementing primary key + ResourceKind string `gorm:"type:varchar(64);not null;index:idx_kind_name_value"` // Resource kind (e.g., "Instance") + IndexName string `gorm:"type:varchar(128);not null;index:idx_kind_name_value"` // Index name (e.g., "idx_instance_ip") + IndexValue string `gorm:"type:varchar(255);not null;index:idx_kind_name_value"` // Indexed value (e.g., "192.168.1.1") + ResourceKey string `gorm:"type:varchar(255);not null;index:idx_resource_key"` // Resource unique key + Operator string `gorm:"type:varchar(32);not null;default:Equals"` // Index operator type, e.g., Equals, HasPrefix +} + +// TableName specifies the table name for ResourceIndexModel +// Unlike ResourceModel which uses dynamic per-kind tables, resource_indices is a shared global table +func (ResourceIndexModel) TableName() string { + return "resource_indices" +} diff --git a/pkg/core/cmd/util.go b/pkg/store/memory/factory.go similarity index 59% rename from pkg/core/cmd/util.go rename to pkg/store/memory/factory.go index 3e8e27ceb..3e53f2945 100644 --- a/pkg/core/cmd/util.go +++ b/pkg/store/memory/factory.go @@ -15,21 +15,26 @@ * limitations under the License. */ -package cmd +package memory import ( - "context" - - "github.com/apache/dubbo-admin/pkg/core" + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" ) -type RunCmdOpts struct { - // The first returned context is closed upon receiving first signal (SIGSTOP, SIGTERM). - // The second returned context is closed upon receiving second signal. - // We can start graceful shutdown when first context is closed and forcefully stop when the second one is closed. - SetupSignalHandler func() (context.Context, context.Context) +func init() { + store.RegisterFactory(&storeFactory{}) +} + +type storeFactory struct{} + +var _ store.Factory = &storeFactory{} + +func (sf *storeFactory) Support(s storecfg.Type) bool { + return s == storecfg.Memory } -var DefaultRunCmdOpts = RunCmdOpts{ - SetupSignalHandler: core.SetupSignalHandler, +func (sf *storeFactory) New(rk coremodel.ResourceKind, _ *storecfg.Config) (store.ManagedResourceStore, error) { + return NewMemoryResourceStore(rk), nil } diff --git a/pkg/store/memory/memory.go b/pkg/store/memory/memory.go deleted file mode 100644 index cff9dd2cf..000000000 --- a/pkg/store/memory/memory.go +++ /dev/null @@ -1,5 +0,0 @@ -package memory - -import _ "k8s.io/client-go/tools/cache" - -// TODO implement memory resource store, refer to client-go cache.Store diff --git a/pkg/store/memory/store.go b/pkg/store/memory/store.go new file mode 100644 index 000000000..0b392bd58 --- /dev/null +++ b/pkg/store/memory/store.go @@ -0,0 +1,367 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package memory + +import ( + "fmt" + "reflect" + "sort" + "strings" + "sync" + + "github.com/armon/go-radix" + set "github.com/duke-git/lancet/v2/datastructure/set" + "github.com/duke-git/lancet/v2/slice" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/common/bizerror" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/runtime" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +type resourceStore struct { + rk coremodel.ResourceKind + storeProxy cache.Indexer + prefixTrees map[string]*radix.Tree + treesMu sync.RWMutex +} + +var _ store.ManagedResourceStore = &resourceStore{} + +func NewMemoryResourceStore(rk coremodel.ResourceKind) store.ManagedResourceStore { + return &resourceStore{rk: rk} +} + +func (rs *resourceStore) Init(_ runtime.BuilderContext) error { + indexers := index.IndexersRegistry().Indexers(rs.rk) + rs.storeProxy = cache.NewIndexer( + func(obj interface{}) (string, error) { + r, ok := obj.(coremodel.Resource) + if !ok { + return "", bizerror.NewAssertionError("Resource", reflect.TypeOf(obj).Name()) + } + return r.ResourceKey(), nil + }, + indexers, + ) + // Initialize RadixTree for each index for prefix matching support + rs.prefixTrees = make(map[string]*radix.Tree) + for indexName := range indexers { + rs.prefixTrees[indexName] = radix.New() + } + return nil +} + +func (rs *resourceStore) Start(_ runtime.Runtime, _ <-chan struct{}) error { + return nil +} + +func (rs *resourceStore) Add(obj interface{}) error { + if err := rs.storeProxy.Add(obj); err != nil { + return err + } + r, ok := obj.(coremodel.Resource) + if ok { + rs.addToTrees(r) + } + return nil +} + +func (rs *resourceStore) Update(obj interface{}) error { + r, ok := obj.(coremodel.Resource) + var oldRes coremodel.Resource + if ok { + // Fetch old resource before mutating the store + oldObj, exists, err := rs.storeProxy.Get(r) + if exists && err == nil { + oldRes, _ = oldObj.(coremodel.Resource) + } + } + if err := rs.storeProxy.Update(obj); err != nil { + return err + } + // Only mutate trees after a successful store update + if ok { + if oldRes != nil { + rs.removeFromTrees(oldRes) + } + rs.addToTrees(r) + } + return nil +} + +func (rs *resourceStore) Delete(obj interface{}) error { + if err := rs.storeProxy.Delete(obj); err != nil { + return err + } + if r, ok := obj.(coremodel.Resource); ok { + rs.removeFromTrees(r) + } + return nil +} + +func (rs *resourceStore) List() []interface{} { + return rs.storeProxy.List() +} + +func (rs *resourceStore) ListKeys() []string { + return rs.storeProxy.ListKeys() +} + +func (rs *resourceStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return rs.storeProxy.Get(obj) +} + +func (rs *resourceStore) GetByKey(key string) (item interface{}, exists bool, err error) { + return rs.storeProxy.GetByKey(key) +} + +func (rs *resourceStore) Replace(i []interface{}, s string) error { + // Clear all trees before replace + rs.treesMu.Lock() + for indexName := range rs.prefixTrees { + rs.prefixTrees[indexName] = radix.New() + } + rs.treesMu.Unlock() + + if err := rs.storeProxy.Replace(i, s); err != nil { + return err + } + + // Add all new resources to trees + for _, obj := range i { + r, ok := obj.(coremodel.Resource) + if ok { + rs.addToTrees(r) + } + } + return nil +} + +func (rs *resourceStore) Resync() error { + return rs.storeProxy.Resync() +} + +func (rs *resourceStore) Index(indexName string, obj interface{}) ([]interface{}, error) { + return rs.storeProxy.Index(indexName, obj) +} + +func (rs *resourceStore) IndexKeys(indexName, indexedValue string) ([]string, error) { + return rs.storeProxy.IndexKeys(indexName, indexedValue) +} + +func (rs *resourceStore) ListIndexFuncValues(indexName string) []string { + return rs.storeProxy.ListIndexFuncValues(indexName) +} + +func (rs *resourceStore) ByIndex(indexName, indexedValue string) ([]interface{}, error) { + return rs.storeProxy.ByIndex(indexName, indexedValue) +} + +func (rs *resourceStore) GetIndexers() cache.Indexers { + return rs.storeProxy.GetIndexers() +} + +func (rs *resourceStore) AddIndexers(newIndexers cache.Indexers) error { + rs.treesMu.Lock() + defer rs.treesMu.Unlock() + + if err := rs.storeProxy.AddIndexers(newIndexers); err != nil { + return err + } + + // Add RadixTrees for new indexers + for indexName := range newIndexers { + if _, exists := rs.prefixTrees[indexName]; !exists { + rs.prefixTrees[indexName] = radix.New() + } + } + return nil +} + +func (rs *resourceStore) GetByKeys(keys []string) ([]coremodel.Resource, error) { + resources := make([]coremodel.Resource, 0) + for _, key := range keys { + r, exists, err := rs.storeProxy.GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + continue + } + res, ok := r.(coremodel.Resource) + if !ok { + return nil, bizerror.NewAssertionError("Resource", reflect.TypeOf(r).Name()) + } + resources = append(resources, res) + } + return resources, nil +} + +func (rs *resourceStore) ListByIndexes(indexes []index.IndexCondition) ([]coremodel.Resource, error) { + keys, err := rs.getKeysByIndexes(indexes) + if err != nil { + return nil, err + } + resources, err := rs.GetByKeys(keys) + if err != nil { + return nil, err + } + slice.SortBy(resources, func(r1 coremodel.Resource, r2 coremodel.Resource) bool { + return r1.ResourceKey() < r2.ResourceKey() + }) + return resources, nil +} + +func (rs *resourceStore) PageListByIndexes(indexes []index.IndexCondition, pq coremodel.PageReq) (*coremodel.PageData[coremodel.Resource], error) { + keys, err := rs.getKeysByIndexes(indexes) + if err != nil { + return nil, err + } + sort.Strings(keys) + total := len(keys) + resources := make([]coremodel.Resource, 0, pq.PageSize) + for i := pq.PageOffset; len(resources) < pq.PageSize && i < total; i++ { + r, exists, err := rs.storeProxy.GetByKey(keys[i]) + if err != nil { + return nil, err + } + if !exists { + total -= 1 + continue + } + res, ok := r.(coremodel.Resource) + if !ok { + return nil, bizerror.NewAssertionError("Resource", reflect.TypeOf(r).Name()) + } + resources = append(resources, res) + } + pageData := coremodel.NewPageData(total, pq.PageOffset, pq.PageSize, resources) + return pageData, nil +} + +func (rs *resourceStore) getKeysByIndexes(indexes []index.IndexCondition) ([]string, error) { + if len(indexes) == 0 { + return []string{}, nil + } + keySet := set.New[string]() + first := true + for _, condition := range indexes { + var keys []string + var err error + + switch condition.Operator { + case index.Equals: + keys, err = rs.storeProxy.IndexKeys(condition.IndexName, condition.Value) + case index.HasPrefix: + keys, err = rs.getKeysByPrefix(condition.IndexName, condition.Value) + default: + return nil, bizerror.New(bizerror.InvalidArgument, "operator not yet supported: "+string(condition.Operator)) + } + + if err != nil { + return nil, err + } + + if first { + keySet = set.FromSlice(keys) + first = false + } else { + nextSet := set.FromSlice(keys) + keySet = keySet.Intersection(nextSet) + } + } + return keySet.ToSlice(), nil +} + +// addToTrees adds a resource to all relevant RadixTrees for prefix matching +func (rs *resourceStore) addToTrees(resource coremodel.Resource) { + rs.treesMu.Lock() + defer rs.treesMu.Unlock() + + // Get indexers from storeProxy, not from global registry + // This ensures we include both init-time and dynamically-added indexers + indexers := rs.storeProxy.GetIndexers() + for indexName, indexFunc := range indexers { + values, err := indexFunc(resource) + if err != nil { + continue + } + tree, ok := rs.prefixTrees[indexName] + if !ok || tree == nil { + continue + } + for _, v := range values { + // Key format: "indexValue/resourceKey" + key := v + "/" + resource.ResourceKey() + tree.Insert(key, struct{}{}) + } + } +} + +// removeFromTrees removes a resource from all relevant RadixTrees +func (rs *resourceStore) removeFromTrees(resource coremodel.Resource) { + rs.treesMu.Lock() + defer rs.treesMu.Unlock() + + // Get indexers from storeProxy, not from global registry + // This ensures we include both init-time and dynamically-added indexers + indexers := rs.storeProxy.GetIndexers() + for indexName, indexFunc := range indexers { + values, err := indexFunc(resource) + if err != nil { + continue + } + tree, ok := rs.prefixTrees[indexName] + if !ok || tree == nil { + continue + } + for _, v := range values { + // Key format: "indexValue/resourceKey" + key := v + "/" + resource.ResourceKey() + tree.Delete(key) + } + } +} + +// getKeysByPrefix retrieves resource keys by prefix match using RadixTree +func (rs *resourceStore) getKeysByPrefix(indexName, prefix string) ([]string, error) { + rs.treesMu.RLock() + defer rs.treesMu.RUnlock() + + tree, ok := rs.prefixTrees[indexName] + if !ok { + return nil, fmt.Errorf("index %s does not exist", indexName) + } + + var keys []string + tree.WalkPrefix(prefix, func(k string, v interface{}) bool { + // Key format: "indexValue/resourceKey" + // Key format: "indexValue/resourceKey" + // Use Index (first "/") because resourceKey itself contains "/" (mesh/name) + idx := strings.Index(k, "/") + if idx >= 0 && idx < len(k)-1 { + keys = append(keys, k[idx+1:]) + } + return false // Continue walking + }) + + return keys, nil +} diff --git a/pkg/store/memory/store_test.go b/pkg/store/memory/store_test.go new file mode 100644 index 000000000..8ad401995 --- /dev/null +++ b/pkg/store/memory/store_test.go @@ -0,0 +1,1209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package memory + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store/index" +) + +// mockResource is a mock implementation of model.Resource for testing +type mockResource struct { + kind model.ResourceKind + key string + mesh string + meta metav1.ObjectMeta + spec model.ResourceSpec + objectRef runtime.Object +} + +func (mr *mockResource) ResourceMesh() string { + return mr.mesh +} + +func (mr *mockResource) GetObjectKind() schema.ObjectKind { + return schema.EmptyObjectKind +} + +func (mr *mockResource) DeepCopyObject() runtime.Object { + return mr.objectRef +} + +func (mr *mockResource) ResourceKind() model.ResourceKind { + return mr.kind +} + +func (mr *mockResource) ResourceKey() string { + return mr.key +} + +func (mr *mockResource) ResourceMeta() metav1.ObjectMeta { + return mr.meta +} + +func (mr *mockResource) ResourceSpec() model.ResourceSpec { + return mr.spec +} + +func (mr *mockResource) String() string { + b, err := json.Marshal(mr) + if err != nil { + return "" + } + return string(b) +} + +func TestNewMemoryResourceStore(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + assert.NotNil(t, store) +} + +func TestResourceStore_Init(t *testing.T) { + store := &resourceStore{} + err := store.Init(nil) + assert.NoError(t, err) + assert.NotNil(t, store.storeProxy) +} + +func TestResourceStore_AddAndGet(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + kind: "TestResource", + key: "test-key", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + assert.NoError(t, err) + + // Get the resource + item, exists, err := store.Get(mockRes) + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, mockRes, item) + + // Get by key + item, exists, err = store.GetByKey("test-key") + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, mockRes, item) +} + +func TestResourceStore_Update(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + kind: "TestResource", + key: "test-key", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + assert.NoError(t, err) + + // Update the resource + updatedRes := &mockResource{ + kind: "TestResource", + key: "test-key", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "updated-resource", + Namespace: "default", + }, + } + + err = store.Update(updatedRes) + assert.NoError(t, err) + + // Get the updated resource + item, exists, err := store.Get(updatedRes) + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, updatedRes, item) + assert.Equal(t, "updated-resource", item.(*mockResource).meta.Name) +} + +func TestResourceStore_Delete(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create a mock resource + mockRes := &mockResource{ + kind: "TestResource", + key: "test-key", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "test-resource", + Namespace: "default", + }, + } + + // Add the resource + err = store.Add(mockRes) + assert.NoError(t, err) + + // Delete the resource + err = store.Delete(mockRes) + assert.NoError(t, err) + + // Try to get the deleted resource + _, exists, err := store.Get(mockRes) + assert.NoError(t, err) + assert.False(t, exists) +} + +func TestResourceStore_List(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "test-key-1", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "test-key-2", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + + // List resources + list := store.List() + assert.Len(t, list, 2) + assert.Contains(t, list, mockRes1) + assert.Contains(t, list, mockRes2) +} + +func TestResourceStore_ListKeys(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "test-key-1", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "test-key-2", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + + // List keys + keys := store.ListKeys() + assert.Len(t, keys, 2) + assert.Contains(t, keys, "test-key-1") + assert.Contains(t, keys, "test-key-2") +} + +func TestResourceStore_Replace(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create initial mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "test-key-1", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "test-key-2", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + + // Replace with new set of resources + newResources := []interface{}{mockRes2} + err = store.Replace(newResources, "version-1") + assert.NoError(t, err) + + // Check that only the new resource exists + keys := store.ListKeys() + assert.Len(t, keys, 1) + assert.Contains(t, keys, "test-key-2") + assert.NotContains(t, keys, "test-key-1") +} + +func TestResourceStore_GetByKeys(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "test-key-1", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "test-key-2", + mesh: "default", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + // Add only first resource + err = store.Add(mockRes1) + assert.NoError(t, err) + + err = store.Add(mockRes2) + assert.NoError(t, err) + + // Get by multiple keys + keys := []string{"test-key-1", "test-key-2", "test-key-3"} + resources, err := store.GetByKeys(keys) + assert.NoError(t, err) + assert.Len(t, resources, 2) + assert.Equal(t, mockRes1, resources[0]) + assert.Equal(t, mockRes2, resources[1]) +} + +func TestResourceStore_ListByIndexes(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "mesh1/test-key-1", + mesh: "mesh1", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "mesh1/test-key-2", + mesh: "mesh1", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + mockRes3 := &mockResource{ + kind: "TestResource", + key: "mesh2/test-key-3", + mesh: "mesh2", + meta: metav1.ObjectMeta{Name: "test-resource-3"}, + } + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + err = store.Add(mockRes3) + assert.NoError(t, err) + + // List by indexes + indexes := []index.IndexCondition{{IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}} + resources, err := store.ListByIndexes(indexes) + assert.NoError(t, err) + assert.Len(t, resources, 2) + // Should be sorted by ResourceKey + assert.Equal(t, mockRes1, resources[0]) + assert.Equal(t, mockRes2, resources[1]) +} + +func TestResourceStore_PageListByIndexes(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "mesh1/test-key-1", + mesh: "mesh1", + meta: metav1.ObjectMeta{Name: "test-resource-1"}, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "mesh1/test-key-2", + mesh: "mesh1", + meta: metav1.ObjectMeta{Name: "test-resource-2"}, + } + + mockRes3 := &mockResource{ + kind: "TestResource", + key: "mesh1/test-key-3", + mesh: "mesh1", + meta: metav1.ObjectMeta{Name: "test-resource-3"}, + } + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + err = store.Add(mockRes3) + assert.NoError(t, err) + + // Page list by indexes + indexes := []index.IndexCondition{{IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}} + pageReq := model.PageReq{ + PageOffset: 0, + PageSize: 2, + } + pageData, err := store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + // Total 3 resources + assert.Equal(t, 3, pageData.Total) + // Page offset 0 + assert.Equal(t, 0, pageData.PageOffset) + // Page size 2 + assert.Equal(t, 2, pageData.PageSize) + // 2 items in this page + assert.Len(t, pageData.Data, 2) + // Sorted by key + assert.Equal(t, mockRes1, pageData.Data[0]) + assert.Equal(t, mockRes2, pageData.Data[1]) + + // Second page + pageReq.PageOffset = 2 + pageData, err = store.PageListByIndexes(indexes, pageReq) + assert.NoError(t, err) + // Total still 3 + assert.Equal(t, 3, pageData.Total) + // Page offset 2 + assert.Equal(t, 2, pageData.PageOffset) + // Page size 2 + assert.Equal(t, 2, pageData.PageSize) + // Only 1 item left + assert.Len(t, pageData.Data, 1) + // Last item + assert.Equal(t, mockRes3, pageData.Data[0]) +} + +func TestResourceStore_MultipleIndexes(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestApplication", + key: "mesh1/app1", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "app1", + Namespace: "default", + Labels: map[string]string{ + "version": "v1", + "env": "prod", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestApplication", + key: "mesh1/app2", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "app2", + Namespace: "default", + Labels: map[string]string{ + "version": "v2", + "env": "prod", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestApplication", + key: "mesh2/app3", + mesh: "mesh2", + meta: metav1.ObjectMeta{ + Name: "app3", + Namespace: "default", + Labels: map[string]string{ + "version": "v1", + "env": "dev", + }, + }, + } + + // Add indexers for multiple fields + indexers := map[string]cache.IndexFunc{ + "by-mesh": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + return []string{resource.ResourceMesh()}, nil + }, + "by-version": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + version := resource.ResourceMeta().Labels["version"] + return []string{version}, nil + }, + "by-env": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + env := resource.ResourceMeta().Labels["env"] + return []string{env}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + resources := []model.Resource{mockRes1, mockRes2, mockRes3} + for _, res := range resources { + err = store.Add(res) + assert.NoError(t, err) + } + + // Test multiple indexes - get all prod env resources in mesh1 + indexes := []index.IndexCondition{ + {IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}, + {IndexName: "by-version", Value: "v1", Operator: index.Equals}, + } + result, err := store.ListByIndexes(indexes) + assert.NoError(t, err) + assert.Len(t, result, 1) + // Should contain app1 + keys := make([]string, len(result)) + for i, res := range result { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "mesh1/app1") +} + +func TestResourceStore_IndexKeys(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestService", + key: "mesh1/service1", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "service1", + Labels: map[string]string{ + "group": "frontend", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestService", + key: "mesh1/service2", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "service2", + Labels: map[string]string{ + "group": "backend", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestService", + key: "mesh1/service3", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "service3", + Labels: map[string]string{ + "group": "frontend", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-group": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + group := resource.ResourceMeta().Labels["group"] + return []string{group}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + resources := []model.Resource{mockRes1, mockRes2, mockRes3} + for _, res := range resources { + err = store.Add(res) + assert.NoError(t, err) + } + + // Test IndexKeys method + keys, err := store.IndexKeys("by-group", "frontend") + assert.NoError(t, err) + assert.Len(t, keys, 2) + assert.Contains(t, keys, "mesh1/service1") + assert.Contains(t, keys, "mesh1/service3") + + keys, err = store.IndexKeys("by-group", "backend") + assert.NoError(t, err) + assert.Len(t, keys, 1) + assert.Contains(t, keys, "mesh1/service2") +} + +func TestResourceStore_ByIndex(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "mesh1/instance1", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "instance1", + Labels: map[string]string{ + "type": "web", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestInstance", + key: "mesh1/instance2", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "instance2", + Labels: map[string]string{ + "type": "database", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-type": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + instanceType := resource.ResourceMeta().Labels["type"] + return []string{instanceType}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + + // Test ByIndex method + items, err := store.ByIndex("by-type", "web") + assert.NoError(t, err) + assert.Len(t, items, 1) + assert.Equal(t, mockRes1, items[0]) + + items, err = store.ByIndex("by-type", "database") + assert.NoError(t, err) + assert.Len(t, items, 1) + assert.Equal(t, mockRes2, items[0]) +} + +func TestResourceStore_GetIndexers(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Initially no indexers + indexers := store.GetIndexers() + assert.Empty(t, indexers) + + // Add indexers + newIndexers := map[string]cache.IndexFunc{ + "by-name": func(obj interface{}) ([]string, error) { + return []string{obj.(model.Resource).ResourceMeta().Name}, nil + }, + "by-kind": func(obj interface{}) ([]string, error) { + return []string{string(obj.(model.Resource).ResourceKind())}, nil + }, + } + err = store.AddIndexers(newIndexers) + assert.NoError(t, err) + + // Check if indexers were added + indexers = store.GetIndexers() + assert.Len(t, indexers, 2) + assert.Contains(t, indexers, "by-name") + assert.Contains(t, indexers, "by-kind") +} + +func TestResourceStore_ListIndexFuncValues(t *testing.T) { + store := NewMemoryResourceStore("TestResource") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestResource", + key: "mesh1/resource1", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "resource1", + Labels: map[string]string{ + "status": "active", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestResource", + key: "mesh1/resource2", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "resource2", + Labels: map[string]string{ + "status": "inactive", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestResource", + key: "mesh1/resource3", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "resource3", + Labels: map[string]string{ + "status": "active", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-status": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + status := resource.ResourceMeta().Labels["status"] + return []string{status}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + resources := []model.Resource{mockRes1, mockRes2, mockRes3} + for _, res := range resources { + err = store.Add(res) + assert.NoError(t, err) + } + + // Test ListIndexFuncValues method + values := store.ListIndexFuncValues("by-status") + assert.Len(t, values, 2) + assert.Contains(t, values, "active") + assert.Contains(t, values, "inactive") +} + +func TestResourceStore_HasPrefixMatch(t *testing.T) { + store := NewMemoryResourceStore("TestInstance") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources with IP-like values for prefix matching + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "192.168.1.10", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestInstance", + key: "instance-2", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-2", + Labels: map[string]string{ + "ip": "192.168.1.20", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestInstance", + key: "instance-3", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-3", + Labels: map[string]string{ + "ip": "10.0.0.5", + }, + }, + } + + mockRes4 := &mockResource{ + kind: "TestInstance", + key: "instance-4", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-4", + Labels: map[string]string{ + "ip": "192.168.2.1", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + ip := resource.ResourceMeta().Labels["ip"] + return []string{ip}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + err = store.Add(mockRes3) + assert.NoError(t, err) + err = store.Add(mockRes4) + assert.NoError(t, err) + + // Test HasPrefix match: find all IPs starting with "192.168.1." + conditions := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.1.", Operator: index.HasPrefix}, + } + result, err := store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 2) + + // Verify the correct instances are returned + keys := make([]string, len(result)) + for i, res := range result { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "instance-1") + assert.Contains(t, keys, "instance-2") + + // Test HasPrefix match: find all IPs starting with "192.168." + conditions = []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.", Operator: index.HasPrefix}, + } + result, err = store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 3) + + keys = make([]string, len(result)) + for i, res := range result { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "instance-1") + assert.Contains(t, keys, "instance-2") + assert.Contains(t, keys, "instance-4") + + // Test HasPrefix match: find all IPs starting with "10." + conditions = []index.IndexCondition{ + {IndexName: "by-ip", Value: "10.", Operator: index.HasPrefix}, + } + result, err = store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 1) + assert.Equal(t, "instance-3", result[0].ResourceKey()) +} + +func TestResourceStore_HasPrefixPageList(t *testing.T) { + store := NewMemoryResourceStore("TestInstance") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "192.168.1.10", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestInstance", + key: "instance-2", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-2", + Labels: map[string]string{ + "ip": "192.168.1.20", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestInstance", + key: "instance-3", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-3", + Labels: map[string]string{ + "ip": "192.168.1.30", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + ip := resource.ResourceMeta().Labels["ip"] + return []string{ip}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + err = store.Add(mockRes3) + assert.NoError(t, err) + + // Test HasPrefix with pagination + conditions := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.1.", Operator: index.HasPrefix}, + } + pageReq := model.PageReq{ + PageOffset: 0, + PageSize: 2, + } + + pageData, err := store.PageListByIndexes(conditions, pageReq) + assert.NoError(t, err) + assert.Equal(t, 3, pageData.Total) + assert.Equal(t, 0, pageData.PageOffset) + assert.Equal(t, 2, pageData.PageSize) + assert.Len(t, pageData.Data, 2) + + // Test second page + pageReq.PageOffset = 2 + pageData, err = store.PageListByIndexes(conditions, pageReq) + assert.NoError(t, err) + assert.Equal(t, 3, pageData.Total) + assert.Equal(t, 2, pageData.PageOffset) + assert.Len(t, pageData.Data, 1) +} + +func TestResourceStore_HasPrefixWithMultipleConditions(t *testing.T) { + store := NewMemoryResourceStore("TestInstance") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "192.168.1.10", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestInstance", + key: "instance-2", + mesh: "mesh1", + meta: metav1.ObjectMeta{ + Name: "instance-2", + Labels: map[string]string{ + "ip": "192.168.1.20", + }, + }, + } + + mockRes3 := &mockResource{ + kind: "TestInstance", + key: "instance-3", + mesh: "mesh2", + meta: metav1.ObjectMeta{ + Name: "instance-3", + Labels: map[string]string{ + "ip": "192.168.1.30", + }, + }, + } + + // Add indexers + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + ip := resource.ResourceMeta().Labels["ip"] + return []string{ip}, nil + }, + "by-mesh": func(obj interface{}) ([]string, error) { + return []string{obj.(model.Resource).ResourceMesh()}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + err = store.Add(mockRes3) + assert.NoError(t, err) + + // Test combined: HasPrefix on IP AND Equals on mesh + conditions := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.1.", Operator: index.HasPrefix}, + {IndexName: "by-mesh", Value: "mesh1", Operator: index.Equals}, + } + result, err := store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 2) + + keys := make([]string, len(result)) + for i, res := range result { + keys[i] = res.ResourceKey() + } + assert.Contains(t, keys, "instance-1") + assert.Contains(t, keys, "instance-2") + assert.NotContains(t, keys, "instance-3") +} + +func TestResourceStore_HasPrefixAfterUpdate(t *testing.T) { + store := NewMemoryResourceStore("TestInstance") + err := store.Init(nil) + assert.NoError(t, err) + + // Create initial mock resource + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "192.168.1.10", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + ip := resource.ResourceMeta().Labels["ip"] + return []string{ip}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resource + err = store.Add(mockRes1) + assert.NoError(t, err) + + // Verify it matches 192.168.1. + conditions := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.1.", Operator: index.HasPrefix}, + } + result, err := store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 1) + + // Update resource with different IP + updatedRes := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "10.0.0.5", + }, + }, + } + err = store.Update(updatedRes) + assert.NoError(t, err) + + // Verify it no longer matches 192.168.1. + result, err = store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 0) + + // Verify it matches 10.0. + conditions = []index.IndexCondition{ + {IndexName: "by-ip", Value: "10.0.", Operator: index.HasPrefix}, + } + result, err = store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 1) + assert.Equal(t, "instance-1", result[0].ResourceKey()) +} + +func TestResourceStore_HasPrefixAfterDelete(t *testing.T) { + store := NewMemoryResourceStore("TestInstance") + err := store.Init(nil) + assert.NoError(t, err) + + // Create mock resources + mockRes1 := &mockResource{ + kind: "TestInstance", + key: "instance-1", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-1", + Labels: map[string]string{ + "ip": "192.168.1.10", + }, + }, + } + + mockRes2 := &mockResource{ + kind: "TestInstance", + key: "instance-2", + mesh: "default", + meta: metav1.ObjectMeta{ + Name: "instance-2", + Labels: map[string]string{ + "ip": "192.168.1.20", + }, + }, + } + + // Add indexer + indexers := map[string]cache.IndexFunc{ + "by-ip": func(obj interface{}) ([]string, error) { + resource := obj.(model.Resource) + ip := resource.ResourceMeta().Labels["ip"] + return []string{ip}, nil + }, + } + err = store.AddIndexers(indexers) + assert.NoError(t, err) + + // Add resources + err = store.Add(mockRes1) + assert.NoError(t, err) + err = store.Add(mockRes2) + assert.NoError(t, err) + + // Verify both match 192.168.1. + conditions := []index.IndexCondition{ + {IndexName: "by-ip", Value: "192.168.1.", Operator: index.HasPrefix}, + } + result, err := store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 2) + + // Delete one resource + err = store.Delete(mockRes1) + assert.NoError(t, err) + + // Verify only one still matches + result, err = store.ListByIndexes(conditions) + assert.NoError(t, err) + assert.Len(t, result, 1) + assert.Equal(t, "instance-2", result[0].ResourceKey()) +} diff --git a/pkg/store/mysql/mysql.go b/pkg/store/mysql/mysql.go new file mode 100644 index 000000000..4dff0cb1d --- /dev/null +++ b/pkg/store/mysql/mysql.go @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mysql + +import ( + "gorm.io/driver/mysql" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/store/dbcommon" +) + +func init() { + store.RegisterFactory(&mysqlStoreFactory{}) +} + +// mysqlStoreFactory is the factory for creating MySQL store instances +type mysqlStoreFactory struct{} + +var _ store.Factory = &mysqlStoreFactory{} + +// Support checks if this factory supports the given store type +func (f *mysqlStoreFactory) Support(s storecfg.Type) bool { + return s == storecfg.MySQL +} + +// New creates a new MySQL store instance for the specified resource kind +func (f *mysqlStoreFactory) New(kind model.ResourceKind, cfg *storecfg.Config) (store.ManagedResourceStore, error) { + // Get or create connection pool with MySQL dialector + pool, err := dbcommon.GetOrCreatePool( + mysql.Open(cfg.Address), + storecfg.MySQL, + cfg.Address, + dbcommon.DefaultConnectionPoolConfig(), + ) + if err != nil { + return nil, err + } + + // Create GormStore with the pool + return dbcommon.NewGormStore(kind, cfg.Address, pool), nil +} diff --git a/pkg/store/postgres/postgres.go b/pkg/store/postgres/postgres.go new file mode 100644 index 000000000..27874805e --- /dev/null +++ b/pkg/store/postgres/postgres.go @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package postgres + +import ( + "gorm.io/driver/postgres" + + storecfg "github.com/apache/dubbo-admin/pkg/config/store" + "github.com/apache/dubbo-admin/pkg/core/resource/model" + "github.com/apache/dubbo-admin/pkg/core/store" + "github.com/apache/dubbo-admin/pkg/store/dbcommon" +) + +func init() { + store.RegisterFactory(&postgresStoreFactory{}) +} + +// postgresStoreFactory is the factory for creating PostgreSQL store instances +type postgresStoreFactory struct{} + +var _ store.Factory = &postgresStoreFactory{} + +// Support checks if this factory supports the given store type +func (f *postgresStoreFactory) Support(s storecfg.Type) bool { + return s == storecfg.Postgres +} + +// New creates a new PostgreSQL store instance for the specified resource kind +func (f *postgresStoreFactory) New(kind model.ResourceKind, cfg *storecfg.Config) (store.ManagedResourceStore, error) { + // Get or create connection pool with PostgreSQL dialector + pool, err := dbcommon.GetOrCreatePool( + postgres.Open(cfg.Address), + storecfg.Postgres, + cfg.Address, + dbcommon.DefaultConnectionPoolConfig(), + ) + if err != nil { + return nil, err + } + + // Create GormStore with the pool + return dbcommon.NewGormStore(kind, cfg.Address, pool), nil +} diff --git a/pkg/version/compatibility.go b/pkg/version/compatibility.go deleted file mode 100644 index e61b91cd0..000000000 --- a/pkg/version/compatibility.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package version - -import ( - "fmt" - "strings" - - "github.com/Masterminds/semver/v3" - - "github.com/apache/dubbo-admin/pkg/core" -) - -var log = core.Log.WithName("version").WithName("compatibility") - -var PreviewVersionPrefix = "preview" - -func IsPreviewVersion(version string) bool { - return strings.Contains(version, PreviewVersionPrefix) -} - -// DeploymentVersionCompatible returns true if the given component version -// is compatible with the installed version of dubbo CP. -// For all binaries which share a common version (dubbo DP, CP, Zone CP...), we -// support backwards compatibility of at most two prior minor versions. -func DeploymentVersionCompatible(dubboVersionStr, componentVersionStr string) bool { - if IsPreviewVersion(dubboVersionStr) || IsPreviewVersion(componentVersionStr) { - return true - } - - dubboVersion, err := semver.NewVersion(dubboVersionStr) - if err != nil { - // Assume some kind of dev version - log.Info("cannot parse semantic version", "version", dubboVersionStr) - return true - } - - componentVersion, err := semver.NewVersion(componentVersionStr) - if err != nil { - // Assume some kind of dev version - log.Info("cannot parse semantic version", "version", componentVersionStr) - return true - } - - minMinor := int64(dubboVersion.Minor()) - 2 - if minMinor < 0 { - minMinor = 0 - } - - maxMinor := dubboVersion.Minor() + 2 - - constraint, err := semver.NewConstraint( - fmt.Sprintf(">= %d.%d, <= %d.%d", dubboVersion.Major(), minMinor, dubboVersion.Major(), maxMinor), - ) - if err != nil { - // Programmer error - panic(err) - } - - return constraint.Check(componentVersion) -} diff --git a/pkg/version/version.go b/pkg/version/version.go index 56dce9065..ef968771c 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -19,40 +19,33 @@ package version import ( "fmt" - "runtime" "strings" ) var ( - buildVersion = "unknown" + buildVersion = "0.7.0" ) -// type BuildInfo struct { -// Version string `json:"version"` -// } - -func (b BuildInfo) String() string { - return fmt.Sprintf("%v", b.Version) -} - -func (b BuildInfo) LongForm() string { - return fmt.Sprintf("%#v", b) -} +var Build BuildInfo func init() { - Info = BuildInfo{ - Version: buildVersion, + Build = BuildInfo{ + Product: Product, + Version: version, + GitTag: gitTag, + GitCommit: gitCommit, + BuildDate: buildDate, + BasedOnDubbo: basedOnDubbo, } } var ( - Product = "Dubbo" - basedOndubbo = "" - version = "unknown" - gitTag = "unknown" - gitCommit = "unknown" - buildDate = "unknown" - Envoy = "unknown" + Product = "Dubbo Admin" + basedOnDubbo = "Dubbo3.x" + version = "0.7.0" + gitTag = "0.7.0" + gitCommit = "-" + buildDate = "2026-01" ) type BuildInfo struct { @@ -64,6 +57,14 @@ type BuildInfo struct { BasedOnDubbo string } +func (b BuildInfo) String() string { + return fmt.Sprintf("%v", b.Version) +} + +func (b BuildInfo) LongForm() string { + return fmt.Sprintf("%#v", b) +} + func (b BuildInfo) FormatDetailedProductInfo() string { base := []string{ fmt.Sprintf("Product: %s", b.Product), @@ -101,30 +102,3 @@ func (b BuildInfo) AsMap() map[string]string { } return res } - -func (b BuildInfo) UserAgent(component string) string { - commit := shortCommit(b.GitCommit) - if b.BasedOnDubbo != "" { - commit = fmt.Sprintf("%s/dubbo-%s", commit, b.BasedOnDubbo) - } - return fmt.Sprintf("%s/%s (%s; %s; %s/%s)", - component, - b.Version, - runtime.GOOS, - runtime.GOARCH, - b.Product, - commit) -} - -var Build BuildInfo - -func init() { - Build = BuildInfo{ - Product: Product, - Version: version, - GitTag: gitTag, - GitCommit: gitCommit, - BuildDate: buildDate, - BasedOnDubbo: basedOndubbo, - } -} diff --git a/release/kubernetes/dubbo-samples-shop/dubbo-samples-shop-all.yaml b/release/kubernetes/dubbo-samples-shop/dubbo-samples-shop-all.yaml new file mode 100644 index 000000000..1bcdfdc36 --- /dev/null +++ b/release/kubernetes/dubbo-samples-shop/dubbo-samples-shop-all.yaml @@ -0,0 +1,621 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: dubbo-samples-shop + +--- + +apiVersion: v1 +kind: Service +metadata: + name: dubbo-qos + namespace: dubbo-samples-shop + labels: + org.apache.dubbo/service: dubbo-qos +spec: + type: ClusterIP + sessionAffinity: None + selector: + app-type: dubbo + ports: + - port: 22222 + name: dubbo-qos + targetPort: 22222 + +--- +apiVersion: v1 +kind: Service +metadata: + name: shop-frontend + namespace: dubbo-samples-shop +spec: + type: ClusterIP + sessionAffinity: None + selector: + app: shop-frontend + ports: + - port: 8080 + name: web + targetPort: 8080 +--- +# App FrontEnd +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-frontend + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-frontend + template: + metadata: + labels: + app: shop-frontend + app-type: dubbo + spec: + containers: + - name: shop-frontend + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-frontend:0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20881 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.application.qos-port=22222 -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" +--- + +# App Order V1-1 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-order-v1 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-order + orderVersion: v1 + template: + metadata: + labels: + app: shop-order + orderVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20882" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-order + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-order:v1_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20882 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "orderVersion=v1" +--- + +# App Order V2 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-order-v2 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-order + orderVersion: v2 + template: + metadata: + labels: + app: shop-order + orderVersion: v2 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20883" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-order + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-order:v2_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20883 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "orderVersion=v2;" +--- + +# App User +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-user + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-user + template: + metadata: + labels: + app: shop-user + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20884" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-user + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-user:0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20884 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + +--- + +# App Detail-1 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-detail-v1 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-detail + detailVersion: v1 + template: + metadata: + labels: + app: shop-detail + detailVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20885" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-detail + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-detail:v1_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20885 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "detailVersion=v1; region=beijing" +--- + +# App Detail-2 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-detail-v2 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-detail + detailVersion: v2 + template: + metadata: + labels: + app: shop-detail + detailVersion: v2 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20886" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-detail + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-detail:v2_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20886 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "detailVersion=v2; region=hangzhou;" +--- + +#App Comment v1 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-comment-v1 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-comment + commentVersion: v1 + template: + metadata: + labels: + app: shop-comment + commentVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20887" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-comment + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-comment:v1_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20887 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "commentVersion=v1; region=beijing" +--- + +#App Comment v2 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-comment-v2 + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-comment + commentVersion: v2 + template: + metadata: + labels: + app: shop-comment + commentVersion: v2 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20888" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-comment + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-comment:v2_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20888 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "commentVersion=v2; region=hangzhou;" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-user-gray + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-user + template: + metadata: + labels: + app: shop-user + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20892" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-user-gray + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-user:gray_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20892 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "env=gray" +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-order-v1-gray + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-order + orderVersion: v1 + template: + metadata: + labels: + app: shop-order + orderVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20891" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-order + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-order:gray_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20891 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "env=gray" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-detail-v1-gray + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-detail + detailVersion: v1 + template: + metadata: + labels: + app: shop-detail + detailVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20890" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-detail + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-detail:gray_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20890 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "env=gray" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shop-comment-v1-gray + namespace: dubbo-samples-shop +spec: + replicas: 1 + selector: + matchLabels: + app: shop-comment + commentVersion: v1 + template: + metadata: + labels: + app: shop-comment + commentVersion: v1 + app-type: dubbo + org.apache.dubbo/dubbo-rpc-port: "20889" + org.apache.dubbo/registry: nacos2.5 + spec: + containers: + - name: shop-comment + image: registry.cn-hangzhou.aliyuncs.com/robocanic-public/shop-comment:gray_0.0.1 + imagePullPolicy: Always + ports: + - name: dubbo + containerPort: 20889 + protocol: TCP + - name: dubbo-qos + containerPort: 22222 + protocol: TCP + env: + - name: JAVA_TOOL_OPTIONS + value: " + -Ddubbo.registry.parameters.register-consumer-url=true + -Ddubbo.registry.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.config-center.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.metadata-report.address=nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + -Ddubbo.application.qos-port=22222 + -Ddubbo.application.qos-accept-foreign-ip=true + -Ddubbo.application.qos-anonymous-allow-commands=metrics + -Ddubbo.tracing.enabled=true + -Ddubbo.tracing.sampling.probability=1.0 + -Ddubbo.tracing.tracing-exporter.otlp-config.endpoint=http://jaeger.monitoring.svc:4317" + - name: DUBBO_LABELS + value: "env=gray" diff --git a/release/kubernetes/dubbo-system/dubbo-admin.yaml b/release/kubernetes/dubbo-system/dubbo-admin.yaml new file mode 100644 index 000000000..54216c4f2 --- /dev/null +++ b/release/kubernetes/dubbo-system/dubbo-admin.yaml @@ -0,0 +1,176 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dubbo-admin + namespace: dubbo-system + labels: + app: dubbo-admin +spec: + replicas: 1 + selector: + matchLabels: + app: dubbo-admin + template: + metadata: + name: dubbo-admin + labels: + app: dubbo-admin + spec: + securityContext: + runAsUser: 65532 + runAsGroup: 65532 + fsGroup: 65532 + runAsNonRoot: true + serviceAccountName: dubbo-admin + containers: + - name: dubbo-admin + image: apache/dubbo-admin:0.7.0 + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /etc/dubbo-admin + name: dubbo-admin-config + readOnly: true + - name: dubbo-admin-logs + mountPath: /app/logs + command: + - /app/dubbo-admin + args: + - run + - -c + - /etc/dubbo-admin/dubbo-admin.yaml + livenessProbe: + httpGet: + port: 5680 + path: /healthy + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + port: 5680 + path: /ready + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + ports: + - containerPort: 8888 + protocol: TCP + restartPolicy: Always + volumes: + - name: dubbo-admin-config + configMap: + name: dubbo-admin-config + - name: dubbo-admin-logs + # You can replace it with hostPath or pvc to store logs. + emptyDir: { } +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: dubbo-admin-config + namespace: dubbo-system + +data: + dubbo-admin.yaml: | + observability: + grafana: http://grafana.monitoringg.svc:3000 + prometheus: http://prometheus-k8s.monitoring.svc:9090/ + console: + auth: + user: admin + password: dubbo@2025 + expirationTime: 3600 + discovery: + - type: nacos2 + name: nacos2.5-standalone + id: nacos2.5 + address: + registry: nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + configCenter: nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + metadataReport: nacos://nacos.dubbo-system.svc:8848?username=nacos&password=nacos + engine: + id: default + name: default + type: kubernetes + properties: + podWatchSelector: metadata.namespace=dubbo-samples-shop + dubboAppIdentifier: + type: ByLabel + labelKey: app + dubboRPCPortIdentifier: + type: ByLabel + labelKey: org.apache.dubbo/dubbo-rpc-port + dubboDiscoveryIdentifier: + type: ByLabel + labelKey: org.apache.dubbo/registry + mainContainerChooseStrategy: + type: ByIndex + index: 0 +--- +apiVersion: v1 +kind: Service +metadata: + name: dubbo-admin + namespace: dubbo-system +spec: + type: ClusterIP + selector: + app: dubbo-admin + ports: + - protocol: TCP + port: 8888 + targetPort: 8888 + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: dubbo-admin-cluster-role +rules: + - apiGroups: [""] + resources: ["pods", "services"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apps"] + resources: ["deployments", "statefulsets", "replicasets"] + verbs: ["get", "list", "watch"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: dubbo-admin + namespace: dubbo-system + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: dubbo-admin-cluster-binding +subjects: + - kind: ServiceAccount + name: dubbo-admin + namespace: dubbo-system +roleRef: + kind: ClusterRole + name: dubbo-admin-cluster-role + apiGroup: rbac.authorization.k8s.io diff --git a/release/kubernetes/dubbo-system/nacos.yaml b/release/kubernetes/dubbo-system/nacos.yaml new file mode 100644 index 000000000..315579421 --- /dev/null +++ b/release/kubernetes/dubbo-system/nacos.yaml @@ -0,0 +1,91 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Nacos +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nacos + namespace: dubbo-system +spec: + replicas: 1 + selector: + matchLabels: + app: nacos + template: + metadata: + labels: + app: nacos + spec: + containers: + - name: consumer + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nacos/nacos-server:v2.5.2 + imagePullPolicy: IfNotPresent + livenessProbe: + tcpSocket: + port: 8848 + initialDelaySeconds: 20 + timeoutSeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + successThreshold: 1 + readinessProbe: + tcpSocket: + port: 8848 + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + successThreshold: 1 + ports: + - containerPort: 8848 + name: client + - containerPort: 9848 + name: client-rpc + env: + - name: NACOS_AUTH_TOKEN + value: "aHR0cHM6Ly9jbG91ZC50ZW5jZW50LmNvbS9sb2dpbi9zdWJBY2NvdW50LzEwMDA0NDgzNzM2Nj90eXBlPXN1YkFjY291bnQmdXNlcm5hbWU9Y2M=" + - name: NACOS_AUTH_IDENTITY_KEY + value: "serverIdentity" + - name: NACOS_AUTH_IDENTITY_VALUE + value: "security" + - name: NACOS_SERVER_PORT + value: "8848" + - name: NACOS_APPLICATION_PORT + value: "8848" + - name: PREFER_HOST_MODE + value: "hostname" + - name: MODE + value: "standalone" +--- +apiVersion: v1 +kind: Service +metadata: + name: nacos + namespace: dubbo-system +spec: + type: ClusterIP + sessionAffinity: None + selector: + app: nacos + ports: + - port: 8848 + name: server + targetPort: 8848 + nodePort: 30848 + - port: 9848 + name: client-rpc + targetPort: 9848 + nodePort: 31848 \ No newline at end of file diff --git a/release/kubernetes/monitoring/alertmanager-alertmanager.yaml b/release/kubernetes/monitoring/alertmanager-alertmanager.yaml new file mode 100644 index 000000000..85e7865dd --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-alertmanager.yaml @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: Alertmanager +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: main + namespace: monitoring +spec: + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus/alertmanager:v0.28.1 + nodeSelector: + kubernetes.io/os: linux + podMetadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + replicas: 3 + resources: + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 4m + memory: 100Mi + secrets: [] + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccountName: alertmanager-main + version: 0.28.1 diff --git a/release/kubernetes/monitoring/alertmanager-networkPolicy.yaml b/release/kubernetes/monitoring/alertmanager-networkPolicy.yaml new file mode 100644 index 000000000..e9a490980 --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-networkPolicy.yaml @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 9093 + protocol: TCP + - port: 8080 + protocol: TCP + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: alertmanager + ports: + - port: 9094 + protocol: TCP + - port: 9094 + protocol: UDP + podSelector: + matchLabels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/alertmanager-podDisruptionBudget.yaml b/release/kubernetes/monitoring/alertmanager-podDisruptionBudget.yaml new file mode 100644 index 000000000..59b746ce0 --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-podDisruptionBudget.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring +spec: + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/alertmanager-prometheusRule.yaml b/release/kubernetes/monitoring/alertmanager-prometheusRule.yaml new file mode 100644 index 000000000..47e433401 --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-prometheusRule.yaml @@ -0,0 +1,154 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + prometheus: k8s + role: alert-rules + name: alertmanager-main-rules + namespace: monitoring +spec: + groups: + - name: alertmanager.rules + rules: + - alert: AlertmanagerFailedReload + annotations: + description: Configuration has failed to load for {{ $labels.namespace }}/{{ $labels.pod}}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerfailedreload + summary: Reloading an Alertmanager configuration has failed. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(alertmanager_config_last_reload_successful{job="alertmanager-main",namespace="monitoring"}[5m]) == 0 + for: 10m + labels: + severity: critical + - alert: AlertmanagerMembersInconsistent + annotations: + description: Alertmanager {{ $labels.namespace }}/{{ $labels.pod}} has only found {{ $value }} members of the {{$labels.job}} cluster. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagermembersinconsistent + summary: A member of an Alertmanager cluster has not found all other cluster members. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(alertmanager_cluster_members{job="alertmanager-main",namespace="monitoring"}[5m]) + < on (namespace,service) group_left + count by (namespace,service) (max_over_time(alertmanager_cluster_members{job="alertmanager-main",namespace="monitoring"}[5m])) + for: 15m + labels: + severity: critical + - alert: AlertmanagerFailedToSendAlerts + annotations: + description: Alertmanager {{ $labels.namespace }}/{{ $labels.pod}} failed to send {{ $value | humanizePercentage }} of notifications to {{ $labels.integration }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerfailedtosendalerts + summary: An Alertmanager instance failed to send notifications. + expr: | + ( + rate(alertmanager_notifications_failed_total{job="alertmanager-main",namespace="monitoring"}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="alertmanager-main",namespace="monitoring"}[5m]) + ) + > 0.01 + for: 5m + labels: + severity: warning + - alert: AlertmanagerClusterFailedToSendAlerts + annotations: + description: The minimum notification failure rate to {{ $labels.integration }} sent from any instance in the {{$labels.job}} cluster is {{ $value | humanizePercentage }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerclusterfailedtosendalerts + summary: All Alertmanager instances in a cluster failed to send notifications to a critical integration. + expr: | + min by (namespace,service, integration) ( + rate(alertmanager_notifications_failed_total{job="alertmanager-main",namespace="monitoring", integration=~`.*`}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="alertmanager-main",namespace="monitoring", integration=~`.*`}[5m]) + ) + > 0.01 + for: 5m + labels: + severity: critical + - alert: AlertmanagerClusterFailedToSendAlerts + annotations: + description: The minimum notification failure rate to {{ $labels.integration }} sent from any instance in the {{$labels.job}} cluster is {{ $value | humanizePercentage }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerclusterfailedtosendalerts + summary: All Alertmanager instances in a cluster failed to send notifications to a non-critical integration. + expr: | + min by (namespace,service, integration) ( + rate(alertmanager_notifications_failed_total{job="alertmanager-main",namespace="monitoring", integration!~`.*`}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="alertmanager-main",namespace="monitoring", integration!~`.*`}[5m]) + ) + > 0.01 + for: 5m + labels: + severity: warning + - alert: AlertmanagerConfigInconsistent + annotations: + description: Alertmanager instances within the {{$labels.job}} cluster have different configurations. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerconfiginconsistent + summary: Alertmanager instances within the same cluster have different configurations. + expr: | + count by (namespace,service) ( + count_values by (namespace,service) ("config_hash", alertmanager_config_hash{job="alertmanager-main",namespace="monitoring"}) + ) + != 1 + for: 20m + labels: + severity: critical + - alert: AlertmanagerClusterDown + annotations: + description: '{{ $value | humanizePercentage }} of Alertmanager instances within the {{$labels.job}} cluster have been up for less than half of the last 5m.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerclusterdown + summary: Half or more of the Alertmanager instances within the same cluster are down. + expr: | + ( + count by (namespace,service) ( + avg_over_time(up{job="alertmanager-main",namespace="monitoring"}[5m]) < 0.5 + ) + / + count by (namespace,service) ( + up{job="alertmanager-main",namespace="monitoring"} + ) + ) + >= 0.5 + for: 5m + labels: + severity: critical + - alert: AlertmanagerClusterCrashlooping + annotations: + description: '{{ $value | humanizePercentage }} of Alertmanager instances within the {{$labels.job}} cluster have restarted at least 5 times in the last 10m.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerclustercrashlooping + summary: Half or more of the Alertmanager instances within the same cluster are crashlooping. + expr: | + ( + count by (namespace,service) ( + changes(process_start_time_seconds{job="alertmanager-main",namespace="monitoring"}[10m]) > 4 + ) + / + count by (namespace,service) ( + up{job="alertmanager-main",namespace="monitoring"} + ) + ) + >= 0.5 + for: 5m + labels: + severity: critical diff --git a/release/kubernetes/monitoring/alertmanager-secret.yaml b/release/kubernetes/monitoring/alertmanager-secret.yaml new file mode 100644 index 000000000..fad86e547 --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-secret.yaml @@ -0,0 +1,74 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring +stringData: + alertmanager.yaml: |- + "global": + "resolve_timeout": "5m" + "inhibit_rules": + - "equal": + - "namespace" + - "alertname" + "source_matchers": + - "severity = critical" + "target_matchers": + - "severity =~ warning|info" + - "equal": + - "namespace" + - "alertname" + "source_matchers": + - "severity = warning" + "target_matchers": + - "severity = info" + - "equal": + - "namespace" + "source_matchers": + - "alertname = InfoInhibitor" + "target_matchers": + - "severity = info" + "receivers": + - "name": "Default" + - "name": "Watchdog" + - "name": "Critical" + - "name": "null" + "route": + "group_by": + - "namespace" + "group_interval": "5m" + "group_wait": "30s" + "receiver": "Default" + "repeat_interval": "12h" + "routes": + - "matchers": + - "alertname = Watchdog" + "receiver": "Watchdog" + - "matchers": + - "alertname = InfoInhibitor" + "receiver": "null" + - "matchers": + - "severity = critical" + "receiver": "Critical" +type: Opaque diff --git a/release/kubernetes/monitoring/alertmanager-service.yaml b/release/kubernetes/monitoring/alertmanager-service.yaml new file mode 100644 index 000000000..e087f019d --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-service.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring +spec: + ports: + - name: web + port: 9093 + targetPort: web + - name: reloader-web + port: 8080 + targetPort: reloader-web + selector: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + sessionAffinity: ClientIP diff --git a/release/kubernetes/monitoring/alertmanager-serviceAccount.yaml b/release/kubernetes/monitoring/alertmanager-serviceAccount.yaml new file mode 100644 index 000000000..e6817a61f --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-serviceAccount.yaml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring diff --git a/release/kubernetes/monitoring/alertmanager-serviceMonitor.yaml b/release/kubernetes/monitoring/alertmanager-serviceMonitor.yaml new file mode 100644 index 000000000..7816bc0ee --- /dev/null +++ b/release/kubernetes/monitoring/alertmanager-serviceMonitor.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.28.1 + name: alertmanager-main + namespace: monitoring +spec: + endpoints: + - interval: 30s + port: web + - interval: 30s + port: reloader-web + selector: + matchLabels: + app.kubernetes.io/component: alert-router + app.kubernetes.io/instance: main + app.kubernetes.io/name: alertmanager + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/blackboxExporter-clusterRole.yaml b/release/kubernetes/monitoring/blackboxExporter-clusterRole.yaml new file mode 100644 index 000000000..0d769c785 --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-clusterRole.yaml @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/release/kubernetes/monitoring/blackboxExporter-clusterRoleBinding.yaml b/release/kubernetes/monitoring/blackboxExporter-clusterRoleBinding.yaml new file mode 100644 index 000000000..bb4012908 --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-clusterRoleBinding.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: blackbox-exporter +subjects: +- kind: ServiceAccount + name: blackbox-exporter + namespace: monitoring diff --git a/release/kubernetes/monitoring/blackboxExporter-configuration.yaml b/release/kubernetes/monitoring/blackboxExporter-configuration.yaml new file mode 100644 index 000000000..6a5084328 --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-configuration.yaml @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +data: + config.yml: |- + "modules": + "http_2xx": + "http": + "preferred_ip_protocol": "ip4" + "prober": "http" + "http_post_2xx": + "http": + "method": "POST" + "preferred_ip_protocol": "ip4" + "prober": "http" + "irc_banner": + "prober": "tcp" + "tcp": + "preferred_ip_protocol": "ip4" + "query_response": + - "send": "NICK prober" + - "send": "USER prober prober prober :prober" + - "expect": "PING :([^ ]+)" + "send": "PONG ${1}" + - "expect": "^:[^ ]+ 001" + "pop3s_banner": + "prober": "tcp" + "tcp": + "preferred_ip_protocol": "ip4" + "query_response": + - "expect": "^+OK" + "tls": true + "tls_config": + "insecure_skip_verify": false + "ssh_banner": + "prober": "tcp" + "tcp": + "preferred_ip_protocol": "ip4" + "query_response": + - "expect": "^SSH-2.0-" + "tcp_connect": + "prober": "tcp" + "tcp": + "preferred_ip_protocol": "ip4" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter-configuration + namespace: monitoring diff --git a/release/kubernetes/monitoring/blackboxExporter-deployment.yaml b/release/kubernetes/monitoring/blackboxExporter-deployment.yaml new file mode 100644 index 000000000..0872dba2c --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-deployment.yaml @@ -0,0 +1,133 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: blackbox-exporter + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + spec: + automountServiceAccountToken: true + containers: + - args: + - --config.file=/etc/blackbox_exporter/config.yml + - --web.listen-address=:19115 + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus/blackbox-exporter:v0.27.0 + name: blackbox-exporter + ports: + - containerPort: 19115 + name: http + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + volumeMounts: + - mountPath: /etc/blackbox_exporter/ + name: config + readOnly: true + - args: + - --webhook-url=http://localhost:19115/-/reload + - --volume-dir=/etc/blackbox_exporter/ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jimmidyson/configmap-reload:v0.15.0 + name: module-configmap-reloader + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/blackbox_exporter/ + name: config + readOnly: true + - args: + - --secure-listen-address=:9115 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:19115/ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/brancz/kube-rbac-proxy:v0.19.1 + name: kube-rbac-proxy + ports: + - containerPort: 9115 + name: https + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: blackbox-exporter + volumes: + - configMap: + name: blackbox-exporter-configuration + name: config diff --git a/release/kubernetes/monitoring/blackboxExporter-networkPolicy.yaml b/release/kubernetes/monitoring/blackboxExporter-networkPolicy.yaml new file mode 100644 index 000000000..64e1a4894 --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-networkPolicy.yaml @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 9115 + protocol: TCP + - port: 19115 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/blackboxExporter-service.yaml b/release/kubernetes/monitoring/blackboxExporter-service.yaml new file mode 100644 index 000000000..6eb6e33de --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-service.yaml @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter + namespace: monitoring +spec: + ports: + - name: https + port: 9115 + targetPort: https + - name: probe + port: 19115 + targetPort: http + selector: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/blackboxExporter-serviceAccount.yaml b/release/kubernetes/monitoring/blackboxExporter-serviceAccount.yaml new file mode 100644 index 000000000..72077c849 --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter + namespace: monitoring diff --git a/release/kubernetes/monitoring/blackboxExporter-serviceMonitor.yaml b/release/kubernetes/monitoring/blackboxExporter-serviceMonitor.yaml new file mode 100644 index 000000000..015a20d2c --- /dev/null +++ b/release/kubernetes/monitoring/blackboxExporter-serviceMonitor.yaml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.27.0 + name: blackbox-exporter + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + path: /metrics + port: https + scheme: https + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: blackbox-exporter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/dubbo-serviceMonitor.yaml b/release/kubernetes/monitoring/dubbo-serviceMonitor.yaml new file mode 100644 index 000000000..dd4c1cfbf --- /dev/null +++ b/release/kubernetes/monitoring/dubbo-serviceMonitor.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + org.apache.dubbo/service-monitor: dubbo-metrics + name: dubbo-metrics + namespace: monitoring +spec: + endpoints: + - metricRelabelings: + - action: keep + regex: '(.*):.*' + replacement: $1 + sourceLabels: + - instance + targetLabel: instance + port: dubbo-qos + path: /metrics + interval: 1s + namespaceSelector: + any: true + selector: + matchLabels: + org.apache.dubbo/service: dubbo-qos + diff --git a/release/kubernetes/monitoring/grafana-config.yaml b/release/kubernetes/monitoring/grafana-config.yaml new file mode 100644 index 000000000..cb188466b --- /dev/null +++ b/release/kubernetes/monitoring/grafana-config.yaml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-config + namespace: monitoring +stringData: + grafana.ini: | + [date_formats] + default_timezone = UTC +type: Opaque diff --git a/release/kubernetes/monitoring/grafana-dashboardDatasources.yaml b/release/kubernetes/monitoring/grafana-dashboardDatasources.yaml new file mode 100644 index 000000000..be9a8baa6 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-dashboardDatasources.yaml @@ -0,0 +1,42 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-datasources + namespace: monitoring +stringData: + datasources.yaml: |- + { + "apiVersion": 1, + "datasources": [ + { + "access": "proxy", + "editable": false, + "name": "prometheus", + "orgId": 1, + "type": "prometheus", + "url": "http://prometheus-k8s.monitoring.svc:9090", + "version": 1 + } + ] + } +type: Opaque diff --git a/release/kubernetes/monitoring/grafana-dashboardDefinitions.yaml b/release/kubernetes/monitoring/grafana-dashboardDefinitions.yaml new file mode 100644 index 000000000..bcd0bbee5 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-dashboardDefinitions.yaml @@ -0,0 +1,39060 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +items: + - apiVersion: v1 + data: + dubbo-application-metrics.json: |- + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 39, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 14, + "panels": [], + "title": "应用概览", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "无", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 90 + }, + { + "color": "dark-green", + "value": 100 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 19, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "(sum(dubbo_consumer_requests_succeed_total{application_name=\"$application\"}) / sum(dubbo_consumer_requests_total{application_name=\"$application\"}) ) OR on() vector(NAN)", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "调用成功率(作为消费者)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "No data", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 90 + }, + { + "color": "dark-green", + "value": 100 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 20, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (dubbo_provider_requests_succeed_total{application_name=\"$application\"}) / sum (dubbo_provider_requests_total{application_name=\"$application\"}) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "被调用成功率(作为生产者)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 43, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_provider_qps_total{application_name=\"$application\"})", + "instant": false, + "legendFormat": "生产者被调用", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_consumer_qps_total{application_name=\"$application\"})", + "hide": false, + "instant": false, + "legendFormat": "消费者调用", + "range": true, + "refId": "B" + } + ], + "title": "QPS", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 48, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_avg_milliseconds_aggregate{application_name=\"$application\"}>0)", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "调用 avg RT", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_avg_milliseconds_aggregate{application_name=\"$application\"}>0)", + "hide": false, + "instant": false, + "legendFormat": "被调用 avg RT", + "range": true, + "refId": "B" + } + ], + "title": "RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "当前正在处理的请求", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 1 + }, + "id": 60, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_requests_processing{application_name=\"$application\"} or vector(0)", + "instant": false, + "legendFormat": "生产者处理并发量", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_requests_processing{application_name=\"$application\"} or vector(0)", + "hide": false, + "instant": false, + "legendFormat": "消费者调用并发量", + "range": true, + "refId": "B" + } + ], + "title": "并发", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 8 + }, + "id": 63, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_milliseconds_last{application_name=\"$application\"})", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近调用RT(作为生产者)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 6, + "y": 8 + }, + "id": 31, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_business_failed_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_timeout_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_unknown_failed_tota{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_network_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_codec_total{application_name=\"$application\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "编解码错误数", + "range": true, + "refId": "I" + } + ], + "title": "调用总览(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 15, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{application_name=\"$application\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{application_name=\"$application\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_total{application_name=\"$application\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_business_failed_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_timeout_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_unknown_failed_tota{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_network_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_codec_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "序列化错误数", + "range": true, + "refId": "I" + } + ], + "title": "被调用总览(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 13 + }, + "id": 62, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_consumer_rt_milliseconds_last{application_name=\"$application\"})", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近调用RT(作为消费者)", + "type": "stat" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 6, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 1, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(sum(dubbo_provider_qps_total{application_name=\"$application\"}) by (instance))", + "hide": false, + "instant": false, + "legendFormat": "平均QPS", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_provider_qps_total{application_name=\"$application\"}) by (instance, pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "被调用QPS(作为生产者)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 2, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(sum(dubbo_consumer_qps_total{application_name=\"$application\"}) by (instance))", + "hide": false, + "instant": false, + "legendFormat": "平均QPS", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_consumer_qps_total{application_name=\"$application\"}) by (instance, pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "调用QPS(作为消费者)", + "type": "timeseries" + } + ], + "title": "QPS (生产者 & 消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 36, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 37 + }, + "id": 32, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{application_name=\"$application\"}[2m])>0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_total{application_name=\"$application\"}[2m])>0) by (instance,pod) ", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "调用总数(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 37 + }, + "id": 33, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_succeed_total{application_name=\"$application\"}[2m])>0) ", + "instant": false, + "legendFormat": "成功总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{application_name=\"$application\"}[2m])>0) by (instance,pod) ", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "调用成功(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 37 + }, + "id": 34, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_total{application_name=\"$application\"}[2m])>0) ", + "instant": false, + "legendFormat": "失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{application_name=\"$application\"}[2m])>0) by (instance,pod) ", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "调用失败(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 47 + }, + "id": 35, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_business_failed_total{application_name=\"$application\"}[2m]))", + "instant": false, + "legendFormat": "业务原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_business_failed_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 47 + }, + "id": 38, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_timeout_total{application_name=\"$application\"}[2m])) ", + "instant": false, + "legendFormat": "超时错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_timeout_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "超时错误(Consumer 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 47 + }, + "id": 40, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "服务不可用总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m])) by (instance,pod) >0", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 57 + }, + "id": 41, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_network_total{application_name=\"$application\"}[2m])) ", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_network_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 57 + }, + "id": 42, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_codec_total{application_name=\"$application\"}[2m])) ", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_codec_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 57 + }, + "id": 39, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_unknown_failed_tota{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "未知原因失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_unknown_failed_total{application_name=\"$application\"}[2m])) by (instance,pod)>0", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(作为消费者 2min)", + "type": "timeseries" + } + ], + "title": "应用调用详情(作为消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 5, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 21 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_total{application_name=\"$application\"}[2m])) by (instance,pod)>0", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "被调用总数(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 21 + }, + "id": 23, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_succeed_total{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{application_name=\"$application\"}[2m])) by (instance,pod)>0", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "被调用成功(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 21 + }, + "id": 22, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_total{application_name=\"$application\"}[2m]))>0", + "instant": false, + "legendFormat": "失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_total{application_name=\"$application\"}[2m])) by (instance,pod)>0", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "被调用失败(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 31 + }, + "id": 25, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_business_failed_total{application_name=\"$application\"}[2m]))>0", + "instant": false, + "legendFormat": "业务原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_business_failed_total{application_name=\"$application\"} [2m]) )by(instance,pod)>0\r\n", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 31 + }, + "id": 26, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_timeout_total{application_name=\"$application\"}[2m]))", + "instant": false, + "legendFormat": "超时总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_timeout_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "超时错误(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 31 + }, + "id": 28, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m]))", + "instant": false, + "legendFormat": "服务不可用总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 41 + }, + "id": 29, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_network_total{application_name=\"$application\"}[2m]))>0", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(label_replace(increase(dubbo_provider_requests_failed_network_total{application_name=\"$application\"}[2m]), \"instance\", \"$1\", \"instance\", \"(.*):.*\")) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 41 + }, + "id": 30, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_codec_total{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_codec_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 41 + }, + "id": 27, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_unknown_failed_total{application_name=\"$application\"}[2m])) >0", + "instant": false, + "legendFormat": "未知原因失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_unknown_failed_total{application_name=\"$application\"}[2m])) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(作为生产者 2min)", + "type": "timeseries" + } + ], + "title": "应用被调用详情(作为生产者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 51, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 13, + "x": 0, + "y": 22 + }, + "id": 49, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p95{application_name=\"$application\",}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p95{application_name=\"$application\",}>0) by(instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{pod}", + "range": true, + "refId": "B" + } + ], + "title": "调用 RT P95(作为消费者)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 11, + "x": 13, + "y": 22 + }, + "id": 50, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p99{application_name=\"$application\",}>0)", + "hide": true, + "instant": false, + "legendFormat": "avg (RT P99)", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p99{application_name=\"$application\",}>0) by (instance,pod)", + "hide": false, + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "调用 RT P99(作为消费者)", + "type": "timeseries" + } + ], + "title": "应用请求时延RT (Consumer)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 7, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 13, + "x": 0, + "y": 23 + }, + "id": 10, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p95{application_name=\"$application\",}>0) by (instance,pod)", + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "A" + } + ], + "title": "RT P95(作为生产者)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 11, + "x": 13, + "y": 23 + }, + "id": 11, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p99{application_name=\"$application\",}>0) by (instance,pod)", + "instant": false, + "legendFormat": "{{instance}}_{{pod}}", + "range": true, + "refId": "A" + } + ], + "title": "响应平均时延 P99(Provider)", + "type": "timeseries" + } + ], + "title": "应用响应时延RT (Provider)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 54, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 9, + "gradientMode": "hue", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 52, + "interval": "30s", + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(dubbo_registry_register_requests_total{application_name=\"$application\"})", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "注册总次数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_registry_register_requests_succeed_total{application_name=\"$application\"})OR on() vector(0)", + "format": "time_series", + "hide": false, + "legendFormat": "注册成功数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(dubbo_registry_register_requests_failed_total{application_name=\"$application\"}) OR on() vector(0)", + "hide": false, + "instant": false, + "legendFormat": "注册失败数", + "range": true, + "refId": "C" + } + ], + "title": "注册实例次数", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 53, + "interval": "30s", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "dubbo_register_rt_milliseconds_sum{application_name=\"$application\"}", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "range": true, + "refId": "A" + } + ], + "title": "实例注册时长", + "type": "timeseries" + } + ], + "title": "注册中心", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 61, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "只有启动成功的实例并接入监控的才会显示", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "center", + "cellOptions": { + "type": "json-view" + }, + "inspect": false + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "application_version" + }, + "properties": [ + { + "id": "custom.width", + "value": 151 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "clusterName" + }, + "properties": [ + { + "id": "custom.width", + "value": 107 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "custom.width", + "value": 133 + }, + { + "id": "displayName", + "value": "ip" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "application_name" + }, + "properties": [ + { + "id": "custom.width", + "value": 167 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 0, + "y": 139 + }, + "id": 15, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": true, + "enablePagination": true, + "fields": [], + "reducer": [ + "count" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count (dubbo_application_info_total{application_name=\"$application\"}) by(application_name,instance,application_version,host,pod,clusterName)", + "format": "table", + "instant": true, + "legendFormat": "实例总数", + "range": false, + "refId": "A" + } + ], + "title": "实例", + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "有请求的接口才会展示", + "fieldConfig": { + "defaults": { + "color": { + "mode": "fixed" + }, + "custom": { + "align": "center", + "cellOptions": { + "type": "json-view" + }, + "filterable": false, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 7, + "x": 10, + "y": 139 + }, + "id": 56, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": [ + "Value" + ], + "reducer": [ + "sum" + ], + "show": true + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count by(interface,version) (dubbo_provider_requests_total{application_name=\"$application\",interface!~\"org.apache.dubbo.metrics.service.MetricsService|org.apache.dubbo.metadata.MetadataService\"})", + "format": "table", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "提供接口", + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "有请求的接口才会展示", + "fieldConfig": { + "defaults": { + "color": { + "mode": "fixed" + }, + "custom": { + "align": "center", + "cellOptions": { + "type": "json-view" + }, + "filterable": false, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 7, + "x": 17, + "y": 139 + }, + "id": 58, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": [ + "Value" + ], + "reducer": [ + "sum" + ], + "show": true + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count by(interface,version) (dubbo_consumer_requests_total{application_name=\"$application\",interface!~\"org.apache.dubbo.metrics.service.MetricsService|org.apache.dubbo.metadata.MetadataService\"})", + "format": "table", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "消费接口", + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "noValue": "NAN" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 2, + "x": 0, + "y": 146 + }, + "id": 55, + "options": { + "displayLabels": [ + "name", + "value" + ], + "legend": { + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count by(application_version)(dubbo_application_info_total{application_name=\"$application\",instance=~\".*\"})", + "instant": true, + "legendFormat": "{{application_version}}", + "range": false, + "refId": "A" + } + ], + "title": "实例版本分布", + "type": "piechart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "准确的提供接口数量", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 2, + "y": 146 + }, + "id": 16, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": { + "titleSize": 100 + }, + "textMode": "value" + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count(count by(interface) (dubbo_provider_requests_total{application_name=\"$application\",interface!~\"org.apache.dubbo.metrics.service.MetricsService|org.apache.dubbo.metadata.MetadataService\"}))", + "format": "time_series", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "提供接口数", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "准确的提供接口数量", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 5, + "y": 146 + }, + "id": 59, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": { + "titleSize": 100 + }, + "textMode": "value" + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count(count by(interface) (dubbo_consumer_requests_total{application_name=\"$application\",interface!~\"org.apache.dubbo.metrics.service.MetricsService|org.apache.dubbo.metadata.MetadataService\"}))", + "format": "time_series", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "消费接口数", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 151 + }, + "id": 47, + "options": { + "calculate": true, + "calculation": { + "xBuckets": { + "mode": "size" + }, + "yBuckets": { + "mode": "size", + "scale": { + "log": 10, + "type": "log" + } + } + }, + "cellGap": 0, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true, + "showLegend": true + }, + "rowsFrame": { + "layout": "le" + }, + "tooltip": { + "show": true, + "yHistogram": true + }, + "yAxis": { + "axisPlacement": "right", + "decimals": 1, + "reverse": false, + "unit": "ms" + } + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "histogram_quantile(0.9, sum(rate(dubbo_provider_rt_milliseconds_histogram_seconds_bucket{application_name=\"$application\",method=\"getItem\"}[2m])) by (le))", + "format": "heatmap", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "响应时延热点图 (Provider)", + "type": "heatmap" + } + ], + "title": "deprecated", + "type": "row" + } + ], + "refresh": "1m", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "prometheus", + "value": "P1809F7CD0C75ACF3" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "shop-detail", + "value": "shop-detail" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_application_info_total{},application_name)", + "hide": 0, + "includeAll": false, + "multi": false, + "name": "application", + "options": [], + "query": { + "query": "label_values(dubbo_application_info_total{},application_name)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + }, + { + "allValue": ".*", + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_application_info_total{application_name=\"$application\"},instance)", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "instance", + "options": [], + "query": { + "query": "label_values(dubbo_application_info_total{application_name=\"$application\"},instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Application metrics", + "uid": "a0b114ca-edf7-4dfe-ac2c-34a4fc545fed", + "version": 2, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-application-metrics + namespace: monitoring + - apiVersion: v1 + data: + dubbo-application-traces.json: |- + { + "title": "Application traces", + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 34, + "links": [], + "panels": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 15, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "mean" + ], + "show": true + }, + "showHeader": true + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "queryType": "search", + "refId": "A", + "service": "${application}", + "tags": "" + } + ], + "title": "Trace Table", + "type": "table" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "jaeger", + "value": "fe670vj54q48wc" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "datasource", + "options": [], + "query": "jaeger", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "text": "shop-detail", + "value": "shop-detail" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "application", + "options": [], + "query": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Application traces", + "uid": "e968a89b-f03d-42e3-8ad3-930ae815cb0f", + "version": 8, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-application-traces + namespace: monitoring + - apiVersion: v1 + data: + dubbo-instance-metrics.json: |- + { + "title": "Instance metrics", + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 41, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [], + "title": "实例概览", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "无", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 90 + }, + { + "color": "dark-green", + "value": 95 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 10, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "(sum(dubbo_consumer_requests_succeed_total{application_name=\"$application\",instance=\"$instance\"}) / sum(dubbo_consumer_requests_total{application_name=\"$application\",instance=\"$instance\"}) ) OR on() vector(NAN)", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "调用成功率(作为消费者)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "No data", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 90 + }, + { + "color": "dark-green", + "value": 95 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 9, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (dubbo_provider_requests_succeed_total{application_name=\"$application\",instance=\"$instance\"}) / sum (dubbo_provider_requests_total{application_name=\"$application\",instance=\"$instance\"}) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "被调用成功率(作为生产者)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 7, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_provider_qps_total{application_name=\"$application\",instance=\"$instance\"})", + "instant": false, + "legendFormat": "提供端QPS", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_consumer_qps_total{application_name=\"$application\",instance=\"$instance\"})", + "hide": false, + "instant": false, + "legendFormat": "消费者QPS", + "range": true, + "refId": "B" + } + ], + "title": "QPS", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 16, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_consumer_rt_avg_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0)", + "instant": false, + "legendFormat": "消费者RT", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_avg_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0)", + "hide": false, + "instant": false, + "legendFormat": "提供端RT", + "range": true, + "refId": "C" + } + ], + "title": "RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 1 + }, + "id": 51, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum (dubbo_provider_requests_processing{instance=\"$instance\"} ) OR vector (0)", + "instant": false, + "legendFormat": "生产者处理并发量", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_consumer_requests_processing{instance=\"$instance\"}) OR vector (0)", + "hide": false, + "instant": false, + "legendFormat": "消费者调用并发量", + "range": true, + "refId": "B" + } + ], + "title": "并发", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "": { + "index": 0, + "text": "{{.Value}}ms" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 8 + }, + "id": 23, + "interval": "15", + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_rt_milliseconds_last{application_name=\"$application\",instance=\"$instance\"}", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近被调用RT(作为生产者)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 6, + "y": 8 + }, + "id": 5, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{application_name=\"$application\",instance=\"$instance\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{application_name=\"$application\",instance=\"$instance\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_timeout_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "请求超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_unknown_failed_tota{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_network_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_codec_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "序列化错误数", + "range": true, + "refId": "I" + } + ], + "title": "实例调用(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 15, + "y": 8 + }, + "id": 4, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{application_name=\"$application\",instance=\"$instance\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_total{application_name=\"$application\",instance=\"$instance\"}[2m]) ) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_timeout_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_unknown_failed_tota{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_network_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_provider_requests_failed_codec_total{application_name=\"$application\"}[2m])) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "序列化错误数", + "range": true, + "refId": "I" + } + ], + "title": "实例被调用(作为生产者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "": { + "index": 0, + "text": "{{.Value}}ms" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 13 + }, + "id": 28, + "interval": "5", + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_rt_milliseconds_last{application_name=\"$application\",instance=\"$instance\"}", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近调用时延(作为消费者)", + "type": "stat" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 6, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 44 + }, + "id": 29, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_provider_qps_total{application_name=\"$application\",instance=\"$instance\",}) by (interface)", + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "A" + } + ], + "title": "提供接口QPS(作为生产者)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 44 + }, + "id": 30, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_consumer_qps_total{application_name=\"$application\",instance=\"$instance\",}) by (interface)", + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "A" + } + ], + "title": "依赖接口QPS(作为消费者)", + "type": "timeseries" + } + ], + "title": "实例QPS 详情(生产者&消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 38, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 45 + }, + "id": 45, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "请求总数(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 45 + }, + "id": 46, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_succeed_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求成功总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "请求成功(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 45 + }, + "id": 47, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "请求失败(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 53 + }, + "id": 39, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) or vector(0)", + "instant": false, + "legendFormat": "业务原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface)", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 53 + }, + "id": 40, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_timeout_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "超时错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_timeout_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "超时错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 53 + }, + "id": 42, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "服务不可用错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 61 + }, + "id": 43, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_network_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_network_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 61 + }, + "id": 44, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_codec_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_codec_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 61 + }, + "id": 41, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_unknown_failed_tota{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "未知原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_unknown_failed_tota{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface)", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(2min)", + "type": "timeseries" + } + ], + "title": "实例被调用详情(作为生产者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 31, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 46 + }, + "id": 48, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "调用总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "调用总数(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 46 + }, + "id": 49, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_succeed_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "调用成功总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "调用成功(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 46 + }, + "id": 50, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_total{instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "调用失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{instance=\"$instance\",}[2m])) by (interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "调用失败(作为消费者 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "Value" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 54 + }, + "id": 32, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "业务原因错误", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_business_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface)", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 54 + }, + "id": 33, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_timeout_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "超时错误", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_timeout_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface)", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "超时错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 54 + }, + "id": 35, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "服务不可用", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_service_unavailable_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 62 + }, + "id": 36, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_network_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_network_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface)", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 62 + }, + "id": 37, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_codec_total{application_name=\"$application\",instance=\"$instance\",}[2m])) or vector(0)", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_codec_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 62 + }, + "id": 34, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_unknown_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) or vector(0)", + "instant": false, + "legendFormat": "未知原因错误", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_unknown_failed_total{application_name=\"$application\",instance=\"$instance\",}[2m])) by(interface) ", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(2min)", + "type": "timeseries" + } + ], + "title": "实例调用详情(作为消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 8, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为生产者,响应上游服务的95%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 47 + }, + "id": 13, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p95{application_name=\"$application\",instance=\"$instance\",}>0)", + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_rt_milliseconds_p95{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}.{{method}} P95 RT", + "range": true, + "refId": "B" + } + ], + "title": "RT P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为生产者,响应上游服务的99%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 47 + }, + "id": 14, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p99{application_name=\"$application\",instance=\"$instance\",}>0)", + "instant": false, + "legendFormat": "avgRT P99", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_rt_milliseconds_p99{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}.{{method}} P99 RT", + "range": true, + "refId": "B" + } + ], + "title": "RT P99", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为生产者,响应上游服务请求的最小RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 15, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_provider_rt_min_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_rt_min_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}.{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "min RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为生产者,响应上游服务请求的最大RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 12, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "max(dubbo_provider_rt_max_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "maxRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_provider_rt_min_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}.{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "max RT", + "type": "timeseries" + } + ], + "title": "实例 RT 详情(作为生产者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 17, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为消费者,调用下游服务时95%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p95{application_name=\"$application\",instance=\"$instance\",}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_rt_milliseconds_p95{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为消费者,调用下游服务时99%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 48 + }, + "id": 19, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p99{application_name=\"$application\",instance=\"$instance\",}>0)", + "instant": false, + "legendFormat": "avgRT P99", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_rt_milliseconds_p99{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P99(Consumer)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为消费者,调用下游服务的最小RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 57 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_consumer_rt_min_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_rt_min_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "A" + } + ], + "title": "min RT ", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "作为消费者,调用下游服务的最大RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 57 + }, + "id": 20, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "max(dubbo_consumer_rt_max_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "maxRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "dubbo_consumer_rt_max_milliseconds_aggregate{application_name=\"$application\",instance=\"$instance\",}>0", + "hide": false, + "instant": false, + "legendFormat": "{{interface}}", + "range": true, + "refId": "A" + } + ], + "title": "max RT", + "type": "timeseries" + } + ], + "title": "实例 RT 详情 (作为消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 27, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 4, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "dubbo_thread_pool_core_size{application_name=\"$application\",instance=\"$instance\",thread_pool_name!~\".*MetadataService.*|.*MetricsService.*\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{thread_pool_name}}", + "range": true, + "refId": "A" + } + ], + "title": "线程池核心", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 4, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "dubbo_thread_pool_active_size{application_name=\"$application\",instance=\"$instance\",thread_pool_name!~\".*MetadataService.*|.*MetricsService.*\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{thread_pool_name}}", + "range": true, + "refId": "A" + } + ], + "title": "线程池活跃", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 4, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 55 + }, + "id": 25, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "dubbo_thread_pool_queue_size{application_name=\"$application\",instance=\"$instance\",thread_pool_name!~\".*MetadataService.*|.*MetricsService.*\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{thread_pool_name}}", + "range": true, + "refId": "A" + } + ], + "title": "线程池队列", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 4, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 55 + }, + "id": 26, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "dubbo_thread_pool_largest_size{application_name=\"$application\",instance=\"$instance\",thread_pool_name!~\".*MetadataService.*|.*MetricsService.*\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{thread_pool_name}}", + "range": true, + "refId": "A" + } + ], + "title": "线程池最大", + "type": "timeseries" + } + ], + "title": "Dubbo线程池", + "type": "row" + } + ], + "preload": false, + "refresh": "1m", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "prometheus", + "value": "P1809F7CD0C75ACF3" + }, + "includeAll": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": { + "text": "shop-detail", + "value": "shop-detail" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_application_info_total{},application_name)", + "includeAll": false, + "name": "application", + "options": [], + "query": { + "query": "label_values(dubbo_application_info_total{},application_name)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "type": "query" + }, + { + "current": { + "text": "10.111.251.103:22222", + "value": "10.111.251.103:22222" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_application_info_total{application_name=\"$application\"},instance)", + "includeAll": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values(dubbo_application_info_total{application_name=\"$application\"},instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "type": "query" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Instance metrics", + "uid": "dcf5defe-d198-4704-9edf-6520838880e9", + "version": 1, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-instance-metrics + namespace: monitoring + - apiVersion: v1 + data: + dubbo-instance-traces.json: |- + { + "title": "Instance traces", + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 35, + "links": [], + "panels": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "queryType": "search", + "refId": "A", + "service": "${application}", + "tags": "net.peer.name=${instance}" + } + ], + "title": "Panel Title", + "type": "table" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "jaeger", + "value": "fe670vj54q48wc" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "datasource", + "options": [], + "query": "jaeger", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "text": "", + "value": "" + }, + "hide": 0, + "includeAll": false, + "label": "application", + "multi": false, + "name": "application", + "options": [], + "query": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": { + "text": "", + "value": "" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "instance", + "options": [], + "query": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Instance traces", + "uid": "f5f48f75-13ec-489b-88ae-635ae38d8618", + "version": 8, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-instance-traces + namespace: monitoring + - apiVersion: v1 + data: + dubbo-service-metrics.json: |- + { + "title": "Service metrics", + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 42, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 5, + "panels": [], + "title": "接口总览", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "无", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 95 + }, + { + "color": "dark-green", + "value": 100 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 1, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "(sum(dubbo_consumer_requests_succeed_total{interface=\"$service\",method=~\"$method\"}) / sum(dubbo_consumer_requests_total{interface=\"$service\",method=~\"$method\"}) ) OR on() vector(NAN)", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "调用成功率(Consumer)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "noValue": "No data", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-yellow", + "value": 95 + }, + { + "color": "dark-green", + "value": 100 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 2, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": true, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(sum(dubbo_provider_requests_succeed_total{interface=\"$service\",method=~\"$method\"}) / sum(dubbo_provider_requests_total{interface=\"$service\",method=~\"$method\"}) ) OR on() vector(NAN)", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "被调用成功率(Provider)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 3, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_consumer_qps_total{interface=\"$service\",method=~\"$method\"})", + "instant": false, + "legendFormat": "调用(消费者视角)", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_provider_qps_total{interface=\"$service\",method=~\"$method\"})", + "hide": false, + "instant": false, + "legendFormat": "被调用(生产者视角)", + "range": true, + "refId": "B" + } + ], + "title": "QPS", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 25, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "asc" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_avg_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0)", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "调用 avg RT", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_avg_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0)", + "hide": false, + "instant": false, + "legendFormat": "被调用 avg RT", + "range": true, + "refId": "B" + } + ], + "title": "RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 1 + }, + "id": 26, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum (dubbo_provider_requests_processing{interface=\"$service\"} ) OR vector (0)", + "instant": false, + "legendFormat": "生产者处理并发量", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(dubbo_consumer_requests_processing{interface=\"$service\"}) OR vector (0)", + "hide": false, + "instant": false, + "legendFormat": "消费者调用并发量", + "range": true, + "refId": "B" + } + ], + "title": "并发", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 8 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_milliseconds_last{interface=\"$service\",method=~\"$method\"})", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近被调用时延(RT)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 6, + "y": 8 + }, + "id": 28, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "请求失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_business_failed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_timeout_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_unknown_failed_tota{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_service_unavailable_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_network_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_codec_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "序列化错误数", + "range": true, + "refId": "I" + } + ], + "title": "被调用总览(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 9, + "x": 15, + "y": 8 + }, + "id": 10, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "instant": false, + "legendFormat": "总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "成功数", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "请求失败数", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_business_failed_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "业务原因失败数", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_timeout_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "超时数", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_unknown_failed_tota{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "未知原因失败数", + "range": true, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_service_unavailable_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "服务不可用数", + "range": true, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_network_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "网络错误数", + "range": true, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase (dubbo_consumer_requests_failed_codec_total{interface=\"$service\"}[2m])>0) OR vector(0)", + "hide": false, + "instant": false, + "legendFormat": "编解码错误数", + "range": true, + "refId": "I" + } + ], + "title": "调用总览(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 13 + }, + "id": 27, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^实时时延$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_consumer_rt_milliseconds_last{interface=\"$service\",method=~\"$method\"})", + "instant": false, + "legendFormat": "实时时延", + "range": true, + "refId": "A" + } + ], + "title": "最近调用时延(RT)", + "type": "stat" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 6, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 3 + }, + "id": 7, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_provider_qps_total{interface=\"$service\"}) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "被调用QPS (生产者视角)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 8, + "interval": "1s", + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(dubbo_consumer_qps_total{interface=\"$service\"}) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "调用QPS(消费者视角)", + "type": "timeseries" + } + ], + "title": "接口QPS详情(生产者&消费者)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 38, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 20 + }, + "id": 39, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求总数(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 20 + }, + "id": 40, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_succeed_total{interface=\"$service\"}[2m])) or vector(0) ", + "instant": false, + "legendFormat": "请求成功总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_succeed_total{interface=\"$service\",method=~\"$method\"}[2m])>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求成功(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 20 + }, + "id": 41, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求失败数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_total{interface=\"$service\",method=~\"$method\"}[2m])>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求失败(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 28 + }, + "id": 42, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_business_failed_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "业务原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_business_failed_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 28 + }, + "id": 43, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_timeout_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "请求超时总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_timeout_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求超时错误(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 28 + }, + "id": 44, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_service_unavailable_total{interface=\"$service\"}[2m])) ", + "instant": false, + "legendFormat": "服务不可用总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_service_unavailable_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 36 + }, + "id": 45, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_network_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_network_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 36 + }, + "id": 46, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_failed_codec_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_failed_codec_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(生产者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 36 + }, + "id": 47, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_provider_requests_unknown_failed_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "未知原因失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_provider_requests_unknown_failed_total{interface=\"$service\",method=~\"method\"}[2m])) by (mehtod)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(生产者视角 2min)", + "type": "timeseries" + } + ], + "title": "接口被调用详情(生产者详情)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 9, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 4 + }, + "id": 12, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求总数(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 4 + }, + "id": 13, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_succeed_total{interface=\"$service\"}[2m])) or vector(0) ", + "instant": false, + "legendFormat": "请求成功数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_succeed_total{interface=\"$service\",method=~\"$method\"}[2m])>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求成功(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 4 + }, + "id": 14, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "请求失败数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_total{interface=\"$service\",method=~\"$method\"}[2m])>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求失败(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 12 + }, + "id": 11, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_business_failed_total{interface=\"$service\"}[2m])) or vector(0)", + "instant": false, + "legendFormat": "业务原因错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_business_failed_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "业务原因错误(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 12 + }, + "id": 16, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_timeout_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "请求超时总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_timeout_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "请求超时错误(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 12 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_service_unavailable_total{interface=\"$service\"}[2m])) ", + "instant": false, + "legendFormat": "服务不可用总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_service_unavailable_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "服务不可用错误(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 20 + }, + "id": 19, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_network_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "网络错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_network_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "网络错误(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 20 + }, + "id": 20, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_failed_codec_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "序列化错误总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_failed_codec_total{interface=\"$service\",method=~\"$method\"}[2m])) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "序列化错误(消费者视角 2min)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 20 + }, + "id": 17, + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum (increase(dubbo_consumer_requests_unknown_failed_total{interface=\"$service\"}[2m])) OR vector(0)", + "instant": false, + "legendFormat": "未知原因失败总数", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(increase(dubbo_consumer_requests_unknown_failed_total{interface=\"$service\",method=~\"method\"}[2m])) by (mehtod)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "未知原因错误(消费者视角 2min)", + "type": "timeseries" + } + ], + "title": "接口调用详情(消费者视角)", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 33, + "panels": [], + "title": "接口RT详情(生产者视角)", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "生产者响应 此接口的95%请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 22 + }, + "id": 34, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p95{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p95{interface=\"$service\",method=~\"$method\"}>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "生产者响应 此接口的99%请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 22 + }, + "id": 35, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p99{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_provider_rt_milliseconds_p99{interface=\"$service\",method=~\"$method\"}>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P99", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "生产者响应此接口请求的最小RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "getItem" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 36, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_provider_rt_min_milliseconds_aggregate{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_min_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "min RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "生产者响应此接口请求的最大RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "getItem" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 30 + }, + "id": 37, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_provider_rt_max_milliseconds_aggregate{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_provider_rt_max_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": " max RT", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 39 + }, + "id": 23, + "panels": [], + "title": "接口 RT详情(消费者视角)", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "消费者调用此接口时95%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 29, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p95{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p95{interface=\"$service\",method=~\"$method\"}>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "消费者调用此接口时99%的请求的RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 24, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 30, + "options": { + "legend": { + "calcs": [ + "min", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p99{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "avgRT P95 ", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "avg(dubbo_consumer_rt_milliseconds_p99{interface=\"$service\",method=~\"$method\"}>0) by (method) ", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "B" + } + ], + "title": "RT P99", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "消费者调用此接口的最小RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 31, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_consumer_rt_min_milliseconds_aggregate{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_consumer_rt_min_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "min RT", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "消费者调用此接口最大RT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 48 + }, + "id": 32, + "interval": "15", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "min(dubbo_consumer_rt_max_milliseconds_aggregate{interface=\"$service\"}>0)", + "hide": true, + "instant": false, + "legendFormat": "minRT", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(dubbo_consumer_rt_max_milliseconds_aggregate{interface=\"$service\",method=~\"$method\"}>0) by (method)", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "max RT", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 57 + }, + "id": 24, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "fixed" + }, + "custom": { + "align": "center", + "cellOptions": { + "type": "json-view" + }, + "filterable": false, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 41 + }, + "id": 21, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": [ + "Value" + ], + "reducer": [ + "sum" + ], + "show": true + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count by(method) (dubbo_provider_requests_total{interface=\"$service\"})", + "format": "table", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "接口方法", + "type": "table" + } + ], + "title": "deprecated", + "type": "row" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "prometheus", + "value": "P1809F7CD0C75ACF3" + }, + "includeAll": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": { + "text": "org.apache.dubbo.samples.CommentService", + "value": "org.apache.dubbo.samples.CommentService" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_provider_requests_total{},interface)", + "description": "接口名", + "includeAll": false, + "label": "service", + "name": "service", + "options": [], + "query": { + "query": "label_values(dubbo_provider_requests_total{},interface)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "allValue": ".*", + "current": { + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(dubbo_provider_requests_total{interface=\"$service\"},method)", + "includeAll": true, + "multi": true, + "name": "method", + "options": [], + "query": { + "query": "label_values(dubbo_provider_requests_total{interface=\"$service\"},method)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Service metrics", + "uid": "ec689613-b4a1-45b1-b8bd-9d557059f970", + "version": 1, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-service-metrics + namespace: monitoring + - apiVersion: v1 + data: + dubbo-service-traces.json: |- + { + "title": "Service traces", + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 36, + "links": [], + "panels": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Trace name" + }, + "properties": [ + { + "id": "custom.width", + "value": 315 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.4.14", + "targets": [ + { + "datasource": { + "type": "jaeger", + "uid": "${datasource}" + }, + "queryType": "search", + "refId": "A", + "service": "${application}", + "tags": "rpc.service=${service}" + } + ], + "title": "Panel Title", + "type": "table" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "jaeger", + "value": "fe670vj54q48wc" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "datasource", + "options": [], + "query": "jaeger", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "text": "shop-detail", + "value": "shop-detail" + }, + "hide": 0, + "includeAll": false, + "label": "application", + "multi": false, + "name": "application", + "options": [], + "query": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": { + "text": "All", + "value": "All" + }, + "hide": 0, + "includeAll": false, + "label": "service", + "multi": false, + "name": "service", + "options": [], + "query": "", + "queryValue": "org.apache.dubbo.samples.DetailService", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Service traces", + "uid": "b2e178fb-ada3-4d5e-9f54-de99e7f07662", + "version": 7, + "weekStart": "" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: dubbo-admin + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-dubbo-service-traces + namespace: monitoring + - apiVersion: v1 + data: + alertmanager-overview.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "Alerts", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "current set of alerts stored in the Alertmanager", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(alertmanager_alerts{namespace=~\"$namespace\",service=~\"$service\"}) by (namespace,service,instance)", + "intervalFactor": 2, + "legendFormat": "{{instance}}" + } + ], + "title": "Alerts", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "rate of successful and invalid alerts received by the Alertmanager", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(alertmanager_alerts_received_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", + "intervalFactor": 2, + "legendFormat": "{{instance}} Received" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(alertmanager_alerts_invalid_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", + "intervalFactor": 2, + "legendFormat": "{{instance}} Invalid" + } + ], + "title": "Alerts receive rate", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "panels": [ + + ], + "title": "Notifications", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "rate of successful and invalid notifications sent by the Alertmanager", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "repeat": "integration", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(alertmanager_notifications_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", + "intervalFactor": 2, + "legendFormat": "{{instance}} Total" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(alertmanager_notifications_failed_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", + "intervalFactor": 2, + "legendFormat": "{{instance}} Failed" + } + ], + "title": "$integration: Notifications Send Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "latency of notifications sent by the Alertmanager", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "repeat": "integration", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.99,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n)\n", + "intervalFactor": 2, + "legendFormat": "{{instance}} 99th Percentile" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.50,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n)\n", + "intervalFactor": 2, + "legendFormat": "{{instance}} Median" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(alertmanager_notification_latency_seconds_sum{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n/\nsum(rate(alertmanager_notification_latency_seconds_count{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n", + "intervalFactor": 2, + "legendFormat": "{{instance}} Average" + } + ], + "title": "$integration: Notification Duration", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [ + "alertmanager-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": false, + "label": "namespace", + "name": "namespace", + "query": "label_values(alertmanager_alerts, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": false, + "label": "service", + "name": "service", + "query": "label_values(alertmanager_alerts, service)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "$__all", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "includeAll": true, + "name": "integration", + "query": "label_values(alertmanager_notifications_total{integration=~\".*\"}, integration)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "30s" + ] + }, + "timezone": "utc", + "title": "Alertmanager / Overview", + "uid": "alertmanager-overview" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-alertmanager-overview + namespace: monitoring + - apiVersion: v1 + data: + apiserver.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.", + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "content": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only." + }, + "pluginVersion": "v11.4.0", + "title": "Notice", + "type": "text" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many percent of requests (both read and write) in 30 days have been answered successfully and fast enough?", + "fieldConfig": { + "defaults": { + "decimals": 3, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 2 + }, + "id": 2, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"}" + } + ], + "title": "Availability (30d) > 99.000%", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How much error budget is left looking at our 0.990% availability guarantees?", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100 + }, + "decimals": 3, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 2 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "100 * (apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"} - 0.990000)", + "legendFormat": "errorbudget" + } + ], + "title": "ErrorBudget (30d) > 99.000%", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many percent of read requests (LIST,GET) in 30 days have been answered successfully and fast enough?", + "fieldConfig": { + "defaults": { + "decimals": 3, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 9 + }, + "id": 4, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "apiserver_request:availability30d{verb=\"read\", cluster=\"$cluster\"}" + } + ], + "title": "Read Availability (30d)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many read requests (LIST,GET) per second do the apiservers get by code?", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "stacking": { + "mode": "normal" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/2../i" + }, + "properties": [ + { + "id": "color", + "value": "#56A64B" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/3../i" + }, + "properties": [ + { + "id": "color", + "value": "#F2CC0C" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/4../i" + }, + "properties": [ + { + "id": "color", + "value": "#3274D9" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/5../i" + }, + "properties": [ + { + "id": "color", + "value": "#E02F44" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 9 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", + "legendFormat": "{{ code }}" + } + ], + "title": "Read SLI - Requests", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many percent of read requests (LIST,GET) per second are returned with errors (5xx)?", + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 9 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", + "legendFormat": "{{ resource }}" + } + ], + "title": "Read SLI - Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many seconds is the 99th percentile for reading (LIST|GET) a given resource?", + "fieldConfig": { + "defaults": { + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile{verb=\"read\", cluster=\"$cluster\"}", + "legendFormat": "{{ resource }}" + } + ], + "title": "Read SLI - Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) in 30 days have been answered successfully and fast enough?", + "fieldConfig": { + "defaults": { + "decimals": 3, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 16 + }, + "id": 8, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "apiserver_request:availability30d{verb=\"write\", cluster=\"$cluster\"}" + } + ], + "title": "Write Availability (30d)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many write requests (POST|PUT|PATCH|DELETE) per second do the apiservers get by code?", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "stacking": { + "mode": "normal" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/2../i" + }, + "properties": [ + { + "id": "color", + "value": "#56A64B" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/3../i" + }, + "properties": [ + { + "id": "color", + "value": "#F2CC0C" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/4../i" + }, + "properties": [ + { + "id": "color", + "value": "#3274D9" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/5../i" + }, + "properties": [ + { + "id": "color", + "value": "#E02F44" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 16 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", + "legendFormat": "{{ code }}" + } + ], + "title": "Write SLI - Requests", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) per second are returned with errors (5xx)?", + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 16 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", + "legendFormat": "{{ resource }}" + } + ], + "title": "Write SLI - Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "description": "How many seconds is the 99th percentile for writing (POST|PUT|PATCH|DELETE) a given resource?", + "fieldConfig": { + "defaults": { + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 16 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile{verb=\"write\", cluster=\"$cluster\"}", + "legendFormat": "{{ resource }}" + } + ], + "title": "Write SLI - Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 23 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(workqueue_adds_total{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", + "legendFormat": "{{instance}} {{name}}" + } + ], + "title": "Work Queue Add Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 23 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(workqueue_depth{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", + "legendFormat": "{{instance}} {{name}}" + } + ], + "title": "Work Queue Depth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 14, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name, le))", + "legendFormat": "{{instance}} {{name}}" + } + ], + "title": "Work Queue Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 37 + }, + "id": 15, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "process_resident_memory_bytes{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 37 + }, + "id": 16, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "rate(process_cpu_seconds_total{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 37 + }, + "id": 17, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "go_goroutines{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Goroutines", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"apiserver\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "name": "instance", + "query": "label_values(up{job=\"apiserver\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / API server", + "uid": "09ec8aa1e996d6ffcd6817bbaff4db1b" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-apiserver + namespace: monitoring + - apiVersion: v1 + data: + cluster-total.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bytes/" + }, + "properties": [ + { + "id": "unit", + "value": "binBps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down", + "url": "/d/8b7a8b326d7a6f1f04244066368c67af/kubernetes-networking-namespace-pods?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 3, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg by (namespace) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg by (namespace) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + } + ], + "title": "Current Status", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true, + "Time 8": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Time 8": 7, + "Value #A": 9, + "Value #B": 10, + "Value #C": 11, + "Value #D": 12, + "Value #E": 13, + "Value #F": 14, + "Value #G": 15, + "Value #H": 16, + "namespace": 8 + }, + "renameByName": { + "Value #A": "Rx Bytes", + "Value #B": "Tx Bytes", + "Value #C": "Rx Bytes (Avg)", + "Value #D": "Tx Bytes (Avg)", + "Value #E": "Rx Packets", + "Value #F": "Tx Packets", + "Value #G": "Rx Packets Dropped", + "Value #H": "Tx Packets Dropped", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg by (namespace) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Average Rate of Bytes Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg by (namespace) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Average Rate of Bytes Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 45 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 45 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (namespace) (\n rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 54 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (instance) (\n rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$__rate_interval]) / rate(node_netstat_Tcp_OutSegs{cluster=\"$cluster\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of TCP Retransmits out of all sent segments", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 54 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (instance) (\n rate(node_netstat_TcpExt_TCPSynRetrans{cluster=\"$cluster\"}[$__rate_interval]) / rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of TCP SYN Retransmits out of all retransmits", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Networking / Cluster", + "uid": "ff635a025bcfea7bc3dd4f508990a3e9" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-cluster-total + namespace: monitoring + - apiVersion: v1 + data: + controller-manager.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(up{cluster=\"$cluster\", job=\"kube-controller-manager\"})", + "instant": true + } + ], + "title": "Up", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 20, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(workqueue_adds_total{cluster=\"$cluster\", job=\"kube-controller-manager\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", + "legendFormat": "{{cluster}} {{instance}} {{name}}" + } + ], + "title": "Work Queue Add Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(workqueue_depth{cluster=\"$cluster\", job=\"kube-controller-manager\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", + "legendFormat": "{{cluster}} {{instance}} {{name}}" + } + ], + "title": "Work Queue Depth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-controller-manager\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name, le))", + "legendFormat": "{{cluster}} {{instance}} {{name}}" + } + ], + "title": "Work Queue Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 21 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{job=\"kube-controller-manager\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "legendFormat": "2xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{job=\"kube-controller-manager\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "legendFormat": "3xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{job=\"kube-controller-manager\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "legendFormat": "4xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{job=\"kube-controller-manager\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "legendFormat": "5xx" + } + ], + "title": "Kube API Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 21 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-controller-manager\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Post Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-controller-manager\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Get Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 35 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"kube-controller-manager\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 35 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"kube-controller-manager\",instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 35 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "go_goroutines{cluster=\"$cluster\", job=\"kube-controller-manager\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Goroutines", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-controller-manager\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "instance", + "name": "instance", + "query": "label_values(up{cluster=\"$cluster\", job=\"kube-controller-manager\"}, instance)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Controller Manager", + "uid": "72e0e05bef5099e5f049b05fdc429ed4" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-controller-manager + namespace: monitoring + - apiVersion: v1 + data: + grafana-overview.json: |- + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ + + ], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 3085, + "iteration": 1631554945276, + "links": [ + + ], + "panels": [ + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + + ], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": { + + }, + "textMode": "auto" + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "grafana_alerting_result_total{job=~\"$job\", instance=~\"$instance\", state=\"alerting\"}", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Firing Alerts", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": { + + }, + "textMode": "auto" + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "sum(grafana_stat_totals_dashboard{job=~\"$job\", instance=~\"$instance\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Dashboards", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "auto" + }, + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 10, + "options": { + "showHeader": true + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "grafana_build_info{job=~\"$job\", instance=~\"$instance\"}", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Build Info", + "transformations": [ + { + "id": "labelsToFields", + "options": { + + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value": true, + "branch": true, + "container": true, + "goversion": true, + "namespace": true, + "pod": true, + "revision": true + }, + "indexByName": { + "Time": 7, + "Value": 11, + "branch": 4, + "container": 8, + "edition": 2, + "goversion": 6, + "instance": 1, + "job": 0, + "namespace": 9, + "pod": 10, + "revision": 5, + "version": 3 + }, + "renameByName": { + + } + } + } + ], + "type": "table" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ] + }, + "overrides": [ + + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 5 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status_code) (irate(grafana_http_request_duration_seconds_count{job=~\"$job\", instance=~\"$instance\"}[1m])) ", + "interval": "", + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeRegions": [ + + ], + "timeShift": null, + "title": "RPS", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "$$hashKey": "object:157", + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:158", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ] + }, + "overrides": [ + + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 5 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", + "interval": "", + "legendFormat": "99th Percentile", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.50, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", + "interval": "", + "legendFormat": "50th Percentile", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(irate(grafana_http_request_duration_seconds_sum{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) * 1 / sum(irate(grafana_http_request_duration_seconds_count{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Average", + "refId": "C" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeRegions": [ + + ], + "timeShift": null, + "title": "Request Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "$$hashKey": "object:210", + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:211", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 30, + "tags": [ + + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "dev-cortex", + "value": "dev-cortex" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": [ + "default/grafana" + ], + "value": [ + "default/grafana" + ] + }, + "datasource": "$datasource", + "definition": "label_values(grafana_build_info, job)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "job", + "options": [ + + ], + "query": { + "query": "label_values(grafana_build_info, job)", + "refId": "Billing Admin-job-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "definition": "label_values(grafana_build_info, instance)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "instance", + "options": [ + + ], + "query": { + "query": "label_values(grafana_build_info, instance)", + "refId": "Billing Admin-instance-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Grafana Overview", + "uid": "6be0s85Mk", + "version": 2 + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-grafana-overview + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-cluster.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "cluster:node_cpu:ratio_rate5m{cluster=\"$cluster\"}", + "instant": true + } + ], + "title": "CPU Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "CPU Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "CPU Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 4, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "1 - sum(:node_memory_MemAvailable_bytes:sum{cluster=\"$cluster\"}) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\",cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 5, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 6, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\"}) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 8, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Value #A": 8, + "Value #B": 9, + "Value #C": 10, + "Value #D": 11, + "Value #E": 12, + "Value #F": 13, + "Value #G": 14, + "namespace": 7 + }, + "renameByName": { + "Value #A": "Pods", + "Value #B": "Workloads", + "Value #C": "CPU Usage", + "Value #D": "CPU Requests", + "Value #E": "CPU Requests %", + "Value #F": "CPU Limits", + "Value #G": "CPU Limits %", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Usage" + }, + "properties": [ + { + "id": "unit", + "value": "bytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Requests" + }, + "properties": [ + { + "id": "unit", + "value": "bytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Limits" + }, + "properties": [ + { + "id": "unit", + "value": "bytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 10, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + } + ], + "title": "Memory Requests by Namespace", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Value #A": 8, + "Value #B": 9, + "Value #C": 10, + "Value #D": 11, + "Value #E": 12, + "Value #F": 13, + "Value #G": 14, + "namespace": 7 + }, + "renameByName": { + "Value #A": "Pods", + "Value #B": "Workloads", + "Value #C": "Memory Usage", + "Value #D": "Memory Requests", + "Value #E": "Memory Requests %", + "Value #F": "Memory Limits", + "Value #G": "Memory Limits %", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bandwidth/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 11, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true + } + ], + "title": "Current Network Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "namespace": 6 + }, + "renameByName": { + "Value #A": "Current Receive Bandwidth", + "Value #B": "Current Transmit Bandwidth", + "Value #C": "Rate of Received Packets", + "Value #D": "Rate of Transmitted Packets", + "Value #E": "Rate of Received Packets Dropped", + "Value #F": "Rate of Transmitted Packets Dropped", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 48 + }, + "id": 14, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg(irate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Namespace: Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 54 + }, + "id": 15, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "avg(irate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Namespace: Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 60 + }, + "id": 16, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 66 + }, + "id": 17, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 18, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 78 + }, + "id": 19, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "iops" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 84 + }, + "id": 20, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "ceil(sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval])))", + "legendFormat": "__auto" + } + ], + "title": "IOPS(Reads+Writes)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 90 + }, + "id": 21, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "legendFormat": "__auto" + } + ], + "title": "ThroughPut(Read+Write)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/IOPS/" + }, + "properties": [ + { + "id": "unit", + "value": "iops" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Throughput/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 96 + }, + "id": 22, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true + } + ], + "title": "Current Storage IO", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "namespace": 6 + }, + "renameByName": { + "Value #A": "IOPS(Reads)", + "Value #B": "IOPS(Writes)", + "Value #C": "IOPS(Reads + Writes)", + "Value #D": "Throughput(Read)", + "Value #E": "Throughput(Write)", + "Value #F": "Throughput(Read + Write)", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Cluster", + "uid": "efa86fd1d0c121a26444b636a3f509a8" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-cluster + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-multicluster.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:node_cpu:ratio_rate5m) / count(cluster:node_cpu:ratio_rate5m)", + "instant": true + } + ], + "title": "CPU Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})", + "instant": true + } + ], + "title": "CPU Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})", + "instant": true + } + ], + "title": "CPU Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 4, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "1 - sum(:node_memory_MemAvailable_bytes:sum) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\"})", + "instant": true + } + ], + "title": "Memory Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 5, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})", + "instant": true + } + ], + "title": "Memory Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 6, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})", + "instant": true + } + ], + "title": "Memory Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + } + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster)", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Cluster" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down", + "url": "/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 8, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "cluster", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "cluster": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "cluster": "Cluster" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)", + "legendFormat": "__auto" + } + ], + "title": "Memory Usage (w/o cache)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Cluster" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down", + "url": "/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 4 + }, + "id": 10, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)", + "format": "table", + "instant": true + } + ], + "title": "Memory Requests by Cluster", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "cluster", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "cluster": 5 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "cluster": "Cluster" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Multi-Cluster", + "uid": "b59e6c9f2fcbe2e16d77fc492374cc4f" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-multicluster + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-namespace.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", + "instant": true + } + ], + "title": "CPU Utilisation (from requests)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", + "instant": true + } + ], + "title": "CPU Utilisation (from limits)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", + "instant": true + } + ], + "title": "Memory Utilisation (from requests)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 4, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", + "instant": true + } + ], + "title": "Memory Utilisation (from limits)", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "legendFormat": "__auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.cpu\"}))", + "legendFormat": "quota - requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.cpu\"}))", + "legendFormat": "quota - limits" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 6, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "pod": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}) by (pod)", + "legendFormat": "__auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.memory\"}))", + "legendFormat": "quota - requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.memory\"}))", + "legendFormat": "quota - limits" + } + ], + "title": "Memory Usage (w/o cache)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 8, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_cache{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_swap{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true, + "Time 8": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Time 8": 7, + "Value #A": 9, + "Value #B": 10, + "Value #C": 11, + "Value #D": 12, + "Value #E": 13, + "Value #F": 14, + "Value #G": 15, + "Value #H": 16, + "pod": 8 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "Value #F": "Memory Usage (RSS)", + "Value #G": "Memory Usage (Cache)", + "Value #H": "Memory Usage (Swap)", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bandwidth/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 9, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "Current Network Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "pod": 6 + }, + "renameByName": { + "Value #A": "Current Receive Bandwidth", + "Value #B": "Current Transmit Bandwidth", + "Value #C": "Rate of Received Packets", + "Value #D": "Rate of Transmitted Packets", + "Value #E": "Rate of Received Packets Dropped", + "Value #F": "Rate of Transmitted Packets Dropped", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 14, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 15, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "iops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 63 + }, + "id": 16, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "ceil(sum by(pod) (rate(container_fs_reads_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "__auto" + } + ], + "title": "IOPS(Reads+Writes)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 63 + }, + "id": 17, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "__auto" + } + ], + "title": "ThroughPut(Read+Write)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/IOPS/" + }, + "properties": [ + { + "id": "unit", + "value": "iops" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Throughput/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 18, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true + } + ], + "title": "Current Storage IO", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "pod": 6 + }, + "renameByName": { + "Value #A": "IOPS(Reads)", + "Value #B": "IOPS(Writes)", + "Value #C": "IOPS(Reads + Writes)", + "Value #D": "Throughput(Read)", + "Value #E": "Throughput(Write)", + "Value #F": "Throughput(Read + Write)", + "pod": "Pod" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Namespace (Pods)", + "uid": "85a562078cdf77779eaa1add43ccec1e" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-namespace + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-node.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "mode": "normal" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "max capacity" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.stacking", + "value": { + "mode": "none" + } + }, + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": false + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", job=\"kube-state-metrics\", node=~\"$node\", resource=\"cpu\"})", + "legendFormat": "max capacity" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "legendFormat": "{{pod}}" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "mode": "normal" + } + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "max capacity" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.stacking", + "value": { + "mode": "none" + } + }, + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": false + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", job=\"kube-state-metrics\", node=~\"$node\", resource=\"memory\"})", + "legendFormat": "max capacity" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\", container!=\"\"}) by (pod)", + "legendFormat": "{{pod}}" + } + ], + "title": "Memory Usage (w/cache)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "mode": "normal" + } + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "max capacity" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.stacking", + "value": { + "mode": "none" + } + }, + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": false + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", job=\"kube-state-metrics\", node=~\"$node\", resource=\"memory\"})", + "legendFormat": "max capacity" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_rss{cluster=\"$cluster\", node=~\"$node\", container!=\"\"}) by (pod)", + "legendFormat": "{{pod}}" + } + ], + "title": "Memory Usage (w/o cache)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 5, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_rss{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_cache{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_memory_swap{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true, + "Time 8": true + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "Value #F": "Memory Usage (RSS)", + "Value #G": "Memory Usage (Cache)", + "Value #H": "Memory Usage (Swap)", + "pod": "Pod" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "node", + "multi": true, + "name": "node", + "query": "label_values(kube_node_info{cluster=\"$cluster\"}, node)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Node (Pods)", + "uid": "200ac8fdbfbb74b39aff88118e4d1c2c" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-node + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-pod.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{namespace=\"$namespace\", pod=\"$pod\", cluster=\"$cluster\", container!=\"\"}) by (container)", + "legendFormat": "__auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", + "legendFormat": "requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", + "legendFormat": "limits" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "axisColorMode": "thresholds", + "axisSoftMax": 1, + "axisSoftMin": 0, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true, + "thresholdsStyle": { + "mode": "dashed+area" + } + }, + "unit": "percentunit" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 0.25 + } + ] + } + }, + { + "id": "color", + "value": { + "mode": "thresholds", + "seriesBy": "lastNotNull" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(increase(container_cpu_cfs_throttled_periods_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container) /sum(increase(container_cpu_cfs_periods_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container)", + "legendFormat": "__auto" + } + ], + "title": "CPU Throttling", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\"}) by (container)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "container", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "container": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "container": "Container" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", + "legendFormat": "__auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", + "legendFormat": "requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", + "legendFormat": "limits" + } + ], + "title": "Memory Usage (WSS)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 5, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_cache{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(container_memory_swap{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "container", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true, + "Time 8": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Time 8": 7, + "Value #A": 9, + "Value #B": 10, + "Value #C": 11, + "Value #D": 12, + "Value #E": 13, + "Value #F": 14, + "Value #G": 15, + "Value #H": 16, + "container": 8 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "Value #F": "Memory Usage (RSS)", + "Value #G": "Memory Usage (Cache)", + "Value #H": "Memory Usage (Swap)", + "container": "Container" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 35 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(irate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 35 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "iops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "ceil(sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "legendFormat": "Reads" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "ceil(sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\",namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "legendFormat": "Writes" + } + ], + "title": "IOPS (Pod)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "Reads" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "Writes" + } + ], + "title": "ThroughPut (Pod)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "iops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 63 + }, + "id": 14, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "ceil(sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval])))", + "legendFormat": "__auto" + } + ], + "title": "IOPS (Containers)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 63 + }, + "id": 15, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "legendFormat": "__auto" + } + ], + "title": "ThroughPut (Containers)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/IOPS/" + }, + "properties": [ + { + "id": "unit", + "value": "iops" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Throughput/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 16, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true + } + ], + "title": "Current Storage IO", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "container", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "container": 6 + }, + "renameByName": { + "Value #A": "IOPS(Reads)", + "Value #B": "IOPS(Writes)", + "Value #C": "IOPS(Reads + Writes)", + "Value #D": "Throughput(Read)", + "Value #E": "Throughput(Write)", + "Value #F": "Throughput(Read + Write)", + "container": "Container" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "pod", + "name": "pod", + "query": "label_values(kube_pod_info{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\"}, pod)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Pod", + "uid": "6581e46e4e5c7ba40a07646395ef7b23" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-pod + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-windows-cluster.json: |- + { + "editable": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "1 - avg(rate(windows_cpu_time_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", mode=\"idle\"}[$__rate_interval]))", + "instant": true + } + ], + "title": "CPU Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "CPU Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "CPU Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 4, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "1 - sum(:windows_node_memory_MemFreeCached_bytes:sum{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Utilisation", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 5, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Requests Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit" + } + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 6, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})", + "instant": true + } + ], + "title": "Memory Limits Commitment", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 8, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "namespace": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "decbytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)", + "legendFormat": "__auto" + } + ], + "title": "Memory Usage (Private Working Set)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Usage" + }, + "properties": [ + { + "id": "unit", + "value": "decbytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Requests" + }, + "properties": [ + { + "id": "unit", + "value": "decbytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Limits" + }, + "properties": [ + { + "id": "unit", + "value": "decbytes" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 10, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true + } + ], + "title": "Memory Requests by Namespace", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "namespace", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "namespace": 5 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "namespace": "Namespace" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubernetes-windows-exporter\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Kubernetes / Compute Resources / Cluster(Windows)", + "uid": "4d08557fd9391b100730f2494bccac68" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-windows-cluster + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-windows-namespace.json: |- + { + "editable": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "pod": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "decbytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Memory Usage (Private Working Set)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 4, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "pod": 5 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubernetes-windows-exporter\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Kubernetes / Compute Resources / Namespace(Windows)", + "uid": "490b402361724ab1d4c45666c1fa9b6f" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-windows-namespace + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-windows-pod.json: |- + { + "editable": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "container", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "container": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "container": "Container" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "decbytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "legendFormat": "__auto" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 4, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "container", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "container": 5 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "container": "Container" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum by (container) (rate(windows_container_network_received_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval])))", + "legendFormat": "Received : {{ container }}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum by (container) (rate(windows_container_network_transmitted_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval])))", + "legendFormat": "Transmitted : {{ container }}" + } + ], + "title": "Network I/O", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubernetes-windows-exporter\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "pod", + "name": "pod", + "query": "label_values(windows_pod_container_available{cluster=\"$cluster\",namespace=\"$namespace\"}, pod)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Kubernetes / Compute Resources / Pod(Windows)", + "uid": "40597a704a610e936dc6ed374a7ce023" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-windows-pod + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-workload.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "legendFormat": "__auto" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 6, + "Value #B": 7, + "Value #C": 8, + "Value #D": 9, + "Value #E": 10, + "pod": 5 + }, + "renameByName": { + "Value #A": "CPU Usage", + "Value #B": "CPU Requests", + "Value #C": "CPU Requests %", + "Value #D": "CPU Limits", + "Value #E": "CPU Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "legendFormat": "__auto" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 4, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=~\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Value #A": 9, + "Value #B": 10, + "Value #C": 11, + "Value #D": 12, + "Value #E": 13, + "pod": 8 + }, + "renameByName": { + "Value #A": "Memory Usage", + "Value #B": "Memory Requests", + "Value #C": "Memory Requests %", + "Value #D": "Memory Limits", + "Value #E": "Memory Limits %", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bandwidth/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to pods", + "url": "/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 5, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "format": "table", + "instant": true + } + ], + "title": "Current Network Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "pod": 6 + }, + "renameByName": { + "Value #A": "Current Receive Bandwidth", + "Value #B": "Current Transmit Bandwidth", + "Value #C": "Rate of Received Packets", + "Value #D": "Rate of Transmitted Packets", + "Value #E": "Rate of Received Packets Dropped", + "Value #F": "Rate of Transmitted Packets Dropped", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 35 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 35 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(avg(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Pod: Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(avg(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Pod: Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "workload_type", + "name": "type", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\"}, workload_type)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "workload", + "name": "workload", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}, workload)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Workload", + "uid": "a164a7f0339f99e89cea5cb47e9be617" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-workload + namespace: monitoring + - apiVersion: v1 + data: + k8s-resources-workloads-namespace.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + } + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "legendFormat": "{{workload}} - {{workload_type}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=~\"requests.cpu|cpu\"}))", + "legendFormat": "quota - requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=~\"limits.cpu\"}))", + "legendFormat": "quota - limits" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Workload" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to workloads", + "url": "/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Running Pods" + }, + "properties": [ + { + "id": "unit", + "value": "none" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload, workload_type)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + } + ], + "title": "CPU Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "workload", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "workload_type 2": true, + "workload_type 3": true, + "workload_type 4": true, + "workload_type 5": true, + "workload_type 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 8, + "Value #B": 9, + "Value #C": 10, + "Value #D": 11, + "Value #E": 12, + "Value #F": 13, + "workload": 6, + "workload_type 1": 7, + "workload_type 2": 14, + "workload_type 3": 15, + "workload_type 4": 16, + "workload_type 5": 17, + "workload_type 6": 18 + }, + "renameByName": { + "Value #A": "Running Pods", + "Value #B": "CPU Usage", + "Value #C": "CPU Requests", + "Value #D": "CPU Requests %", + "Value #E": "CPU Limits", + "Value #F": "CPU Limits %", + "workload": "Workload", + "workload_type 1": "Type" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "C" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "legendFormat": "{{workload}} - {{workload_type}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=~\"requests.memory|memory\"}))", + "legendFormat": "quota - requests" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "scalar(max(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=~\"limits.memory\"}))", + "legendFormat": "quota - limits" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/%/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Workload" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to workloads", + "url": "/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Running Pods" + }, + "properties": [ + { + "id": "unit", + "value": "none" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 4, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload, workload_type)", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(\n container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true + } + ], + "title": "Memory Quota", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "workload", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "workload_type 2": true, + "workload_type 3": true, + "workload_type 4": true, + "workload_type 5": true, + "workload_type 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 8, + "Value #B": 9, + "Value #C": 10, + "Value #D": 11, + "Value #E": 12, + "Value #F": 13, + "workload": 6, + "workload_type 1": 7, + "workload_type 2": 14, + "workload_type 3": 15, + "workload_type 4": 16, + "workload_type 5": 17, + "workload_type 6": 18 + }, + "renameByName": { + "Value #A": "Running Pods", + "Value #B": "Memory Usage", + "Value #C": "Memory Requests", + "Value #D": "Memory Requests %", + "Value #E": "Memory Limits", + "Value #F": "Memory Limits %", + "workload": "Workload", + "workload_type 1": "Type" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bandwidth/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Workload" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down to workloads", + "url": "/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 5, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=~\"$type\"}) by (workload))\n", + "format": "table", + "instant": true + } + ], + "title": "Current Network Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "workload", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "workload": 6 + }, + "renameByName": { + "Value #A": "Current Receive Bandwidth", + "Value #B": "Current Transmit Bandwidth", + "Value #C": "Rate of Received Packets", + "Value #D": "Rate of Transmitted Packets", + "Value #E": "Rate of Received Packets Dropped", + "Value #F": "Rate of Transmitted Packets Dropped", + "workload": "Workload" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 35 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 35 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(avg(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Workload: Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(avg(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Workload: Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "workload_type", + "name": "type", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Compute Resources / Namespace (Workloads)", + "uid": "a87fb0d919ec0ea5f6543124e16c42a5" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-resources-workloads-namespace + namespace: monitoring + - apiVersion: v1 + data: + k8s-windows-cluster-rsrc-use.json: |- + { + "editable": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\"} * node:windows_node_num_cpu:sum{cluster=\"$cluster\"} / scalar(sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"}))", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_memory_utilisation:ratio{cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory Saturation (Swap I/O Pages)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\"} / scalar(node:windows_node:sum{cluster=\"$cluster\"})", + "legendFormat": "{{instance}}" + } + ], + "title": "Disk IO Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Net Utilisation (Transmitted)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Net Utilisation (Dropped)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (instance)(node:windows_node_filesystem_usage:{cluster=\"$cluster\"})", + "legendFormat": "{{instance}}" + } + ], + "title": "Disk Capacity", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubernetes-windows-exporter\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Kubernetes / USE Method / Cluster(Windows)", + "uid": "53a43377ec9aaf2ff64dfc7a1f539334" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-windows-cluster-rsrc-use + namespace: monitoring + - apiVersion: v1 + data: + k8s-windows-node-rsrc-use.json: |- + { + "editable": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Utilisation" + } + ], + "title": "CPU Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (core) (irate(windows_cpu_time_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", mode!=\"idle\", instance=\"$instance\"}[$__rate_interval]))", + "legendFormat": "{{core}}" + } + ], + "title": "CPU Usage Per Core", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_memory_utilisation:{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Memory" + } + ], + "title": "Memory Utilisation %", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(\n windows_os_visible_memory_bytes{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}\n - windows_memory_available_bytes{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}\n)\n", + "legendFormat": "memory used" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(node:windows_node_memory_totalCached_bytes:sum{cluster=\"$cluster\", instance=\"$instance\"})", + "legendFormat": "memory cached" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(windows_memory_available_bytes{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"})", + "legendFormat": "memory free" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Swap IO" + } + ], + "title": "Memory Saturation (Swap I/O) Pages", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 14 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Utilisation" + } + ], + "title": "Disk IO Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/io time/" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 14 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(rate(windows_logical_disk_read_bytes_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}[$__rate_interval]))", + "legendFormat": "read" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(rate(windows_logical_disk_write_bytes_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}[$__rate_interval]))", + "legendFormat": "written" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max(rate(windows_logical_disk_read_seconds_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}[$__rate_interval]) + rate(windows_logical_disk_write_seconds_total{cluster=\"$cluster\", job=\"kubernetes-windows-exporter\", instance=\"$instance\"}[$__rate_interval]))", + "legendFormat": "io time" + } + ], + "title": "Disk IO", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_filesystem_usage:{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "{{volume}}" + } + ], + "title": "Disk Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Utilisation" + } + ], + "title": "Net Utilisation (Transmitted)", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}", + "legendFormat": "Saturation" + } + ], + "title": "Net Saturation (Dropped)", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubernetes-windows-exporter\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "instance", + "name": "instance", + "query": "label_values(windows_system_boot_time_timestamp_seconds{cluster=\"$cluster\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Kubernetes / USE Method / Node(Windows)", + "uid": "96e7484b0bb53b74fbc2bcb7723cd40b" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-k8s-windows-node-rsrc-use + namespace: monitoring + - apiVersion: v1 + data: + kubelet.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kubelet_node_name{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\"})", + "instant": true + } + ], + "title": "Running Kubelets", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kubelet_running_pods{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"})", + "instant": true + } + ], + "title": "Running Pods", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(kubelet_running_containers{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"})", + "instant": true + } + ], + "title": "Running Containers", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 4, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\", state=\"actual_state_of_world\"})", + "instant": true + } + ], + "title": "Actual Volume Count", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 5, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\",state=\"desired_state_of_world\"})", + "instant": true + } + ], + "title": "Desired Volume Count", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 6, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_node_config_error{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval]))", + "instant": true + } + ], + "title": "Config Error Count", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_runtime_operations_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (operation_type, instance)", + "legendFormat": "{{instance}} {{operation_type}}" + } + ], + "title": "Operation Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_runtime_operations_errors_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", + "legendFormat": "{{instance}} {{operation_type}}" + } + ], + "title": "Operation Error Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_runtime_operations_duration_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", + "legendFormat": "{{instance}} {{operation_type}}" + } + ], + "title": "Operation Duration 99th quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_pod_start_duration_seconds_count{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "legendFormat": "{{instance}} pod" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_pod_worker_duration_seconds_count{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "legendFormat": "{{instance}} worker" + } + ], + "title": "Pod Start Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "legendFormat": "{{instance}} pod" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "legendFormat": "{{instance}} worker" + } + ], + "title": "Pod Start Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 12, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(storage_operation_duration_seconds_count{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", + "legendFormat": "{{instance}} {{operation_name}} {{volume_plugin}}" + } + ], + "title": "Storage Operation Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 13, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(storage_operation_errors_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", + "legendFormat": "{{instance}} {{operation_name}} {{volume_plugin}}" + } + ], + "title": "Storage Operation Error Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 14, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(storage_operation_duration_seconds_bucket{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin, le))", + "legendFormat": "{{instance}} {{operation_name}} {{volume_plugin}}" + } + ], + "title": "Storage Operation Duration 99th quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 15, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_cgroup_manager_duration_seconds_count{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", + "legendFormat": "{{operation_type}}" + } + ], + "title": "Cgroup manager operation rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 16, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_cgroup_manager_duration_seconds_bucket{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", + "legendFormat": "{{instance}} {{operation_type}}" + } + ], + "title": "Cgroup manager 99th quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 17, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubelet_pleg_relist_duration_seconds_count{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "legendFormat": "{{instance}}" + } + ], + "title": "PLEG relist rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 18, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_interval_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "legendFormat": "{{instance}}" + } + ], + "title": "PLEG relist interval", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 56 + }, + "id": 19, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "legendFormat": "{{instance}}" + } + ], + "title": "PLEG relist duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 63 + }, + "id": 20, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "legendFormat": "2xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "legendFormat": "3xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "legendFormat": "4xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "legendFormat": "5xx" + } + ], + "title": "RPC rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 21, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, verb, le))", + "legendFormat": "{{instance}} {{verb}}" + } + ], + "title": "Request duration 99th quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 77 + }, + "id": 22, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "process_resident_memory_bytes{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 77 + }, + "id": 23, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 77 + }, + "id": 24, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "go_goroutines{cluster=\"$cluster\",job=\"kubelet\", metrics_path=\"/metrics\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Goroutines", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "instance", + "name": "instance", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics\",cluster=\"$cluster\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Kubelet", + "uid": "3138fa155d5915769fbded898ac09fd9" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-kubelet + namespace: monitoring + - apiVersion: v1 + data: + namespace-by-pod.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "displayName": "$namespace", + "max": 10000000000, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ] + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Received", + "type": "gauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "displayName": "$namespace", + "max": 10000000000, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ] + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Transmitted", + "type": "gauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bandwidth/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Pod" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down", + "url": "/d/7a18067ce943a40ae25454675c19ff5c/kubernetes-networking-pod?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${namespace}&var-pod=${__data.fields.Pod}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 3, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "format": "table", + "instant": true + } + ], + "title": "Current Network Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "pod", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Value #A": 7, + "Value #B": 8, + "Value #C": 9, + "Value #D": 10, + "Value #E": 11, + "Value #F": 12, + "pod": 6 + }, + "renameByName": { + "Value #A": "Current Receive Bandwidth", + "Value #B": "Current Transmit Bandwidth", + "Value #C": "Rate of Received Packets", + "Value #D": "Rate of Transmitted Packets", + "Value #E": "Rate of Received Packets Dropped", + "Value #F": "Rate of Transmitted Packets Dropped", + "pod": "Pod" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace!=\"\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (pod) (\n rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n * on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n)\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "current": { + "selected": false, + "text": "kube-system", + "value": "kube-system" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "namespace", + "name": "namespace", + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Networking / Namespace (Pods)", + "uid": "8b7a8b326d7a6f1f04244066368c67af" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-namespace-by-pod + namespace: monitoring + - apiVersion: v1 + data: + namespace-by-workload.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Received", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Transmitted", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Bytes/" + }, + "properties": [ + { + "id": "unit", + "value": "binBps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Packets/" + }, + "properties": [ + { + "id": "unit", + "value": "pps" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Workload" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Drill down", + "url": "/d/728bf77cc1166d2f3133bf25846876cc/kubernetes-networking-workload?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${namespace}&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 3, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod) kube_pod_info{cluster=\"$cluster\",namespace=\"$namespace\",host_network=\"false\"}\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload, workload_type))\n", + "format": "table", + "instant": true + } + ], + "title": "Current Status", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "workload", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "Time 4": true, + "Time 5": true, + "Time 6": true, + "Time 7": true, + "Time 8": true, + "workload_type 2": true, + "workload_type 3": true, + "workload_type 4": true, + "workload_type 5": true, + "workload_type 6": true, + "workload_type 7": true, + "workload_type 8": true + }, + "indexByName": { + "Time 1": 0, + "Time 2": 1, + "Time 3": 2, + "Time 4": 3, + "Time 5": 4, + "Time 6": 5, + "Time 7": 6, + "Time 8": 7, + "Value #A": 10, + "Value #B": 11, + "Value #C": 12, + "Value #D": 13, + "Value #E": 14, + "Value #F": 15, + "Value #G": 16, + "Value #H": 17, + "workload": 8, + "workload_type 1": 9, + "workload_type 2": 18, + "workload_type 3": 19, + "workload_type 4": 20, + "workload_type 5": 21, + "workload_type 6": 22, + "workload_type 7": 23, + "workload_type 8": 24 + }, + "renameByName": { + "Value #A": "Rx Bytes", + "Value #B": "Tx Bytes", + "Value #C": "Rx Bytes (Avg)", + "Value #D": "Tx Bytes (Avg)", + "Value #E": "Rx Packets", + "Value #F": "Tx Packets", + "Value #G": "Rx Packets Dropped", + "Value #H": "Tx Packets Dropped", + "workload": "Workload", + "workload_type 1": "Type" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Workload: Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Container Bandwidth by Workload: Transmitted", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 45 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 45 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$__rate_interval])\n* on (cluster,namespace,pod) group_left ()\n topk by (cluster,namespace,pod) (\n 1,\n max by (cluster,namespace,pod) (kube_pod_info{host_network=\"false\"})\n )\n* on (cluster,namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=~\"$type\"}) by (workload))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "kube-system", + "value": "kube-system" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "namespace", + "name": "namespace", + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "workload_type", + "name": "type", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Networking / Namespace (Workload)", + "uid": "bbb2a765a623ae38130206c7d94a160f" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-namespace-by-workload + namespace: monitoring + - apiVersion: v1 + data: + node-cluster-rsrc-use.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "CPU", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "((\n instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n *\n instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}\n) != 0 )\n/ scalar(sum(instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}))\n", + "legendFormat": "{{ instance }}" + } + ], + "title": "CPU Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "legendFormat": "{{ instance }}" + } + ], + "title": "CPU Saturation (Load1 per CPU)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "panels": [ + + ], + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "legendFormat": "{{ instance }}" + } + ], + "title": "Memory Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "rds" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}", + "legendFormat": "{{ instance }}" + } + ], + "title": "Memory Saturation (Major Page Faults)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 7, + "panels": [ + + ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Transmit/" + }, + "properties": [ + { + "id": "custom.transform", + "value": "negative-Y" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 8, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{ instance }} Receive" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{ instance }} Transmit" + } + ], + "title": "Network Utilisation (Bytes Receive/Transmit)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Transmit/" + }, + "properties": [ + { + "id": "custom.transform", + "value": "negative-Y" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 9, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{ instance }} Receive" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{ instance }} Transmit" + } + ], + "title": "Network Saturation (Drops Receive/Transmit)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 10, + "panels": [ + + ], + "title": "Disk IO", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 11, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n/ scalar(count(instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n", + "legendFormat": "{{ instance }} {{device}}" + } + ], + "title": "Disk IO Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 12, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n/ scalar(count(instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n", + "legendFormat": "{{ instance }} {{device}}" + } + ], + "title": "Disk IO Saturation", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 13, + "panels": [ + + ], + "title": "Disk Space", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 14, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum without (device) (\n max without (fstype, mountpoint) ((\n node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n -\n node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n ) != 0)\n)\n/ scalar(sum(max without (fstype, mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"})))\n", + "legendFormat": "{{ instance }}" + } + ], + "title": "Disk Space Utilisation", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "includeAll": false, + "name": "cluster", + "query": "label_values(node_time_seconds, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "refresh": 2, + "sort": 1 + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Node Exporter / USE Method / Cluster", + "uid": "3e97d1d02672cdd0861f4c97c64f89b2" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-node-cluster-rsrc-use + namespace: monitoring + - apiVersion: v1 + data: + node-rsrc-use.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "CPU", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Utilisation" + } + ], + "title": "CPU Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_load1_per_cpu:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Saturation" + } + ], + "title": "CPU Saturation (Load1 per CPU)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "panels": [ + + ], + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_memory_utilisation:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Utilisation" + } + ], + "title": "Memory Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "rds" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 6, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Major page Faults" + } + ], + "title": "Memory Saturation (Major Page Faults)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 7, + "panels": [ + + ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Transmit/" + }, + "properties": [ + { + "id": "custom.transform", + "value": "negative-Y" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 8, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Receive" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Transmit" + } + ], + "title": "Network Utilisation (Bytes Receive/Transmit)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Transmit/" + }, + "properties": [ + { + "id": "custom.transform", + "value": "negative-Y" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 9, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Receive" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "Transmit" + } + ], + "title": "Network Saturation (Drops Receive/Transmit)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 10, + "panels": [ + + ], + "title": "Disk IO", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 11, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{device}}" + } + ], + "title": "Disk IO Utilisation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 12, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "legendFormat": "{{device}}" + } + ], + "title": "Disk IO Saturation", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 13, + "panels": [ + + ], + "title": "Disk Space", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 14, + "options": { + "legend": { + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sort_desc(1 -\n (\n max without (mountpoint, fstype) (node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n /\n max without (mountpoint, fstype) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n ) != 0\n)\n", + "legendFormat": "{{device}}" + } + ], + "title": "Disk Space Utilisation", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "includeAll": false, + "name": "cluster", + "query": "label_values(node_time_seconds, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "name": "instance", + "query": "label_values(node_exporter_build_info{job=\"node-exporter\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Node Exporter / USE Method / Node", + "uid": "fac67cfbe174d3ef53eb473d73d9212f" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-node-rsrc-use + namespace: monitoring + - apiVersion: v1 + data: + nodes-aix.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "CPU", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "max": 1, + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\", cluster=\"$cluster\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\", cluster=\"$cluster\"})\n)\n", + "intervalFactor": 5, + "legendFormat": "{{cpu}}" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "1m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "5m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "15m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", mode=\"idle\"})", + "legendFormat": "logical cores" + } + ], + "title": "Load Average", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "none" + } + }, + "min": 0, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "Physical Memory" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} -\n node_memory_available_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n)\n", + "legendFormat": "Memory Used" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "max": 100, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)" + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 6, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "100 -\n(\n avg(node_memory_available_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}) /\n avg(node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"})\n * 100\n)\n" + } + ], + "title": "Memory Usage", + "type": "gauge" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 7, + "panels": [ + + ], + "title": "Disk", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0 + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/ read| written/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/ io time/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 8, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} read" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} written" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} io time" + } + ], + "title": "Disk I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "steps": [ + { + "color": "green" + }, + { + "color": "yellow", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Mounted on" + }, + "properties": [ + { + "id": "custom.width", + "value": 260 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Available" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used, %" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "custom.cellOptions", + "value": { + "type": "gauge" + } + }, + { + "id": "max", + "value": 1 + }, + { + "id": "min", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 9, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + } + ], + "title": "Disk Space Usage", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value #A": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "Value #B": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "mountpoint": { + "aggregations": [ + + ], + "operation": "groupby" + } + } + } + }, + { + "id": "merge" + }, + { + "id": "calculateField", + "options": { + "alias": "Used", + "binary": { + "left": "Value #A (lastNotNull)", + "operator": "-", + "reducer": "sum", + "right": "Value #B (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used, %", + "binary": { + "left": "Used", + "operator": "/", + "reducer": "sum", + "right": "Value #A (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + + }, + "indexByName": { + + }, + "renameByName": { + "Value #A (lastNotNull)": "Size", + "Value #B (lastNotNull)": "Available", + "mountpoint": "Mounted on" + } + } + }, + { + "id": "sortBy", + "options": { + "fields": { + + }, + "sort": [ + { + "field": "Mounted on" + } + ] + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 10, + "panels": [ + + ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network received (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 11, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network transmitted (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0 + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 12, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Transmitted", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "label": "Cluster", + "name": "cluster", + "query": "label_values(node_uname_info{job=\"node-exporter\", sysname!=\"Darwin\"}, cluster)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "label": "Instance", + "name": "instance", + "query": "label_values(node_uname_info{job=\"node-exporter\", cluster=\"$cluster\", sysname!=\"Darwin\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Node Exporter / AIX", + "uid": "7e0a61e486f727d763fb1d86fdd629c2" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-nodes-aix + namespace: monitoring + - apiVersion: v1 + data: + nodes-darwin.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "CPU", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "max": 1, + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\", cluster=\"$cluster\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\", cluster=\"$cluster\"})\n)\n", + "intervalFactor": 5, + "legendFormat": "{{cpu}}" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "1m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "5m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "15m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", mode=\"idle\"})", + "legendFormat": "logical cores" + } + ], + "title": "Load Average", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "none" + } + }, + "min": 0, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "Physical Memory" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} +\n node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} +\n node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n)\n", + "legendFormat": "Memory Used" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n)\n", + "legendFormat": "App Memory" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "Wired Memory" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "Compressed" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "max": 100, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)" + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 6, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n (\n avg(node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}) -\n avg(node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}) +\n avg(node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}) +\n avg(node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"})\n ) /\n avg(node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"})\n)\n*\n100\n" + } + ], + "title": "Memory Usage", + "type": "gauge" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 7, + "panels": [ + + ], + "title": "Disk", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0 + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/ read| written/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/ io time/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 8, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} read" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} written" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} io time" + } + ], + "title": "Disk I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "steps": [ + { + "color": "green" + }, + { + "color": "yellow", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Mounted on" + }, + "properties": [ + { + "id": "custom.width", + "value": 260 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Available" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used, %" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "custom.cellOptions", + "value": { + "type": "gauge" + } + }, + { + "id": "max", + "value": 1 + }, + { + "id": "min", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 9, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + } + ], + "title": "Disk Space Usage", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value #A": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "Value #B": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "mountpoint": { + "aggregations": [ + + ], + "operation": "groupby" + } + } + } + }, + { + "id": "merge" + }, + { + "id": "calculateField", + "options": { + "alias": "Used", + "binary": { + "left": "Value #A (lastNotNull)", + "operator": "-", + "reducer": "sum", + "right": "Value #B (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used, %", + "binary": { + "left": "Used", + "operator": "/", + "reducer": "sum", + "right": "Value #A (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + + }, + "indexByName": { + + }, + "renameByName": { + "Value #A (lastNotNull)": "Size", + "Value #B (lastNotNull)": "Available", + "mountpoint": "Mounted on" + } + } + }, + { + "id": "sortBy", + "options": { + "fields": { + + }, + "sort": [ + { + "field": "Mounted on" + } + ] + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 10, + "panels": [ + + ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network received (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 11, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network transmitted (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0 + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 12, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Transmitted", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "label": "Cluster", + "name": "cluster", + "query": "label_values(node_uname_info{job=\"node-exporter\", sysname=\"Darwin\"}, cluster)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "label": "Instance", + "name": "instance", + "query": "label_values(node_uname_info{job=\"node-exporter\", cluster=\"$cluster\", sysname=\"Darwin\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Node Exporter / MacOS", + "uid": "629701ea43bf69291922ea45f4a87d37" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-nodes-darwin + namespace: monitoring + - apiVersion: v1 + data: + nodes.json: |- + { + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "CPU", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "max": 1, + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\", cluster=\"$cluster\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\", cluster=\"$cluster\"})\n)\n", + "intervalFactor": 5, + "legendFormat": "{{cpu}}" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "1m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "5m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "15m load average" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", mode=\"idle\"})", + "legendFormat": "logical cores" + } + ], + "title": "Load Average", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n-\n node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n-\n node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n-\n node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}\n)\n", + "legendFormat": "memory used" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "memory buffers" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "memory cached" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}", + "legendFormat": "memory free" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "max": 100, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)" + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 6, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "100 -\n(\n avg(node_memory_MemAvailable_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"}) /\n avg(node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"})\n* 100\n)\n" + } + ], + "title": "Memory Usage", + "type": "gauge" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 7, + "panels": [ + + ], + "title": "Disk", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0 + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/ read| written/" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/ io time/" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 8, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} read" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} written" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "intervalFactor": 1, + "legendFormat": "{{device}} io time" + } + ], + "title": "Disk I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "steps": [ + { + "color": "green" + }, + { + "color": "yellow", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Mounted on" + }, + "properties": [ + { + "id": "custom.width", + "value": 260 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Available" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used, %" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "custom.cellOptions", + "value": { + "type": "gauge" + } + }, + { + "id": "max", + "value": 1 + }, + { + "id": "min", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 9, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "legendFormat": "" + } + ], + "title": "Disk Space Usage", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value #A": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "Value #B": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "mountpoint": { + "aggregations": [ + + ], + "operation": "groupby" + } + } + } + }, + { + "id": "merge" + }, + { + "id": "calculateField", + "options": { + "alias": "Used", + "binary": { + "left": "Value #A (lastNotNull)", + "operator": "-", + "reducer": "sum", + "right": "Value #B (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used, %", + "binary": { + "left": "Used", + "operator": "/", + "reducer": "sum", + "right": "Value #A (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + + }, + "indexByName": { + + }, + "renameByName": { + "Value #A (lastNotNull)": "Size", + "Value #B (lastNotNull)": "Available", + "mountpoint": "Mounted on" + } + } + }, + { + "id": "sortBy", + "options": { + "fields": { + + }, + "sort": [ + { + "field": "Mounted on" + } + ] + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 10, + "panels": [ + + ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network received (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 11, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "description": "Network transmitted (bits/s)", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0 + }, + "min": 0, + "unit": "bps" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 12, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\", device!=\"lo\"}[$__rate_interval]) * 8", + "intervalFactor": 1, + "legendFormat": "{{device}}" + } + ], + "title": "Network Transmitted", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 2, + "label": "Cluster", + "name": "cluster", + "query": "label_values(node_uname_info{job=\"node-exporter\", sysname!=\"Darwin\"}, cluster)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "label": "Instance", + "name": "instance", + "query": "label_values(node_uname_info{job=\"node-exporter\", cluster=\"$cluster\", sysname!=\"Darwin\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Node Exporter / Nodes", + "uid": "7d57716318ee0dddbac5a7f451fb7753" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-nodes + namespace: monitoring + - apiVersion: v1 + data: + persistentvolumesusage.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 18, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", + "legendFormat": "Used Space" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n", + "legendFormat": "Free Space" + } + ], + "title": "Volume Space Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 80 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 2, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max without(instance,node) (\n(\n topk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n -\n topk(1, kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n)\n/\ntopk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", + "instant": true + } + ], + "title": "Volume Space Usage", + "type": "gauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 18, + "y": 7 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))", + "legendFormat": "Used inodes" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", + "legendFormat": "Free inodes" + } + ], + "title": "Volume inodes Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 80 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 7 + }, + "id": 4, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "max without(instance,node) (\ntopk(1, kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n/\ntopk(1, kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", + "instant": true + } + ], + "title": "Volume inodes Usage", + "type": "gauge" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(kubelet_volume_stats_capacity_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "Namespace", + "name": "namespace", + "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "PersistentVolumeClaim", + "name": "volume", + "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", metrics_path=\"/metrics\", namespace=\"$namespace\"}, persistentvolumeclaim)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Persistent Volumes", + "uid": "919b92a8e8041bd567af9edab12c840c" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-persistentvolumesusage + namespace: monitoring + - apiVersion: v1 + data: + pod-total.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "displayName": "$pod", + "max": 10000000000, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ] + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Received", + "type": "gauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "displayName": "$pod", + "max": 10000000000, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ] + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Transmitted", + "type": "gauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "showPoints": "never" + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "current": { + "selected": false, + "text": "kube-system", + "value": "kube-system" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "namespace", + "name": "namespace", + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "kube-system", + "value": "kube-system" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "pod", + "name": "pod", + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}, pod)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Networking / Pod", + "uid": "7a18067ce943a40ae25454675c19ff5c" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-pod-total + namespace: monitoring + - apiVersion: v1 + data: + prometheus-remote-write.json: |- + { + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "Timestamps", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "(\n prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}\n-\n ignoring(remote_name, url) group_right(instance) (prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"} != 0)\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}::{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Highest Timestamp In vs. Highest Timestamp Sent", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "clamp_min(\n rate(prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n-\n ignoring (remote_name, url) group_right(instance) rate(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m])\n, 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Rate[5m]", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "panels": [ + + ], + "title": "Samples", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 5, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(\n prometheus_remote_storage_samples_in_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n-\n ignoring(remote_name, url) group_right(instance) (rate(prometheus_remote_storage_succeeded_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]))\n-\n (rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Rate, in vs. succeeded or dropped [5m]", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 6, + "panels": [ + + ], + "title": "Shards", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 7, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Current Shards", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 23 + }, + "id": 8, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_shards_max{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Max Shards", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 23 + }, + "id": 9, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_shards_min{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Min Shards", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 23 + }, + "id": 10, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_shards_desired{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Desired Shards", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 11, + "panels": [ + + ], + "title": "Shard Details", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 12, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_shard_capacity{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Shard Capacity", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 13, + "options": { + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_remote_storage_pending_samples{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"} or prometheus_remote_storage_samples_pending{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Pending Samples", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 14, + "panels": [ + + ], + "title": "Segments", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 33 + }, + "id": 15, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_tsdb_wal_segment_current{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}}" + } + ], + "title": "TSDB Current Segment", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 33 + }, + "id": 16, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_wal_watcher_current_segment{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{consumer}}" + } + ], + "title": "Remote Write Current Segment", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 17, + "panels": [ + + ], + "title": "Misc. Rates", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + } + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 41 + }, + "id": 18, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Dropped Samples", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + } + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 41 + }, + "id": 19, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_remote_storage_failed_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Failed Samples", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + } + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 41 + }, + "id": 20, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_remote_storage_retried_samples_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m]) or rate(prometheus_remote_storage_samples_retried_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Retried Samples", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 0, + "showPoints": "never" + } + } + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 41 + }, + "id": 21, + "options": { + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_remote_storage_enqueue_retries_total{cluster=~\"$cluster\", instance=~\"$instance\", url=~\"$url\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{cluster}}:{{instance}} {{remote_name}}:{{url}}" + } + ], + "title": "Enqueue Retries", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [ + "prometheus-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "default", + "value": "default" + }, + "hide": 0, + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "$__all", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "name": "cluster", + "query": "label_values(prometheus_build_info, cluster)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "name": "instance", + "query": "label_values(prometheus_build_info{cluster=~\"$cluster\"}, instance)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "name": "url", + "query": "label_values(prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\"}, url)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "60s" + ] + }, + "timezone": "utc", + "title": "Prometheus / Remote Write" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-prometheus-remote-write + namespace: monitoring + - apiVersion: v1 + data: + prometheus.json: |- + { + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ + + ], + "title": "Prometheus Stats", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "displayName": "", + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "displayName", + "value": "Time" + }, + { + "id": "custom.align", + "value": null + }, + { + "id": "custom.hidden", + "value": "true" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "cluster" + }, + "properties": [ + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "displayName", + "value": "Cluster" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "job" + }, + "properties": [ + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "displayName", + "value": "Job" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "displayName", + "value": "Instance" + }, + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "version" + }, + "properties": [ + { + "id": "displayName", + "value": "Version" + }, + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value #A" + }, + "properties": [ + { + "id": "displayName", + "value": "Count" + }, + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "custom.hidden", + "value": "true" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value #B" + }, + "properties": [ + { + "id": "displayName", + "value": "Uptime" + }, + { + "id": "custom.align", + "value": null + }, + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 2, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count by (cluster, job, instance, version) (prometheus_build_info{cluster=~\"$cluster\", job=~\"$job\", instance=~\"$instance\"})", + "format": "table", + "instant": true, + "legendFormat": "" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (cluster, job, instance) (time() - process_start_time_seconds{cluster=~\"$cluster\", job=~\"$job\", instance=~\"$instance\"})", + "format": "table", + "instant": true, + "legendFormat": "" + } + ], + "title": "Prometheus Stats", + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "panels": [ + + ], + "title": "Discovery", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "min": 0, + "unit": "ms" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 4, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(rate(prometheus_target_sync_length_seconds_sum{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[5m])) by (cluster, job, scrape_job, instance) * 1e3", + "format": "time_series", + "legendFormat": "{{cluster}}:{{job}}:{{instance}}:{{scrape_job}}" + } + ], + "title": "Target Sync", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 5, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (prometheus_sd_discovered_targets{cluster=~\"$cluster\", job=~\"$job\",instance=~\"$instance\"})", + "format": "time_series", + "legendFormat": "{{cluster}}:{{job}}:{{instance}}" + } + ], + "title": "Targets", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 6, + "panels": [ + + ], + "title": "Retrieval", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never" + }, + "min": 0, + "unit": "ms" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 17 + }, + "id": 7, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_target_interval_length_seconds_sum{cluster=~\"$cluster\", job=~\"$job\",instance=~\"$instance\"}[5m]) / rate(prometheus_target_interval_length_seconds_count{cluster=~\"$cluster\", job=~\"$job\",instance=~\"$instance\"}[5m]) * 1e3", + "format": "time_series", + "legendFormat": "{{cluster}}:{{job}}:{{instance}} {{interval}} configured" + } + ], + "title": "Average Scrape Interval Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 17 + }, + "id": 8, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (rate(prometheus_target_scrapes_exceeded_body_size_limit_total{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[1m]))", + "format": "time_series", + "legendFormat": "exceeded body size limit: {{cluster}} {{job}} {{instance}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (rate(prometheus_target_scrapes_exceeded_sample_limit_total{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[1m]))", + "format": "time_series", + "legendFormat": "exceeded sample limit: {{cluster}} {{job}} {{instance}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[1m]))", + "format": "time_series", + "legendFormat": "duplicate timestamp: {{cluster}} {{job}} {{instance}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_out_of_bounds_total{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[1m]))", + "format": "time_series", + "legendFormat": "out of bounds: {{cluster}} {{job}} {{instance}}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_out_of_order_total{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}[1m]))", + "format": "time_series", + "legendFormat": "out of order: {{cluster}} {{job}} {{instance}}" + } + ], + "title": "Scrape failures", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 17 + }, + "id": 9, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_tsdb_head_samples_appended_total{cluster=~\"$cluster\", job=~\"$job\",instance=~\"$instance\"}[5m])", + "format": "time_series", + "legendFormat": "{{cluster}} {{job}} {{instance}}" + } + ], + "title": "Appended Samples", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 10, + "panels": [ + + ], + "title": "Storage", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 11, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_tsdb_head_series{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}", + "format": "time_series", + "legendFormat": "{{cluster}} {{job}} {{instance}} head series" + } + ], + "title": "Head Series", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 12, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "prometheus_tsdb_head_chunks{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\"}", + "format": "time_series", + "legendFormat": "{{cluster}} {{job}} {{instance}} head chunks" + } + ], + "title": "Head Chunks", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 13, + "panels": [ + + ], + "title": "Query", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 33 + }, + "id": 14, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(prometheus_engine_query_duration_seconds_count{cluster=~\"$cluster\",job=~\"$job\",instance=~\"$instance\",slice=\"inner_eval\"}[5m])", + "format": "time_series", + "legendFormat": "{{cluster}} {{job}} {{instance}}" + } + ], + "title": "Query Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "lineWidth": 0, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "min": 0, + "unit": "ms" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 33 + }, + "id": 15, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max by (slice) (prometheus_engine_query_duration_seconds{quantile=\"0.9\",cluster=~\"$cluster\", job=~\"$job\",instance=~\"$instance\"}) * 1e3", + "format": "time_series", + "legendFormat": "{{slice}}" + } + ], + "title": "Stage Duration", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [ + "prometheus-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "allValue": ".+", + "current": { + "selected": false, + "text": [ + "$__all" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "cluster", + "multi": true, + "name": "cluster", + "query": "label_values(prometheus_build_info{job=\"prometheus-k8s\",namespace=\"monitoring\"}, cluster)", + "refresh": 2, + "sort": 2, + "type": "query" + }, + { + "allValue": ".+", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "label": "job", + "multi": true, + "name": "job", + "query": "label_values(prometheus_build_info{cluster=~\"$cluster\"}, job)", + "refresh": 2, + "sort": 2, + "type": "query" + }, + { + "allValue": ".+", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "label": "instance", + "multi": true, + "name": "instance", + "query": "label_values(prometheus_build_info{cluster=~\"$cluster\", job=~\"$job\"}, instance)", + "refresh": 2, + "sort": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "60s" + ] + }, + "timezone": "utc", + "title": "Prometheus / Overview" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-prometheus + namespace: monitoring + - apiVersion: v1 + data: + proxy.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(up{cluster=\"$cluster\", job=\"kube-proxy\"})", + "instant": true + } + ], + "title": "Up", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_count{cluster=\"$cluster\", job=\"kube-proxy\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "rate" + } + ], + "title": "Rules Sync Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 14, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99,rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-proxy\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "{{instance}}" + } + ], + "title": "Rules Sync Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(kubeproxy_network_programming_duration_seconds_count{cluster=\"$cluster\", job=\"kube-proxy\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "rate" + } + ], + "title": "Network Programming Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(kubeproxy_network_programming_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-proxy\", instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "legendFormat": "{{instance}}" + } + ], + "title": "Network Programming Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kube-proxy\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "legendFormat": "2xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kube-proxy\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "legendFormat": "3xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kube-proxy\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "legendFormat": "4xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"kube-proxy\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "legendFormat": "5xx" + } + ], + "title": "Kube API Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 14 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-proxy\",instance=~\"$instance\",verb=\"POST\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Post Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-proxy\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Get Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 28 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"kube-proxy\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 28 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"kube-proxy\",instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 28 + }, + "id": 11, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "go_goroutines{cluster=\"$cluster\", job=\"kube-proxy\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Goroutines", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-proxy\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "instance", + "name": "instance", + "query": "label_values(up{job=\"kube-proxy\", cluster=\"$cluster\", job=\"kube-proxy\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Proxy", + "uid": "632e265de029684c40b21cb76bca4f94" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-proxy + namespace: monitoring + - apiVersion: v1 + data: + scheduler.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "colorMode": "none" + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(up{cluster=\"$cluster\", job=\"kube-scheduler\"})", + "instant": true + } + ], + "title": "Up", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 4, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(scheduler_e2e_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "legendFormat": "{{cluster}} {{instance}} e2e" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(scheduler_binding_duration_seconds_count{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "legendFormat": "{{cluster}} {{instance}} binding" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(scheduler_scheduling_algorithm_duration_seconds_count{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "legendFormat": "{{cluster}} {{instance}} scheduling algorithm" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(scheduler_volume_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "legendFormat": "{{cluster}} {{instance}} volume" + } + ], + "title": "Scheduling Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 14, + "y": 0 + }, + "id": 3, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "legendFormat": "{{cluster}} {{instance}} e2e" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "legendFormat": "{{cluster}} {{instance}} binding" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "legendFormat": "{{cluster}} {{instance}} scheduling algorithm" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(scheduler_volume_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "legendFormat": "{{cluster}} {{instance}} volume" + } + ], + "title": "Scheduling latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "id": 4, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "legendFormat": "2xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "legendFormat": "3xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "legendFormat": "4xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "legendFormat": "5xx" + } + ], + "title": "Kube API Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 7 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Post Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "s" + } + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, le))", + "legendFormat": "{{verb}}" + } + ], + "title": "Get Request Latency 99th Quantile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "bytes" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 21 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 21 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"kube-scheduler\", instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "{{instance}}" + } + ], + "title": "CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "short" + } + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 21 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "go_goroutines{cluster=\"$cluster\", job=\"kube-scheduler\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}" + } + ], + "title": "Goroutines", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(up{job=\"kube-scheduler\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "instance", + "name": "instance", + "query": "label_values(up{job=\"kube-scheduler\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Scheduler", + "uid": "2e6b6a3b4bddf1427b3a55aa1311c656" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-scheduler + namespace: monitoring + - apiVersion: v1 + data: + workload-total.json: |- + { + "editable": false, + "links": [ + { + "asDropdown": true, + "includeVars": true, + "keepTime": true, + "tags": [ + "kubernetes-mixin" + ], + "targetBlank": false, + "title": "Kubernetes", + "type": "dashboards" + } + ], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Received", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Current Rate of Bytes Transmitted", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 3, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Rate of Bytes Received", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "unit": "Bps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 4, + "interval": "1m", + "options": { + "displayMode": "basic", + "showUnfilled": false + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(avg(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Average Rate of Bytes Transmitted", + "type": "bargauge" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 5, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Receive Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "binBps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 6, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Transmit Bandwidth", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 7, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 8, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 9, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_receive_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Received Packets Dropped", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": true + }, + "unit": "pps" + } + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 10, + "interval": "1m", + "options": { + "legend": { + "asTable": true, + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "v11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sort_desc(sum(rate(container_network_transmit_packets_dropped_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=~\"$type\"}) by (pod))\n", + "legendFormat": "__auto" + } + ], + "title": "Rate of Transmitted Packets Dropped", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data source", + "name": "datasource", + "query": "prometheus", + "regex": "", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "cluster", + "name": "cluster", + "query": "label_values(kube_pod_info{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "current": { + "selected": false, + "text": "kube-system", + "value": "kube-system" + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "namespace", + "name": "namespace", + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "label": "workload", + "name": "workload", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=~\"$namespace\", workload=~\".+\"}, workload)", + "refresh": 2, + "sort": 1, + "type": "query" + }, + { + "allValue": ".+", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "hide": 0, + "includeAll": true, + "label": "workload_type", + "name": "type", + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=~\"$namespace\", workload=~\"$workload\"}, workload_type)", + "refresh": 2, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "UTC", + "title": "Kubernetes / Networking / Workload", + "uid": "728bf77cc1166d2f3133bf25846876cc" + } + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboard-workload-total + namespace: monitoring +kind: ConfigMapList diff --git a/release/kubernetes/monitoring/grafana-dashboardSources.yaml b/release/kubernetes/monitoring/grafana-dashboardSources.yaml new file mode 100644 index 000000000..b2bbd6677 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-dashboardSources.yaml @@ -0,0 +1,42 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +data: + dashboards.yaml: |- + { + "apiVersion": 1, + "providers": [ + { + "folder": "Default", + "folderUid": "", + "name": "0", + "options": { + "path": "/grafana-dashboard-definitions/0" + }, + "orgId": 1, + "type": "file" + } + ] + } +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana-dashboards + namespace: monitoring diff --git a/release/kubernetes/monitoring/grafana-deployment.yaml b/release/kubernetes/monitoring/grafana-deployment.yaml new file mode 100644 index 000000000..ae5146796 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-deployment.yaml @@ -0,0 +1,304 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + template: + metadata: + annotations: + checksum/grafana-config: fbb6fa9bc8072c0f9758c30eac1a7ce6 + checksum/grafana-dashboardproviders: 4c364bf7811a4eff194596a272550ae5 + checksum/grafana-datasources: 34dc6d0eeebe415ac38992ae3518ab8e + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + spec: + + automountServiceAccountToken: false + containers: + - env: [] + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/grafana/grafana:12.1.0 + name: grafana + ports: + - containerPort: 3000 + name: http + readinessProbe: + httpGet: + path: /api/health + port: http + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/lib/grafana + name: grafana-storage + readOnly: false + - mountPath: /etc/grafana/provisioning/datasources + name: grafana-datasources + readOnly: false + - mountPath: /etc/grafana/provisioning/dashboards + name: grafana-dashboards + readOnly: false + - mountPath: /tmp + name: tmp-plugins + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/alertmanager-overview + name: grafana-dashboard-alertmanager-overview + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/apiserver + name: grafana-dashboard-apiserver + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/cluster-total + name: grafana-dashboard-cluster-total + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/controller-manager + name: grafana-dashboard-controller-manager + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/grafana-overview + name: grafana-dashboard-grafana-overview + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-cluster + name: grafana-dashboard-k8s-resources-cluster + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-multicluster + name: grafana-dashboard-k8s-resources-multicluster + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-namespace + name: grafana-dashboard-k8s-resources-namespace + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-node + name: grafana-dashboard-k8s-resources-node + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-pod + name: grafana-dashboard-k8s-resources-pod + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-cluster + name: grafana-dashboard-k8s-resources-windows-cluster + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-namespace + name: grafana-dashboard-k8s-resources-windows-namespace + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-pod + name: grafana-dashboard-k8s-resources-windows-pod + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-workload + name: grafana-dashboard-k8s-resources-workload + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-resources-workloads-namespace + name: grafana-dashboard-k8s-resources-workloads-namespace + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-windows-cluster-rsrc-use + name: grafana-dashboard-k8s-windows-cluster-rsrc-use + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/k8s-windows-node-rsrc-use + name: grafana-dashboard-k8s-windows-node-rsrc-use + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/kubelet + name: grafana-dashboard-kubelet + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/namespace-by-pod + name: grafana-dashboard-namespace-by-pod + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/namespace-by-workload + name: grafana-dashboard-namespace-by-workload + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/node-cluster-rsrc-use + name: grafana-dashboard-node-cluster-rsrc-use + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/node-rsrc-use + name: grafana-dashboard-node-rsrc-use + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/nodes-aix + name: grafana-dashboard-nodes-aix + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/nodes-darwin + name: grafana-dashboard-nodes-darwin + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/nodes + name: grafana-dashboard-nodes + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/persistentvolumesusage + name: grafana-dashboard-persistentvolumesusage + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/pod-total + name: grafana-dashboard-pod-total + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/prometheus-remote-write + name: grafana-dashboard-prometheus-remote-write + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/prometheus + name: grafana-dashboard-prometheus + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/proxy + name: grafana-dashboard-proxy + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/scheduler + name: grafana-dashboard-scheduler + readOnly: false + - mountPath: /grafana-dashboard-definitions/0/workload-total + name: grafana-dashboard-workload-total + readOnly: false + - mountPath: /etc/grafana + name: grafana-config + readOnly: false + nodeSelector: + kubernetes.io/os: linux + node-role.kubernetes.io/control-plane: "" + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + serviceAccountName: grafana + volumes: + - emptyDir: {} + name: grafana-storage + - name: grafana-datasources + secret: + secretName: grafana-datasources + - configMap: + name: grafana-dashboards + name: grafana-dashboards + - emptyDir: + medium: Memory + name: tmp-plugins + - configMap: + name: grafana-dashboard-alertmanager-overview + name: grafana-dashboard-alertmanager-overview + - configMap: + name: grafana-dashboard-apiserver + name: grafana-dashboard-apiserver + - configMap: + name: grafana-dashboard-cluster-total + name: grafana-dashboard-cluster-total + - configMap: + name: grafana-dashboard-controller-manager + name: grafana-dashboard-controller-manager + - configMap: + name: grafana-dashboard-grafana-overview + name: grafana-dashboard-grafana-overview + - configMap: + name: grafana-dashboard-k8s-resources-cluster + name: grafana-dashboard-k8s-resources-cluster + - configMap: + name: grafana-dashboard-k8s-resources-multicluster + name: grafana-dashboard-k8s-resources-multicluster + - configMap: + name: grafana-dashboard-k8s-resources-namespace + name: grafana-dashboard-k8s-resources-namespace + - configMap: + name: grafana-dashboard-k8s-resources-node + name: grafana-dashboard-k8s-resources-node + - configMap: + name: grafana-dashboard-k8s-resources-pod + name: grafana-dashboard-k8s-resources-pod + - configMap: + name: grafana-dashboard-k8s-resources-windows-cluster + name: grafana-dashboard-k8s-resources-windows-cluster + - configMap: + name: grafana-dashboard-k8s-resources-windows-namespace + name: grafana-dashboard-k8s-resources-windows-namespace + - configMap: + name: grafana-dashboard-k8s-resources-windows-pod + name: grafana-dashboard-k8s-resources-windows-pod + - configMap: + name: grafana-dashboard-k8s-resources-workload + name: grafana-dashboard-k8s-resources-workload + - configMap: + name: grafana-dashboard-k8s-resources-workloads-namespace + name: grafana-dashboard-k8s-resources-workloads-namespace + - configMap: + name: grafana-dashboard-k8s-windows-cluster-rsrc-use + name: grafana-dashboard-k8s-windows-cluster-rsrc-use + - configMap: + name: grafana-dashboard-k8s-windows-node-rsrc-use + name: grafana-dashboard-k8s-windows-node-rsrc-use + - configMap: + name: grafana-dashboard-kubelet + name: grafana-dashboard-kubelet + - configMap: + name: grafana-dashboard-namespace-by-pod + name: grafana-dashboard-namespace-by-pod + - configMap: + name: grafana-dashboard-namespace-by-workload + name: grafana-dashboard-namespace-by-workload + - configMap: + name: grafana-dashboard-node-cluster-rsrc-use + name: grafana-dashboard-node-cluster-rsrc-use + - configMap: + name: grafana-dashboard-node-rsrc-use + name: grafana-dashboard-node-rsrc-use + - configMap: + name: grafana-dashboard-nodes-aix + name: grafana-dashboard-nodes-aix + - configMap: + name: grafana-dashboard-nodes-darwin + name: grafana-dashboard-nodes-darwin + - configMap: + name: grafana-dashboard-nodes + name: grafana-dashboard-nodes + - configMap: + name: grafana-dashboard-persistentvolumesusage + name: grafana-dashboard-persistentvolumesusage + - configMap: + name: grafana-dashboard-pod-total + name: grafana-dashboard-pod-total + - configMap: + name: grafana-dashboard-prometheus-remote-write + name: grafana-dashboard-prometheus-remote-write + - configMap: + name: grafana-dashboard-prometheus + name: grafana-dashboard-prometheus + - configMap: + name: grafana-dashboard-proxy + name: grafana-dashboard-proxy + - configMap: + name: grafana-dashboard-scheduler + name: grafana-dashboard-scheduler + - configMap: + name: grafana-dashboard-workload-total + name: grafana-dashboard-workload-total + - name: grafana-config + secret: + secretName: grafana-config diff --git a/release/kubernetes/monitoring/grafana-networkPolicy.yaml b/release/kubernetes/monitoring/grafana-networkPolicy.yaml new file mode 100644 index 000000000..52892b788 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-networkPolicy.yaml @@ -0,0 +1,44 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 3000 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/grafana-prometheusRule.yaml b/release/kubernetes/monitoring/grafana-prometheusRule.yaml new file mode 100644 index 000000000..d80d3213b --- /dev/null +++ b/release/kubernetes/monitoring/grafana-prometheusRule.yaml @@ -0,0 +1,48 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + prometheus: k8s + role: alert-rules + name: grafana-rules + namespace: monitoring +spec: + groups: + - name: GrafanaAlerts + rules: + - alert: GrafanaRequestsFailing + annotations: + message: '{{ $labels.namespace }}/{{ $labels.job }}/{{ $labels.handler }} is experiencing {{ $value | humanize }}% errors' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/grafana/grafanarequestsfailing + expr: | + 100 * sum without (status_code) (namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m{handler!~"/api/datasources/proxy/:id.*|/api/ds/query|/api/tsdb/query", status_code=~"5.."}) + / + sum without (status_code) (namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m{handler!~"/api/datasources/proxy/:id.*|/api/ds/query|/api/tsdb/query"}) + > 50 + for: 5m + labels: + severity: warning + - name: grafana_rules + rules: + - expr: | + sum by (namespace, job, handler, status_code) (rate(grafana_http_request_duration_seconds_count[5m])) + record: namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m diff --git a/release/kubernetes/monitoring/grafana-service.yaml b/release/kubernetes/monitoring/grafana-service.yaml new file mode 100644 index 000000000..6e87cf906 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-service.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana + namespace: monitoring +spec: + ports: + - name: http + port: 3000 + targetPort: http + selector: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/grafana-serviceAccount.yaml b/release/kubernetes/monitoring/grafana-serviceAccount.yaml new file mode 100644 index 000000000..551b521f1 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana + namespace: monitoring diff --git a/release/kubernetes/monitoring/grafana-serviceMonitor.yaml b/release/kubernetes/monitoring/grafana-serviceMonitor.yaml new file mode 100644 index 000000000..7f4d5bd38 --- /dev/null +++ b/release/kubernetes/monitoring/grafana-serviceMonitor.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: grafana + app.kubernetes.io/name: grafana + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 12.1.0 + name: grafana + namespace: monitoring +spec: + endpoints: + - interval: 15s + port: http + selector: + matchLabels: + app.kubernetes.io/name: grafana diff --git a/release/kubernetes/monitoring/jaeger-deployment.yaml b/release/kubernetes/monitoring/jaeger-deployment.yaml new file mode 100644 index 000000000..40a1b6724 --- /dev/null +++ b/release/kubernetes/monitoring/jaeger-deployment.yaml @@ -0,0 +1,48 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +kind: Deployment +apiVersion: apps/v1 +metadata: + name: jaeger + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: jaeger + template: + metadata: + labels: + app: jaeger + spec: + containers: + - name: jaeger-all-in-one + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jaegertracing/all-in-one:1.70.0 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: {} + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 diff --git a/release/kubernetes/monitoring/jaeger-service.yaml b/release/kubernetes/monitoring/jaeger-service.yaml new file mode 100644 index 000000000..4c234ce17 --- /dev/null +++ b/release/kubernetes/monitoring/jaeger-service.yaml @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +kind: Service +apiVersion: v1 +metadata: + name: jaeger + namespace: monitoring +spec: + selector: + app: jaeger + type: ClusterIP + ports: + - name: query + port: 16686 + targetPort: 16686 + protocol: TCP + - name: otlp-grpc + port: 4317 + targetPort: 4317 + protocol: TCP + - name: otlp-http + port: 4318 + targetPort: 4318 + protocol: TCP + - name: thrift + port: 14268 + targetPort: 14268 + protocol: TCP + - name: zipkin + port: 9411 + targetPort: 9411 + protocol: TCP \ No newline at end of file diff --git a/release/kubernetes/monitoring/kubePrometheus-prometheusRule.yaml b/release/kubernetes/monitoring/kubePrometheus-prometheusRule.yaml new file mode 100644 index 000000000..fd76f09a1 --- /dev/null +++ b/release/kubernetes/monitoring/kubePrometheus-prometheusRule.yaml @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-prometheus + app.kubernetes.io/part-of: kube-prometheus + prometheus: k8s + role: alert-rules + name: kube-prometheus-rules + namespace: monitoring +spec: + groups: + - name: general.rules + rules: + - alert: TargetDown + annotations: + description: '{{ printf "%.4g" $value }}% of the {{ $labels.job }}/{{ $labels.service }} targets in {{ $labels.namespace }} namespace are down.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/targetdown + summary: One or more targets are unreachable. + expr: 100 * (count(up == 0) BY (cluster, job, namespace, service) / count(up) BY (cluster, job, namespace, service)) > 10 + for: 10m + labels: + severity: warning + - alert: Watchdog + annotations: + description: | + This is an alert meant to ensure that the entire alerting pipeline is functional. + This alert is always firing, therefore it should always be firing in Alertmanager + and always fire against a receiver. There are integrations with various notification + mechanisms that send a notification when this alert is not firing. For example the + "DeadMansSnitch" integration in PagerDuty. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/watchdog + summary: An alert that should always be firing to certify that Alertmanager is working properly. + expr: vector(1) + labels: + severity: none + - alert: InfoInhibitor + annotations: + description: | + This is an alert that is used to inhibit info alerts. + By themselves, the info-level alerts are sometimes very noisy, but they are relevant when combined with + other alerts. + This alert fires whenever there's a severity="info" alert, and stops firing when another alert with a + severity of 'warning' or 'critical' starts firing on the same namespace. + This alert should be routed to a null receiver and configured to inhibit alerts with severity="info". + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/infoinhibitor + summary: Info-level alert inhibition. + expr: ALERTS{severity = "info"} == 1 unless on(namespace) ALERTS{alertname != "InfoInhibitor", severity =~ "warning|critical", alertstate="firing"} == 1 + labels: + severity: none + - name: node-network + rules: + - alert: NodeNetworkInterfaceFlapping + annotations: + description: Network interface "{{ $labels.device }}" changing its up status often on node-exporter {{ $labels.namespace }}/{{ $labels.pod }} + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/nodenetworkinterfaceflapping + summary: Network interface is often changing its status + expr: | + changes(node_network_up{job="node-exporter",device!~"veth.+"}[2m]) > 2 + for: 2m + labels: + severity: warning + - name: kube-prometheus-node-recording.rules + rules: + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[3m])) BY (instance) + record: instance:node_cpu:rate:sum + - expr: sum(rate(node_network_receive_bytes_total[3m])) BY (instance) + record: instance:node_network_receive_bytes:rate:sum + - expr: sum(rate(node_network_transmit_bytes_total[3m])) BY (instance) + record: instance:node_network_transmit_bytes:rate:sum + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) WITHOUT (cpu, mode) / ON(instance) GROUP_LEFT() count(sum(node_cpu_seconds_total) BY (instance, cpu)) BY (instance) + record: instance:node_cpu:ratio + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) + record: cluster:node_cpu:sum_rate5m + - expr: cluster:node_cpu:sum_rate5m / count(sum(node_cpu_seconds_total) BY (instance, cpu)) + record: cluster:node_cpu:ratio + - name: kube-prometheus-general.rules + rules: + - expr: count without(instance, pod, node) (up == 1) + record: count:up1 + - expr: count without(instance, pod, node) (up == 0) + record: count:up0 diff --git a/release/kubernetes/monitoring/kubeStateMetrics-clusterRole.yaml b/release/kubernetes/monitoring/kubeStateMetrics-clusterRole.yaml new file mode 100644 index 000000000..79cb1bbff --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-clusterRole.yaml @@ -0,0 +1,144 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + - nodes + - pods + - services + - serviceaccounts + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - list + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingressclasses + - ingresses + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch diff --git a/release/kubernetes/monitoring/kubeStateMetrics-clusterRoleBinding.yaml b/release/kubernetes/monitoring/kubeStateMetrics-clusterRoleBinding.yaml new file mode 100644 index 000000000..3f2c57c97 --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-clusterRoleBinding.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kube-state-metrics +subjects: +- kind: ServiceAccount + name: kube-state-metrics + namespace: monitoring diff --git a/release/kubernetes/monitoring/kubeStateMetrics-deployment.yaml b/release/kubernetes/monitoring/kubeStateMetrics-deployment.yaml new file mode 100644 index 000000000..1c1830057 --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-deployment.yaml @@ -0,0 +1,126 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: kube-state-metrics + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + spec: + automountServiceAccountToken: true + containers: + - args: + - --host=127.0.0.1 + - --port=8081 + - --telemetry-host=127.0.0.1 + - --telemetry-port=8082 + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.16.0 + name: kube-state-metrics + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 10m + memory: 190Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + - args: + - --secure-listen-address=:8443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8081/ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/brancz/kube-rbac-proxy:v0.19.1 + name: kube-rbac-proxy-main + ports: + - containerPort: 8443 + name: https-main + resources: + limits: + cpu: 40m + memory: 40Mi + requests: + cpu: 20m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + - args: + - --secure-listen-address=:9443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8082/ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/brancz/kube-rbac-proxy:v0.19.1 + name: kube-rbac-proxy-self + ports: + - containerPort: 9443 + name: https-self + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: kube-state-metrics diff --git a/release/kubernetes/monitoring/kubeStateMetrics-networkPolicy.yaml b/release/kubernetes/monitoring/kubeStateMetrics-networkPolicy.yaml new file mode 100644 index 000000000..df677d9fe --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-networkPolicy.yaml @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 8443 + protocol: TCP + - port: 9443 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/kubeStateMetrics-prometheusRule.yaml b/release/kubernetes/monitoring/kubeStateMetrics-prometheusRule.yaml new file mode 100644 index 000000000..178a3bc3d --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-prometheusRule.yaml @@ -0,0 +1,80 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + prometheus: k8s + role: alert-rules + name: kube-state-metrics-rules + namespace: monitoring +spec: + groups: + - name: kube-state-metrics + rules: + - alert: KubeStateMetricsListErrors + annotations: + description: kube-state-metrics is experiencing errors at an elevated rate in list operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricslisterrors + summary: kube-state-metrics is experiencing errors in list operations. + expr: | + (sum(rate(kube_state_metrics_list_total{job="kube-state-metrics",result="error"}[5m])) by (cluster) + / + sum(rate(kube_state_metrics_list_total{job="kube-state-metrics"}[5m])) by (cluster)) + > 0.01 + for: 15m + labels: + severity: critical + - alert: KubeStateMetricsWatchErrors + annotations: + description: kube-state-metrics is experiencing errors at an elevated rate in watch operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricswatcherrors + summary: kube-state-metrics is experiencing errors in watch operations. + expr: | + (sum(rate(kube_state_metrics_watch_total{job="kube-state-metrics",result="error"}[5m])) by (cluster) + / + sum(rate(kube_state_metrics_watch_total{job="kube-state-metrics"}[5m])) by (cluster)) + > 0.01 + for: 15m + labels: + severity: critical + - alert: KubeStateMetricsShardingMismatch + annotations: + description: kube-state-metrics pods are running with different --total-shards configuration, some Kubernetes objects may be exposed multiple times or not exposed at all. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricsshardingmismatch + summary: kube-state-metrics sharding is misconfigured. + expr: | + stdvar (kube_state_metrics_total_shards{job="kube-state-metrics"}) by (cluster) != 0 + for: 15m + labels: + severity: critical + - alert: KubeStateMetricsShardsMissing + annotations: + description: kube-state-metrics shards are missing, some Kubernetes objects are not being exposed. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricsshardsmissing + summary: kube-state-metrics shards are missing. + expr: | + 2^max(kube_state_metrics_total_shards{job="kube-state-metrics"}) by (cluster) - 1 + - + sum( 2 ^ max by (cluster, shard_ordinal) (kube_state_metrics_shard_ordinal{job="kube-state-metrics"}) ) by (cluster) + != 0 + for: 15m + labels: + severity: critical diff --git a/release/kubernetes/monitoring/kubeStateMetrics-service.yaml b/release/kubernetes/monitoring/kubeStateMetrics-service.yaml new file mode 100644 index 000000000..332db5809 --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-service.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics + namespace: monitoring +spec: + clusterIP: None + ports: + - name: https-main + port: 8443 + targetPort: https-main + - name: https-self + port: 9443 + targetPort: https-self + selector: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/kubeStateMetrics-serviceAccount.yaml b/release/kubernetes/monitoring/kubeStateMetrics-serviceAccount.yaml new file mode 100644 index 000000000..41411a767 --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics + namespace: monitoring diff --git a/release/kubernetes/monitoring/kubeStateMetrics-serviceMonitor.yaml b/release/kubernetes/monitoring/kubeStateMetrics-serviceMonitor.yaml new file mode 100644 index 000000000..ff10af443 --- /dev/null +++ b/release/kubernetes/monitoring/kubeStateMetrics-serviceMonitor.yaml @@ -0,0 +1,55 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 2.16.0 + name: kube-state-metrics + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 30s + metricRelabelings: + - action: drop + regex: kube_(endpoint_(address_not_ready|address_available|ports)) + sourceLabels: + - __name__ + port: https-main + relabelings: + - action: labeldrop + regex: (pod|service|endpoint|namespace) + scheme: https + scrapeTimeout: 30s + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + port: https-self + scheme: https + tlsConfig: + insecureSkipVerify: true + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-prometheusRule.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-prometheusRule.yaml new file mode 100644 index 000000000..4987500ff --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-prometheusRule.yaml @@ -0,0 +1,1693 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: kube-prometheus + app.kubernetes.io/part-of: kube-prometheus + prometheus: k8s + role: alert-rules + name: kubernetes-monitoring-rules + namespace: monitoring +spec: + groups: + - name: kubernetes-apps + rules: + - alert: KubePodCrashLooping + annotations: + description: 'Pod {{ $labels.namespace }}/{{ $labels.pod }} ({{ $labels.container }}) is in waiting state (reason: "CrashLoopBackOff") on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepodcrashlooping + summary: Pod is crash looping. + expr: | + max_over_time(kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff", job="kube-state-metrics"}[5m]) >= 1 + for: 15m + labels: + severity: warning + - alert: KubePodNotReady + annotations: + description: Pod {{ $labels.namespace }}/{{ $labels.pod }} has been in a non-ready state for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepodnotready + summary: Pod has been in a non-ready state for more than 15 minutes. + expr: | + sum by (namespace, pod, cluster) ( + max by(namespace, pod, cluster) ( + kube_pod_status_phase{job="kube-state-metrics", phase=~"Pending|Unknown|Failed"} + ) * on(namespace, pod, cluster) group_left(owner_kind) topk by(namespace, pod, cluster) ( + 1, max by(namespace, pod, owner_kind, cluster) (kube_pod_owner{owner_kind!="Job"}) + ) + ) > 0 + for: 15m + labels: + severity: warning + - alert: KubeDeploymentGenerationMismatch + annotations: + description: Deployment generation for {{ $labels.namespace }}/{{ $labels.deployment }} does not match, this indicates that the Deployment has failed but has not been rolled back on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentgenerationmismatch + summary: Deployment generation mismatch due to possible roll-back + expr: | + kube_deployment_status_observed_generation{job="kube-state-metrics"} + != + kube_deployment_metadata_generation{job="kube-state-metrics"} + for: 15m + labels: + severity: warning + - alert: KubeDeploymentReplicasMismatch + annotations: + description: Deployment {{ $labels.namespace }}/{{ $labels.deployment }} has not matched the expected number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentreplicasmismatch + summary: Deployment has not matched the expected number of replicas. + expr: | + ( + kube_deployment_spec_replicas{job="kube-state-metrics"} + > + kube_deployment_status_replicas_available{job="kube-state-metrics"} + ) and ( + changes(kube_deployment_status_replicas_updated{job="kube-state-metrics"}[10m]) + == + 0 + ) + for: 15m + labels: + severity: warning + - alert: KubeDeploymentRolloutStuck + annotations: + description: Rollout of deployment {{ $labels.namespace }}/{{ $labels.deployment }} is not progressing for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentrolloutstuck + summary: Deployment rollout is not progressing. + expr: | + kube_deployment_status_condition{condition="Progressing", status="false",job="kube-state-metrics"} + != 0 + for: 15m + labels: + severity: warning + - alert: KubeStatefulSetReplicasMismatch + annotations: + description: StatefulSet {{ $labels.namespace }}/{{ $labels.statefulset }} has not matched the expected number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetreplicasmismatch + summary: StatefulSet has not matched the expected number of replicas. + expr: | + ( + kube_statefulset_status_replicas_ready{job="kube-state-metrics"} + != + kube_statefulset_replicas{job="kube-state-metrics"} + ) and ( + changes(kube_statefulset_status_replicas_updated{job="kube-state-metrics"}[10m]) + == + 0 + ) + for: 15m + labels: + severity: warning + - alert: KubeStatefulSetGenerationMismatch + annotations: + description: StatefulSet generation for {{ $labels.namespace }}/{{ $labels.statefulset }} does not match, this indicates that the StatefulSet has failed but has not been rolled back on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetgenerationmismatch + summary: StatefulSet generation mismatch due to possible roll-back + expr: | + kube_statefulset_status_observed_generation{job="kube-state-metrics"} + != + kube_statefulset_metadata_generation{job="kube-state-metrics"} + for: 15m + labels: + severity: warning + - alert: KubeStatefulSetUpdateNotRolledOut + annotations: + description: StatefulSet {{ $labels.namespace }}/{{ $labels.statefulset }} update has not been rolled out on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetupdatenotrolledout + summary: StatefulSet update has not been rolled out. + expr: | + ( + max by(namespace, statefulset, job, cluster) ( + kube_statefulset_status_current_revision{job="kube-state-metrics"} + unless + kube_statefulset_status_update_revision{job="kube-state-metrics"} + ) + * on(namespace, statefulset, job, cluster) + ( + kube_statefulset_replicas{job="kube-state-metrics"} + != + kube_statefulset_status_replicas_updated{job="kube-state-metrics"} + ) + ) and on(namespace, statefulset, job, cluster) ( + changes(kube_statefulset_status_replicas_updated{job="kube-state-metrics"}[5m]) + == + 0 + ) + for: 15m + labels: + severity: warning + - alert: KubeDaemonSetRolloutStuck + annotations: + description: DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} has not finished or progressed for at least 15m on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetrolloutstuck + summary: DaemonSet rollout is stuck. + expr: | + ( + ( + kube_daemonset_status_current_number_scheduled{job="kube-state-metrics"} + != + kube_daemonset_status_desired_number_scheduled{job="kube-state-metrics"} + ) or ( + kube_daemonset_status_number_misscheduled{job="kube-state-metrics"} + != + 0 + ) or ( + kube_daemonset_status_updated_number_scheduled{job="kube-state-metrics"} + != + kube_daemonset_status_desired_number_scheduled{job="kube-state-metrics"} + ) or ( + kube_daemonset_status_number_available{job="kube-state-metrics"} + != + kube_daemonset_status_desired_number_scheduled{job="kube-state-metrics"} + ) + ) and ( + changes(kube_daemonset_status_updated_number_scheduled{job="kube-state-metrics"}[5m]) + == + 0 + ) + for: 15m + labels: + severity: warning + - alert: KubeContainerWaiting + annotations: + description: 'pod/{{ $labels.pod }} in namespace {{ $labels.namespace }} on container {{ $labels.container}} has been in waiting state for longer than 1 hour. (reason: "{{ $labels.reason }}") on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecontainerwaiting + summary: Pod container waiting longer than 1 hour + expr: | + kube_pod_container_status_waiting_reason{reason!="CrashLoopBackOff", job="kube-state-metrics"} > 0 + for: 1h + labels: + severity: warning + - alert: KubeDaemonSetNotScheduled + annotations: + description: '{{ $value }} Pods of DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} are not scheduled on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetnotscheduled + summary: DaemonSet pods are not scheduled. + expr: | + kube_daemonset_status_desired_number_scheduled{job="kube-state-metrics"} + - + kube_daemonset_status_current_number_scheduled{job="kube-state-metrics"} > 0 + for: 10m + labels: + severity: warning + - alert: KubeDaemonSetMisScheduled + annotations: + description: '{{ $value }} Pods of DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} are running where they are not supposed to run on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetmisscheduled + summary: DaemonSet pods are misscheduled. + expr: | + kube_daemonset_status_number_misscheduled{job="kube-state-metrics"} > 0 + for: 15m + labels: + severity: warning + - alert: KubeJobNotCompleted + annotations: + description: Job {{ $labels.namespace }}/{{ $labels.job_name }} is taking more than {{ "43200" | humanizeDuration }} to complete on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubejobnotcompleted + summary: Job did not complete in time + expr: | + time() - max by(namespace, job_name, cluster) (kube_job_status_start_time{job="kube-state-metrics"} + and + kube_job_status_active{job="kube-state-metrics"} > 0) > 43200 + labels: + severity: warning + - alert: KubeJobFailed + annotations: + description: Job {{ $labels.namespace }}/{{ $labels.job_name }} failed to complete. Removing failed job after investigation should clear this alert on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubejobfailed + summary: Job failed to complete. + expr: | + kube_job_failed{job="kube-state-metrics"} > 0 + for: 15m + labels: + severity: warning + - alert: KubeHpaReplicasMismatch + annotations: + description: HPA {{ $labels.namespace }}/{{ $labels.horizontalpodautoscaler }} has not matched the desired number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubehpareplicasmismatch + summary: HPA has not matched desired number of replicas. + expr: | + (kube_horizontalpodautoscaler_status_desired_replicas{job="kube-state-metrics"} + != + kube_horizontalpodautoscaler_status_current_replicas{job="kube-state-metrics"}) + and + (kube_horizontalpodautoscaler_status_current_replicas{job="kube-state-metrics"} + > + kube_horizontalpodautoscaler_spec_min_replicas{job="kube-state-metrics"}) + and + (kube_horizontalpodautoscaler_status_current_replicas{job="kube-state-metrics"} + < + kube_horizontalpodautoscaler_spec_max_replicas{job="kube-state-metrics"}) + and + changes(kube_horizontalpodautoscaler_status_current_replicas{job="kube-state-metrics"}[15m]) == 0 + for: 15m + labels: + severity: warning + - alert: KubeHpaMaxedOut + annotations: + description: HPA {{ $labels.namespace }}/{{ $labels.horizontalpodautoscaler }} has been running at max replicas for longer than 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubehpamaxedout + summary: HPA is running at max replicas + expr: | + kube_horizontalpodautoscaler_status_current_replicas{job="kube-state-metrics"} + == + kube_horizontalpodautoscaler_spec_max_replicas{job="kube-state-metrics"} + for: 15m + labels: + severity: warning + - alert: KubePdbNotEnoughHealthyPods + annotations: + description: PDB {{ $labels.cluster }}/{{ $labels.namespace }}/{{ $labels.poddisruptionbudget }} expects {{ $value }} more healthy pods. The desired number of healthy pods has not been met for at least 15m. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepdbnotenoughhealthypods + summary: PDB does not have enough healthy pods. + expr: | + ( + kube_poddisruptionbudget_status_desired_healthy{job="kube-state-metrics"} + - + kube_poddisruptionbudget_status_current_healthy{job="kube-state-metrics"} + ) + > 0 + for: 15m + labels: + severity: warning + - name: kubernetes-resources + rules: + - alert: KubeCPUOvercommit + annotations: + description: Cluster {{ $labels.cluster }} has overcommitted CPU resource requests for Pods by {{ printf "%.2f" $value }} CPU shares and cannot tolerate node failure. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecpuovercommit + summary: Cluster has overcommitted CPU resource requests. + expr: | + # Non-HA clusters. + ( + ( + sum by(cluster) (namespace_cpu:kube_pod_container_resource_requests:sum{}) + - + sum by(cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="cpu"}) > 0 + ) + and + count by (cluster) (max by (cluster, node) (kube_node_role{job="kube-state-metrics", role="control-plane"})) < 3 + ) + or + # HA clusters. + ( + sum by(cluster) (namespace_cpu:kube_pod_container_resource_requests:sum{}) + - + ( + # Skip clusters with only one allocatable node. + ( + sum by (cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="cpu"}) + - + max by (cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="cpu"}) + ) > 0 + ) > 0 + ) + for: 10m + labels: + severity: warning + - alert: KubeMemoryOvercommit + annotations: + description: Cluster {{ $labels.cluster }} has overcommitted memory resource requests for Pods by {{ $value | humanize }} bytes and cannot tolerate node failure. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubememoryovercommit + summary: Cluster has overcommitted memory resource requests. + expr: | + # Non-HA clusters. + ( + ( + sum by(cluster) (namespace_memory:kube_pod_container_resource_requests:sum{}) + - + sum by(cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="memory"}) > 0 + ) + and + count by (cluster) (max by (cluster, node) (kube_node_role{job="kube-state-metrics", role="control-plane"})) < 3 + ) + or + # HA clusters. + ( + sum by(cluster) (namespace_memory:kube_pod_container_resource_requests:sum{}) + - + ( + # Skip clusters with only one allocatable node. + ( + sum by (cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="memory"}) + - + max by (cluster) (kube_node_status_allocatable{job="kube-state-metrics",resource="memory"}) + ) > 0 + ) > 0 + ) + for: 10m + labels: + severity: warning + - alert: KubeCPUQuotaOvercommit + annotations: + description: Cluster {{ $labels.cluster }} has overcommitted CPU resource requests for Namespaces. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecpuquotaovercommit + summary: Cluster has overcommitted CPU resource requests. + expr: | + sum by(cluster) ( + min without(resource) (kube_resourcequota{job="kube-state-metrics", type="hard", resource=~"(cpu|requests.cpu)"}) + ) + / + sum by(cluster) ( + kube_node_status_allocatable{resource="cpu", job="kube-state-metrics"} + ) > 1.5 + for: 5m + labels: + severity: warning + - alert: KubeMemoryQuotaOvercommit + annotations: + description: Cluster {{ $labels.cluster }} has overcommitted memory resource requests for Namespaces. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubememoryquotaovercommit + summary: Cluster has overcommitted memory resource requests. + expr: | + sum by(cluster) ( + min without(resource) (kube_resourcequota{job="kube-state-metrics", type="hard", resource=~"(memory|requests.memory)"}) + ) + / + sum by(cluster) ( + kube_node_status_allocatable{resource="memory", job="kube-state-metrics"} + ) > 1.5 + for: 5m + labels: + severity: warning + - alert: KubeQuotaAlmostFull + annotations: + description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotaalmostfull + summary: Namespace quota is going to be full. + expr: | + kube_resourcequota{job="kube-state-metrics", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="kube-state-metrics", type="hard"} > 0) + > 0.9 < 1 + for: 15m + labels: + severity: info + - alert: KubeQuotaFullyUsed + annotations: + description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotafullyused + summary: Namespace quota is fully used. + expr: | + kube_resourcequota{job="kube-state-metrics", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="kube-state-metrics", type="hard"} > 0) + == 1 + for: 15m + labels: + severity: info + - alert: KubeQuotaExceeded + annotations: + description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotaexceeded + summary: Namespace quota has exceeded the limits. + expr: | + kube_resourcequota{job="kube-state-metrics", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="kube-state-metrics", type="hard"} > 0) + > 1 + for: 15m + labels: + severity: warning + - alert: CPUThrottlingHigh + annotations: + description: '{{ $value | humanizePercentage }} throttling of CPU in namespace {{ $labels.namespace }} for container {{ $labels.container }} in pod {{ $labels.pod }} on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/cputhrottlinghigh + summary: Processes experience elevated CPU throttling. + expr: | + sum(increase(container_cpu_cfs_throttled_periods_total{container!="", job="kubelet", metrics_path="/metrics/cadvisor", }[5m])) without (id, metrics_path, name, image, endpoint, job, node) + / on (cluster, namespace, pod, container, instance) group_left + sum(increase(container_cpu_cfs_periods_total{job="kubelet", metrics_path="/metrics/cadvisor", }[5m])) without (id, metrics_path, name, image, endpoint, job, node) + > ( 25 / 100 ) + for: 15m + labels: + severity: info + - name: kubernetes-storage + rules: + - alert: KubePersistentVolumeFillingUp + annotations: + description: The PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is only {{ $value | humanizePercentage }} free. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumefillingup + summary: PersistentVolume is filling up. + expr: | + ( + kubelet_volume_stats_available_bytes{job="kubelet", metrics_path="/metrics"} + / + kubelet_volume_stats_capacity_bytes{job="kubelet", metrics_path="/metrics"} + ) < 0.03 + and + kubelet_volume_stats_used_bytes{job="kubelet", metrics_path="/metrics"} > 0 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: 1m + labels: + severity: critical + - alert: KubePersistentVolumeFillingUp + annotations: + description: Based on recent sampling, the PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is expected to fill up within four days. Currently {{ $value | humanizePercentage }} is available. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumefillingup + summary: PersistentVolume is filling up. + expr: | + ( + kubelet_volume_stats_available_bytes{job="kubelet", metrics_path="/metrics"} + / + kubelet_volume_stats_capacity_bytes{job="kubelet", metrics_path="/metrics"} + ) < 0.15 + and + kubelet_volume_stats_used_bytes{job="kubelet", metrics_path="/metrics"} > 0 + and + predict_linear(kubelet_volume_stats_available_bytes{job="kubelet", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: 1h + labels: + severity: warning + - alert: KubePersistentVolumeInodesFillingUp + annotations: + description: The PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} only has {{ $value | humanizePercentage }} free inodes. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeinodesfillingup + summary: PersistentVolumeInodes are filling up. + expr: | + ( + kubelet_volume_stats_inodes_free{job="kubelet", metrics_path="/metrics"} + / + kubelet_volume_stats_inodes{job="kubelet", metrics_path="/metrics"} + ) < 0.03 + and + kubelet_volume_stats_inodes_used{job="kubelet", metrics_path="/metrics"} > 0 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: 1m + labels: + severity: critical + - alert: KubePersistentVolumeInodesFillingUp + annotations: + description: Based on recent sampling, the PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is expected to run out of inodes within four days. Currently {{ $value | humanizePercentage }} of its inodes are free. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeinodesfillingup + summary: PersistentVolumeInodes are filling up. + expr: | + ( + kubelet_volume_stats_inodes_free{job="kubelet", metrics_path="/metrics"} + / + kubelet_volume_stats_inodes{job="kubelet", metrics_path="/metrics"} + ) < 0.15 + and + kubelet_volume_stats_inodes_used{job="kubelet", metrics_path="/metrics"} > 0 + and + predict_linear(kubelet_volume_stats_inodes_free{job="kubelet", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on(cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: 1h + labels: + severity: warning + - alert: KubePersistentVolumeErrors + annotations: + description: The persistent volume {{ $labels.persistentvolume }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} has status {{ $labels.phase }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeerrors + summary: PersistentVolume is having issues with provisioning. + expr: | + kube_persistentvolume_status_phase{phase=~"Failed|Pending",job="kube-state-metrics"} > 0 + for: 5m + labels: + severity: critical + - name: kubernetes-system + rules: + - alert: KubeVersionMismatch + annotations: + description: There are {{ $value }} different semantic versions of Kubernetes components running on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeversionmismatch + summary: Different semantic versions of Kubernetes components running. + expr: | + count by (cluster) (count by (git_version, cluster) (label_replace(kubernetes_build_info{job!~"kube-dns|coredns"},"git_version","$1","git_version","(v[0-9]*.[0-9]*).*"))) > 1 + for: 15m + labels: + severity: warning + - alert: KubeClientErrors + annotations: + description: Kubernetes API server client '{{ $labels.job }}/{{ $labels.instance }}' is experiencing {{ $value | humanizePercentage }} errors on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclienterrors + summary: Kubernetes API server client is experiencing errors. + expr: | + (sum(rate(rest_client_requests_total{job="apiserver",code=~"5.."}[5m])) by (cluster, instance, job, namespace) + / + sum(rate(rest_client_requests_total{job="apiserver"}[5m])) by (cluster, instance, job, namespace)) + > 0.01 + for: 15m + labels: + severity: warning + - name: kube-apiserver-slos + rules: + - alert: KubeAPIErrorBudgetBurn + annotations: + description: The API server is burning too much error budget on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: | + sum by(cluster) (apiserver_request:burnrate1h) > (14.40 * 0.01000) + and on(cluster) + sum by(cluster) (apiserver_request:burnrate5m) > (14.40 * 0.01000) + for: 2m + labels: + long: 1h + severity: critical + short: 5m + - alert: KubeAPIErrorBudgetBurn + annotations: + description: The API server is burning too much error budget on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: | + sum by(cluster) (apiserver_request:burnrate6h) > (6.00 * 0.01000) + and on(cluster) + sum by(cluster) (apiserver_request:burnrate30m) > (6.00 * 0.01000) + for: 15m + labels: + long: 6h + severity: critical + short: 30m + - alert: KubeAPIErrorBudgetBurn + annotations: + description: The API server is burning too much error budget on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: | + sum by(cluster) (apiserver_request:burnrate1d) > (3.00 * 0.01000) + and on(cluster) + sum by(cluster) (apiserver_request:burnrate2h) > (3.00 * 0.01000) + for: 1h + labels: + long: 1d + severity: warning + short: 2h + - alert: KubeAPIErrorBudgetBurn + annotations: + description: The API server is burning too much error budget on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: | + sum by(cluster) (apiserver_request:burnrate3d) > (1.00 * 0.01000) + and on(cluster) + sum by(cluster) (apiserver_request:burnrate6h) > (1.00 * 0.01000) + for: 3h + labels: + long: 3d + severity: warning + short: 6h + - name: kubernetes-system-apiserver + rules: + - alert: KubeClientCertificateExpiration + annotations: + description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 7.0 days on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclientcertificateexpiration + summary: Client certificate is about to expire. + expr: | + histogram_quantile(0.01, sum without (namespace, service, endpoint) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 604800 + and + on(job, cluster, instance) apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 + for: 5m + labels: + severity: warning + - alert: KubeClientCertificateExpiration + annotations: + description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 24.0 hours on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclientcertificateexpiration + summary: Client certificate is about to expire. + expr: | + histogram_quantile(0.01, sum without (namespace, service, endpoint) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 86400 + and + on(job, cluster, instance) apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 + for: 5m + labels: + severity: critical + - alert: KubeAggregatedAPIErrors + annotations: + description: Kubernetes aggregated API {{ $labels.instance }}/{{ $labels.name }} has reported {{ $labels.reason }} errors on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeaggregatedapierrors + summary: Kubernetes aggregated API has reported errors. + expr: | + sum by(cluster, instance, name, reason)(increase(aggregator_unavailable_apiservice_total{job="apiserver"}[1m])) > 0 + for: 10m + labels: + severity: warning + - alert: KubeAggregatedAPIDown + annotations: + description: Kubernetes aggregated API {{ $labels.name }}/{{ $labels.namespace }} has been only {{ $value | humanize }}% available over the last 10m on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeaggregatedapidown + summary: Kubernetes aggregated API is down. + expr: | + (1 - max by(name, namespace, cluster)(avg_over_time(aggregator_unavailable_apiservice{job="apiserver"}[10m]))) * 100 < 85 + for: 5m + labels: + severity: warning + - alert: KubeAPIDown + annotations: + description: KubeAPI has disappeared from Prometheus target discovery. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapidown + summary: Target disappeared from Prometheus target discovery. + expr: | + absent(up{job="apiserver"} == 1) + for: 15m + labels: + severity: critical + - alert: KubeAPITerminatedRequests + annotations: + description: The kubernetes apiserver has terminated {{ $value | humanizePercentage }} of its incoming requests on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapiterminatedrequests + summary: The kubernetes apiserver has terminated {{ $value | humanizePercentage }} of its incoming requests. + expr: | + sum by(cluster) (rate(apiserver_request_terminations_total{job="apiserver"}[10m])) / ( sum by(cluster) (rate(apiserver_request_total{job="apiserver"}[10m])) + sum by(cluster) (rate(apiserver_request_terminations_total{job="apiserver"}[10m])) ) > 0.20 + for: 5m + labels: + severity: warning + - name: kubernetes-system-kubelet + rules: + - alert: KubeNodeNotReady + annotations: + description: '{{ $labels.node }} has been unready for more than 15 minutes on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodenotready + summary: Node is not ready. + expr: | + kube_node_status_condition{job="kube-state-metrics",condition="Ready",status="true"} == 0 + and on (cluster, node) + kube_node_spec_unschedulable{job="kube-state-metrics"} == 0 + for: 15m + labels: + severity: warning + - alert: KubeNodePressure + annotations: + description: '{{ $labels.node }} on cluster {{ $labels.cluster }} has active Condition {{ $labels.condition }}. This is caused by resource usage exceeding eviction thresholds.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodepressure + summary: Node has as active Condition. + expr: | + kube_node_status_condition{job="kube-state-metrics",condition=~"(MemoryPressure|DiskPressure|PIDPressure)",status="true"} == 1 + and on (cluster, node) + kube_node_spec_unschedulable{job="kube-state-metrics"} == 0 + for: 10m + labels: + severity: info + - alert: KubeNodeUnreachable + annotations: + description: '{{ $labels.node }} is unreachable and some workloads may be rescheduled on cluster {{ $labels.cluster }}.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodeunreachable + summary: Node is unreachable. + expr: | + (kube_node_spec_taint{job="kube-state-metrics",key="node.kubernetes.io/unreachable",effect="NoSchedule"} unless ignoring(key,value) kube_node_spec_taint{job="kube-state-metrics",key=~"ToBeDeletedByClusterAutoscaler|cloud.google.com/impending-node-termination|aws-node-termination-handler/spot-itn"}) == 1 + for: 15m + labels: + severity: warning + - alert: KubeletTooManyPods + annotations: + description: Kubelet '{{ $labels.node }}' is running at {{ $value | humanizePercentage }} of its Pod capacity on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubelettoomanypods + summary: Kubelet is running at capacity. + expr: | + ( + max by (cluster, instance) ( + kubelet_running_pods{job="kubelet", metrics_path="/metrics"} > 1 + ) + * on (cluster, instance) group_left(node) + max by (cluster, instance, node) ( + kubelet_node_name{job="kubelet", metrics_path="/metrics"} + ) + ) + / on (cluster, node) group_left() + max by (cluster, node) ( + kube_node_status_capacity{job="kube-state-metrics", resource="pods"} != 1 + ) > 0.95 + for: 15m + labels: + severity: info + - alert: KubeNodeReadinessFlapping + annotations: + description: The readiness status of node {{ $labels.node }} has changed {{ $value }} times in the last 15 minutes on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodereadinessflapping + summary: Node readiness status is flapping. + expr: | + sum(changes(kube_node_status_condition{job="kube-state-metrics",status="true",condition="Ready"}[15m])) by (cluster, node) > 2 + and on (cluster, node) + kube_node_spec_unschedulable{job="kube-state-metrics"} == 0 + for: 15m + labels: + severity: warning + - alert: KubeNodeEviction + annotations: + description: Node {{ $labels.node }} on {{ $labels.cluster }} is evicting Pods due to {{ $labels.eviction_signal }}. Eviction occurs when eviction thresholds are crossed, typically caused by Pods exceeding RAM/ephemeral-storage limits. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodeeviction + summary: Node is evicting pods. + expr: | + sum(rate(kubelet_evictions{job="kubelet", metrics_path="/metrics"}[15m])) by(cluster, eviction_signal, instance) + * on (cluster, instance) group_left(node) + max by (cluster, instance, node) ( + kubelet_node_name{job="kubelet", metrics_path="/metrics"} + ) + > 0 + for: 0s + labels: + severity: info + - alert: KubeletPlegDurationHigh + annotations: + description: The Kubelet Pod Lifecycle Event Generator has a 99th percentile duration of {{ $value }} seconds on node {{ $labels.node }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletplegdurationhigh + summary: Kubelet Pod Lifecycle Event Generator is taking too long to relist. + expr: | + node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile{quantile="0.99"} >= 10 + for: 5m + labels: + severity: warning + - alert: KubeletPodStartUpLatencyHigh + annotations: + description: Kubelet Pod startup 99th percentile latency is {{ $value }} seconds on node {{ $labels.node }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletpodstartuplatencyhigh + summary: Kubelet Pod startup latency is too high. + expr: | + histogram_quantile(0.99, + sum by (cluster, instance, le) ( + topk by (cluster, instance, le, operation_type) (1, + rate(kubelet_pod_worker_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m]) + ) + ) + ) + * on(cluster, instance) group_left(node) + topk by (cluster, instance, node) (1, + kubelet_node_name{job="kubelet", metrics_path="/metrics"} + ) + > 60 + for: 15m + labels: + severity: warning + - alert: KubeletClientCertificateExpiration + annotations: + description: Client certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificateexpiration + summary: Kubelet client certificate is about to expire. + expr: | + kubelet_certificate_manager_client_ttl_seconds < 604800 + labels: + severity: warning + - alert: KubeletClientCertificateExpiration + annotations: + description: Client certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificateexpiration + summary: Kubelet client certificate is about to expire. + expr: | + kubelet_certificate_manager_client_ttl_seconds < 86400 + labels: + severity: critical + - alert: KubeletServerCertificateExpiration + annotations: + description: Server certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificateexpiration + summary: Kubelet server certificate is about to expire. + expr: | + kubelet_certificate_manager_server_ttl_seconds < 604800 + labels: + severity: warning + - alert: KubeletServerCertificateExpiration + annotations: + description: Server certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificateexpiration + summary: Kubelet server certificate is about to expire. + expr: | + kubelet_certificate_manager_server_ttl_seconds < 86400 + labels: + severity: critical + - alert: KubeletClientCertificateRenewalErrors + annotations: + description: Kubelet on node {{ $labels.node }} has failed to renew its client certificate ({{ $value | humanize }} errors in the last 5 minutes) on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificaterenewalerrors + summary: Kubelet has failed to renew its client certificate. + expr: | + increase(kubelet_certificate_manager_client_expiration_renew_errors[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: KubeletServerCertificateRenewalErrors + annotations: + description: Kubelet on node {{ $labels.node }} has failed to renew its server certificate ({{ $value | humanize }} errors in the last 5 minutes) on cluster {{ $labels.cluster }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificaterenewalerrors + summary: Kubelet has failed to renew its server certificate. + expr: | + increase(kubelet_server_expiration_renew_errors[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: KubeletDown + annotations: + description: Kubelet has disappeared from Prometheus target discovery. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletdown + summary: Target disappeared from Prometheus target discovery. + expr: | + absent(up{job="kubelet", metrics_path="/metrics"} == 1) + for: 15m + labels: + severity: critical + - name: kubernetes-system-scheduler + rules: + - alert: KubeSchedulerDown + annotations: + description: KubeScheduler has disappeared from Prometheus target discovery. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeschedulerdown + summary: Target disappeared from Prometheus target discovery. + expr: | + absent(up{job="kube-scheduler"} == 1) + for: 15m + labels: + severity: critical + - name: kubernetes-system-controller-manager + rules: + - alert: KubeControllerManagerDown + annotations: + description: KubeControllerManager has disappeared from Prometheus target discovery. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecontrollermanagerdown + summary: Target disappeared from Prometheus target discovery. + expr: | + absent(up{job="kube-controller-manager"} == 1) + for: 15m + labels: + severity: critical + - interval: 3m + name: kube-apiserver-availability.rules + rules: + - expr: | + avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30 + record: code_verb:apiserver_request_total:increase30d + - expr: | + sum by (cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"LIST|GET"}) + labels: + verb: read + record: code:apiserver_request_total:increase30d + - expr: | + sum by (cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + labels: + verb: write + record: code:apiserver_request_total:increase30d + - expr: | + sum by (cluster, verb, scope, le) (increase(apiserver_request_sli_duration_seconds_bucket[1h])) + record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h + - expr: | + sum by (cluster, verb, scope, le) (avg_over_time(cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h[30d]) * 24 * 30) + record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d + - expr: | + sum by (cluster, verb, scope) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h{le="+Inf"}) + record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h + - expr: | + sum by (cluster, verb, scope) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{le="+Inf"}) + record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d + - expr: | + 1 - ( + ( + # write too slow + sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + - + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le=~"1(\\.0)?"} or vector(0)) + ) + + ( + # read too slow + sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~"LIST|GET"}) + - + ( + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le=~"1(\\.0)?"} or vector(0)) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le=~"5(\\.0)?"} or vector(0)) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le=~"30(\\.0)?"} or vector(0)) + ) + ) + + # errors + sum by (cluster) (code:apiserver_request_total:increase30d{code=~"5.."} or vector(0)) + ) + / + sum by (cluster) (code:apiserver_request_total:increase30d) + labels: + verb: all + record: apiserver_request:availability30d + - expr: | + 1 - ( + sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~"LIST|GET"}) + - + ( + # too slow + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le=~"1(\\.0)?"} or vector(0)) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le=~"5(\\.0)?"} or vector(0)) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le=~"30(\\.0)?"} or vector(0)) + ) + + + # errors + sum by (cluster) (code:apiserver_request_total:increase30d{verb="read",code=~"5.."} or vector(0)) + ) + / + sum by (cluster) (code:apiserver_request_total:increase30d{verb="read"}) + labels: + verb: read + record: apiserver_request:availability30d + - expr: | + 1 - ( + ( + # too slow + sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + - + sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le=~"1(\\.0)?"} or vector(0)) + ) + + + # errors + sum by (cluster) (code:apiserver_request_total:increase30d{verb="write",code=~"5.."} or vector(0)) + ) + / + sum by (cluster) (code:apiserver_request_total:increase30d{verb="write"}) + labels: + verb: write + record: apiserver_request:availability30d + - expr: | + sum by (cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) + labels: + verb: read + record: code_resource:apiserver_request_total:rate5m + - expr: | + sum by (cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) + labels: + verb: write + record: code_resource:apiserver_request_total:rate5m + - expr: | + sum by (cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"2.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + - expr: | + sum by (cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"3.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + - expr: | + sum by (cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"4.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + - expr: | + sum by (cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + - name: kube-apiserver-burnrate.rules + rules: + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1d])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[1d])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[1d])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[1d])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1d])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1d])) + labels: + verb: read + record: apiserver_request:burnrate1d + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[1h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[1h])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[1h])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1h])) + labels: + verb: read + record: apiserver_request:burnrate1h + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[2h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[2h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[2h])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[2h])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[2h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[2h])) + labels: + verb: read + record: apiserver_request:burnrate2h + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[30m])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[30m])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[30m])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[30m])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[30m])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[30m])) + labels: + verb: read + record: apiserver_request:burnrate30m + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[3d])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[3d])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[3d])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[3d])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[3d])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[3d])) + labels: + verb: read + record: apiserver_request:burnrate3d + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[5m])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[5m])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[5m])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[5m])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) + labels: + verb: read + record: apiserver_request:burnrate5m + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[6h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le=~"1(\\.0)?"}[6h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le=~"5(\\.0)?"}[6h])) + + + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le=~"30(\\.0)?"}[6h])) + ) + ) + + + # errors + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[6h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[6h])) + labels: + verb: read + record: apiserver_request:burnrate6h + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1d])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[1d])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1d])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1d])) + labels: + verb: write + record: apiserver_request:burnrate1d + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1h])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[1h])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1h])) + labels: + verb: write + record: apiserver_request:burnrate1h + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[2h])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[2h])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[2h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[2h])) + labels: + verb: write + record: apiserver_request:burnrate2h + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[30m])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[30m])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[30m])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[30m])) + labels: + verb: write + record: apiserver_request:burnrate30m + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[3d])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[3d])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[3d])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[3d])) + labels: + verb: write + record: apiserver_request:burnrate3d + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[5m])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[5m])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) + labels: + verb: write + record: apiserver_request:burnrate5m + - expr: | + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[6h])) + - + sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le=~"1(\\.0)?"}[6h])) + ) + + + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[6h])) + ) + / + sum by (cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[6h])) + labels: + verb: write + record: apiserver_request:burnrate6h + - name: kube-apiserver-histogram.rules + rules: + - expr: | + histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 + labels: + quantile: "0.99" + verb: read + record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 + labels: + quantile: "0.99" + verb: write + record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile + - name: k8s.rules.container_cpu_usage_seconds_total + rules: + - expr: | + sum by (cluster, namespace, pod, container) ( + rate(container_cpu_usage_seconds_total{job="kubelet", metrics_path="/metrics/cadvisor", image!=""}[5m]) + ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) ( + 1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m + - expr: | + sum by (cluster, namespace, pod, container) ( + irate(container_cpu_usage_seconds_total{job="kubelet", metrics_path="/metrics/cadvisor", image!=""}[5m]) + ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) ( + 1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate + - name: k8s.rules.container_memory_working_set_bytes + rules: + - expr: | + container_memory_working_set_bytes{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_working_set_bytes + - name: k8s.rules.container_memory_rss + rules: + - expr: | + container_memory_rss{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_rss + - name: k8s.rules.container_memory_cache + rules: + - expr: | + container_memory_cache{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_cache + - name: k8s.rules.container_memory_swap + rules: + - expr: | + container_memory_swap{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_swap + - name: k8s.rules.container_memory_requests + rules: + - expr: | + kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests + - expr: | + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_requests:sum + - name: k8s.rules.container_cpu_requests + rules: + - expr: | + kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests + - expr: | + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_requests:sum + - name: k8s.rules.container_memory_limits + rules: + - expr: | + kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits + - expr: | + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_limits:sum + - name: k8s.rules.container_cpu_limits + rules: + - expr: | + kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits + - expr: | + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_limits:sum + - name: k8s.rules.pod_owner + rules: + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"}, + "replicaset", "$1", "owner_name", "(.*)" + ) * on (cluster, replicaset, namespace) group_left(owner_name) topk by(cluster, replicaset, namespace) ( + 1, max by (cluster, replicaset, namespace, owner_name) ( + kube_replicaset_owner{job="kube-state-metrics", owner_kind=""} + ) + ), + "workload", "$1", "replicaset", "(.*)" + ) + ) + labels: + workload_type: replicaset + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"}, + "replicaset", "$1", "owner_name", "(.*)" + ) * on(replicaset, namespace, cluster) group_left(owner_name) topk by(cluster, replicaset, namespace) ( + 1, max by (cluster, replicaset, namespace, owner_name) ( + kube_replicaset_owner{job="kube-state-metrics", owner_kind="Deployment"} + ) + ), + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: deployment + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="DaemonSet"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: daemonset + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="StatefulSet"}, + "workload", "$1", "owner_name", "(.*)") + ) + labels: + workload_type: statefulset + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + group by (cluster, namespace, workload, pod) ( + label_join( + group by (cluster, namespace, job_name, pod, owner_name) ( + label_join( + kube_pod_owner{job="kube-state-metrics", owner_kind="Job"} + , "job_name", "", "owner_name") + ) + * on (cluster, namespace, job_name) group_left() + group by (cluster, namespace, job_name) ( + kube_job_owner{job="kube-state-metrics", owner_kind=~"Pod|"} + ) + , "workload", "", "owner_name") + ) + labels: + workload_type: job + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="", owner_name=""}, + "workload", "$1", "pod", "(.+)") + ) + labels: + workload_type: barepod + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="Node"}, + "workload", "$1", "pod", "(.+)") + ) + labels: + workload_type: staticpod + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: | + group by (cluster, namespace, workload, workload_type, pod) ( + label_join( + label_join( + group by (cluster, namespace, job_name, pod) ( + label_join( + kube_pod_owner{job="kube-state-metrics", owner_kind="Job"} + , "job_name", "", "owner_name") + ) + * on (cluster, namespace, job_name) group_left(owner_kind, owner_name) + group by (cluster, namespace, job_name, owner_kind, owner_name) ( + kube_job_owner{job="kube-state-metrics", owner_kind!="Pod", owner_kind!=""} + ) + , "workload", "", "owner_name") + , "workload_type", "", "owner_kind") + + OR + + label_replace( + label_replace( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"} + , "replicaset", "$1", "owner_name", "(.+)" + ) + * on(cluster, namespace, replicaset) group_left(owner_kind, owner_name) + group by (cluster, namespace, replicaset, owner_kind, owner_name) ( + kube_replicaset_owner{job="kube-state-metrics", owner_kind!="Deployment", owner_kind!=""} + ) + , "workload", "$1", "owner_name", "(.+)") + OR + label_replace( + group by (cluster, namespace, pod, owner_name, owner_kind) ( + kube_pod_owner{job="kube-state-metrics", owner_kind!="ReplicaSet", owner_kind!="DaemonSet", owner_kind!="StatefulSet", owner_kind!="Job", owner_kind!="Node", owner_kind!=""} + ) + , "workload", "$1", "owner_name", "(.+)" + ) + , "workload_type", "$1", "owner_kind", "(.+)") + ) + record: namespace_workload_pod:kube_pod_owner:relabel + - name: kube-scheduler.rules + rules: + - expr: | + histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.99" + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.99" + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.99" + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.9, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.9" + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.9, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.9" + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.9, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.9" + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.5, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.5" + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.5, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.5" + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: | + histogram_quantile(0.5, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: "0.5" + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile + - name: node.rules + rules: + - expr: | + topk by(cluster, namespace, pod) (1, + max by (cluster, node, namespace, pod) ( + label_replace(kube_pod_info{job="kube-state-metrics",node!=""}, "pod", "$1", "pod", "(.*)") + )) + record: 'node_namespace_pod:kube_pod_info:' + - expr: | + count by (cluster, node) ( + node_cpu_seconds_total{mode="idle",job="node-exporter"} + * on (cluster, namespace, pod) group_left(node) + topk by(cluster, namespace, pod) (1, node_namespace_pod:kube_pod_info:) + ) + record: node:node_num_cpu:sum + - expr: | + sum( + node_memory_MemAvailable_bytes{job="node-exporter"} or + ( + node_memory_Buffers_bytes{job="node-exporter"} + + node_memory_Cached_bytes{job="node-exporter"} + + node_memory_MemFree_bytes{job="node-exporter"} + + node_memory_Slab_bytes{job="node-exporter"} + ) + ) by (cluster) + record: :node_memory_MemAvailable_bytes:sum + - expr: | + avg by (cluster, node) ( + sum without (mode) ( + rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",job="node-exporter"}[5m]) + ) + ) + record: node:node_cpu_utilization:ratio_rate5m + - expr: | + avg by (cluster) ( + node:node_cpu_utilization:ratio_rate5m + ) + record: cluster:node_cpu:ratio_rate5m + - name: kubelet.rules + rules: + - expr: | + histogram_quantile( + 0.99, + sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by (cluster, instance, le) + * on(cluster, instance) group_left (node) + max by (cluster, instance, node) (kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + ) + labels: + quantile: "0.99" + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile + - expr: | + histogram_quantile( + 0.9, + sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by (cluster, instance, le) + * on(cluster, instance) group_left (node) + max by (cluster, instance, node) (kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + ) + labels: + quantile: "0.9" + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile + - expr: | + histogram_quantile( + 0.5, + sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by (cluster, instance, le) + * on(cluster, instance) group_left (node) + max by (cluster, instance, node) (kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + ) + labels: + quantile: "0.5" + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorApiserver.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorApiserver.yaml new file mode 100644 index 000000000..46a5d23a4 --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorApiserver.yaml @@ -0,0 +1,109 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: apiserver + app.kubernetes.io/part-of: kube-prometheus + name: kube-apiserver + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + metricRelabelings: + - action: drop + regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds) + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use) + sourceLabels: + - __name__ + - action: drop + regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(debugging|disk|server).* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: (apiserver_request|apiserver_request_sli|etcd_request)_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50) + sourceLabels: + - __name__ + - le + - action: drop + regex: apiserver_request_body_size_bytes_bucket;(150000|350000|550000|650000|850000|950000|(1\.15|1\.35|1\.55|1\.65|1\.85|1\.95|2\.15|2\.35|2\.55|2\.65|2\.85|2\.95)e\+06) + sourceLabels: + - __name__ + - le + port: https + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + serverName: kubernetes + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 5s + metricRelabelings: + - action: drop + regex: process_start_time_seconds + sourceLabels: + - __name__ + path: /metrics/slis + port: https + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + serverName: kubernetes + jobLabel: component + namespaceSelector: + matchNames: + - default + selector: + matchLabels: + component: apiserver + provider: kubernetes diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorCoreDNS.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorCoreDNS.yaml new file mode 100644 index 000000000..e6929df0a --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorCoreDNS.yaml @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: coredns + app.kubernetes.io/part-of: kube-prometheus + name: coredns + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 15s + metricRelabelings: + - action: drop + regex: coredns_cache_misses_total + sourceLabels: + - __name__ + port: metrics + jobLabel: app.kubernetes.io/name + namespaceSelector: + matchNames: + - kube-system + selector: + matchLabels: + k8s-app: kube-dns diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml new file mode 100644 index 000000000..d5d4aa070 --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml @@ -0,0 +1,88 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: kube-controller-manager + app.kubernetes.io/part-of: kube-prometheus + name: kube-controller-manager + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + metricRelabelings: + - action: drop + regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds) + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use) + sourceLabels: + - __name__ + - action: drop + regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(debugging|disk|request|server).* + sourceLabels: + - __name__ + port: https-metrics + scheme: https + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 5s + metricRelabelings: + - action: drop + regex: process_start_time_seconds + sourceLabels: + - __name__ + path: /metrics/slis + port: https-metrics + scheme: https + tlsConfig: + insecureSkipVerify: true + jobLabel: app.kubernetes.io/name + namespaceSelector: + matchNames: + - kube-system + selector: + matchLabels: + app.kubernetes.io/name: kube-controller-manager diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeScheduler.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeScheduler.yaml new file mode 100644 index 000000000..161f0c277 --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubeScheduler.yaml @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: kube-scheduler + app.kubernetes.io/part-of: kube-prometheus + name: kube-scheduler + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + port: https-metrics + scheme: https + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 5s + metricRelabelings: + - action: drop + regex: process_start_time_seconds + sourceLabels: + - __name__ + path: /metrics/slis + port: https-metrics + scheme: https + tlsConfig: + insecureSkipVerify: true + jobLabel: app.kubernetes.io/name + namespaceSelector: + matchNames: + - kube-system + selector: + matchLabels: + app.kubernetes.io/name: kube-scheduler diff --git a/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubelet.yaml b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubelet.yaml new file mode 100644 index 000000000..2c7c33e44 --- /dev/null +++ b/release/kubernetes/monitoring/kubernetesControlPlane-serviceMonitorKubelet.yaml @@ -0,0 +1,139 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: kubernetes + app.kubernetes.io/name: kubelet + app.kubernetes.io/part-of: kube-prometheus + name: kubelet + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 30s + metricRelabelings: + - action: drop + regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds) + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use) + sourceLabels: + - __name__ + - action: drop + regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count) + sourceLabels: + - __name__ + port: https-metrics + relabelings: + - action: replace + sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + scheme: https + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + honorTimestamps: false + interval: 30s + metricRelabelings: + - action: drop + regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) + sourceLabels: + - __name__ + - action: drop + regex: (container_spec_.*|container_file_descriptors|container_sockets|container_threads_max|container_threads|container_start_time_seconds|container_last_seen);; + sourceLabels: + - __name__ + - pod + - namespace + - action: drop + regex: (container_blkio_device_usage_total);.+ + sourceLabels: + - __name__ + - container + path: /metrics/cadvisor + port: https-metrics + relabelings: + - action: replace + sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + scheme: https + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 30s + path: /metrics/probes + port: https-metrics + relabelings: + - action: replace + sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + scheme: https + tlsConfig: + insecureSkipVerify: true + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 5s + metricRelabelings: + - action: drop + regex: process_start_time_seconds + sourceLabels: + - __name__ + path: /metrics/slis + port: https-metrics + relabelings: + - action: replace + sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + scheme: https + tlsConfig: + insecureSkipVerify: true + jobLabel: app.kubernetes.io/name + namespaceSelector: + matchNames: + - kube-system + selector: + matchLabels: + app.kubernetes.io/name: kubelet diff --git a/release/kubernetes/monitoring/nodeExporter-clusterRole.yaml b/release/kubernetes/monitoring/nodeExporter-clusterRole.yaml new file mode 100644 index 000000000..2f82c8ad9 --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-clusterRole.yaml @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/release/kubernetes/monitoring/nodeExporter-clusterRoleBinding.yaml b/release/kubernetes/monitoring/nodeExporter-clusterRoleBinding.yaml new file mode 100644 index 000000000..52100d4dc --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-clusterRoleBinding.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: node-exporter +subjects: +- kind: ServiceAccount + name: node-exporter + namespace: monitoring diff --git a/release/kubernetes/monitoring/nodeExporter-daemonset.yaml b/release/kubernetes/monitoring/nodeExporter-daemonset.yaml new file mode 100644 index 000000000..d501b0355 --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-daemonset.yaml @@ -0,0 +1,137 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter + namespace: monitoring +spec: + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: node-exporter + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + spec: + automountServiceAccountToken: true + containers: + - args: + - --web.listen-address=127.0.0.1:9101 + - --path.sysfs=/host/sys + - --path.rootfs=/host/root + - --path.procfs=/host/root/proc + - --path.udev.data=/host/root/run/udev/data + - --no-collector.wifi + - --no-collector.hwmon + - --no-collector.btrfs + - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run/k3s/containerd/.+|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/) + - --collector.netclass.ignored-devices=^(veth.*|[a-f0-9]{15})$ + - --collector.netdev.device-exclude=^(veth.*|[a-f0-9]{15})$ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus/node-exporter:v1.9.1 + name: node-exporter + resources: + limits: + cpu: 250m + memory: 180Mi + requests: + cpu: 102m + memory: 180Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - SYS_TIME + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /host/sys + mountPropagation: HostToContainer + name: sys + readOnly: true + - mountPath: /host/root + mountPropagation: HostToContainer + name: root + readOnly: true + - args: + - --secure-listen-address=[$(IP)]:9100 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:9101/ + env: + - name: IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/brancz/kube-rbac-proxy:v0.19.1 + name: kube-rbac-proxy + ports: + - containerPort: 9100 + hostPort: 9100 + name: https + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + hostNetwork: true + hostPID: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + serviceAccountName: node-exporter + tolerations: + - operator: Exists + volumes: + - hostPath: + path: /sys + name: sys + - hostPath: + path: / + name: root + updateStrategy: + rollingUpdate: + maxUnavailable: 10% + type: RollingUpdate diff --git a/release/kubernetes/monitoring/nodeExporter-networkPolicy.yaml b/release/kubernetes/monitoring/nodeExporter-networkPolicy.yaml new file mode 100644 index 000000000..ea993c7cf --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-networkPolicy.yaml @@ -0,0 +1,44 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 9100 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/nodeExporter-prometheusRule.yaml b/release/kubernetes/monitoring/nodeExporter-prometheusRule.yaml new file mode 100644 index 000000000..73787c938 --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-prometheusRule.yaml @@ -0,0 +1,420 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + prometheus: k8s + role: alert-rules + name: node-exporter-rules + namespace: monitoring +spec: + groups: + - name: node-exporter + rules: + - alert: NodeFilesystemSpaceFillingUp + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available space left and is filling up. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemspacefillingup + summary: Filesystem is predicted to run out of space within the next 24 hours. + expr: | + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 15 + and + predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: warning + - alert: NodeFilesystemSpaceFillingUp + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available space left and is filling up fast. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemspacefillingup + summary: Filesystem is predicted to run out of space within the next 4 hours. + expr: | + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 10 + and + predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: critical + - alert: NodeFilesystemAlmostOutOfSpace + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available space left. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutofspace + summary: Filesystem has less than 5% space left. + expr: | + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 30m + labels: + severity: warning + - alert: NodeFilesystemAlmostOutOfSpace + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available space left. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutofspace + summary: Filesystem has less than 3% space left. + expr: | + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 30m + labels: + severity: critical + - alert: NodeFilesystemFilesFillingUp + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available inodes left and is filling up. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemfilesfillingup + summary: Filesystem is predicted to run out of inodes within the next 24 hours. + expr: | + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 40 + and + predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: warning + - alert: NodeFilesystemFilesFillingUp + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available inodes left and is filling up fast. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemfilesfillingup + summary: Filesystem is predicted to run out of inodes within the next 4 hours. + expr: | + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 20 + and + predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: critical + - alert: NodeFilesystemAlmostOutOfFiles + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available inodes left. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutoffiles + summary: Filesystem has less than 5% inodes left. + expr: | + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: warning + - alert: NodeFilesystemAlmostOutOfFiles + annotations: + description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf "%.2f" $value }}% available inodes left. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutoffiles + summary: Filesystem has less than 3% inodes left. + expr: | + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: 1h + labels: + severity: critical + - alert: NodeNetworkReceiveErrs + annotations: + description: '{{ $labels.instance }} interface {{ $labels.device }} has encountered {{ printf "%.0f" $value }} receive errors in the last two minutes.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodenetworkreceiveerrs + summary: Network interface is reporting many receive errors. + expr: | + rate(node_network_receive_errs_total{job="node-exporter"}[2m]) / rate(node_network_receive_packets_total{job="node-exporter"}[2m]) > 0.01 + for: 1h + labels: + severity: warning + - alert: NodeNetworkTransmitErrs + annotations: + description: '{{ $labels.instance }} interface {{ $labels.device }} has encountered {{ printf "%.0f" $value }} transmit errors in the last two minutes.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodenetworktransmiterrs + summary: Network interface is reporting many transmit errors. + expr: | + rate(node_network_transmit_errs_total{job="node-exporter"}[2m]) / rate(node_network_transmit_packets_total{job="node-exporter"}[2m]) > 0.01 + for: 1h + labels: + severity: warning + - alert: NodeHighNumberConntrackEntriesUsed + annotations: + description: '{{ $labels.instance }} {{ $value | humanizePercentage }} of conntrack entries are used.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodehighnumberconntrackentriesused + summary: Number of conntrack are getting close to the limit. + expr: | + (node_nf_conntrack_entries{job="node-exporter"} / node_nf_conntrack_entries_limit) > 0.75 + labels: + severity: warning + - alert: NodeTextFileCollectorScrapeError + annotations: + description: Node Exporter text file collector on {{ $labels.instance }} failed to scrape. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodetextfilecollectorscrapeerror + summary: Node Exporter text file collector failed to scrape. + expr: | + node_textfile_scrape_error{job="node-exporter"} == 1 + labels: + severity: warning + - alert: NodeClockSkewDetected + annotations: + description: Clock at {{ $labels.instance }} is out of sync by more than 0.05s. Ensure NTP is configured correctly on this host. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodeclockskewdetected + summary: Clock skew detected. + expr: | + ( + node_timex_offset_seconds{job="node-exporter"} > 0.05 + and + deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) >= 0 + ) + or + ( + node_timex_offset_seconds{job="node-exporter"} < -0.05 + and + deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) <= 0 + ) + for: 10m + labels: + severity: warning + - alert: NodeClockNotSynchronising + annotations: + description: Clock at {{ $labels.instance }} is not synchronising. Ensure NTP is configured on this host. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodeclocknotsynchronising + summary: Clock not synchronising. + expr: | + min_over_time(node_timex_sync_status{job="node-exporter"}[5m]) == 0 + and + node_timex_maxerror_seconds{job="node-exporter"} >= 16 + for: 10m + labels: + severity: warning + - alert: NodeRAIDDegraded + annotations: + description: RAID array '{{ $labels.device }}' at {{ $labels.instance }} is in degraded state due to one or more disks failures. Number of spare drives is insufficient to fix issue automatically. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/noderaiddegraded + summary: RAID Array is degraded. + expr: | + node_md_disks_required{job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} - ignoring (state) (node_md_disks{state="active",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}) > 0 + for: 15m + labels: + severity: critical + - alert: NodeRAIDDiskFailure + annotations: + description: At least one device in RAID array at {{ $labels.instance }} failed. Array '{{ $labels.device }}' needs attention and possibly a disk swap. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/noderaiddiskfailure + summary: Failed device in RAID array. + expr: | + node_md_disks{state="failed",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} > 0 + labels: + severity: warning + - alert: NodeFileDescriptorLimit + annotations: + description: File descriptors limit at {{ $labels.instance }} is currently at {{ printf "%.2f" $value }}%. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefiledescriptorlimit + summary: Kernel is predicted to exhaust file descriptors limit soon. + expr: | + ( + node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 70 + ) + for: 15m + labels: + severity: warning + - alert: NodeFileDescriptorLimit + annotations: + description: File descriptors limit at {{ $labels.instance }} is currently at {{ printf "%.2f" $value }}%. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefiledescriptorlimit + summary: Kernel is predicted to exhaust file descriptors limit soon. + expr: | + ( + node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 90 + ) + for: 15m + labels: + severity: critical + - alert: NodeCPUHighUsage + annotations: + description: | + CPU usage at {{ $labels.instance }} has been above 90% for the last 15 minutes, is currently at {{ printf "%.2f" $value }}%. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodecpuhighusage + summary: High CPU usage. + expr: | + sum without(mode) (avg without (cpu) (rate(node_cpu_seconds_total{job="node-exporter", mode!~"idle|iowait"}[2m]))) * 100 > 90 + for: 15m + labels: + severity: info + - alert: NodeSystemSaturation + annotations: + description: | + System load per core at {{ $labels.instance }} has been above 2 for the last 15 minutes, is currently at {{ printf "%.2f" $value }}. + This might indicate this instance resources saturation and can cause it becoming unresponsive. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemsaturation + summary: System saturated, load per core is very high. + expr: | + node_load1{job="node-exporter"} + / count without (cpu, mode) (node_cpu_seconds_total{job="node-exporter", mode="idle"}) > 2 + for: 15m + labels: + severity: warning + - alert: NodeMemoryMajorPagesFaults + annotations: + description: | + Memory major pages are occurring at very high rate at {{ $labels.instance }}, 500 major page faults per second for the last 15 minutes, is currently at {{ printf "%.2f" $value }}. + Please check that there is enough memory available at this instance. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodememorymajorpagesfaults + summary: Memory major page faults are occurring at very high rate. + expr: | + rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) > 500 + for: 15m + labels: + severity: warning + - alert: NodeMemoryHighUtilization + annotations: + description: | + Memory is filling up at {{ $labels.instance }}, has been above 90% for the last 15 minutes, is currently at {{ printf "%.2f" $value }}%. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodememoryhighutilization + summary: Host is running out of memory. + expr: | + 100 - (node_memory_MemAvailable_bytes{job="node-exporter"} / node_memory_MemTotal_bytes{job="node-exporter"} * 100) > 90 + for: 15m + labels: + severity: warning + - alert: NodeDiskIOSaturation + annotations: + description: | + Disk IO queue (aqu-sq) is high on {{ $labels.device }} at {{ $labels.instance }}, has been above 10 for the last 30 minutes, is currently at {{ printf "%.2f" $value }}. + This symptom might indicate disk saturation. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodediskiosaturation + summary: Disk IO queue is high. + expr: | + rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) > 10 + for: 30m + labels: + severity: warning + - alert: NodeSystemdServiceFailed + annotations: + description: Systemd service {{ $labels.name }} has entered failed state at {{ $labels.instance }} + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemdservicefailed + summary: Systemd service has entered failed state. + expr: | + node_systemd_unit_state{job="node-exporter", state="failed"} == 1 + for: 5m + labels: + severity: warning + - alert: NodeSystemdServiceCrashlooping + annotations: + description: Systemd service {{ $labels.name }} has being restarted too many times at {{ $labels.instance }} for the last 15 minutes. Please check if service is crash looping. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemdservicecrashlooping + summary: Systemd service keeps restaring, possibly crash looping. + expr: | + increase(node_systemd_service_restart_total{job="node-exporter"}[5m]) > 2 + for: 15m + labels: + severity: warning + - alert: NodeBondingDegraded + annotations: + description: Bonding interface {{ $labels.master }} on {{ $labels.instance }} is in degraded state due to one or more slave failures. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodebondingdegraded + summary: Bonding interface is degraded + expr: | + (node_bonding_slaves - node_bonding_active) != 0 + for: 5m + labels: + severity: warning + - name: node-exporter.rules + rules: + - expr: | + count without (cpu, mode) ( + node_cpu_seconds_total{job="node-exporter",mode="idle"} + ) + record: instance:node_num_cpu:sum + - expr: | + 1 - avg without (cpu) ( + sum without (mode) (rate(node_cpu_seconds_total{job="node-exporter", mode=~"idle|iowait|steal"}[5m])) + ) + record: instance:node_cpu_utilisation:rate5m + - expr: | + ( + node_load1{job="node-exporter"} + / + instance:node_num_cpu:sum{job="node-exporter"} + ) + record: instance:node_load1_per_cpu:ratio + - expr: | + 1 - ( + ( + node_memory_MemAvailable_bytes{job="node-exporter"} + or + ( + node_memory_Buffers_bytes{job="node-exporter"} + + + node_memory_Cached_bytes{job="node-exporter"} + + + node_memory_MemFree_bytes{job="node-exporter"} + + + node_memory_Slab_bytes{job="node-exporter"} + ) + ) + / + node_memory_MemTotal_bytes{job="node-exporter"} + ) + record: instance:node_memory_utilisation:ratio + - expr: | + rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) + record: instance:node_vmstat_pgmajfault:rate5m + - expr: | + rate(node_disk_io_time_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) + record: instance_device:node_disk_io_time_seconds:rate5m + - expr: | + rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) + record: instance_device:node_disk_io_time_weighted_seconds:rate5m + - expr: | + sum without (device) ( + rate(node_network_receive_bytes_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_receive_bytes_excluding_lo:rate5m + - expr: | + sum without (device) ( + rate(node_network_transmit_bytes_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_transmit_bytes_excluding_lo:rate5m + - expr: | + sum without (device) ( + rate(node_network_receive_drop_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_receive_drop_excluding_lo:rate5m + - expr: | + sum without (device) ( + rate(node_network_transmit_drop_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_transmit_drop_excluding_lo:rate5m diff --git a/release/kubernetes/monitoring/nodeExporter-service.yaml b/release/kubernetes/monitoring/nodeExporter-service.yaml new file mode 100644 index 000000000..19175b8fc --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-service.yaml @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter + namespace: monitoring +spec: + clusterIP: None + ports: + - name: https + port: 9100 + targetPort: https + selector: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/nodeExporter-serviceAccount.yaml b/release/kubernetes/monitoring/nodeExporter-serviceAccount.yaml new file mode 100644 index 000000000..a046d372c --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter + namespace: monitoring diff --git a/release/kubernetes/monitoring/nodeExporter-serviceMonitor.yaml b/release/kubernetes/monitoring/nodeExporter-serviceMonitor.yaml new file mode 100644 index 000000000..bee7d3993 --- /dev/null +++ b/release/kubernetes/monitoring/nodeExporter-serviceMonitor.yaml @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 1.9.1 + name: node-exporter + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 15s + port: https + relabelings: + - action: replace + regex: (.*) + replacement: $1 + sourceLabels: + - __meta_kubernetes_pod_node_name + targetLabel: instance + scheme: https + tlsConfig: + insecureSkipVerify: true + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: node-exporter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheus-clusterRole.yaml b/release/kubernetes/monitoring/prometheus-clusterRole.yaml new file mode 100644 index 000000000..b74ecade4 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-clusterRole.yaml @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s +rules: + - apiGroups: [""] + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + verbs: ["list", "watch"] + - apiGroups: [""] + resources: + - configmaps + verbs: ["get"] + - apiGroups: ["networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] + - apiGroups: [""] + resources: + - nodes/metrics + verbs: ["get"] + - nonResourceURLs: + - /metrics + - /metrics/slis + verbs: ["get"] diff --git a/release/kubernetes/monitoring/prometheus-clusterRoleBinding.yaml b/release/kubernetes/monitoring/prometheus-clusterRoleBinding.yaml new file mode 100644 index 000000000..76f5a8375 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-clusterRoleBinding.yaml @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus-k8s +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheus-networkPolicy.yaml b/release/kubernetes/monitoring/prometheus-networkPolicy.yaml new file mode 100644 index 000000000..f1ba4fbdc --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-networkPolicy.yaml @@ -0,0 +1,62 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 9090 + protocol: TCP + - port: 8080 + protocol: TCP + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus-adapter + ports: + - port: 9090 + protocol: TCP + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: grafana + ports: + - port: 9090 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/prometheus-podDisruptionBudget.yaml b/release/kubernetes/monitoring/prometheus-podDisruptionBudget.yaml new file mode 100644 index 000000000..24e6065f6 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-podDisruptionBudget.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheus-prometheus.yaml b/release/kubernetes/monitoring/prometheus-prometheus.yaml new file mode 100644 index 000000000..a2e24d077 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-prometheus.yaml @@ -0,0 +1,65 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: Prometheus +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: k8s + namespace: monitoring +spec: + alerting: + alertmanagers: + - apiVersion: v2 + name: alertmanager-main + namespace: monitoring + port: web + enableFeatures: [] + externalLabels: {} + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus/prometheus:v3.5.0 + nodeSelector: + kubernetes.io/os: linux + podMetadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + podMonitorNamespaceSelector: {} + podMonitorSelector: {} + probeNamespaceSelector: {} + probeSelector: {} + replicas: 2 + resources: + requests: + memory: 400Mi + ruleNamespaceSelector: {} + ruleSelector: {} + scrapeConfigNamespaceSelector: {} + scrapeConfigSelector: {} + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccountName: prometheus-k8s + serviceMonitorNamespaceSelector: {} + serviceMonitorSelector: {} + version: 3.5.0 diff --git a/release/kubernetes/monitoring/prometheus-prometheusRule.yaml b/release/kubernetes/monitoring/prometheus-prometheusRule.yaml new file mode 100644 index 000000000..ec9b5ed21 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-prometheusRule.yaml @@ -0,0 +1,315 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + prometheus: k8s + role: alert-rules + name: prometheus-k8s-prometheus-rules + namespace: monitoring +spec: + groups: + - name: prometheus + rules: + - alert: PrometheusBadConfig + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to reload its configuration. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusbadconfig + summary: Failed Prometheus configuration reload. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(prometheus_config_last_reload_successful{job="prometheus-k8s",namespace="monitoring"}[5m]) == 0 + for: 10m + labels: + severity: critical + - alert: PrometheusSDRefreshFailure + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to refresh SD with mechanism {{$labels.mechanism}}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheussdrefreshfailure + summary: Failed Prometheus SD refresh. + expr: | + increase(prometheus_sd_refresh_failures_total{job="prometheus-k8s",namespace="monitoring"}[10m]) > 0 + for: 20m + labels: + severity: warning + - alert: PrometheusKubernetesListWatchFailures + annotations: + description: Kubernetes service discovery of Prometheus {{$labels.namespace}}/{{$labels.pod}} is experiencing {{ printf "%.0f" $value }} failures with LIST/WATCH requests to the Kubernetes API in the last 5 minutes. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuskuberneteslistwatchfailures + summary: Requests in Kubernetes SD are failing. + expr: | + increase(prometheus_sd_kubernetes_failures_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusNotificationQueueRunningFull + annotations: + description: Alert notification queue of Prometheus {{$labels.namespace}}/{{$labels.pod}} is running full. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotificationqueuerunningfull + summary: Prometheus alert notification queue predicted to run full in less than 30m. + expr: | + # Without min_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + predict_linear(prometheus_notifications_queue_length{job="prometheus-k8s",namespace="monitoring"}[5m], 60 * 30) + > + min_over_time(prometheus_notifications_queue_capacity{job="prometheus-k8s",namespace="monitoring"}[5m]) + ) + for: 15m + labels: + severity: warning + - alert: PrometheusErrorSendingAlertsToSomeAlertmanagers + annotations: + description: '{{ printf "%.1f" $value }}% of alerts sent by Prometheus {{$labels.namespace}}/{{$labels.pod}} to Alertmanager {{$labels.alertmanager}} were affected by errors.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuserrorsendingalertstosomealertmanagers + summary: More than 1% of alerts sent by Prometheus to a specific Alertmanager were affected by errors. + expr: | + ( + rate(prometheus_notifications_errors_total{job="prometheus-k8s",namespace="monitoring"}[5m]) + / + rate(prometheus_notifications_sent_total{job="prometheus-k8s",namespace="monitoring"}[5m]) + ) + * 100 + > 1 + for: 15m + labels: + severity: warning + - alert: PrometheusNotConnectedToAlertmanagers + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is not connected to any Alertmanagers. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotconnectedtoalertmanagers + summary: Prometheus is not connected to any Alertmanagers. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(prometheus_notifications_alertmanagers_discovered{job="prometheus-k8s",namespace="monitoring"}[5m]) < 1 + for: 10m + labels: + severity: warning + - alert: PrometheusTSDBReloadsFailing + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has detected {{$value | humanize}} reload failures over the last 3h. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustsdbreloadsfailing + summary: Prometheus has issues reloading blocks from disk. + expr: | + increase(prometheus_tsdb_reloads_failures_total{job="prometheus-k8s",namespace="monitoring"}[3h]) > 0 + for: 4h + labels: + severity: warning + - alert: PrometheusTSDBCompactionsFailing + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has detected {{$value | humanize}} compaction failures over the last 3h. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustsdbcompactionsfailing + summary: Prometheus has issues compacting blocks. + expr: | + increase(prometheus_tsdb_compactions_failed_total{job="prometheus-k8s",namespace="monitoring"}[3h]) > 0 + for: 4h + labels: + severity: warning + - alert: PrometheusNotIngestingSamples + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is not ingesting samples. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotingestingsamples + summary: Prometheus is not ingesting samples. + expr: | + ( + sum without(type) (rate(prometheus_tsdb_head_samples_appended_total{job="prometheus-k8s",namespace="monitoring"}[5m])) <= 0 + and + ( + sum without(scrape_job) (prometheus_target_metadata_cache_entries{job="prometheus-k8s",namespace="monitoring"}) > 0 + or + sum without(rule_group) (prometheus_rule_group_rules{job="prometheus-k8s",namespace="monitoring"}) > 0 + ) + ) + for: 10m + labels: + severity: warning + - alert: PrometheusDuplicateTimestamps + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is dropping {{ printf "%.4g" $value }} samples/s with different values but duplicated timestamp. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusduplicatetimestamps + summary: Prometheus is dropping samples with duplicate timestamps. + expr: | + rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 10m + labels: + severity: warning + - alert: PrometheusOutOfOrderTimestamps + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is dropping {{ printf "%.4g" $value }} samples/s with timestamps arriving out of order. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusoutofordertimestamps + summary: Prometheus drops samples with out-of-order timestamps. + expr: | + rate(prometheus_target_scrapes_sample_out_of_order_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 10m + labels: + severity: warning + - alert: PrometheusRemoteStorageFailures + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} failed to send {{ printf "%.1f" $value }}% of the samples to {{ $labels.remote_name}}:{{ $labels.url }} + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotestoragefailures + summary: Prometheus fails to send samples to remote storage. + expr: | + ( + (rate(prometheus_remote_storage_failed_samples_total{job="prometheus-k8s",namespace="monitoring"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="prometheus-k8s",namespace="monitoring"}[5m])) + / + ( + (rate(prometheus_remote_storage_failed_samples_total{job="prometheus-k8s",namespace="monitoring"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="prometheus-k8s",namespace="monitoring"}[5m])) + + + (rate(prometheus_remote_storage_succeeded_samples_total{job="prometheus-k8s",namespace="monitoring"}[5m]) or rate(prometheus_remote_storage_samples_total{job="prometheus-k8s",namespace="monitoring"}[5m])) + ) + ) + * 100 + > 1 + for: 15m + labels: + severity: critical + - alert: PrometheusRemoteWriteBehind + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} remote write is {{ printf "%.1f" $value }}s behind for {{ $labels.remote_name}}:{{ $labels.url }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotewritebehind + summary: Prometheus remote write is behind. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + max_over_time(prometheus_remote_storage_highest_timestamp_in_seconds{job="prometheus-k8s",namespace="monitoring"}[5m]) + - ignoring(remote_name, url) group_right + max_over_time(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{job="prometheus-k8s",namespace="monitoring"}[5m]) + ) + > 120 + for: 15m + labels: + severity: critical + - alert: PrometheusRemoteWriteDesiredShards + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} remote write desired shards calculation wants to run {{ $value }} shards for queue {{ $labels.remote_name}}:{{ $labels.url }}, which is more than the max of {{ printf `prometheus_remote_storage_shards_max{instance="%s",job="prometheus-k8s",namespace="monitoring"}` $labels.instance | query | first | value }}. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotewritedesiredshards + summary: Prometheus remote write desired shards calculation wants to run more than configured max shards. + expr: | + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + max_over_time(prometheus_remote_storage_shards_desired{job="prometheus-k8s",namespace="monitoring"}[5m]) + > + max_over_time(prometheus_remote_storage_shards_max{job="prometheus-k8s",namespace="monitoring"}[5m]) + ) + for: 15m + labels: + severity: warning + - alert: PrometheusRuleFailures + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to evaluate {{ printf "%.0f" $value }} rules in the last 5m. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusrulefailures + summary: Prometheus is failing rule evaluations. + expr: | + increase(prometheus_rule_evaluation_failures_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: critical + - alert: PrometheusMissingRuleEvaluations + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has missed {{ printf "%.0f" $value }} rule group evaluations in the last 5m. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusmissingruleevaluations + summary: Prometheus is missing rule evaluations due to slow rule group evaluation. + expr: | + increase(prometheus_rule_group_iterations_missed_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusTargetLimitHit + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has dropped {{ printf "%.0f" $value }} targets because the number of targets exceeded the configured target_limit. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustargetlimithit + summary: Prometheus has dropped targets because some scrape configs have exceeded the targets limit. + expr: | + increase(prometheus_target_scrape_pool_exceeded_target_limit_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusLabelLimitHit + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has dropped {{ printf "%.0f" $value }} targets because some samples exceeded the configured label_limit, label_name_length_limit or label_value_length_limit. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuslabellimithit + summary: Prometheus has dropped targets because some scrape configs have exceeded the labels limit. + expr: | + increase(prometheus_target_scrape_pool_exceeded_label_limits_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusScrapeBodySizeLimitHit + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed {{ printf "%.0f" $value }} scrapes in the last 5m because some targets exceeded the configured body_size_limit. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusscrapebodysizelimithit + summary: Prometheus has dropped some targets that exceeded body size limit. + expr: | + increase(prometheus_target_scrapes_exceeded_body_size_limit_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusScrapeSampleLimitHit + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed {{ printf "%.0f" $value }} scrapes in the last 5m because some targets exceeded the configured sample_limit. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusscrapesamplelimithit + summary: Prometheus has failed scrapes that have exceeded the configured sample limit. + expr: | + increase(prometheus_target_scrapes_exceeded_sample_limit_total{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0 + for: 15m + labels: + severity: warning + - alert: PrometheusTargetSyncFailure + annotations: + description: '{{ printf "%.0f" $value }} targets in Prometheus {{$labels.namespace}}/{{$labels.pod}} have failed to sync because invalid configuration was supplied.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustargetsyncfailure + summary: Prometheus has failed to sync targets. + expr: | + increase(prometheus_target_sync_failed_total{job="prometheus-k8s",namespace="monitoring"}[30m]) > 0 + for: 5m + labels: + severity: critical + - alert: PrometheusHighQueryLoad + annotations: + description: Prometheus {{$labels.namespace}}/{{$labels.pod}} query API has less than 20% available capacity in its query engine for the last 15 minutes. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheushighqueryload + summary: Prometheus is reaching its maximum capacity serving concurrent requests. + expr: | + avg_over_time(prometheus_engine_queries{job="prometheus-k8s",namespace="monitoring"}[5m]) / max_over_time(prometheus_engine_queries_concurrent_max{job="prometheus-k8s",namespace="monitoring"}[5m]) > 0.8 + for: 15m + labels: + severity: warning + - alert: PrometheusErrorSendingAlertsToAnyAlertmanager + annotations: + description: '{{ printf "%.1f" $value }}% minimum errors while sending alerts from Prometheus {{$labels.namespace}}/{{$labels.pod}} to any Alertmanager.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuserrorsendingalertstoanyalertmanager + summary: Prometheus encounters more than 3% errors sending alerts to any Alertmanager. + expr: | + min without (alertmanager) ( + rate(prometheus_notifications_errors_total{job="prometheus-k8s",namespace="monitoring",alertmanager!~``}[5m]) + / + rate(prometheus_notifications_sent_total{job="prometheus-k8s",namespace="monitoring",alertmanager!~``}[5m]) + ) + * 100 + > 3 + for: 15m + labels: + severity: critical diff --git a/release/kubernetes/monitoring/prometheus-roleBindingConfig.yaml b/release/kubernetes/monitoring/prometheus-roleBindingConfig.yaml new file mode 100644 index 000000000..79127f648 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-roleBindingConfig.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s-config + namespace: monitoring +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: prometheus-k8s-config +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheus-roleBindingSpecificNamespaces.yaml b/release/kubernetes/monitoring/prometheus-roleBindingSpecificNamespaces.yaml new file mode 100644 index 000000000..f87d40b9c --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-roleBindingSpecificNamespaces.yaml @@ -0,0 +1,75 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +items: +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: default + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: prometheus-k8s + subjects: + - kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: kube-system + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: prometheus-k8s + subjects: + - kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: prometheus-k8s + subjects: + - kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +kind: RoleBindingList diff --git a/release/kubernetes/monitoring/prometheus-roleConfig.yaml b/release/kubernetes/monitoring/prometheus-roleConfig.yaml new file mode 100644 index 000000000..c5b2a1b6d --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-roleConfig.yaml @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s-config + namespace: monitoring +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get diff --git a/release/kubernetes/monitoring/prometheus-roleSpecificNamespaces.yaml b/release/kubernetes/monitoring/prometheus-roleSpecificNamespaces.yaml new file mode 100644 index 000000000..85ab03119 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-roleSpecificNamespaces.yaml @@ -0,0 +1,132 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +items: +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: default + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: kube-system + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +kind: RoleList diff --git a/release/kubernetes/monitoring/prometheus-service.yaml b/release/kubernetes/monitoring/prometheus-service.yaml new file mode 100644 index 000000000..eaf7490d6 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-service.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring +spec: + ports: + - name: web + port: 9090 + targetPort: web + - name: reloader-web + port: 8080 + targetPort: reloader-web + selector: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + sessionAffinity: ClientIP diff --git a/release/kubernetes/monitoring/prometheus-serviceAccount.yaml b/release/kubernetes/monitoring/prometheus-serviceAccount.yaml new file mode 100644 index 000000000..3ae1c5078 --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-serviceAccount.yaml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheus-serviceMonitor.yaml b/release/kubernetes/monitoring/prometheus-serviceMonitor.yaml new file mode 100644 index 000000000..48396adde --- /dev/null +++ b/release/kubernetes/monitoring/prometheus-serviceMonitor.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 3.5.0 + name: prometheus-k8s + namespace: monitoring +spec: + endpoints: + - interval: 30s + port: web + - interval: 30s + port: reloader-web + selector: + matchLabels: + app.kubernetes.io/component: prometheus + app.kubernetes.io/instance: k8s + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheusAdapter-apiService.yaml b/release/kubernetes/monitoring/prometheusAdapter-apiService.yaml new file mode 100644 index 000000000..9e15a61c5 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-apiService.yaml @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: prometheus-adapter + namespace: monitoring + version: v1beta1 + versionPriority: 100 diff --git a/release/kubernetes/monitoring/prometheusAdapter-clusterRole.yaml b/release/kubernetes/monitoring/prometheusAdapter-clusterRole.yaml new file mode 100644 index 000000000..e57aa1b0b --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-clusterRole.yaml @@ -0,0 +1,36 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter +rules: +- apiGroups: + - "" + resources: + - nodes + - namespaces + - pods + - services + verbs: + - get + - list + - watch diff --git a/release/kubernetes/monitoring/prometheusAdapter-clusterRoleAggregatedMetricsReader.yaml b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleAggregatedMetricsReader.yaml new file mode 100644 index 000000000..4f7e3c5a9 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleAggregatedMetricsReader.yaml @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: system:aggregated-metrics-reader +rules: +- apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch diff --git a/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBinding.yaml b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBinding.yaml new file mode 100644 index 000000000..91b3bf75f --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBinding.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus-adapter +subjects: +- kind: ServiceAccount + name: prometheus-adapter + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBindingDelegator.yaml b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBindingDelegator.yaml new file mode 100644 index 000000000..49001b4a9 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleBindingDelegator.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: resource-metrics:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: prometheus-adapter + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusAdapter-clusterRoleServerResources.yaml b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleServerResources.yaml new file mode 100644 index 000000000..016a84a4e --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-clusterRoleServerResources.yaml @@ -0,0 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: resource-metrics-server-resources +rules: +- apiGroups: + - metrics.k8s.io + resources: + - '*' + verbs: + - '*' diff --git a/release/kubernetes/monitoring/prometheusAdapter-configMap.yaml b/release/kubernetes/monitoring/prometheusAdapter-configMap.yaml new file mode 100644 index 000000000..928631938 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-configMap.yaml @@ -0,0 +1,84 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +data: + config.yaml: |- + "resourceRules": + "cpu": + "containerLabel": "container" + "containerQuery": | + sum by (<<.GroupBy>>) ( + irate ( + container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!="",pod!=""}[120s] + ) + ) + "nodeQuery": | + sum by (<<.GroupBy>>) ( + 1 - irate( + node_cpu_seconds_total{mode="idle"}[60s] + ) + * on(namespace, pod) group_left(node) ( + node_namespace_pod:kube_pod_info:{<<.LabelMatchers>>} + ) + ) + or sum by (<<.GroupBy>>) ( + 1 - irate( + windows_cpu_time_total{mode="idle", job="windows-exporter",<<.LabelMatchers>>}[4m] + ) + ) + "resources": + "overrides": + "namespace": + "resource": "namespace" + "node": + "resource": "node" + "pod": + "resource": "pod" + "memory": + "containerLabel": "container" + "containerQuery": | + sum by (<<.GroupBy>>) ( + container_memory_working_set_bytes{<<.LabelMatchers>>,container!="",pod!=""} + ) + "nodeQuery": | + sum by (<<.GroupBy>>) ( + node_memory_MemTotal_bytes{job="node-exporter",<<.LabelMatchers>>} + - + node_memory_MemAvailable_bytes{job="node-exporter",<<.LabelMatchers>>} + ) + or sum by (<<.GroupBy>>) ( + windows_cs_physical_memory_bytes{job="windows-exporter",<<.LabelMatchers>>} + - + windows_memory_available_bytes{job="windows-exporter",<<.LabelMatchers>>} + ) + "resources": + "overrides": + "instance": + "resource": "node" + "namespace": + "resource": "namespace" + "pod": + "resource": "pod" + "window": "5m" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: adapter-config + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusAdapter-deployment.yaml b/release/kubernetes/monitoring/prometheusAdapter-deployment.yaml new file mode 100644 index 000000000..765b116c5 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-deployment.yaml @@ -0,0 +1,118 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + template: + metadata: + annotations: + checksum.config/md5: 3b1ebf7df0232d1675896f67b66373db + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + spec: + automountServiceAccountToken: true + containers: + - args: + - --cert-dir=/var/run/serving-cert + - --config=/etc/adapter/config.yaml + - --metrics-relist-interval=1m + - --prometheus-url=http://prometheus-k8s.monitoring.svc:9090/ + - --secure-port=6443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.12.0 + livenessProbe: + failureThreshold: 5 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 5 + name: prometheus-adapter + ports: + - containerPort: 6443 + name: https + readinessProbe: + failureThreshold: 5 + httpGet: + path: /readyz + port: https + scheme: HTTPS + periodSeconds: 5 + resources: + limits: + cpu: 250m + memory: 180Mi + requests: + cpu: 102m + memory: 180Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + startupProbe: + failureThreshold: 18 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + volumeMounts: + - mountPath: /tmp + name: tmpfs + readOnly: false + - mountPath: /var/run/serving-cert + name: volume-serving-cert + readOnly: false + - mountPath: /etc/adapter + name: config + readOnly: false + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: prometheus-adapter + volumes: + - emptyDir: {} + name: tmpfs + - emptyDir: {} + name: volume-serving-cert + - configMap: + name: adapter-config + name: config diff --git a/release/kubernetes/monitoring/prometheusAdapter-networkPolicy.yaml b/release/kubernetes/monitoring/prometheusAdapter-networkPolicy.yaml new file mode 100644 index 000000000..942947e85 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-networkPolicy.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring +spec: + egress: + - {} + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/prometheusAdapter-podDisruptionBudget.yaml b/release/kubernetes/monitoring/prometheusAdapter-podDisruptionBudget.yaml new file mode 100644 index 000000000..c248b82e7 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-podDisruptionBudget.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheusAdapter-roleBindingAuthReader.yaml b/release/kubernetes/monitoring/prometheusAdapter-roleBindingAuthReader.yaml new file mode 100644 index 000000000..9a4d41f1b --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-roleBindingAuthReader.yaml @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: resource-metrics-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: prometheus-adapter + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusAdapter-service.yaml b/release/kubernetes/monitoring/prometheusAdapter-service.yaml new file mode 100644 index 000000000..0fa9e3574 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-service.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring +spec: + ports: + - name: https + port: 443 + targetPort: 6443 + selector: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheusAdapter-serviceAccount.yaml b/release/kubernetes/monitoring/prometheusAdapter-serviceAccount.yaml new file mode 100644 index 000000000..f8a3aeafd --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusAdapter-serviceMonitor.yaml b/release/kubernetes/monitoring/prometheusAdapter-serviceMonitor.yaml new file mode 100644 index 000000000..ed922374d --- /dev/null +++ b/release/kubernetes/monitoring/prometheusAdapter-serviceMonitor.yaml @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.12.0 + name: prometheus-adapter + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + metricRelabelings: + - action: drop + regex: (apiserver_client_certificate_.*|apiserver_envelope_.*|apiserver_flowcontrol_.*|apiserver_storage_.*|apiserver_webhooks_.*|workqueue_.*) + sourceLabels: + - __name__ + port: https + scheme: https + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + app.kubernetes.io/component: metrics-adapter + app.kubernetes.io/name: prometheus-adapter + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheusOperator-clusterRole.yaml b/release/kubernetes/monitoring/prometheusOperator-clusterRole.yaml new file mode 100644 index 000000000..b597e03a0 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-clusterRole.yaml @@ -0,0 +1,136 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator +rules: +- apiGroups: + - monitoring.coreos.com + resources: + - alertmanagers + - alertmanagers/finalizers + - alertmanagers/status + - alertmanagerconfigs + - prometheuses + - prometheuses/finalizers + - prometheuses/status + - prometheusagents + - prometheusagents/finalizers + - prometheusagents/status + - thanosrulers + - thanosrulers/finalizers + - thanosrulers/status + - scrapeconfigs + - servicemonitors + - servicemonitors/status + - podmonitors + - probes + - prometheusrules + verbs: + - '*' +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - '*' +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - '*' +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - delete +- apiGroups: + - "" + resources: + - services + - services/finalizers + verbs: + - get + - create + - update + - delete +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - patch + - create +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - create + - update + - delete +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/release/kubernetes/monitoring/prometheusOperator-clusterRoleBinding.yaml b/release/kubernetes/monitoring/prometheusOperator-clusterRoleBinding.yaml new file mode 100644 index 000000000..cb41d03d0 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-clusterRoleBinding.yaml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus-operator +subjects: +- kind: ServiceAccount + name: prometheus-operator + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusOperator-deployment.yaml b/release/kubernetes/monitoring/prometheusOperator-deployment.yaml new file mode 100644 index 000000000..2a35bd386 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-deployment.yaml @@ -0,0 +1,106 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: prometheus-operator + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + spec: + automountServiceAccountToken: true + containers: + - args: + - --kubelet-service=kube-system/kubelet + - --prometheus-config-reloader=swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus-operator/prometheus-config-reloader:v0.84.0 + - --kubelet-endpoints=true + - --kubelet-endpointslice=false + env: + - name: GOGC + value: "30" + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus-operator/prometheus-operator:v0.84.0 + name: prometheus-operator + ports: + - containerPort: 8080 + name: http + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + - args: + - --secure-listen-address=:8443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8080/ + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/brancz/kube-rbac-proxy:v0.19.1 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: + limits: + cpu: 20m + memory: 40Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + serviceAccountName: prometheus-operator diff --git a/release/kubernetes/monitoring/prometheusOperator-networkPolicy.yaml b/release/kubernetes/monitoring/prometheusOperator-networkPolicy.yaml new file mode 100644 index 000000000..47ad457ad --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-networkPolicy.yaml @@ -0,0 +1,44 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator + namespace: monitoring +spec: + egress: + - {} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: 8443 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + policyTypes: + - Egress + - Ingress diff --git a/release/kubernetes/monitoring/prometheusOperator-prometheusRule.yaml b/release/kubernetes/monitoring/prometheusOperator-prometheusRule.yaml new file mode 100644 index 000000000..ffdb0d330 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-prometheusRule.yaml @@ -0,0 +1,125 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + prometheus: k8s + role: alert-rules + name: prometheus-operator-rules + namespace: monitoring +spec: + groups: + - name: prometheus-operator + rules: + - alert: PrometheusOperatorListErrors + annotations: + description: Errors while performing List operations in controller {{$labels.controller}} in {{$labels.namespace}} namespace. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorlisterrors + summary: Errors while performing list operations in controller. + expr: | + (sum by (cluster,controller,namespace) (rate(prometheus_operator_list_operations_failed_total{job="prometheus-operator",namespace="monitoring"}[10m])) / sum by (cluster,controller,namespace) (rate(prometheus_operator_list_operations_total{job="prometheus-operator",namespace="monitoring"}[10m]))) > 0.4 + for: 15m + labels: + severity: warning + - alert: PrometheusOperatorWatchErrors + annotations: + description: Errors while performing watch operations in controller {{$labels.controller}} in {{$labels.namespace}} namespace. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorwatcherrors + summary: Errors while performing watch operations in controller. + expr: | + (sum by (cluster,controller,namespace) (rate(prometheus_operator_watch_operations_failed_total{job="prometheus-operator",namespace="monitoring"}[5m])) / sum by (cluster,controller,namespace) (rate(prometheus_operator_watch_operations_total{job="prometheus-operator",namespace="monitoring"}[5m]))) > 0.4 + for: 15m + labels: + severity: warning + - alert: PrometheusOperatorSyncFailed + annotations: + description: Controller {{ $labels.controller }} in {{ $labels.namespace }} namespace fails to reconcile {{ $value }} objects. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorsyncfailed + summary: Last controller reconciliation failed + expr: | + min_over_time(prometheus_operator_syncs{status="failed",job="prometheus-operator",namespace="monitoring"}[5m]) > 0 + for: 10m + labels: + severity: warning + - alert: PrometheusOperatorReconcileErrors + annotations: + description: '{{ $value | humanizePercentage }} of reconciling operations failed for {{ $labels.controller }} controller in {{ $labels.namespace }} namespace.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorreconcileerrors + summary: Errors while reconciling objects. + expr: | + (sum by (cluster,controller,namespace) (rate(prometheus_operator_reconcile_errors_total{job="prometheus-operator",namespace="monitoring"}[5m]))) / (sum by (cluster,controller,namespace) (rate(prometheus_operator_reconcile_operations_total{job="prometheus-operator",namespace="monitoring"}[5m]))) > 0.1 + for: 10m + labels: + severity: warning + - alert: PrometheusOperatorStatusUpdateErrors + annotations: + description: '{{ $value | humanizePercentage }} of status update operations failed for {{ $labels.controller }} controller in {{ $labels.namespace }} namespace.' + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorstatusupdateerrors + summary: Errors while updating objects status. + expr: | + (sum by (cluster,controller,namespace) (rate(prometheus_operator_status_update_errors_total{job="prometheus-operator",namespace="monitoring"}[5m]))) / (sum by (cluster,controller,namespace) (rate(prometheus_operator_status_update_operations_total{job="prometheus-operator",namespace="monitoring"}[5m]))) > 0.1 + for: 10m + labels: + severity: warning + - alert: PrometheusOperatorNodeLookupErrors + annotations: + description: Errors while reconciling Prometheus in {{ $labels.namespace }} Namespace. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatornodelookuperrors + summary: Errors while reconciling Prometheus. + expr: | + rate(prometheus_operator_node_address_lookup_errors_total{job="prometheus-operator",namespace="monitoring"}[5m]) > 0.1 + for: 10m + labels: + severity: warning + - alert: PrometheusOperatorNotReady + annotations: + description: Prometheus operator in {{ $labels.namespace }} namespace isn't ready to reconcile {{ $labels.controller }} resources. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatornotready + summary: Prometheus operator not ready + expr: | + min by (cluster,controller,namespace) (max_over_time(prometheus_operator_ready{job="prometheus-operator",namespace="monitoring"}[5m]) == 0) + for: 5m + labels: + severity: warning + - alert: PrometheusOperatorRejectedResources + annotations: + description: Prometheus operator in {{ $labels.namespace }} namespace rejected {{ printf "%0.0f" $value }} {{ $labels.controller }}/{{ $labels.resource }} resources. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorrejectedresources + summary: Resources rejected by Prometheus operator + expr: | + min_over_time(prometheus_operator_managed_resources{state="rejected",job="prometheus-operator",namespace="monitoring"}[5m]) > 0 + for: 5m + labels: + severity: warning + - name: config-reloaders + rules: + - alert: ConfigReloaderSidecarErrors + annotations: + description: |- + Errors encountered while the {{$labels.pod}} config-reloader sidecar attempts to sync config in {{$labels.namespace}} namespace. + As a result, configuration for service running in {{$labels.pod}} may be stale and cannot be updated anymore. + runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/configreloadersidecarerrors + summary: config-reloader sidecar has not had a successful reload for 10m + expr: | + max_over_time(reloader_last_reload_successful{namespace=~".+"}[5m]) == 0 + for: 10m + labels: + severity: warning diff --git a/release/kubernetes/monitoring/prometheusOperator-service.yaml b/release/kubernetes/monitoring/prometheusOperator-service.yaml new file mode 100644 index 000000000..36bc96da1 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-service.yaml @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator + namespace: monitoring +spec: + clusterIP: None + ports: + - name: https + port: 8443 + targetPort: https + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus diff --git a/release/kubernetes/monitoring/prometheusOperator-serviceAccount.yaml b/release/kubernetes/monitoring/prometheusOperator-serviceAccount.yaml new file mode 100644 index 000000000..4e92cc4d2 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-serviceAccount.yaml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator + namespace: monitoring diff --git a/release/kubernetes/monitoring/prometheusOperator-serviceMonitor.yaml b/release/kubernetes/monitoring/prometheusOperator-serviceMonitor.yaml new file mode 100644 index 000000000..1e038da20 --- /dev/null +++ b/release/kubernetes/monitoring/prometheusOperator-serviceMonitor.yaml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 + name: prometheus-operator + namespace: monitoring +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + port: https + scheme: https + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/name: prometheus-operator + app.kubernetes.io/part-of: kube-prometheus + app.kubernetes.io/version: 0.85.0 diff --git a/release/kubernetes/monitoring/setup/0alertmanagerConfigCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0alertmanagerConfigCustomResourceDefinition.yaml new file mode 100644 index 000000000..83de03412 --- /dev/null +++ b/release/kubernetes/monitoring/setup/0alertmanagerConfigCustomResourceDefinition.yaml @@ -0,0 +1,10615 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: alertmanagerconfigs.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: AlertmanagerConfig + listKind: AlertmanagerConfigList + plural: alertmanagerconfigs + shortNames: + - amcfg + singular: alertmanagerconfig + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AlertmanagerConfig configures the Prometheus Alertmanager, + specifying how alerts should be grouped, inhibited and notified to external systems. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + AlertmanagerConfigSpec is a specification of the desired behavior of the + Alertmanager configuration. + By default, the Alertmanager configuration only applies to alerts for which + the `namespace` label is equal to the namespace of the AlertmanagerConfig + resource (see the `.spec.alertmanagerConfigMatcherStrategy` field of the + Alertmanager CRD). + properties: + inhibitRules: + description: |- + List of inhibition rules. The rules will only apply to alerts matching + the resource's namespace. + items: + description: |- + InhibitRule defines an inhibition rule that allows to mute alerts when other + alerts are already firing. + See https://prometheus.io/docs/alerting/latest/configuration/#inhibit_rule + properties: + equal: + description: |- + Labels that must have an equal value in the source and target alert for + the inhibition to take effect. + items: + type: string + type: array + sourceMatch: + description: |- + Matchers for which one or more alerts have to exist for the inhibition + to take effect. The operator enforces that the alert matches the + resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - = + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + targetMatch: + description: |- + Matchers that have to be fulfilled in the alerts to be muted. The + operator enforces that the alert matches the resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - = + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + type: object + type: array + muteTimeIntervals: + description: List of MuteTimeInterval specifying when the routes should be muted. + items: + description: MuteTimeInterval specifies the periods in time when notifications will be muted + properties: + name: + description: Name of the time interval + type: string + timeIntervals: + description: TimeIntervals is a list of TimeInterval + items: + description: TimeInterval describes intervals of time + properties: + daysOfMonth: + description: DaysOfMonth is a list of DayOfMonthRange + items: + description: DayOfMonthRange is an inclusive range of days of the month beginning at 1 + properties: + end: + description: End of the inclusive range + maximum: 31 + minimum: -31 + type: integer + start: + description: Start of the inclusive range + maximum: 31 + minimum: -31 + type: integer + type: object + type: array + months: + description: Months is a list of MonthRange + items: + description: |- + MonthRange is an inclusive range of months of the year beginning in January + Months can be specified by name (e.g 'January') by numerical month (e.g '1') or as an inclusive range (e.g 'January:March', '1:3', '1:March') + pattern: ^((?i)january|february|march|april|may|june|july|august|september|october|november|december|1[0-2]|[1-9])(?:((:((?i)january|february|march|april|may|june|july|august|september|october|november|december|1[0-2]|[1-9]))$)|$) + type: string + type: array + times: + description: Times is a list of TimeRange + items: + description: TimeRange defines a start and end time in 24hr format + properties: + endTime: + description: EndTime is the end time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + startTime: + description: StartTime is the start time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + type: object + type: array + weekdays: + description: Weekdays is a list of WeekdayRange + items: + description: |- + WeekdayRange is an inclusive range of days of the week beginning on Sunday + Days can be specified by name (e.g 'Sunday') or as an inclusive range (e.g 'Monday:Friday') + pattern: ^((?i)sun|mon|tues|wednes|thurs|fri|satur)day(?:((:(sun|mon|tues|wednes|thurs|fri|satur)day)$)|$) + type: string + type: array + years: + description: Years is a list of YearRange + items: + description: YearRange is an inclusive range of years + pattern: ^2\d{3}(?::2\d{3}|$) + type: string + type: array + type: object + type: array + required: + - name + type: object + type: array + receivers: + description: List of receivers. + items: + description: Receiver defines one or more notification integrations. + properties: + discordConfigs: + description: List of Discord configurations. + items: + description: |- + DiscordConfig configures notifications via Discord. + See https://prometheus.io/docs/alerting/latest/configuration/#discord_config + properties: + apiURL: + description: |- + The secret's key that contains the Discord webhook URL. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + avatarURL: + description: The avatar url of the message sender. + pattern: ^https?://.+$ + type: string + content: + description: The template of the content's body. + minLength: 1 + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: The template of the message's body. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + title: + description: The template of the message's title. + type: string + username: + description: The username of the message sender. + minLength: 1 + type: string + required: + - apiURL + type: object + type: array + emailConfigs: + description: List of Email configurations. + items: + description: EmailConfig configures notifications via Email. + properties: + authIdentity: + description: The identity to use for authentication. + type: string + authPassword: + description: |- + The secret's key that contains the password to use for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authSecret: + description: |- + The secret's key that contains the CRAM-MD5 secret. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authUsername: + description: The username to use for authentication. + type: string + from: + description: The sender address. + type: string + headers: + description: |- + Further headers email header key/value pairs. Overrides any headers + previously set by the notification implementation. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + hello: + description: The hostname to identify to the SMTP server. + type: string + html: + description: The HTML body of the email notification. + type: string + requireTLS: + description: |- + The SMTP TLS requirement. + Note that Go does not support unencrypted connections to remote SMTP endpoints. + type: boolean + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + smarthost: + description: The SMTP host and port through which emails are sent. E.g. example.com:25 + type: string + text: + description: The text body of the email notification. + type: string + tlsConfig: + description: TLS configuration + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + to: + description: The email address to send notifications to. + type: string + type: object + type: array + msteamsConfigs: + description: |- + List of MSTeams configurations. + It requires Alertmanager >= 0.26.0. + items: + description: |- + MSTeamsConfig configures notifications via Microsoft Teams. + It requires Alertmanager >= 0.26.0. + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + summary: + description: |- + Message summary template. + It requires Alertmanager >= 0.27.0. + type: string + text: + description: Message body template. + type: string + title: + description: Message title template. + type: string + webhookUrl: + description: MSTeams webhook URL. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - webhookUrl + type: object + type: array + msteamsv2Configs: + description: |- + List of MSTeamsV2 configurations. + It requires Alertmanager >= 0.28.0. + items: + description: |- + MSTeamsV2Config configures notifications via Microsoft Teams using the new message format with adaptive cards as required by flows + See https://prometheus.io/docs/alerting/latest/configuration/#msteamsv2_config + It requires Alertmanager >= 0.28.0. + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + text: + description: Message body template. + minLength: 1 + type: string + title: + description: Message title template. + minLength: 1 + type: string + webhookURL: + description: MSTeams incoming webhook URL. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: array + name: + description: Name of the receiver. Must be unique across all items from the list. + minLength: 1 + type: string + opsgenieConfigs: + description: List of OpsGenie configurations. + items: + description: |- + OpsGenieConfig configures notifications via OpsGenie. + See https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config + properties: + actions: + description: Comma separated list of actions that will be available for the alert. + type: string + apiKey: + description: |- + The secret's key that contains the OpsGenie API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: The URL to send OpsGenie API requests to. + type: string + description: + description: Description of the incident. + type: string + details: + description: A set of arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entity: + description: Optional field that can be used to specify which domain alert is related to. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Alert text limited to 130 characters. + type: string + note: + description: Additional alert note. + type: string + priority: + description: Priority level of alert. Possible values are P1, P2, P3, P4, and P5. + type: string + responders: + description: List of responders responsible for notifications. + items: + description: |- + OpsGenieConfigResponder defines a responder to an incident. + One of `id`, `name` or `username` has to be defined. + properties: + id: + description: ID of the responder. + type: string + name: + description: Name of the responder. + type: string + type: + description: Type of responder. + minLength: 1 + type: string + username: + description: Username of the responder. + type: string + required: + - type + type: object + type: array + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + source: + description: Backlink to the sender of the notification. + type: string + tags: + description: Comma separated list of tags attached to the notifications. + type: string + updateAlerts: + description: |- + Whether to update message and description of the alert in OpsGenie if it already exists + By default, the alert is never updated in OpsGenie, the new message only appears in activity log. + type: boolean + type: object + type: array + pagerdutyConfigs: + description: List of PagerDuty configurations. + items: + description: |- + PagerDutyConfig configures notifications via PagerDuty. + See https://prometheus.io/docs/alerting/latest/configuration/#pagerduty_config + properties: + class: + description: The class/type of the event. + type: string + client: + description: Client identification. + type: string + clientURL: + description: Backlink to the sender of notification. + type: string + component: + description: The part or component of the affected system that is broken. + type: string + description: + description: Description of the incident. + type: string + details: + description: Arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + group: + description: A cluster or grouping of sources. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + pagerDutyImageConfigs: + description: A list of image details to attach that provide further detail about an incident. + items: + description: PagerDutyImageConfig attaches images to an incident + properties: + alt: + description: Alt is the optional alternative text for the image. + type: string + href: + description: Optional URL; makes the image a clickable link. + type: string + src: + description: Src of the image being attached to the incident + type: string + type: object + type: array + pagerDutyLinkConfigs: + description: A list of link details to attach that provide further detail about an incident. + items: + description: PagerDutyLinkConfig attaches text links to an incident + properties: + alt: + description: Text that describes the purpose of the link, and can be used as the link's text. + type: string + href: + description: Href is the URL of the link to be attached + type: string + type: object + type: array + routingKey: + description: |- + The secret's key that contains the PagerDuty integration key (when using + Events API v2). Either this field or `serviceKey` needs to be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + serviceKey: + description: |- + The secret's key that contains the PagerDuty service key (when using + integration type "Prometheus"). Either this field or `routingKey` needs to + be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + severity: + description: Severity of the incident. + type: string + source: + description: Unique location of the affected system. + type: string + url: + description: The URL to send requests to. + type: string + type: object + type: array + pushoverConfigs: + description: List of Pushover configurations. + items: + description: |- + PushoverConfig configures notifications via Pushover. + See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config + properties: + device: + description: The name of a device to send the notification to + type: string + expire: + description: |- + How long your notification will continue to be retried for, unless the user + acknowledges the notification. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + html: + description: Whether notification message is HTML or plain text. + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Notification message. + type: string + priority: + description: Priority, see https://pushover.net/api#priority + type: string + retry: + description: |- + How often the Pushover servers will send the same notification to the user. + Must be at least 30 seconds. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sound: + description: The name of one of the sounds supported by device clients to override the user's default sound choice + type: string + title: + description: Notification title. + type: string + token: + description: |- + The secret's key that contains the registered application's API token, see https://pushover.net/apps. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + Either `token` or `tokenFile` is required. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tokenFile: + description: |- + The token file that contains the registered application's API token, see https://pushover.net/apps. + Either `token` or `tokenFile` is required. + It requires Alertmanager >= v0.26.0. + type: string + ttl: + description: The time to live definition for the alert notification + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + url: + description: A supplementary URL shown alongside the message. + type: string + urlTitle: + description: A title for supplementary URL, otherwise just the URL is shown + type: string + userKey: + description: |- + The secret's key that contains the recipient user's user key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + Either `userKey` or `userKeyFile` is required. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + userKeyFile: + description: |- + The user key file that contains the recipient user's user key. + Either `userKey` or `userKeyFile` is required. + It requires Alertmanager >= v0.26.0. + type: string + type: object + type: array + rocketchatConfigs: + description: |- + List of RocketChat configurations. + It requires Alertmanager >= 0.28.0. + items: + description: |- + RocketChatConfig configures notifications via RocketChat. + It requires Alertmanager >= 0.28.0. + properties: + actions: + description: Actions to include in the message. + items: + description: RocketChatActionConfig defines actions for RocketChat messages. + properties: + msg: + description: The message to send when the button is clicked. + minLength: 1 + type: string + text: + description: The button text. + minLength: 1 + type: string + url: + description: The URL the button links to. + pattern: ^https?://.+$ + type: string + type: object + minItems: 1 + type: array + apiURL: + description: |- + The API URL for RocketChat. + Defaults to https://open.rocket.chat/ if not specified. + pattern: ^https?://.+$ + type: string + channel: + description: The channel to send alerts to. + minLength: 1 + type: string + color: + description: The message color. + minLength: 1 + type: string + emoji: + description: If provided, the avatar will be displayed as an emoji. + minLength: 1 + type: string + fields: + description: Additional fields for the message. + items: + description: RocketChatFieldConfig defines additional fields for RocketChat messages. + properties: + short: + description: Whether this field should be a short field. + type: boolean + title: + description: The title of this field. + minLength: 1 + type: string + value: + description: The value of this field, displayed underneath the title value. + minLength: 1 + type: string + type: object + minItems: 1 + type: array + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + iconURL: + description: Icon URL for the message. + pattern: ^https?://.+$ + type: string + imageURL: + description: Image URL for the message. + pattern: ^https?://.+$ + type: string + linkNames: + description: Whether to enable link names. + type: boolean + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + shortFields: + description: Whether to use short fields. + type: boolean + text: + description: The message text to send, it is optional because of attachments. + minLength: 1 + type: string + thumbURL: + description: Thumbnail URL for the message. + pattern: ^https?://.+$ + type: string + title: + description: The message title. + minLength: 1 + type: string + titleLink: + description: The title link for the message. + minLength: 1 + type: string + token: + description: The sender token. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tokenID: + description: The sender token ID. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - token + - tokenID + type: object + type: array + slackConfigs: + description: List of Slack configurations. + items: + description: |- + SlackConfig configures notifications via Slack. + See https://prometheus.io/docs/alerting/latest/configuration/#slack_config + properties: + actions: + description: A list of Slack actions that are sent with each notification. + items: + description: |- + SlackAction configures a single Slack action that is sent with each + notification. + See https://api.slack.com/docs/message-attachments#action_fields and + https://api.slack.com/docs/message-buttons for more information. + properties: + confirm: + description: |- + SlackConfirmationField protect users from destructive actions or + particularly distinguished decisions by asking them to confirm their button + click one more time. + See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields + for more information. + properties: + dismissText: + type: string + okText: + type: string + text: + minLength: 1 + type: string + title: + type: string + required: + - text + type: object + name: + type: string + style: + type: string + text: + minLength: 1 + type: string + type: + minLength: 1 + type: string + url: + type: string + value: + type: string + required: + - text + - type + type: object + type: array + apiURL: + description: |- + The secret's key that contains the Slack webhook URL. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + callbackId: + type: string + channel: + description: The channel or user to send notifications to. + type: string + color: + type: string + fallback: + type: string + fields: + description: A list of Slack fields that are sent with each notification. + items: + description: |- + SlackField configures a single Slack field that is sent with each notification. + Each field must contain a title, value, and optionally, a boolean value to indicate if the field + is short enough to be displayed next to other fields designated as short. + See https://api.slack.com/docs/message-attachments#fields for more information. + properties: + short: + type: boolean + title: + minLength: 1 + type: string + value: + minLength: 1 + type: string + required: + - title + - value + type: object + type: array + footer: + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + iconEmoji: + type: string + iconURL: + type: string + imageURL: + type: string + linkNames: + type: boolean + mrkdwnIn: + items: + type: string + type: array + pretext: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + shortFields: + type: boolean + text: + type: string + thumbURL: + type: string + title: + type: string + titleLink: + type: string + username: + type: string + type: object + type: array + snsConfigs: + description: List of SNS configurations + items: + description: |- + SNSConfig configures notifications via AWS SNS. + See https://prometheus.io/docs/alerting/latest/configuration/#sns_configs + properties: + apiURL: + description: |- + The SNS API URL i.e. https://sns.us-east-2.amazonaws.com. + If not specified, the SNS API URL from the SNS SDK will be used. + type: string + attributes: + additionalProperties: + type: string + description: SNS message attributes. + type: object + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: The message content of the SNS notification. + type: string + phoneNumber: + description: |- + Phone number if message is delivered via SMS in E.164 format. + If you don't specify this value, you must specify a value for the TopicARN or TargetARN. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sigv4: + description: Configures AWS's Signature Verification 4 signing process to sign requests. + properties: + accessKey: + description: |- + AccessKey is the AWS API key. If not specified, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: |- + SecretKey is the AWS API secret. If not specified, the environment + variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + subject: + description: Subject line when the message is delivered to email endpoints. + type: string + targetARN: + description: |- + The mobile platform endpoint ARN if message is delivered via mobile notifications. + If you don't specify this value, you must specify a value for the topic_arn or PhoneNumber. + type: string + topicARN: + description: |- + SNS topic ARN, i.e. arn:aws:sns:us-east-2:698519295917:My-Topic + If you don't specify this value, you must specify a value for the PhoneNumber or TargetARN. + type: string + type: object + type: array + telegramConfigs: + description: List of Telegram configurations. + items: + description: |- + TelegramConfig configures notifications via Telegram. + See https://prometheus.io/docs/alerting/latest/configuration/#telegram_config + properties: + apiURL: + description: |- + The Telegram API URL i.e. https://api.telegram.org. + If not specified, default API URL will be used. + type: string + botToken: + description: |- + Telegram bot token. It is mutually exclusive with `botTokenFile`. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + + Either `botToken` or `botTokenFile` is required. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + botTokenFile: + description: |- + File to read the Telegram bot token from. It is mutually exclusive with `botToken`. + Either `botToken` or `botTokenFile` is required. + + It requires Alertmanager >= v0.26.0. + type: string + chatID: + description: The Telegram chat ID. + format: int64 + type: integer + disableNotifications: + description: Disable telegram notifications + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Message template + type: string + messageThreadID: + description: |- + The Telegram Group Topic ID. + It requires Alertmanager >= 0.26.0. + format: int64 + type: integer + parseMode: + description: Parse mode for telegram message + enum: + - MarkdownV2 + - Markdown + - HTML + type: string + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + required: + - chatID + type: object + type: array + victoropsConfigs: + description: List of VictorOps configurations. + items: + description: |- + VictorOpsConfig configures notifications via VictorOps. + See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config + properties: + apiKey: + description: |- + The secret's key that contains the API key to use when talking to the VictorOps API. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiUrl: + description: The VictorOps API URL. + type: string + customFields: + description: Additional custom fields for notification. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entityDisplayName: + description: Contains summary of the alerted problem. + type: string + httpConfig: + description: The HTTP client's configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + messageType: + description: Describes the behavior of the alert (CRITICAL, WARNING, INFO). + type: string + monitoringTool: + description: The monitoring tool the state message is from. + type: string + routingKey: + description: A key used to map the alert to a team. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + stateMessage: + description: Contains long explanation of the alerted problem. + type: string + type: object + type: array + webexConfigs: + description: List of Webex configurations. + items: + description: |- + WebexConfig configures notification via Cisco Webex + See https://prometheus.io/docs/alerting/latest/configuration/#webex_config + properties: + apiURL: + description: |- + The Webex Teams API URL i.e. https://webexapis.com/v1/messages + Provide if different from the default API URL. + pattern: ^https?://.+$ + type: string + httpConfig: + description: |- + The HTTP client's configuration. + You must supply the bot token via the `httpConfig.authorization` field. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Message template + type: string + roomID: + description: ID of the Webex Teams room where to send the messages. + minLength: 1 + type: string + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + required: + - roomID + type: object + type: array + webhookConfigs: + description: List of webhook configurations. + items: + description: |- + WebhookConfig configures notifications via a generic receiver supporting the webhook payload. + See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + maxAlerts: + description: Maximum number of alerts to be sent per webhook message. When 0, all alerts are included. + format: int32 + minimum: 0 + type: integer + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + timeout: + description: |- + The maximum time to wait for a webhook request to complete, before failing the + request and allowing it to be retried. + It requires Alertmanager >= v0.28.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + url: + description: |- + The URL to send HTTP POST requests to. `urlSecret` takes precedence over + `url`. One of `urlSecret` and `url` should be defined. + type: string + urlSecret: + description: |- + The secret's key that contains the webhook URL to send HTTP requests to. + `urlSecret` takes precedence over `url`. One of `urlSecret` and `url` + should be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: array + wechatConfigs: + description: List of WeChat configurations. + items: + description: |- + WeChatConfig configures notifications via WeChat. + See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config + properties: + agentID: + type: string + apiSecret: + description: |- + The secret's key that contains the WeChat API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: The WeChat API URL. + type: string + corpID: + description: The corp id for authentication. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyURL: + description: |- + Optional proxy URL. + + If defined, this field takes precedence over `proxyUrl`. + type: string + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: API request data as defined by the WeChat API. + type: string + messageType: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + toParty: + type: string + toTag: + type: string + toUser: + type: string + type: object + type: array + required: + - name + type: object + type: array + route: + description: |- + The Alertmanager route definition for alerts matching the resource's + namespace. If present, it will be added to the generated Alertmanager + configuration as a first-level route. + properties: + activeTimeIntervals: + description: ActiveTimeIntervals is a list of MuteTimeInterval names when this route should be active. + items: + type: string + type: array + continue: + description: |- + Boolean indicating whether an alert should continue matching subsequent + sibling nodes. It will always be overridden to true for the first-level + route by the Prometheus operator. + type: boolean + groupBy: + description: |- + List of labels to group by. + Labels must not be repeated (unique list). + Special label "..." (aggregate by all possible labels), if provided, must be the only element in the list. + items: + type: string + type: array + groupInterval: + description: |- + How long to wait before sending an updated notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "5m" + type: string + groupWait: + description: |- + How long to wait before sending the initial notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "30s" + type: string + matchers: + description: |- + List of matchers that the alert's labels should match. For the first + level route, the operator removes any existing equality and regexp + matcher on the `namespace` label and adds a `namespace: ` matcher. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - = + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + muteTimeIntervals: + description: |- + Note: this comment applies to the field definition above but appears + below otherwise it gets included in the generated manifest. + CRD schema doesn't support self-referential types for now (see + https://github.com/kubernetes/kubernetes/issues/62872). We have to use + an alternative type to circumvent the limitation. The downside is that + the Kube API can't validate the data beyond the fact that it is a valid + JSON representation. + MuteTimeIntervals is a list of MuteTimeInterval names that will mute this route when matched, + items: + type: string + type: array + receiver: + description: |- + Name of the receiver for this route. If not empty, it should be listed in + the `receivers` field. + type: string + repeatInterval: + description: |- + How long to wait before repeating the last notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "4h" + type: string + routes: + description: Child routes. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/release/kubernetes/monitoring/setup/0alertmanagerCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0alertmanagerCustomResourceDefinition.yaml new file mode 100644 index 000000000..578e44681 --- /dev/null +++ b/release/kubernetes/monitoring/setup/0alertmanagerCustomResourceDefinition.yaml @@ -0,0 +1,9053 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: alertmanagers.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Alertmanager + listKind: AlertmanagerList + plural: alertmanagers + shortNames: + - am + singular: alertmanager + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The version of Alertmanager + jsonPath: .spec.version + name: Version + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Replicas + type: integer + - description: The number of ready replicas + jsonPath: .status.availableReplicas + name: Ready + type: integer + - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status + name: Reconciled + type: string + - jsonPath: .status.conditions[?(@.type == 'Available')].status + name: Available + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Whether the resource reconciliation is paused or not + jsonPath: .status.paused + name: Paused + priority: 1 + type: boolean + name: v1 + schema: + openAPIV3Schema: + description: |- + The `Alertmanager` custom resource definition (CRD) defines a desired [Alertmanager](https://prometheus.io/docs/alerting) setup to run in a Kubernetes cluster. It allows to specify many options such as the number of replicas, persistent storage and many more. + + For each `Alertmanager` resource, the Operator deploys a `StatefulSet` in the same namespace. When there are two or more configured replicas, the Operator runs the Alertmanager instances in high-availability mode. + + The resource defines via label and namespace selectors which `AlertmanagerConfig` objects should be associated to the deployed Alertmanager instances. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the Alertmanager cluster. More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + additionalArgs: + description: |- + AdditionalArgs allows setting additional arguments for the 'Alertmanager' container. + It is intended for e.g. activating hidden flags which are not supported by + the dedicated configuration options yet. The arguments are passed as-is to the + Alertmanager container which may cause issues if they are invalid or not supported + by the given Alertmanager version. + items: + description: Argument as part of the AdditionalArgs list. + properties: + name: + description: Name of the argument, e.g. "scrape.discovery-reload-interval". + minLength: 1 + type: string + value: + description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile) + type: string + required: + - name + type: object + type: array + additionalPeers: + description: AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster. + items: + type: string + type: array + affinity: + description: If specified, the pod's scheduling constraints. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + alertmanagerConfigMatcherStrategy: + description: |- + AlertmanagerConfigMatcherStrategy defines how AlertmanagerConfig objects + process incoming alerts. + properties: + type: + default: OnNamespace + description: |- + AlertmanagerConfigMatcherStrategyType defines the strategy used by + AlertmanagerConfig objects to match alerts in the routes and inhibition + rules. + + The default value is `OnNamespace`. + enum: + - OnNamespace + - OnNamespaceExceptForAlertmanagerNamespace + - None + type: string + type: object + alertmanagerConfigNamespaceSelector: + description: |- + Namespaces to be selected for AlertmanagerConfig discovery. If nil, only + check own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + alertmanagerConfigSelector: + description: AlertmanagerConfigs to be selected for to merge and configure Alertmanager with. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + alertmanagerConfiguration: + description: |- + alertmanagerConfiguration specifies the configuration of Alertmanager. + + If defined, it takes precedence over the `configSecret` field. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + properties: + global: + description: Defines the global parameters of the Alertmanager configuration. + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the Alertmanager + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + jira: + description: The default configuration for Jira. + properties: + apiURL: + description: |- + The default Jira API URL. + + It requires Alertmanager >= v0.28.0. + pattern: ^(http|https)://.+$ + type: string + type: object + opsGenieApiKey: + description: The default OpsGenie API Key. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + opsGenieApiUrl: + description: The default OpsGenie API URL. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + pagerdutyUrl: + description: The default Pagerduty URL. + type: string + resolveTimeout: + description: |- + ResolveTimeout is the default value used by alertmanager if the alert does + not include EndsAt, after this time passes it can declare the alert as resolved if it has not been updated. + This has no impact on alerts from Prometheus, as they always include EndsAt. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + rocketChat: + description: The default configuration for Rocket Chat. + properties: + apiURL: + description: |- + The default Rocket Chat API URL. + + It requires Alertmanager >= v0.28.0. + pattern: ^(http|https)://.+$ + type: string + token: + description: |- + The default Rocket Chat token. + + It requires Alertmanager >= v0.28.0. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tokenID: + description: |- + The default Rocket Chat Token ID. + + It requires Alertmanager >= v0.28.0. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + slackApiUrl: + description: The default Slack API URL. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + smtp: + description: Configures global SMTP parameters. + properties: + authIdentity: + description: SMTP Auth using PLAIN + type: string + authPassword: + description: SMTP Auth using LOGIN and PLAIN. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authSecret: + description: SMTP Auth using CRAM-MD5. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authUsername: + description: SMTP Auth using CRAM-MD5, LOGIN and PLAIN. If empty, Alertmanager doesn't authenticate to the SMTP server. + type: string + from: + description: The default SMTP From header field. + type: string + hello: + description: The default hostname to identify to the SMTP server. + type: string + requireTLS: + description: |- + The default SMTP TLS requirement. + Note that Go does not support unencrypted connections to remote SMTP endpoints. + type: boolean + smartHost: + description: The default SMTP smarthost used for sending emails. + properties: + host: + description: Defines the host's address, it can be a DNS name or a literal IP address. + minLength: 1 + type: string + port: + description: Defines the host's port, it can be a literal port number or a port name. + minLength: 1 + type: string + required: + - host + - port + type: object + tlsConfig: + description: The default TLS configuration for SMTP receivers + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + telegram: + description: The default Telegram config + properties: + apiURL: + description: |- + The default Telegram API URL. + + It requires Alertmanager >= v0.24.0. + pattern: ^(http|https)://.+$ + type: string + type: object + victorops: + description: The default configuration for VictorOps. + properties: + apiKey: + description: The default VictorOps API Key. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: The default VictorOps API URL. + pattern: ^(http|https)://.+$ + type: string + type: object + webex: + description: The default configuration for Jira. + properties: + apiURL: + description: |- + The default Webex API URL. + + It requires Alertmanager >= v0.25.0. + pattern: ^(http|https)://.+$ + type: string + type: object + wechat: + description: The default WeChat Config + properties: + apiCorpID: + description: The default WeChat API Corporate ID. + minLength: 1 + type: string + apiSecret: + description: The default WeChat API Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: |- + The default WeChat API URL. + The default value is "https://qyapi.weixin.qq.com/cgi-bin/" + pattern: ^(http|https)://.+$ + type: string + type: object + type: object + name: + description: |- + The name of the AlertmanagerConfig resource which is used to generate the Alertmanager configuration. + It must be defined in the same namespace as the Alertmanager object. + The operator will not enforce a `namespace` label for routes and inhibition rules. + minLength: 1 + type: string + templates: + description: Custom notification templates. + items: + description: SecretOrConfigMap allows to specify data as a Secret or ConfigMap. Fields are mutually exclusive. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: array + type: object + automountServiceAccountToken: + description: |- + AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod. + If the service account has `automountServiceAccountToken: true`, set the field to `false` to opt out of automounting API credentials. + type: boolean + baseImage: + description: |- + Base image that is used to deploy pods, without tag. + Deprecated: use 'image' instead. + type: string + clusterAdvertiseAddress: + description: |- + ClusterAdvertiseAddress is the explicit address to advertise in cluster. + Needs to be provided for non RFC1918 [1] (public) addresses. + [1] RFC1918: https://tools.ietf.org/html/rfc1918 + type: string + clusterGossipInterval: + description: Interval between gossip attempts. + pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + clusterLabel: + description: |- + Defines the identifier that uniquely identifies the Alertmanager cluster. + You should only set it when the Alertmanager cluster includes Alertmanager instances which are external to this Alertmanager resource. In practice, the addresses of the external instances are provided via the `.spec.additionalPeers` field. + type: string + clusterPeerTimeout: + description: Timeout for cluster peering. + pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + clusterPushpullInterval: + description: Interval between pushpull attempts. + pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + clusterTLS: + description: |- + Configures the mutual TLS configuration for the Alertmanager cluster's gossip protocol. + + It requires Alertmanager >= 0.24.0. + properties: + client: + description: Client-side configuration for mutual TLS. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + server: + description: Server-side configuration for mutual TLS. + properties: + cert: + description: |- + Secret or ConfigMap containing the TLS certificate for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `certFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: |- + Path to the TLS certificate file in the container for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `cert`. + type: string + cipherSuites: + description: |- + List of supported cipher suites for TLS versions up to TLS 1.2. + + If not defined, the Go default cipher suites are used. + Available cipher suites are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#pkg-constants + items: + type: string + type: array + client_ca: + description: |- + Secret or ConfigMap containing the CA certificate for client certificate + authentication to the server. + + It is mutually exclusive with `clientCAFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientAuthType: + description: |- + The server policy for client TLS authentication. + + For more detail on clientAuth options: + https://golang.org/pkg/crypto/tls/#ClientAuthType + type: string + clientCAFile: + description: |- + Path to the CA certificate file for client certificate authentication to + the server. + + It is mutually exclusive with `client_ca`. + type: string + curvePreferences: + description: |- + Elliptic curves that will be used in an ECDHE handshake, in preference + order. + + Available curves are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#CurveID + items: + type: string + type: array + keyFile: + description: |- + Path to the TLS private key file in the container for the web server. + + If defined, either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keySecret`. + type: string + keySecret: + description: |- + Secret containing the TLS private key for the web server. + + Either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keyFile`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: Maximum TLS version that is acceptable. + type: string + minVersion: + description: Minimum TLS version that is acceptable. + type: string + preferServerCipherSuites: + description: |- + Controls whether the server selects the client's most preferred cipher + suite, or the server's most preferred cipher suite. + + If true then the server's preference, as expressed in + the order of elements in cipherSuites, is used. + type: boolean + type: object + required: + - client + - server + type: object + configMaps: + description: |- + ConfigMaps is a list of ConfigMaps in the same namespace as the Alertmanager + object, which shall be mounted into the Alertmanager Pods. + Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-`. + The ConfigMaps are mounted into `/etc/alertmanager/configmaps/` in the 'alertmanager' container. + items: + type: string + type: array + configSecret: + description: |- + ConfigSecret is the name of a Kubernetes Secret in the same namespace as the + Alertmanager object, which contains the configuration for this Alertmanager + instance. If empty, it defaults to `alertmanager-`. + + The Alertmanager configuration should be available under the + `alertmanager.yaml` key. Additional keys from the original secret are + copied to the generated secret and mounted into the + `/etc/alertmanager/config` directory in the `alertmanager` container. + + If either the secret or the `alertmanager.yaml` key is missing, the + operator provisions a minimal Alertmanager configuration with one empty + receiver (effectively dropping alert notifications). + type: string + containers: + description: |- + Containers allows injecting additional containers. This is meant to + allow adding an authentication proxy to an Alertmanager pod. + Containers described here modify an operator generated container if they + share the same name and modifications are done via a strategic merge + patch. The current container names are: `alertmanager` and + `config-reloader`. Overriding containers is entirely outside the scope + of what the maintainers will support and by doing so, you accept that + this behaviour may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Defines the DNS configuration for the pods. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Name is required and must be unique. + minLength: 1 + type: string + value: + description: Value is optional. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + type: object + dnsPolicy: + description: Defines the DNS policy for the pods. + enum: + - ClusterFirstWithHostNet + - ClusterFirst + - Default + - None + type: string + enableFeatures: + description: |- + Enable access to Alertmanager feature flags. By default, no features are enabled. + Enabling features which are disabled by default is entirely outside the + scope of what the maintainers will support and by doing so, you accept + that this behaviour may break at any time without notice. + + It requires Alertmanager >= 0.27.0. + items: + type: string + type: array + enableServiceLinks: + description: Indicates whether information about services should be injected into pod's environment variables + type: boolean + externalUrl: + description: |- + The external URL the Alertmanager instances will be available under. This is + necessary to generate correct URLs. This is necessary if Alertmanager is not + served from root of a DNS name. + type: string + forceEnableClusterMode: + description: |- + ForceEnableClusterMode ensures Alertmanager does not deactivate the cluster mode when running with a single replica. + Use case is e.g. spanning an Alertmanager cluster across Kubernetes clusters with a single replica in each. + type: boolean + hostAliases: + description: Pods' hostAliases configuration + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + required: + - hostnames + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostUsers: + description: |- + HostUsers supports the user space in Kubernetes. + + More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/ + + The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled. + Starting Kubernetes 1.33, the feature is enabled by default. + type: boolean + image: + description: |- + Image if specified has precedence over baseImage, tag and sha + combinations. Specifying the version is still necessary to ensure the + Prometheus Operator knows what version of Alertmanager is being + configured. + type: string + imagePullPolicy: + description: |- + Image pull policy for the 'alertmanager', 'init-config-reloader' and 'config-reloader' containers. + See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details. + enum: + - "" + - Always + - Never + - IfNotPresent + type: string + imagePullSecrets: + description: |- + An optional list of references to secrets in the same namespace + to use for pulling prometheus and alertmanager images from registries + see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + InitContainers allows adding initContainers to the pod definition. Those can be used to e.g. + fetch secrets for injection into the Alertmanager configuration from external sources. Any + errors during the execution of an initContainer will lead to a restart of the Pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + InitContainers described here modify an operator + generated init containers if they share the same name and modifications are + done via a strategic merge patch. The current init container name is: + `init-config-reloader`. Overriding init containers is entirely outside the + scope of what the maintainers will support and by doing so, you accept that + this behaviour may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + limits: + description: Defines the limits command line flags when starting Alertmanager. + properties: + maxPerSilenceBytes: + description: |- + The maximum size of an individual silence as stored on disk. This corresponds to the Alertmanager's + `--silences.max-per-silence-bytes` flag. + It requires Alertmanager >= v0.28.0. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + maxSilences: + description: |- + The maximum number active and pending silences. This corresponds to the + Alertmanager's `--silences.max-silences` flag. + It requires Alertmanager >= v0.28.0. + format: int32 + minimum: 0 + type: integer + type: object + listenLocal: + description: |- + ListenLocal makes the Alertmanager server listen on loopback, so that it + does not bind against the Pod IP. Note this is only for the Alertmanager + UI, not the gossip communication. + type: boolean + logFormat: + description: Log format for Alertmanager to be configured with. + enum: + - "" + - logfmt + - json + type: string + logLevel: + description: Log level for Alertmanager to be configured with. + enum: + - "" + - debug + - info + - warn + - error + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created pod should be ready + without any of its container crashing for it to be considered available. + + If unset, pods will be considered available as soon as they are ready. + format: int32 + minimum: 0 + type: integer + nodeSelector: + additionalProperties: + type: string + description: Define which Nodes the Pods are scheduled on. + type: object + paused: + description: |- + If set to true all actions on the underlying managed objects are not + going to be performed, except for delete actions. + type: boolean + persistentVolumeClaimRetentionPolicy: + description: |- + The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet. + The default behavior is all PVCs are retained. + This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26. + It requires enabling the StatefulSetAutoDeletePVC feature gate. + properties: + whenDeleted: + description: |- + WhenDeleted specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is deleted. The default policy + of `Retain` causes PVCs to not be affected by StatefulSet deletion. The + `Delete` policy causes those PVCs to be deleted. + type: string + whenScaled: + description: |- + WhenScaled specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is scaled down. The default + policy of `Retain` causes PVCs to not be affected by a scaledown. The + `Delete` policy causes the associated PVCs for any excess pods above + the replica count to be deleted. + type: string + type: object + podMetadata: + description: |- + PodMetadata configures labels and annotations which are propagated to the Alertmanager pods. + + The following items are reserved and cannot be overridden: + * "alertmanager" label, set to the name of the Alertmanager instance. + * "app.kubernetes.io/instance" label, set to the name of the Alertmanager instance. + * "app.kubernetes.io/managed-by" label, set to "prometheus-operator". + * "app.kubernetes.io/name" label, set to "alertmanager". + * "app.kubernetes.io/version" label, set to the Alertmanager version. + * "kubectl.kubernetes.io/default-container" annotation, set to "alertmanager". + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + portName: + default: web + description: |- + Port name used for the pods and governing service. + Defaults to `web`. + type: string + priorityClassName: + description: Priority class assigned to the Pods + type: string + replicas: + description: |- + Size is the expected size of the alertmanager cluster. The controller will + eventually make the size of the running cluster equal to the expected + size. + format: int32 + type: integer + resources: + description: Define resources requests and limits for single Pods. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + retention: + default: 120h + description: |- + Time duration Alertmanager shall retain data for. Default is '120h', + and must match the regular expression `[0-9]+(ms|s|m|h)` (milliseconds seconds minutes hours). + pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + routePrefix: + description: |- + The route prefix Alertmanager registers HTTP handlers for. This is useful, + if using ExternalURL and a proxy is rewriting HTTP routes of a request, + and the actual ExternalURL is still true, but the server serves requests + under a different route prefix. For example for use with `kubectl proxy`. + type: string + secrets: + description: |- + Secrets is a list of Secrets in the same namespace as the Alertmanager + object, which shall be mounted into the Alertmanager Pods. + Each Secret is added to the StatefulSet definition as a volume named `secret-`. + The Secrets are mounted into `/etc/alertmanager/secrets/` in the 'alertmanager' container. + items: + type: string + type: array + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + This defaults to the default PodSecurityContext. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run the + Prometheus Pods. + type: string + serviceName: + description: |- + The name of the service name used by the underlying StatefulSet(s) as the governing service. + If defined, the Service must be created before the Alertmanager resource in the same namespace and it must define a selector that matches the pod labels. + If empty, the operator will create and manage a headless service named `alertmanager-operated` for Alermanager resources. + When deploying multiple Alertmanager resources in the same namespace, it is recommended to specify a different value for each. + See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details. + minLength: 1 + type: string + sha: + description: |- + SHA of Alertmanager container image to be deployed. Defaults to the value of `version`. + Similar to a tag, but the SHA explicitly deploys an immutable container image. + Version and Tag are ignored if SHA is set. + Deprecated: use 'image' instead. The image digest can be specified as part of the image URL. + type: string + storage: + description: |- + Storage is the definition of how storage will be used by the Alertmanager + instances. + properties: + disableMountSubPath: + description: 'Deprecated: subPath usage will be removed in a future release.' + type: boolean + emptyDir: + description: |- + EmptyDirVolumeSource to be used by the StatefulSet. + If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + EphemeralVolumeSource to be used by the StatefulSet. + This is a beta field in k8s 1.21 and GA in 1.15. + For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate. + More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + description: |- + Defines the PVC spec to be used by the Prometheus StatefulSets. + The easiest way to use a volume that cannot be automatically provisioned + is to use a label selector alongside manually created PersistentVolumes. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + spec: + description: |- + Defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + status: + description: 'Deprecated: this field is never set.' + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume operation. It can be in any of following states:\n - Pending\n Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\n the specified VolumeAttributesClass not existing.\n - InProgress\n InProgress indicates that the volume is being modified.\n - Infeasible\n Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass needs to be specified.\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: object + tag: + description: |- + Tag of Alertmanager container image to be deployed. Defaults to the value of `version`. + Version is ignored if Tag is set. + Deprecated: use 'image' instead. The image tag can be specified as part of the image URL. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down) which may lead to data corruption. + + Defaults to 120 seconds. + format: int64 + minimum: 0 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: If specified, the pod's topology spread constraints. + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + version: + description: Version the cluster should be on. + type: string + volumeMounts: + description: |- + VolumeMounts allows configuration of additional VolumeMounts on the output StatefulSet definition. + VolumeMounts specified will be appended to other VolumeMounts in the alertmanager container, + that are generated as a result of StorageSpec objects. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Volumes allows configuration of additional volumes on the output StatefulSet definition. + Volumes specified will be appended to other volumes that are generated as a result of + StorageSpec objects. + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + web: + description: Defines the web command line flags when starting Alertmanager. + properties: + getConcurrency: + description: |- + Maximum number of GET requests processed concurrently. This corresponds to the + Alertmanager's `--web.get-concurrency` flag. + format: int32 + type: integer + httpConfig: + description: Defines HTTP parameters for web server. + properties: + headers: + description: List of headers that can be added to HTTP responses. + properties: + contentSecurityPolicy: + description: |- + Set the Content-Security-Policy header to HTTP responses. + Unset if blank. + type: string + strictTransportSecurity: + description: |- + Set the Strict-Transport-Security header to HTTP responses. + Unset if blank. + Please make sure that you use this with care as this header might force + browsers to load Prometheus and the other applications hosted on the same + domain and subdomains over HTTPS. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + type: string + xContentTypeOptions: + description: |- + Set the X-Content-Type-Options header to HTTP responses. + Unset if blank. Accepted value is nosniff. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + enum: + - "" + - NoSniff + type: string + xFrameOptions: + description: |- + Set the X-Frame-Options header to HTTP responses. + Unset if blank. Accepted values are deny and sameorigin. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + enum: + - "" + - Deny + - SameOrigin + type: string + xXSSProtection: + description: |- + Set the X-XSS-Protection header to all responses. + Unset if blank. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + type: string + type: object + http2: + description: |- + Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS. + When TLSConfig is not configured, HTTP/2 will be disabled. + Whenever the value of the field changes, a rolling update will be triggered. + type: boolean + type: object + timeout: + description: |- + Timeout for HTTP requests. This corresponds to the Alertmanager's + `--web.timeout` flag. + format: int32 + type: integer + tlsConfig: + description: Defines the TLS parameters for HTTPS. + properties: + cert: + description: |- + Secret or ConfigMap containing the TLS certificate for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `certFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: |- + Path to the TLS certificate file in the container for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `cert`. + type: string + cipherSuites: + description: |- + List of supported cipher suites for TLS versions up to TLS 1.2. + + If not defined, the Go default cipher suites are used. + Available cipher suites are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#pkg-constants + items: + type: string + type: array + client_ca: + description: |- + Secret or ConfigMap containing the CA certificate for client certificate + authentication to the server. + + It is mutually exclusive with `clientCAFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientAuthType: + description: |- + The server policy for client TLS authentication. + + For more detail on clientAuth options: + https://golang.org/pkg/crypto/tls/#ClientAuthType + type: string + clientCAFile: + description: |- + Path to the CA certificate file for client certificate authentication to + the server. + + It is mutually exclusive with `client_ca`. + type: string + curvePreferences: + description: |- + Elliptic curves that will be used in an ECDHE handshake, in preference + order. + + Available curves are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#CurveID + items: + type: string + type: array + keyFile: + description: |- + Path to the TLS private key file in the container for the web server. + + If defined, either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keySecret`. + type: string + keySecret: + description: |- + Secret containing the TLS private key for the web server. + + Either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keyFile`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: Maximum TLS version that is acceptable. + type: string + minVersion: + description: Minimum TLS version that is acceptable. + type: string + preferServerCipherSuites: + description: |- + Controls whether the server selects the client's most preferred cipher + suite, or the server's most preferred cipher suite. + + If true then the server's preference, as expressed in + the order of elements in cipherSuites, is used. + type: boolean + type: object + type: object + type: object + status: + description: |- + Most recent observed status of the Alertmanager cluster. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this Alertmanager cluster. + format: int32 + type: integer + conditions: + description: The current state of the Alertmanager object. + items: + description: |- + Condition represents the state of the resources associated with the + Prometheus, Alertmanager or ThanosRuler resource. + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: Human-readable message indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the + instance. + format: int64 + type: integer + reason: + description: Reason for the condition's last transition. + type: string + status: + description: Status of the condition. + minLength: 1 + type: string + type: + description: Type of the condition being reported. + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + paused: + description: |- + Represents whether any actions on the underlying managed objects are + being performed. Only delete actions will be performed. + type: boolean + replicas: + description: |- + Total number of non-terminated pods targeted by this Alertmanager + object (their labels match the selector). + format: int32 + type: integer + selector: + description: The selector used to match the pods targeted by this Alertmanager object. + type: string + unavailableReplicas: + description: Total number of unavailable pods targeted by this Alertmanager object. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this Alertmanager + object that have the desired version spec. + format: int32 + type: integer + required: + - availableReplicas + - paused + - replicas + - unavailableReplicas + - updatedReplicas + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/release/kubernetes/monitoring/setup/0podmonitorCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0podmonitorCustomResourceDefinition.yaml new file mode 100644 index 000000000..e6bd63cab --- /dev/null +++ b/release/kubernetes/monitoring/setup/0podmonitorCustomResourceDefinition.yaml @@ -0,0 +1,1217 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: podmonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PodMonitor + listKind: PodMonitorList + plural: podmonitors + shortNames: + - pmon + singular: podmonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + The `PodMonitor` custom resource definition (CRD) defines how `Prometheus` and `PrometheusAgent` can scrape metrics from a group of pods. + Among other things, it allows to specify: + * The pods to scrape via label selectors. + * The container ports to scrape. + * Authentication credentials to use. + * Target and metric relabeling. + + `Prometheus` and `PrometheusAgent` objects select `PodMonitor` objects using label and namespace selectors. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of desired Pod selection for target discovery by Prometheus. + properties: + attachMetadata: + description: |- + `attachMetadata` defines additional metadata which is added to the + discovered targets. + + It requires Prometheus >= v2.35.0. + properties: + node: + description: |- + When set to true, Prometheus attaches node metadata to the discovered + targets. + + The Prometheus service account must have the `list` and `watch` + permissions on the `Nodes` objects. + type: boolean + type: object + bodySizeLimit: + description: |- + When defined, bodySizeLimit specifies a job level limit on the size + of uncompressed response body that will be accepted by Prometheus. + + It requires Prometheus >= v2.28.0. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + jobLabel: + description: |- + The label to use to retrieve the job name from. + `jobLabel` selects the label from the associated Kubernetes `Pod` + object which will be used as the `job` label for all metrics. + + For example if `jobLabel` is set to `foo` and the Kubernetes `Pod` + object is labeled with `foo: bar`, then Prometheus adds the `job="bar"` + label to all ingested metrics. + + If the value of this field is empty, the `job` label of the metrics + defaults to the namespace and name of the PodMonitor object (e.g. `/`). + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + namespaceSelector: + description: |- + `namespaceSelector` defines in which namespace(s) Prometheus should discover the pods. + By default, the pods are discovered in the same namespace as the `PodMonitor` object but it is possible to select pods across different/all namespaces. + properties: + any: + description: |- + Boolean describing whether all namespaces are selected in contrast to a + list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + nativeHistogramBucketLimit: + description: |- + If there are more than this many buckets in a native histogram, + buckets will be merged to stay within the limit. + It requires Prometheus >= v2.45.0. + format: int64 + type: integer + nativeHistogramMinBucketFactor: + anyOf: + - type: integer + - type: string + description: |- + If the growth factor of one bucket to the next is smaller than this, + buckets will be merged to increase the factor sufficiently. + It requires Prometheus >= v2.50.0. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + podMetricsEndpoints: + description: Defines how to scrape metrics from the selected pods. + items: + description: |- + PodMetricsEndpoint defines an endpoint serving Prometheus metrics to be scraped by + Prometheus. + properties: + authorization: + description: |- + `authorization` configures the Authorization header credentials to use when + scraping the target. + + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + `basicAuth` configures the Basic Authentication credentials to use when + scraping the target. + + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + `bearerTokenSecret` specifies a key of a Secret containing the bearer + token for scraping targets. The secret needs to be in the same namespace + as the PodMonitor object and readable by the Prometheus Operator. + + Deprecated: use `authorization` instead. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: '`enableHttp2` can be used to disable HTTP2 when scraping the target.' + type: boolean + filterRunning: + description: |- + When true, the pods which are not running (e.g. either in Failed or + Succeeded state) are dropped during the target discovery. + + If unset, the filtering is enabled. + + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + type: boolean + followRedirects: + description: |- + `followRedirects` defines whether the scrape requests should follow HTTP + 3xx redirects. + type: boolean + honorLabels: + description: |- + When true, `honorLabels` preserves the metric's labels when they collide + with the target's labels. + type: boolean + honorTimestamps: + description: |- + `honorTimestamps` controls whether Prometheus preserves the timestamps + when exposed by the target. + type: boolean + interval: + description: |- + Interval at which Prometheus scrapes the metrics from the target. + + If empty, Prometheus uses the global scrape interval. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: |- + `metricRelabelings` configures the relabeling rules to apply to the + samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + `oauth2` configures the OAuth2 settings to use when scraping the target. + + It requires Prometheus >= 2.27.0. + + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: '`params` define optional HTTP URL parameters.' + type: object + path: + description: |- + HTTP path from which to scrape for metrics. + + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + port: + description: |- + The `Pod` port name which exposes the endpoint. + + It takes precedence over the `portNumber` and `targetPort` fields. + type: string + portNumber: + description: The `Pod` port number which exposes the endpoint. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + relabelings: + description: |- + `relabelings` configures the relabeling rules to apply the target's + metadata labels. + + The Operator automatically adds relabelings for a few standard Kubernetes fields. + + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: |- + HTTP scheme to use for scraping. + + `http` and `https` are the expected values unless you rewrite the + `__scheme__` label via relabeling. + + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: |- + Timeout after which Prometheus considers the scrape to be failed. + + If empty, Prometheus uses the global scrape timeout unless it is less + than the target's scrape interval value in which the latter is used. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the target port of the `Pod` object behind the Service, the + port must be specified with container port property. + + Deprecated: use 'port' or 'portNumber' instead. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the target. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + trackTimestampsStaleness: + description: |- + `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + the metrics that have an explicit timestamp present in scraped data. + Has no effect if `honorTimestamps` is false. + + It requires Prometheus >= v2.48.0. + type: boolean + type: object + type: array + podTargetLabels: + description: |- + `podTargetLabels` defines the labels which are transferred from the + associated Kubernetes `Pod` object onto the ingested metrics. + items: + type: string + type: array + sampleLimit: + description: |- + `sampleLimit` defines a per-scrape limit on the number of scraped samples + that will be accepted. + format: int64 + type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + type: boolean + scrapeProtocols: + description: |- + `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + type: array + x-kubernetes-list-type: set + selector: + description: Label selector to select the Kubernetes `Pod` objects to scrape metrics from. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + selectorMechanism: + description: |- + Mechanism used to select the endpoints to scrape. + By default, the selection process relies on relabel configurations to filter the discovered targets. + Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters. + Which strategy is best for your use case needs to be carefully evaluated. + + It requires Prometheus >= v2.17.0. + enum: + - RelabelConfig + - RoleSelector + type: string + targetLimit: + description: |- + `targetLimit` defines a limit on the number of scraped targets that will + be accepted. + format: int64 + type: integer + required: + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/release/kubernetes/monitoring/setup/0probeCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0probeCustomResourceDefinition.yaml new file mode 100644 index 000000000..26b5a0ece --- /dev/null +++ b/release/kubernetes/monitoring/setup/0probeCustomResourceDefinition.yaml @@ -0,0 +1,1218 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: probes.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Probe + listKind: ProbeList + plural: probes + shortNames: + - prb + singular: probe + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + The `Probe` custom resource definition (CRD) defines how to scrape metrics from prober exporters such as the [blackbox exporter](https://github.com/prometheus/blackbox_exporter). + + The `Probe` resource needs 2 pieces of information: + * The list of probed addresses which can be defined statically or by discovering Kubernetes Ingress objects. + * The prober which exposes the availability of probed endpoints (over various protocols such HTTP, TCP, ICMP, ...) as Prometheus metrics. + + `Prometheus` and `PrometheusAgent` objects select `Probe` objects using label and namespace selectors. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of desired Ingress selection for target discovery by Prometheus. + properties: + authorization: + description: Authorization section for this endpoint + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth allow an endpoint to authenticate over basic authentication. + More info: https://prometheus.io/docs/operating/configuration/#endpoint + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + Secret to mount to read bearer token for scraping targets. The secret + needs to be in the same namespace as the probe and accessible by + the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + interval: + description: |- + Interval at which targets are probed using the configured prober. + If not specified Prometheus' global scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + jobName: + description: The job name assigned to scraped metrics by default. + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + metricRelabelings: + description: MetricRelabelConfigs to apply to samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + module: + description: |- + The module to use for probing specifying how to probe the target. + Example module configuring in the blackbox exporter: + https://github.com/prometheus/blackbox_exporter/blob/master/example.yml + type: string + nativeHistogramBucketLimit: + description: |- + If there are more than this many buckets in a native histogram, + buckets will be merged to stay within the limit. + It requires Prometheus >= v2.45.0. + format: int64 + type: integer + nativeHistogramMinBucketFactor: + anyOf: + - type: integer + - type: string + description: |- + If the growth factor of one bucket to the next is smaller than this, + buckets will be merged to increase the factor sufficiently. + It requires Prometheus >= v2.50.0. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + oauth2: + description: OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + description: |- + The list of HTTP query parameters for the scrape. + Please note that the `.spec.module` field takes precedence over the `module` parameter from this list when both are defined. + The module name must be added using Module under ProbeSpec. + items: + description: ProbeParam defines specification of extra parameters for a Probe. + properties: + name: + description: The parameter name + minLength: 1 + type: string + values: + description: The parameter values + items: + minLength: 1 + type: string + minItems: 1 + type: array + required: + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + prober: + description: |- + Specification for the prober to use for probing targets. + The prober.URL parameter is required. Targets cannot be probed if left empty. + properties: + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + path: + default: /probe + description: |- + Path to collect metrics from. + Defaults to `/probe`. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scheme: + description: |- + HTTP scheme to use for scraping. + `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + url: + description: Mandatory URL of the prober. + type: string + required: + - url + type: object + sampleLimit: + description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + format: int64 + type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + type: boolean + scrapeProtocols: + description: |- + `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + type: array + x-kubernetes-list-type: set + scrapeTimeout: + description: |- + Timeout for scraping metrics from the Prometheus exporter. + If not specified, the Prometheus global scrape timeout is used. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetLimit: + description: TargetLimit defines a limit on the number of scraped targets that will be accepted. + format: int64 + type: integer + targets: + description: Targets defines a set of static or dynamically discovered targets to probe. + properties: + ingress: + description: |- + ingress defines the Ingress objects to probe and the relabeling + configuration. + If `staticConfig` is also defined, `staticConfig` takes precedence. + properties: + namespaceSelector: + description: From which namespaces to select Ingress objects. + properties: + any: + description: |- + Boolean describing whether all namespaces are selected in contrast to a + list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + relabelingConfigs: + description: |- + RelabelConfigs to apply to the label set of the target before it gets + scraped. + The original ingress address is available via the + `__tmp_prometheus_ingress_address` label. It can be used to customize the + probed URL. + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + selector: + description: Selector to select the Ingress objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + staticConfig: + description: |- + staticConfig defines the static list of targets to probe and the + relabeling configuration. + If `ingress` is also defined, `staticConfig` takes precedence. + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config. + properties: + labels: + additionalProperties: + type: string + description: Labels assigned to all metrics scraped from the targets. + type: object + relabelingConfigs: + description: |- + RelabelConfigs to apply to the label set of the targets before it gets + scraped. + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + static: + description: The list of hosts to probe. + items: + type: string + type: array + type: object + type: object + tlsConfig: + description: TLS configuration to use when scraping the endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/release/kubernetes/monitoring/setup/0prometheusCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0prometheusCustomResourceDefinition.yaml new file mode 100644 index 000000000..8c7656058 --- /dev/null +++ b/release/kubernetes/monitoring/setup/0prometheusCustomResourceDefinition.yaml @@ -0,0 +1,12597 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: prometheuses.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Prometheus + listKind: PrometheusList + plural: prometheuses + shortNames: + - prom + singular: prometheus + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The version of Prometheus + jsonPath: .spec.version + name: Version + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Desired + type: integer + - description: The number of ready replicas + jsonPath: .status.availableReplicas + name: Ready + type: integer + - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status + name: Reconciled + type: string + - jsonPath: .status.conditions[?(@.type == 'Available')].status + name: Available + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Whether the resource reconciliation is paused or not + jsonPath: .status.paused + name: Paused + priority: 1 + type: boolean + name: v1 + schema: + openAPIV3Schema: + description: |- + The `Prometheus` custom resource definition (CRD) defines a desired [Prometheus](https://prometheus.io/docs/prometheus) setup to run in a Kubernetes cluster. It allows to specify many options such as the number of replicas, persistent storage, and Alertmanagers where firing alerts should be sent and many more. + + For each `Prometheus` resource, the Operator deploys one or several `StatefulSet` objects in the same namespace. The number of StatefulSets is equal to the number of shards which is 1 by default. + + The resource defines via label and namespace selectors which `ServiceMonitor`, `PodMonitor`, `Probe` and `PrometheusRule` objects should be associated to the deployed Prometheus instances. + + The Operator continuously reconciles the scrape and rules configuration and a sidecar container running in the Prometheus pods triggers a reload of the configuration when needed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the Prometheus cluster. More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + additionalAlertManagerConfigs: + description: |- + AdditionalAlertManagerConfigs specifies a key of a Secret containing + additional Prometheus Alertmanager configurations. The Alertmanager + configurations are appended to the configuration generated by the + Prometheus Operator. They must be formatted according to the official + Prometheus documentation: + + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config + + The user is responsible for making sure that the configurations are valid + + Note that using this feature may expose the possibility to break + upgrades of Prometheus. It is advised to review Prometheus release notes + to ensure that no incompatible AlertManager configs are going to break + Prometheus after the upgrade. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + additionalAlertRelabelConfigs: + description: |- + AdditionalAlertRelabelConfigs specifies a key of a Secret containing + additional Prometheus alert relabel configurations. The alert relabel + configurations are appended to the configuration generated by the + Prometheus Operator. They must be formatted according to the official + Prometheus documentation: + + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs + + The user is responsible for making sure that the configurations are valid + + Note that using this feature may expose the possibility to break + upgrades of Prometheus. It is advised to review Prometheus release notes + to ensure that no incompatible alert relabel configs are going to break + Prometheus after the upgrade. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + additionalArgs: + description: |- + AdditionalArgs allows setting additional arguments for the 'prometheus' container. + + It is intended for e.g. activating hidden flags which are not supported by + the dedicated configuration options yet. The arguments are passed as-is to the + Prometheus container which may cause issues if they are invalid or not supported + by the given Prometheus version. + + In case of an argument conflict (e.g. an argument which is already set by the + operator itself) or when providing an invalid argument, the reconciliation will + fail and an error will be logged. + items: + description: Argument as part of the AdditionalArgs list. + properties: + name: + description: Name of the argument, e.g. "scrape.discovery-reload-interval". + minLength: 1 + type: string + value: + description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile) + type: string + required: + - name + type: object + type: array + additionalScrapeConfigs: + description: |- + AdditionalScrapeConfigs allows specifying a key of a Secret containing + additional Prometheus scrape configurations. Scrape configurations + specified are appended to the configurations generated by the Prometheus + Operator. Job configurations specified must have the form as specified + in the official Prometheus documentation: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. + As scrape configs are appended, the user is responsible to make sure it + is valid. Note that using this feature may expose the possibility to + break upgrades of Prometheus. It is advised to review Prometheus release + notes to ensure that no incompatible scrape configs are going to break + Prometheus after the upgrade. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + affinity: + description: Defines the Pods' affinity scheduling rules if specified. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + alerting: + description: Defines the settings related to Alertmanager. + properties: + alertmanagers: + description: Alertmanager endpoints where Prometheus should send alerts to. + items: + description: |- + AlertmanagerEndpoints defines a selection of a single Endpoints object + containing Alertmanager IPs to fire alerts against. + properties: + alertRelabelings: + description: |- + Relabeling configs applied before sending alerts to a specific Alertmanager. + It requires Prometheus >= v2.51.0. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + apiVersion: + description: |- + Version of the Alertmanager API that Prometheus uses to send alerts. + It can be "V1" or "V2". + The field has no effect for Prometheus >= v3.0.0 because only the v2 API is supported. + enum: + - v1 + - V1 + - v2 + - V2 + type: string + authorization: + description: |- + Authorization section for Alertmanager. + + Cannot be set at the same time as `basicAuth`, `bearerTokenFile` or `sigv4`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth configuration for Alertmanager. + + Cannot be set at the same time as `bearerTokenFile`, `authorization` or `sigv4`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + description: |- + File to read bearer token for Alertmanager. + + Cannot be set at the same time as `basicAuth`, `authorization`, or `sigv4`. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + enableHttp2: + description: Whether to enable HTTP2. + type: boolean + name: + description: Name of the Endpoints object in the namespace. + minLength: 1 + type: string + namespace: + description: |- + Namespace of the Endpoints object. + + If not set, the object will be discovered in the namespace of the + Prometheus object. + minLength: 1 + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + pathPrefix: + description: Prefix for the HTTP path alerts are pushed to. + type: string + port: + anyOf: + - type: integer + - type: string + description: Port on which the Alertmanager API is exposed. + x-kubernetes-int-or-string: true + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + relabelings: + description: Relabel configuration applied to the discovered Alertmanagers. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: Scheme to use when firing alerts. + type: string + sigv4: + description: |- + Sigv4 allows to configures AWS's Signature Verification 4 for the URL. + + It requires Prometheus >= v2.48.0. + + Cannot be set at the same time as `basicAuth`, `bearerTokenFile` or `authorization`. + properties: + accessKey: + description: |- + AccessKey is the AWS API key. If not specified, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: |- + SecretKey is the AWS API secret. If not specified, the environment + variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + timeout: + description: Timeout is a per-target Alertmanager timeout when pushing alerts. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS Config to use for Alertmanager. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - name + - port + type: object + type: array + required: + - alertmanagers + type: object + allowOverlappingBlocks: + description: |- + AllowOverlappingBlocks enables vertical compaction and vertical query + merge in Prometheus. + + Deprecated: this flag has no effect for Prometheus >= 2.39.0 where overlapping blocks are enabled by default. + type: boolean + apiserverConfig: + description: |- + APIServerConfig allows specifying a host and auth methods to access the + Kuberntees API server. + If null, Prometheus is assumed to run inside of the cluster: it will + discover the API servers automatically and use the Pod's CA certificate + and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. + properties: + authorization: + description: |- + Authorization section for the API server. + + Cannot be set at the same time as `basicAuth`, `bearerToken`, or + `bearerTokenFile`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth configuration for the API server. + + Cannot be set at the same time as `authorization`, `bearerToken`, or + `bearerTokenFile`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File to read bearer token for accessing apiserver. + + Cannot be set at the same time as `basicAuth`, `authorization`, or `bearerToken`. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + host: + description: |- + Kubernetes API address consisting of a hostname or IP address followed + by an optional port number. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS Config to use for the API server. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - host + type: object + arbitraryFSAccessThroughSMs: + description: |- + When true, ServiceMonitor, PodMonitor and Probe object are forbidden to + reference arbitrary files on the file system of the 'prometheus' + container. + When a ServiceMonitor's endpoint specifies a `bearerTokenFile` value + (e.g. '/var/run/secrets/kubernetes.io/serviceaccount/token'), a + malicious target can get access to the Prometheus service account's + token in the Prometheus' scrape request. Setting + `spec.arbitraryFSAccessThroughSM` to 'true' would prevent the attack. + Users should instead provide the credentials using the + `spec.bearerTokenSecret` field. + properties: + deny: + type: boolean + type: object + automountServiceAccountToken: + description: |- + AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod. + If the field isn't set, the operator mounts the service account token by default. + + **Warning:** be aware that by default, Prometheus requires the service account token for Kubernetes service discovery. + It is possible to use strategic merge patch to project the service account token into the 'prometheus' container. + type: boolean + baseImage: + description: 'Deprecated: use ''spec.image'' instead.' + type: string + bodySizeLimit: + description: |- + BodySizeLimit defines per-scrape on response body size. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedBodySizeLimit. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + configMaps: + description: |- + ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus + object, which shall be mounted into the Prometheus Pods. + Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-`. + The ConfigMaps are mounted into /etc/prometheus/configmaps/ in the 'prometheus' container. + items: + type: string + type: array + containers: + description: |- + Containers allows injecting additional containers or modifying operator + generated containers. This can be used to allow adding an authentication + proxy to the Pods or to change the behavior of an operator generated + container. Containers described here modify an operator generated + container if they share the same name and modifications are done via a + strategic merge patch. + + The names of containers managed by the operator are: + * `prometheus` + * `config-reloader` + * `thanos-sidecar` + + Overriding containers is entirely outside the scope of what the + maintainers will support and by doing so, you accept that this behaviour + may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native + histogram with custom buckets. + + It requires Prometheus >= v3.4.0. + type: boolean + disableCompaction: + description: |- + When true, the Prometheus compaction is disabled. + When `spec.thanos.objectStorageConfig` or `spec.objectStorageConfigFile` are defined, the operator automatically + disables block compaction to avoid race conditions during block uploads (as the Thanos documentation recommends). + type: boolean + dnsConfig: + description: Defines the DNS configuration for the pods. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Name is required and must be unique. + minLength: 1 + type: string + value: + description: Value is optional. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + type: object + dnsPolicy: + description: Defines the DNS policy for the pods. + enum: + - ClusterFirstWithHostNet + - ClusterFirst + - Default + - None + type: string + enableAdminAPI: + description: |- + Enables access to the Prometheus web admin API. + + WARNING: Enabling the admin APIs enables mutating endpoints, to delete data, + shutdown Prometheus, and more. Enabling this should be done with care and the + user is advised to add additional authentication authorization via a proxy to + ensure only clients authorized to perform these actions can do so. + + For more information: + https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis + type: boolean + enableFeatures: + description: |- + Enable access to Prometheus feature flags. By default, no features are enabled. + + Enabling features which are disabled by default is entirely outside the + scope of what the maintainers will support and by doing so, you accept + that this behaviour may break at any time without notice. + + For more information see https://prometheus.io/docs/prometheus/latest/feature_flags/ + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + enableOTLPReceiver: + description: |- + Enable Prometheus to be used as a receiver for the OTLP Metrics protocol. + + Note that the OTLP receiver endpoint is automatically enabled if `.spec.otlpConfig` is defined. + + It requires Prometheus >= v2.47.0. + type: boolean + enableRemoteWriteReceiver: + description: |- + Enable Prometheus to be used as a receiver for the Prometheus remote + write protocol. + + WARNING: This is not considered an efficient way of ingesting samples. + Use it with caution for specific low-volume use cases. + It is not suitable for replacing the ingestion via scraping and turning + Prometheus into a push-based metrics collection system. + For more information see https://prometheus.io/docs/prometheus/latest/querying/api/#remote-write-receiver + + It requires Prometheus >= v2.33.0. + type: boolean + enableServiceLinks: + description: Indicates whether information about services should be injected into pod's environment variables + type: boolean + enforcedBodySizeLimit: + description: |- + When defined, enforcedBodySizeLimit specifies a global limit on the size + of uncompressed response body that will be accepted by Prometheus. + Targets responding with a body larger than this many bytes will cause + the scrape to fail. + + It requires Prometheus >= v2.28.0. + + When both `enforcedBodySizeLimit` and `bodySizeLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined bodySizeLimit value will inherit the global bodySizeLimit value (Prometheus >= 2.45.0) or the enforcedBodySizeLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedBodySizeLimit` is greater than the `bodySizeLimit`, the `bodySizeLimit` will be set to `enforcedBodySizeLimit`. + * Scrape objects with a bodySizeLimit value less than or equal to enforcedBodySizeLimit keep their specific value. + * Scrape objects with a bodySizeLimit value greater than enforcedBodySizeLimit are set to enforcedBodySizeLimit. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + enforcedKeepDroppedTargets: + description: |- + When defined, enforcedKeepDroppedTargets specifies a global limit on the number of targets + dropped by relabeling that will be kept in memory. The value overrides + any `spec.keepDroppedTargets` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.keepDroppedTargets` is + greater than zero and less than `spec.enforcedKeepDroppedTargets`. + + It requires Prometheus >= v2.47.0. + + When both `enforcedKeepDroppedTargets` and `keepDroppedTargets` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined keepDroppedTargets value will inherit the global keepDroppedTargets value (Prometheus >= 2.45.0) or the enforcedKeepDroppedTargets value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedKeepDroppedTargets` is greater than the `keepDroppedTargets`, the `keepDroppedTargets` will be set to `enforcedKeepDroppedTargets`. + * Scrape objects with a keepDroppedTargets value less than or equal to enforcedKeepDroppedTargets keep their specific value. + * Scrape objects with a keepDroppedTargets value greater than enforcedKeepDroppedTargets are set to enforcedKeepDroppedTargets. + format: int64 + type: integer + enforcedLabelLimit: + description: |- + When defined, enforcedLabelLimit specifies a global limit on the number + of labels per sample. The value overrides any `spec.labelLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelLimit` is + greater than zero and less than `spec.enforcedLabelLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelLimit` and `labelLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelLimit value will inherit the global labelLimit value (Prometheus >= 2.45.0) or the enforcedLabelLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelLimit` is greater than the `labelLimit`, the `labelLimit` will be set to `enforcedLabelLimit`. + * Scrape objects with a labelLimit value less than or equal to enforcedLabelLimit keep their specific value. + * Scrape objects with a labelLimit value greater than enforcedLabelLimit are set to enforcedLabelLimit. + format: int64 + type: integer + enforcedLabelNameLengthLimit: + description: |- + When defined, enforcedLabelNameLengthLimit specifies a global limit on the length + of labels name per sample. The value overrides any `spec.labelNameLengthLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelNameLengthLimit` is + greater than zero and less than `spec.enforcedLabelNameLengthLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelNameLengthLimit` and `labelNameLengthLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelNameLengthLimit value will inherit the global labelNameLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelNameLengthLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelNameLengthLimit` is greater than the `labelNameLengthLimit`, the `labelNameLengthLimit` will be set to `enforcedLabelNameLengthLimit`. + * Scrape objects with a labelNameLengthLimit value less than or equal to enforcedLabelNameLengthLimit keep their specific value. + * Scrape objects with a labelNameLengthLimit value greater than enforcedLabelNameLengthLimit are set to enforcedLabelNameLengthLimit. + format: int64 + type: integer + enforcedLabelValueLengthLimit: + description: |- + When not null, enforcedLabelValueLengthLimit defines a global limit on the length + of labels value per sample. The value overrides any `spec.labelValueLengthLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelValueLengthLimit` is + greater than zero and less than `spec.enforcedLabelValueLengthLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelValueLengthLimit` and `labelValueLengthLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelValueLengthLimit value will inherit the global labelValueLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelValueLengthLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelValueLengthLimit` is greater than the `labelValueLengthLimit`, the `labelValueLengthLimit` will be set to `enforcedLabelValueLengthLimit`. + * Scrape objects with a labelValueLengthLimit value less than or equal to enforcedLabelValueLengthLimit keep their specific value. + * Scrape objects with a labelValueLengthLimit value greater than enforcedLabelValueLengthLimit are set to enforcedLabelValueLengthLimit. + format: int64 + type: integer + enforcedNamespaceLabel: + description: |- + When not empty, a label will be added to: + + 1. All metrics scraped from `ServiceMonitor`, `PodMonitor`, `Probe` and `ScrapeConfig` objects. + 2. All metrics generated from recording rules defined in `PrometheusRule` objects. + 3. All alerts generated from alerting rules defined in `PrometheusRule` objects. + 4. All vector selectors of PromQL expressions defined in `PrometheusRule` objects. + + The label will not added for objects referenced in `spec.excludedFromEnforcement`. + + The label's name is this field's value. + The label's value is the namespace of the `ServiceMonitor`, + `PodMonitor`, `Probe`, `PrometheusRule` or `ScrapeConfig` object. + type: string + enforcedSampleLimit: + description: |- + When defined, enforcedSampleLimit specifies a global limit on the number + of scraped samples that will be accepted. This overrides any + `spec.sampleLimit` set by ServiceMonitor, PodMonitor, Probe objects + unless `spec.sampleLimit` is greater than zero and less than + `spec.enforcedSampleLimit`. + + It is meant to be used by admins to keep the overall number of + samples/series under a desired limit. + + When both `enforcedSampleLimit` and `sampleLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined sampleLimit value will inherit the global sampleLimit value (Prometheus >= 2.45.0) or the enforcedSampleLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedSampleLimit` is greater than the `sampleLimit`, the `sampleLimit` will be set to `enforcedSampleLimit`. + * Scrape objects with a sampleLimit value less than or equal to enforcedSampleLimit keep their specific value. + * Scrape objects with a sampleLimit value greater than enforcedSampleLimit are set to enforcedSampleLimit. + format: int64 + type: integer + enforcedTargetLimit: + description: |- + When defined, enforcedTargetLimit specifies a global limit on the number + of scraped targets. The value overrides any `spec.targetLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.targetLimit` is + greater than zero and less than `spec.enforcedTargetLimit`. + + It is meant to be used by admins to to keep the overall number of + targets under a desired limit. + + When both `enforcedTargetLimit` and `targetLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined targetLimit value will inherit the global targetLimit value (Prometheus >= 2.45.0) or the enforcedTargetLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedTargetLimit` is greater than the `targetLimit`, the `targetLimit` will be set to `enforcedTargetLimit`. + * Scrape objects with a targetLimit value less than or equal to enforcedTargetLimit keep their specific value. + * Scrape objects with a targetLimit value greater than enforcedTargetLimit are set to enforcedTargetLimit. + format: int64 + type: integer + evaluationInterval: + default: 30s + description: |- + Interval between rule evaluations. + Default: "30s" + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + excludedFromEnforcement: + description: |- + List of references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects + to be excluded from enforcing a namespace label of origin. + + It is only applicable if `spec.enforcedNamespaceLabel` set to true. + items: + description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object. + properties: + group: + default: monitoring.coreos.com + description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com` + enum: + - monitoring.coreos.com + type: string + name: + description: Name of the referent. When not set, all resources in the namespace are matched. + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + minLength: 1 + type: string + resource: + description: Resource of the referent. + enum: + - prometheusrules + - servicemonitors + - podmonitors + - probes + - scrapeconfigs + type: string + required: + - namespace + - resource + type: object + type: array + exemplars: + description: |- + Exemplars related settings that are runtime reloadable. + It requires to enable the `exemplar-storage` feature flag to be effective. + properties: + maxSize: + description: |- + Maximum number of exemplars stored in memory for all series. + + exemplar-storage itself must be enabled using the `spec.enableFeature` + option for exemplars to be scraped in the first place. + + If not set, Prometheus uses its default value. A value of zero or less + than zero disables the storage. + format: int64 + type: integer + type: object + externalLabels: + additionalProperties: + type: string + description: |- + The labels to add to any time series or alerts when communicating with + external systems (federation, remote storage, Alertmanager). + Labels defined by `spec.replicaExternalLabelName` and + `spec.prometheusExternalLabelName` take precedence over this list. + type: object + externalUrl: + description: |- + The external URL under which the Prometheus service is externally + available. This is necessary to generate correct URLs (for instance if + Prometheus is accessible behind an Ingress resource). + type: string + hostAliases: + description: |- + Optional list of hosts and IPs that will be injected into the Pod's + hosts file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + required: + - hostnames + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostNetwork: + description: |- + Use the host's network namespace if true. + + Make sure to understand the security implications if you want to enable + it (https://kubernetes.io/docs/concepts/configuration/overview/ ). + + When hostNetwork is enabled, this will set the DNS policy to + `ClusterFirstWithHostNet` automatically (unless `.spec.DNSPolicy` is set + to a different value). + type: boolean + hostUsers: + description: |- + HostUsers supports the user space in Kubernetes. + + More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/ + + The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled. + Starting Kubernetes 1.33, the feature is enabled by default. + type: boolean + ignoreNamespaceSelectors: + description: |- + When true, `spec.namespaceSelector` from all PodMonitor, ServiceMonitor + and Probe objects will be ignored. They will only discover targets + within the namespace of the PodMonitor, ServiceMonitor and Probe + object. + type: boolean + image: + description: |- + Container image name for Prometheus. If specified, it takes precedence + over the `spec.baseImage`, `spec.tag` and `spec.sha` fields. + + Specifying `spec.version` is still necessary to ensure the Prometheus + Operator knows which version of Prometheus is being configured. + + If neither `spec.image` nor `spec.baseImage` are defined, the operator + will use the latest upstream version of Prometheus available at the time + when the operator was released. + type: string + imagePullPolicy: + description: |- + Image pull policy for the 'prometheus', 'init-config-reloader' and 'config-reloader' containers. + See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details. + enum: + - "" + - Always + - Never + - IfNotPresent + type: string + imagePullSecrets: + description: |- + An optional list of references to Secrets in the same namespace + to use for pulling images from registries. + See http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + InitContainers allows injecting initContainers to the Pod definition. Those + can be used to e.g. fetch secrets for injection into the Prometheus + configuration from external sources. Any errors during the execution of + an initContainer will lead to a restart of the Pod. More info: + https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + InitContainers described here modify an operator generated init + containers if they share the same name and modifications are done via a + strategic merge patch. + + The names of init container name managed by the operator are: + * `init-config-reloader`. + + Overriding init containers is entirely outside the scope of what the + maintainers will support and by doing so, you accept that this behaviour + may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedKeepDroppedTargets. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelLimit. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelNameLengthLimit. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelValueLengthLimit. + format: int64 + type: integer + listenLocal: + description: |- + When true, the Prometheus server listens on the loopback address + instead of the Pod IP's address. + type: boolean + logFormat: + description: Log format for Log level for Prometheus and the config-reloader sidecar. + enum: + - "" + - logfmt + - json + type: string + logLevel: + description: Log level for Prometheus and the config-reloader sidecar. + enum: + - "" + - debug + - info + - warn + - error + type: string + maximumStartupDurationSeconds: + description: |- + Defines the maximum time that the `prometheus` container's startup probe will wait before being considered failed. The startup probe will return success after the WAL replay is complete. + If set, the value should be greater than 60 (seconds). Otherwise it will be equal to 600 seconds (15 minutes). + format: int32 + minimum: 60 + type: integer + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created Pod should be ready + without any of its container crashing for it to be considered available. + + If unset, pods will be considered available as soon as they are ready. + format: int32 + minimum: 0 + type: integer + nameEscapingScheme: + description: |- + Specifies the character escaping scheme that will be requested when scraping + for metric and label names that do not conform to the legacy Prometheus + character set. + + It requires Prometheus >= v3.4.0. + enum: + - AllowUTF8 + - Underscores + - Dots + - Values + type: string + nameValidationScheme: + description: |- + Specifies the validation scheme for metric and label names. + + It requires Prometheus >= v2.55.0. + enum: + - UTF8 + - Legacy + type: string + nodeSelector: + additionalProperties: + type: string + description: Defines on which Nodes the Pods are scheduled. + type: object + otlp: + description: |- + Settings related to the OTLP receiver feature. + It requires Prometheus >= v2.55.0. + properties: + convertHistogramsToNHCB: + description: |- + Configures optional translation of OTLP explicit bucket histograms into native histograms with custom buckets. + It requires Prometheus >= v3.4.0. + type: boolean + ignoreResourceAttributes: + description: |- + List of OpenTelemetry resource attributes to ignore when `promoteAllResourceAttributes` is true. + + It requires `promoteAllResourceAttributes` to be true. + It requires Prometheus >= v3.5.0. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + keepIdentifyingResourceAttributes: + description: |- + Enables adding `service.name`, `service.namespace` and `service.instance.id` + resource attributes to the `target_info` metric, on top of converting them into the `instance` and `job` labels. + + It requires Prometheus >= v3.1.0. + type: boolean + promoteAllResourceAttributes: + description: |- + Promote all resource attributes to metric labels except the ones defined in `ignoreResourceAttributes`. + + Cannot be true when `promoteResourceAttributes` is defined. + It requires Prometheus >= v3.5.0. + type: boolean + promoteResourceAttributes: + description: |- + List of OpenTelemetry Attributes that should be promoted to metric labels, defaults to none. + Cannot be defined when `promoteAllResourceAttributes` is true. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + translationStrategy: + description: |- + Configures how the OTLP receiver endpoint translates the incoming metrics. + + It requires Prometheus >= v3.0.0. + enum: + - NoUTF8EscapingWithSuffixes + - UnderscoreEscapingWithSuffixes + - NoTranslation + type: string + type: object + overrideHonorLabels: + description: |- + When true, Prometheus resolves label conflicts by renaming the labels in the scraped data + to “exported_” for all targets created from ServiceMonitor, PodMonitor and + ScrapeConfig objects. Otherwise the HonorLabels field of the service or pod monitor applies. + In practice,`overrideHonorLaels:true` enforces `honorLabels:false` + for all ServiceMonitor, PodMonitor and ScrapeConfig objects. + type: boolean + overrideHonorTimestamps: + description: |- + When true, Prometheus ignores the timestamps for all the targets created + from service and pod monitors. + Otherwise the HonorTimestamps field of the service or pod monitor applies. + type: boolean + paused: + description: |- + When a Prometheus deployment is paused, no actions except for deletion + will be performed on the underlying objects. + type: boolean + persistentVolumeClaimRetentionPolicy: + description: |- + The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet. + The default behavior is all PVCs are retained. + This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26. + It requires enabling the StatefulSetAutoDeletePVC feature gate. + properties: + whenDeleted: + description: |- + WhenDeleted specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is deleted. The default policy + of `Retain` causes PVCs to not be affected by StatefulSet deletion. The + `Delete` policy causes those PVCs to be deleted. + type: string + whenScaled: + description: |- + WhenScaled specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is scaled down. The default + policy of `Retain` causes PVCs to not be affected by a scaledown. The + `Delete` policy causes the associated PVCs for any excess pods above + the replica count to be deleted. + type: string + type: object + podMetadata: + description: |- + PodMetadata configures labels and annotations which are propagated to the Prometheus pods. + + The following items are reserved and cannot be overridden: + * "prometheus" label, set to the name of the Prometheus object. + * "app.kubernetes.io/instance" label, set to the name of the Prometheus object. + * "app.kubernetes.io/managed-by" label, set to "prometheus-operator". + * "app.kubernetes.io/name" label, set to "prometheus". + * "app.kubernetes.io/version" label, set to the Prometheus version. + * "operator.prometheus.io/name" label, set to the name of the Prometheus object. + * "operator.prometheus.io/shard" label, set to the shard number of the Prometheus object. + * "kubectl.kubernetes.io/default-container" annotation, set to "prometheus". + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + podMonitorNamespaceSelector: + description: |- + Namespaces to match for PodMonitors discovery. An empty label selector + matches all namespaces. A null label selector (default value) matches the current + namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podMonitorSelector: + description: |- + PodMonitors to be selected for target discovery. An empty label selector + matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podTargetLabels: + description: |- + PodTargetLabels are appended to the `spec.podTargetLabels` field of all + PodMonitor and ServiceMonitor objects. + items: + type: string + type: array + portName: + default: web + description: |- + Port name used for the pods and governing service. + Default: "web" + type: string + priorityClassName: + description: Priority class assigned to the Pods. + type: string + probeNamespaceSelector: + description: |- + Namespaces to match for Probe discovery. An empty label + selector matches all namespaces. A null label selector matches the + current namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + probeSelector: + description: |- + Probes to be selected for target discovery. An empty label selector + matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + prometheusExternalLabelName: + description: |- + Name of Prometheus external label used to denote the Prometheus instance + name. The external label will _not_ be added when the field is set to + the empty string (`""`). + + Default: "prometheus" + type: string + prometheusRulesExcludedFromEnforce: + description: |- + Defines the list of PrometheusRule objects to which the namespace label + enforcement doesn't apply. + This is only relevant when `spec.enforcedNamespaceLabel` is set to true. + Deprecated: use `spec.excludedFromEnforcement` instead. + items: + description: |- + PrometheusRuleExcludeConfig enables users to configure excluded + PrometheusRule names and their namespaces to be ignored while enforcing + namespace label for alerts and metrics. + properties: + ruleName: + description: Name of the excluded PrometheusRule object. + type: string + ruleNamespace: + description: Namespace of the excluded PrometheusRule object. + type: string + required: + - ruleName + - ruleNamespace + type: object + type: array + query: + description: QuerySpec defines the configuration of the Promethus query service. + properties: + lookbackDelta: + description: The delta difference allowed for retrieving metrics during expression evaluations. + type: string + maxConcurrency: + description: Number of concurrent queries that can be run at once. + format: int32 + minimum: 1 + type: integer + maxSamples: + description: |- + Maximum number of samples a single query can load into memory. Note that + queries will fail if they would load more samples than this into memory, + so this also limits the number of samples a query can return. + format: int32 + type: integer + timeout: + description: Maximum time a query may take before being aborted. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + queryLogFile: + description: |- + queryLogFile specifies where the file to which PromQL queries are logged. + + If the filename has an empty path, e.g. 'query.log', The Prometheus Pods + will mount the file into an emptyDir volume at `/var/log/prometheus`. + If a full path is provided, e.g. '/var/log/prometheus/query.log', you + must mount a volume in the specified directory and it must be writable. + This is because the prometheus container runs with a read-only root + filesystem for security reasons. + Alternatively, the location can be set to a standard I/O stream, e.g. + `/dev/stdout`, to log query information to the default Prometheus log + stream. + type: string + reloadStrategy: + description: |- + Defines the strategy used to reload the Prometheus configuration. + If not specified, the configuration is reloaded using the /-/reload HTTP endpoint. + enum: + - HTTP + - ProcessSignal + type: string + remoteRead: + description: Defines the list of remote read configurations. + items: + description: |- + RemoteReadSpec defines the configuration for Prometheus to read back samples + from a remote endpoint. + properties: + authorization: + description: |- + Authorization section for the URL. + + It requires Prometheus >= v2.26.0. + + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth configuration for the URL. + + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File from which to read the bearer token for the URL. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + filterExternalLabels: + description: |- + Whether to use the external labels as selectors for the remote read endpoint. + + It requires Prometheus >= v2.34.0. + type: boolean + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + + It requires Prometheus >= v2.26.0. + type: boolean + headers: + additionalProperties: + type: string + description: |- + Custom HTTP headers to be sent along with each remote read request. + Be aware that headers that are set by Prometheus itself can't be overwritten. + Only valid in Prometheus versions 2.26.0 and newer. + type: object + name: + description: |- + The name of the remote read queue, it must be unique if specified. The + name is used in metrics and logging in order to differentiate read + configurations. + + It requires Prometheus >= v2.15.0. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + OAuth2 configuration for the URL. + + It requires Prometheus >= v2.27.0. + + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + readRecent: + description: |- + Whether reads should be made for queries for time ranges that + the local storage should have complete data for. + type: boolean + remoteTimeout: + description: Timeout for requests to the remote read endpoint. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + requiredMatchers: + additionalProperties: + type: string + description: |- + An optional list of equality matchers which have to be present + in a selector to query the remote read endpoint. + type: object + tlsConfig: + description: TLS Config to use for the URL. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: The URL of the endpoint to query from. + type: string + required: + - url + type: object + type: array + remoteWrite: + description: Defines the list of remote write configurations. + items: + description: |- + RemoteWriteSpec defines the configuration to write samples from Prometheus + to a remote endpoint. + properties: + authorization: + description: |- + Authorization section for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + azureAd: + description: |- + AzureAD for the URL. + + It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`. + properties: + cloud: + description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'. + enum: + - AzureChina + - AzureGovernment + - AzurePublic + type: string + managedIdentity: + description: |- + ManagedIdentity defines the Azure User-assigned Managed identity. + Cannot be set at the same time as `oauth` or `sdk`. + properties: + clientId: + description: The client id + type: string + required: + - clientId + type: object + oauth: + description: |- + OAuth defines the oauth config that is being used to authenticate. + Cannot be set at the same time as `managedIdentity` or `sdk`. + + It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0. + properties: + clientId: + description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + type: string + clientSecret: + description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.' + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tenantId: + description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + pattern: ^[0-9a-zA-Z-.]+$ + type: string + required: + - clientId + - clientSecret + - tenantId + type: object + sdk: + description: |- + SDK defines the Azure SDK config that is being used to authenticate. + See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication + Cannot be set at the same time as `oauth` or `managedIdentity`. + + It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0. + properties: + tenantId: + description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.' + pattern: ^[0-9a-zA-Z-.]+$ + type: string + type: object + type: object + basicAuth: + description: |- + BasicAuth configuration for the URL. + + Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File from which to read bearer token for the URL. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + type: boolean + headers: + additionalProperties: + type: string + description: |- + Custom HTTP headers to be sent along with each remote write request. + Be aware that headers that are set by Prometheus itself can't be overwritten. + + It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0. + type: object + messageVersion: + description: |- + The Remote Write message's version to use when writing to the endpoint. + + `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0. + `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0. + + When `Version2.0` is selected, Prometheus will automatically be + configured to append the metadata of scraped metrics to the WAL. + + Before setting this field, consult with your remote storage provider + what message version it supports. + + It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0. + enum: + - V1.0 + - V2.0 + type: string + metadataConfig: + description: MetadataConfig configures the sending of series metadata to the remote storage. + properties: + maxSamplesPerSend: + description: |- + MaxSamplesPerSend is the maximum number of metadata samples per send. + + It requires Prometheus >= v2.29.0. + format: int32 + minimum: -1 + type: integer + send: + description: Defines whether metric metadata is sent to the remote storage or not. + type: boolean + sendInterval: + description: Defines how frequently metric metadata is sent to the remote storage. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + name: + description: |- + The name of the remote write queue, it must be unique if specified. The + name is used in metrics and logging in order to differentiate queues. + + It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + OAuth2 configuration for the URL. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + queueConfig: + description: QueueConfig allows tuning of the remote write queue parameters. + properties: + batchSendDeadline: + description: BatchSendDeadline is the maximum time a sample will wait in buffer. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + capacity: + description: |- + Capacity is the number of samples to buffer per shard before we start + dropping them. + type: integer + maxBackoff: + description: MaxBackoff is the maximum retry delay. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + maxRetries: + description: MaxRetries is the maximum number of times to retry a batch on recoverable errors. + type: integer + maxSamplesPerSend: + description: MaxSamplesPerSend is the maximum number of samples per send. + type: integer + maxShards: + description: MaxShards is the maximum number of shards, i.e. amount of concurrency. + type: integer + minBackoff: + description: MinBackoff is the initial retry delay. Gets doubled for every retry. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + minShards: + description: MinShards is the minimum number of shards, i.e. amount of concurrency. + type: integer + retryOnRateLimit: + description: |- + Retry upon receiving a 429 status code from the remote-write storage. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + type: boolean + sampleAgeLimit: + description: |- + SampleAgeLimit drops samples older than the limit. + It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + remoteTimeout: + description: Timeout for requests to the remote write endpoint. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + roundRobinDNS: + description: |- + When enabled: + - The remote-write mechanism will resolve the hostname via DNS. + - It will randomly select one of the resolved IP addresses and connect to it. + + When disabled (default behavior): + - The Go standard library will handle hostname resolution. + - It will attempt connections to each resolved IP address sequentially. + + Note: The connection timeout applies to the entire resolution and connection process. + If disabled, the timeout is distributed across all connection attempts. + + It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0. + type: boolean + sendExemplars: + description: |- + Enables sending of exemplars over remote write. Note that + exemplar-storage itself must be enabled using the `spec.enableFeatures` + option for exemplars to be scraped in the first place. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + type: boolean + sendNativeHistograms: + description: |- + Enables sending of native histograms, also known as sparse histograms + over remote write. + + It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0. + type: boolean + sigv4: + description: |- + Sigv4 allows to configures AWS's Signature Verification 4 for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + accessKey: + description: |- + AccessKey is the AWS API key. If not specified, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: |- + SecretKey is the AWS API secret. If not specified, the environment + variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + description: TLS Config to use for the URL. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: The URL of the endpoint to send samples to. + minLength: 1 + type: string + writeRelabelConfigs: + description: The list of remote write relabel configurations. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + required: + - url + type: object + type: array + remoteWriteReceiverMessageVersions: + description: |- + List of the protobuf message versions to accept when receiving the + remote writes. + + It requires Prometheus >= v2.54.0. + items: + enum: + - V1.0 + - V2.0 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + replicaExternalLabelName: + description: |- + Name of Prometheus external label used to denote the replica name. + The external label will _not_ be added when the field is set to the + empty string (`""`). + + Default: "prometheus_replica" + type: string + replicas: + description: |- + Number of replicas of each shard to deploy for a Prometheus deployment. + `spec.replicas` multiplied by `spec.shards` is the total number of Pods + created. + + Default: 1 + format: int32 + type: integer + resources: + description: Defines the resources requests and limits of the 'prometheus' container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + retention: + description: |- + How long to retain the Prometheus data. + + Default: "24h" if `spec.retention` and `spec.retentionSize` are empty. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + retentionSize: + description: Maximum number of bytes used by the Prometheus data. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + routePrefix: + description: |- + The route prefix Prometheus registers HTTP handlers for. + + This is useful when using `spec.externalURL`, and a proxy is rewriting + HTTP routes of a request, and the actual ExternalURL is still true, but + the server serves requests under a different route prefix. For example + for use with `kubectl proxy`. + type: string + ruleNamespaceSelector: + description: |- + Namespaces to match for PrometheusRule discovery. An empty label selector + matches all namespaces. A null label selector matches the current + namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + ruleQueryOffset: + description: |- + Defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past. + It requires Prometheus >= v2.53.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + ruleSelector: + description: |- + PrometheusRule objects to be selected for rule evaluation. An empty + label selector matches all objects. A null label selector matches no + objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + rules: + description: Defines the configuration of the Prometheus rules' engine. + properties: + alert: + description: |- + Defines the parameters of the Prometheus rules' engine. + + Any update to these parameters trigger a restart of the pods. + properties: + forGracePeriod: + description: |- + Minimum duration between alert and restored 'for' state. + + This is maintained only for alerts with a configured 'for' time greater + than the grace period. + type: string + forOutageTolerance: + description: |- + Max time to tolerate prometheus outage for restoring 'for' state of + alert. + type: string + resendDelay: + description: |- + Minimum amount of time to wait before resending an alert to + Alertmanager. + type: string + type: object + type: object + runtime: + description: RuntimeConfig configures the values for the Prometheus process behavior + properties: + goGC: + description: |- + The Go garbage collection target percentage. Lowering this number may increase the CPU usage. + See: https://tip.golang.org/doc/gc-guide#GOGC + format: int32 + minimum: -1 + type: integer + type: object + sampleLimit: + description: |- + SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedSampleLimit. + format: int64 + type: integer + scrapeClasses: + description: |- + List of scrape classes to expose to scraping objects such as + PodMonitors, ServiceMonitors, Probes and ScrapeConfigs. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + items: + properties: + attachMetadata: + description: |- + AttachMetadata configures additional metadata to the discovered targets. + When the scrape object defines its own configuration, it takes + precedence over the scrape class configuration. + properties: + node: + description: |- + When set to true, Prometheus attaches node metadata to the discovered + targets. + + The Prometheus service account must have the `list` and `watch` + permissions on the `Nodes` objects. + type: boolean + type: object + authorization: + description: |- + Authorization section for the ScrapeClass. + It will only apply if the scrape resource doesn't specify any Authorization. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + default: + description: |- + Default indicates that the scrape applies to all scrape objects that + don't configure an explicit scrape class name. + + Only one scrape class can be set as the default. + type: boolean + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + It will only apply if the scrape resource doesn't specify any FallbackScrapeProtocol + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + metricRelabelings: + description: |- + MetricRelabelings configures the relabeling rules to apply to all samples before ingestion. + + The Operator adds the scrape class metric relabelings defined here. + Then the Operator adds the target-specific metric relabelings defined in ServiceMonitors, PodMonitors, Probes and ScrapeConfigs. + Then the Operator adds namespace enforcement relabeling rule, specified in '.spec.enforcedNamespaceLabel'. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + name: + description: Name of the scrape class. + minLength: 1 + type: string + relabelings: + description: |- + Relabelings configures the relabeling rules to apply to all scrape targets. + + The Operator automatically adds relabelings for a few standard Kubernetes fields + like `__meta_kubernetes_namespace` and `__meta_kubernetes_service_name`. + Then the Operator adds the scrape class relabelings defined here. + Then the Operator adds the target-specific relabelings defined in the scrape object. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + tlsConfig: + description: |- + TLSConfig defines the TLS settings to use for the scrape. When the + scrape objects define their own CA, certificate and/or key, they take + precedence over the corresponding scrape class fields. + + For now only the `caFile`, `certFile` and `keyFile` fields are supported. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + + It requires Prometheus >= v3.5.0. + type: boolean + scrapeConfigNamespaceSelector: + description: |- + Namespaces to match for ScrapeConfig discovery. An empty label selector + matches all namespaces. A null label selector matches the current + namespace only. + + Note that the ScrapeConfig custom resource definition is currently at Alpha level. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + scrapeConfigSelector: + description: |- + ScrapeConfigs to be selected for target discovery. An empty label + selector matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + + Note that the ScrapeConfig custom resource definition is currently at Alpha level. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + scrapeFailureLogFile: + description: |- + File to which scrape failures are logged. + Reloading the configuration will reopen the file. + + If the filename has an empty path, e.g. 'file.log', The Prometheus Pods + will mount the file into an emptyDir volume at `/var/log/prometheus`. + If a full path is provided, e.g. '/var/log/prometheus/file.log', you + must mount a volume in the specified directory and it must be writable. + It requires Prometheus >= v2.55.0. + minLength: 1 + type: string + scrapeInterval: + default: 30s + description: |- + Interval between consecutive scrapes. + + Default: "30s" + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + scrapeProtocols: + description: |- + The protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + + `PrometheusText1.0.0` requires Prometheus >= v3.0.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + type: array + x-kubernetes-list-type: set + scrapeTimeout: + description: |- + Number of seconds to wait until a scrape request times out. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + secrets: + description: |- + Secrets is a list of Secrets in the same namespace as the Prometheus + object, which shall be mounted into the Prometheus Pods. + Each Secret is added to the StatefulSet definition as a volume named `secret-`. + The Secrets are mounted into /etc/prometheus/secrets/ in the 'prometheus' container. + items: + type: string + type: array + x-kubernetes-list-type: set + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + This defaults to the default PodSecurityContext. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run the + Prometheus Pods. + type: string + serviceDiscoveryRole: + description: |- + Defines the service discovery role used to discover targets from + `ServiceMonitor` objects and Alertmanager endpoints. + + If set, the value should be either "Endpoints" or "EndpointSlice". + If unset, the operator assumes the "Endpoints" role. + enum: + - Endpoints + - EndpointSlice + type: string + serviceMonitorNamespaceSelector: + description: |- + Namespaces to match for ServicedMonitors discovery. An empty label selector + matches all namespaces. A null label selector (default value) matches the current + namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceMonitorSelector: + description: |- + ServiceMonitors to be selected for target discovery. An empty label + selector matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceName: + description: |- + The name of the service name used by the underlying StatefulSet(s) as the governing service. + If defined, the Service must be created before the Prometheus/PrometheusAgent resource in the same namespace and it must define a selector that matches the pod labels. + If empty, the operator will create and manage a headless service named `prometheus-operated` for Prometheus resources, + or `prometheus-agent-operated` for PrometheusAgent resources. + When deploying multiple Prometheus/PrometheusAgent resources in the same namespace, it is recommended to specify a different value for each. + See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details. + minLength: 1 + type: string + sha: + description: 'Deprecated: use ''spec.image'' instead. The image''s digest can be specified as part of the image name.' + type: string + shardRetentionPolicy: + description: |- + ShardRetentionPolicy defines the retention policy for the Prometheus shards. + (Alpha) Using this field requires the 'PrometheusShardRetentionPolicy' feature gate to be enabled. + + The final goals for this feature can be seen at https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/proposals/202310-shard-autoscaling.md#graceful-scale-down-of-prometheus-servers, + however, the feature is not yet fully implemented in this PR. The limitation being: + * Retention duration is not settable, for now, shards are retained forever. + properties: + retain: + description: |- + Defines the config for retention when the retention policy is set to `Retain`. + This field is ineffective as of now. + properties: + retentionPeriod: + description: |- + Duration is a valid time duration that can be parsed by Prometheus model.ParseDuration() function. + Supported units: y, w, d, h, m, s, ms + Examples: `30s`, `1m`, `1h20m15s`, `15d` + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + required: + - retentionPeriod + type: object + whenScaled: + description: |- + Defines the retention policy when the Prometheus shards are scaled down. + * `Delete`, the operator will delete the pods from the scaled-down shard(s). + * `Retain`, the operator will keep the pods from the scaled-down shard(s), so the data can still be queried. + + If not defined, the operator assumes the `Delete` value. + enum: + - Retain + - Delete + type: string + type: object + shards: + description: |- + Number of shards to distribute the scraped targets onto. + + `spec.replicas` multiplied by `spec.shards` is the total number of Pods + being created. + + When not defined, the operator assumes only one shard. + + Note that scaling down shards will not reshard data onto the remaining + instances, it must be manually moved. Increasing shards will not reshard + data either but it will continue to be available from the same + instances. To query globally, use either + * Thanos sidecar + querier for query federation and Thanos Ruler for rules. + * Remote-write to send metrics to a central location. + + By default, the sharding of targets is performed on: + * The `__address__` target's metadata label for PodMonitor, + ServiceMonitor and ScrapeConfig resources. + * The `__param_target__` label for Probe resources. + + Users can define their own sharding implementation by setting the + `__tmp_hash` label during the target discovery with relabeling + configuration (either in the monitoring resources or via scrape class). + + You can also disable sharding on a specific target by setting the + `__tmp_disable_sharding` label with relabeling configuration. When + the label value isn't empty, all Prometheus shards will scrape the target. + format: int32 + type: integer + storage: + description: Storage defines the storage used by Prometheus. + properties: + disableMountSubPath: + description: 'Deprecated: subPath usage will be removed in a future release.' + type: boolean + emptyDir: + description: |- + EmptyDirVolumeSource to be used by the StatefulSet. + If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + EphemeralVolumeSource to be used by the StatefulSet. + This is a beta field in k8s 1.21 and GA in 1.15. + For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate. + More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + description: |- + Defines the PVC spec to be used by the Prometheus StatefulSets. + The easiest way to use a volume that cannot be automatically provisioned + is to use a label selector alongside manually created PersistentVolumes. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + spec: + description: |- + Defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + status: + description: 'Deprecated: this field is never set.' + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume operation. It can be in any of following states:\n - Pending\n Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\n the specified VolumeAttributesClass not existing.\n - InProgress\n InProgress indicates that the volume is being modified.\n - Infeasible\n Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass needs to be specified.\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: object + tag: + description: 'Deprecated: use ''spec.image'' instead. The image''s tag can be specified as part of the image name.' + type: string + targetLimit: + description: |- + TargetLimit defines a limit on the number of scraped targets that will be accepted. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedTargetLimit. + format: int64 + type: integer + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down) which may lead to data corruption. + + Defaults to 600 seconds. + format: int64 + minimum: 0 + type: integer + thanos: + description: Defines the configuration of the optional Thanos sidecar. + properties: + additionalArgs: + description: |- + AdditionalArgs allows setting additional arguments for the Thanos container. + The arguments are passed as-is to the Thanos container which may cause issues + if they are invalid or not supported the given Thanos version. + In case of an argument conflict (e.g. an argument which is already set by the + operator itself) or when providing an invalid argument, the reconciliation will + fail and an error will be logged. + items: + description: Argument as part of the AdditionalArgs list. + properties: + name: + description: Name of the argument, e.g. "scrape.discovery-reload-interval". + minLength: 1 + type: string + value: + description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile) + type: string + required: + - name + type: object + type: array + baseImage: + description: 'Deprecated: use ''image'' instead.' + type: string + blockSize: + default: 2h + description: |- + BlockDuration controls the size of TSDB blocks produced by Prometheus. + The default value is 2h to match the upstream Prometheus defaults. + + WARNING: Changing the block duration can impact the performance and + efficiency of the entire Prometheus/Thanos stack due to how it interacts + with memory and Thanos compactors. It is recommended to keep this value + set to a multiple of 120 times your longest scrape or rule interval. For + example, 30s * 120 = 1h. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + getConfigInterval: + description: How often to retrieve the Prometheus configuration. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + getConfigTimeout: + description: Maximum time to wait when retrieving the Prometheus configuration. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + grpcListenLocal: + description: |- + When true, the Thanos sidecar listens on the loopback interface instead + of the Pod IP's address for the gRPC endpoints. + + It has no effect if `listenLocal` is true. + type: boolean + grpcServerTlsConfig: + description: |- + Configures the TLS parameters for the gRPC server providing the StoreAPI. + + Note: Currently only the `caFile`, `certFile`, and `keyFile` fields are supported. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + httpListenLocal: + description: |- + When true, the Thanos sidecar listens on the loopback interface instead + of the Pod IP's address for the HTTP endpoints. + + It has no effect if `listenLocal` is true. + type: boolean + image: + description: |- + Container image name for Thanos. If specified, it takes precedence over + the `spec.thanos.baseImage`, `spec.thanos.tag` and `spec.thanos.sha` + fields. + + Specifying `spec.thanos.version` is still necessary to ensure the + Prometheus Operator knows which version of Thanos is being configured. + + If neither `spec.thanos.image` nor `spec.thanos.baseImage` are defined, + the operator will use the latest upstream version of Thanos available at + the time when the operator was released. + type: string + listenLocal: + description: 'Deprecated: use `grpcListenLocal` and `httpListenLocal` instead.' + type: boolean + logFormat: + description: Log format for the Thanos sidecar. + enum: + - "" + - logfmt + - json + type: string + logLevel: + description: Log level for the Thanos sidecar. + enum: + - "" + - debug + - info + - warn + - error + type: string + minTime: + description: |- + Defines the start of time range limit served by the Thanos sidecar's StoreAPI. + The field's value should be a constant time in RFC3339 format or a time + duration relative to current time, such as -1d or 2h45m. Valid duration + units are ms, s, m, h, d, w, y. + type: string + objectStorageConfig: + description: |- + Defines the Thanos sidecar's configuration to upload TSDB blocks to object storage. + + More info: https://thanos.io/tip/thanos/storage.md/ + + objectStorageConfigFile takes precedence over this field. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + objectStorageConfigFile: + description: |- + Defines the Thanos sidecar's configuration file to upload TSDB blocks to object storage. + + More info: https://thanos.io/tip/thanos/storage.md/ + + This field takes precedence over objectStorageConfig. + type: string + readyTimeout: + description: |- + ReadyTimeout is the maximum time that the Thanos sidecar will wait for + Prometheus to start. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + resources: + description: Defines the resources requests and limits of the Thanos sidecar. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + sha: + description: 'Deprecated: use ''image'' instead. The image digest can be specified as part of the image name.' + type: string + tag: + description: 'Deprecated: use ''image'' instead. The image''s tag can be specified as as part of the image name.' + type: string + tracingConfig: + description: |- + Defines the tracing configuration for the Thanos sidecar. + + `tracingConfigFile` takes precedence over this field. + + More info: https://thanos.io/tip/thanos/tracing.md/ + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tracingConfigFile: + description: |- + Defines the tracing configuration file for the Thanos sidecar. + + This field takes precedence over `tracingConfig`. + + More info: https://thanos.io/tip/thanos/tracing.md/ + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + type: string + version: + description: |- + Version of Thanos being deployed. The operator uses this information + to generate the Prometheus StatefulSet + configuration files. + + If not specified, the operator assumes the latest upstream release of + Thanos available at the time when the version of the operator was + released. + type: string + volumeMounts: + description: |- + VolumeMounts allows configuration of additional VolumeMounts for Thanos. + VolumeMounts specified will be appended to other VolumeMounts in the + 'thanos-sidecar' container. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + type: object + tolerations: + description: Defines the Pods' tolerations if specified. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: Defines the pod's topology spread constraints if specified. + items: + properties: + additionalLabelSelectors: + description: Defines what Prometheus Operator managed labels should be added to labelSelector on the topologySpreadConstraint. + enum: + - OnResource + - OnShard + type: string + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + tracingConfig: + description: |- + TracingConfig configures tracing in Prometheus. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + properties: + clientType: + description: Client used to export the traces. Supported values are `http` or `grpc`. + enum: + - http + - grpc + type: string + compression: + description: Compression key for supported compression types. The only supported value is `gzip`. + enum: + - gzip + type: string + endpoint: + description: Endpoint to send the traces to. Should be provided in format :. + minLength: 1 + type: string + headers: + additionalProperties: + type: string + description: Key-value pairs to be used as headers associated with gRPC or HTTP requests. + type: object + insecure: + description: If disabled, the client will use a secure connection. + type: boolean + samplingFraction: + anyOf: + - type: integer + - type: string + description: Sets the probability a given trace will be sampled. Must be a float from 0 through 1. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + timeout: + description: Maximum time the exporter will wait for each batch export. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS Config to use when sending traces. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - endpoint + type: object + tsdb: + description: |- + Defines the runtime reloadable configuration of the timeseries database(TSDB). + It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0. + properties: + outOfOrderTimeWindow: + description: |- + Configures how old an out-of-order/out-of-bounds sample can be with + respect to the TSDB max time. + + An out-of-order/out-of-bounds sample is ingested into the TSDB as long as + the timestamp of the sample is >= (TSDB.MaxTime - outOfOrderTimeWindow). + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + + It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + version: + description: |- + Version of Prometheus being deployed. The operator uses this information + to generate the Prometheus StatefulSet + configuration files. + + If not specified, the operator assumes the latest upstream version of + Prometheus available at the time when the version of the operator was + released. + type: string + volumeMounts: + description: |- + VolumeMounts allows the configuration of additional VolumeMounts. + + VolumeMounts will be appended to other VolumeMounts in the 'prometheus' + container, that are generated as a result of StorageSpec objects. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Volumes allows the configuration of additional volumes on the output + StatefulSet definition. Volumes specified will be appended to other + volumes that are generated as a result of StorageSpec objects. + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + walCompression: + description: |- + Configures compression of the write-ahead log (WAL) using Snappy. + + WAL compression is enabled by default for Prometheus >= 2.20.0 + + Requires Prometheus v2.11.0 and above. + type: boolean + web: + description: Defines the configuration of the Prometheus web server. + properties: + httpConfig: + description: Defines HTTP parameters for web server. + properties: + headers: + description: List of headers that can be added to HTTP responses. + properties: + contentSecurityPolicy: + description: |- + Set the Content-Security-Policy header to HTTP responses. + Unset if blank. + type: string + strictTransportSecurity: + description: |- + Set the Strict-Transport-Security header to HTTP responses. + Unset if blank. + Please make sure that you use this with care as this header might force + browsers to load Prometheus and the other applications hosted on the same + domain and subdomains over HTTPS. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + type: string + xContentTypeOptions: + description: |- + Set the X-Content-Type-Options header to HTTP responses. + Unset if blank. Accepted value is nosniff. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + enum: + - "" + - NoSniff + type: string + xFrameOptions: + description: |- + Set the X-Frame-Options header to HTTP responses. + Unset if blank. Accepted values are deny and sameorigin. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + enum: + - "" + - Deny + - SameOrigin + type: string + xXSSProtection: + description: |- + Set the X-XSS-Protection header to all responses. + Unset if blank. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + type: string + type: object + http2: + description: |- + Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS. + When TLSConfig is not configured, HTTP/2 will be disabled. + Whenever the value of the field changes, a rolling update will be triggered. + type: boolean + type: object + maxConnections: + description: |- + Defines the maximum number of simultaneous connections + A zero value means that Prometheus doesn't accept any incoming connection. + format: int32 + minimum: 0 + type: integer + pageTitle: + description: The prometheus web page title. + type: string + tlsConfig: + description: Defines the TLS parameters for HTTPS. + properties: + cert: + description: |- + Secret or ConfigMap containing the TLS certificate for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `certFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: |- + Path to the TLS certificate file in the container for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `cert`. + type: string + cipherSuites: + description: |- + List of supported cipher suites for TLS versions up to TLS 1.2. + + If not defined, the Go default cipher suites are used. + Available cipher suites are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#pkg-constants + items: + type: string + type: array + client_ca: + description: |- + Secret or ConfigMap containing the CA certificate for client certificate + authentication to the server. + + It is mutually exclusive with `clientCAFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientAuthType: + description: |- + The server policy for client TLS authentication. + + For more detail on clientAuth options: + https://golang.org/pkg/crypto/tls/#ClientAuthType + type: string + clientCAFile: + description: |- + Path to the CA certificate file for client certificate authentication to + the server. + + It is mutually exclusive with `client_ca`. + type: string + curvePreferences: + description: |- + Elliptic curves that will be used in an ECDHE handshake, in preference + order. + + Available curves are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#CurveID + items: + type: string + type: array + keyFile: + description: |- + Path to the TLS private key file in the container for the web server. + + If defined, either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keySecret`. + type: string + keySecret: + description: |- + Secret containing the TLS private key for the web server. + + Either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keyFile`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: Maximum TLS version that is acceptable. + type: string + minVersion: + description: Minimum TLS version that is acceptable. + type: string + preferServerCipherSuites: + description: |- + Controls whether the server selects the client's most preferred cipher + suite, or the server's most preferred cipher suite. + + If true then the server's preference, as expressed in + the order of elements in cipherSuites, is used. + type: boolean + type: object + type: object + type: object + status: + description: |- + Most recent observed status of the Prometheus cluster. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this Prometheus deployment. + format: int32 + type: integer + conditions: + description: The current state of the Prometheus deployment. + items: + description: |- + Condition represents the state of the resources associated with the + Prometheus, Alertmanager or ThanosRuler resource. + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: Human-readable message indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the + instance. + format: int64 + type: integer + reason: + description: Reason for the condition's last transition. + type: string + status: + description: Status of the condition. + minLength: 1 + type: string + type: + description: Type of the condition being reported. + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + paused: + description: |- + Represents whether any actions on the underlying managed objects are + being performed. Only delete actions will be performed. + type: boolean + replicas: + description: |- + Total number of non-terminated pods targeted by this Prometheus deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: The selector used to match the pods targeted by this Prometheus resource. + type: string + shardStatuses: + description: The list has one entry per shard. Each entry provides a summary of the shard status. + items: + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this shard. + format: int32 + type: integer + replicas: + description: Total number of pods targeted by this shard. + format: int32 + type: integer + shardID: + description: Identifier of the shard. + type: string + unavailableReplicas: + description: Total number of unavailable pods targeted by this shard. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this shard + that have the desired spec. + format: int32 + type: integer + required: + - availableReplicas + - replicas + - shardID + - unavailableReplicas + - updatedReplicas + type: object + type: array + x-kubernetes-list-map-keys: + - shardID + x-kubernetes-list-type: map + shards: + description: Shards is the most recently observed number of shards. + format: int32 + type: integer + unavailableReplicas: + description: Total number of unavailable pods targeted by this Prometheus deployment. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this Prometheus deployment + that have the desired version spec. + format: int32 + type: integer + required: + - availableReplicas + - paused + - replicas + - unavailableReplicas + - updatedReplicas + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.shards + statusReplicasPath: .status.shards + status: {} diff --git a/release/kubernetes/monitoring/setup/0prometheusagentCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0prometheusagentCustomResourceDefinition.yaml new file mode 100644 index 000000000..982e5ef2a --- /dev/null +++ b/release/kubernetes/monitoring/setup/0prometheusagentCustomResourceDefinition.yaml @@ -0,0 +1,10474 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: prometheusagents.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PrometheusAgent + listKind: PrometheusAgentList + plural: prometheusagents + shortNames: + - promagent + singular: prometheusagent + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The version of Prometheus agent + jsonPath: .spec.version + name: Version + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Desired + type: integer + - description: The number of ready replicas + jsonPath: .status.availableReplicas + name: Ready + type: integer + - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status + name: Reconciled + type: string + - jsonPath: .status.conditions[?(@.type == 'Available')].status + name: Available + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Whether the resource reconciliation is paused or not + jsonPath: .status.paused + name: Paused + priority: 1 + type: boolean + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + The `PrometheusAgent` custom resource definition (CRD) defines a desired [Prometheus Agent](https://prometheus.io/blog/2021/11/16/agent/) setup to run in a Kubernetes cluster. + + The CRD is very similar to the `Prometheus` CRD except for features which aren't available in agent mode like rule evaluation, persistent storage and Thanos sidecar. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the Prometheus agent. More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + additionalArgs: + description: |- + AdditionalArgs allows setting additional arguments for the 'prometheus' container. + + It is intended for e.g. activating hidden flags which are not supported by + the dedicated configuration options yet. The arguments are passed as-is to the + Prometheus container which may cause issues if they are invalid or not supported + by the given Prometheus version. + + In case of an argument conflict (e.g. an argument which is already set by the + operator itself) or when providing an invalid argument, the reconciliation will + fail and an error will be logged. + items: + description: Argument as part of the AdditionalArgs list. + properties: + name: + description: Name of the argument, e.g. "scrape.discovery-reload-interval". + minLength: 1 + type: string + value: + description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile) + type: string + required: + - name + type: object + type: array + additionalScrapeConfigs: + description: |- + AdditionalScrapeConfigs allows specifying a key of a Secret containing + additional Prometheus scrape configurations. Scrape configurations + specified are appended to the configurations generated by the Prometheus + Operator. Job configurations specified must have the form as specified + in the official Prometheus documentation: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. + As scrape configs are appended, the user is responsible to make sure it + is valid. Note that using this feature may expose the possibility to + break upgrades of Prometheus. It is advised to review Prometheus release + notes to ensure that no incompatible scrape configs are going to break + Prometheus after the upgrade. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + affinity: + description: Defines the Pods' affinity scheduling rules if specified. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + apiserverConfig: + description: |- + APIServerConfig allows specifying a host and auth methods to access the + Kuberntees API server. + If null, Prometheus is assumed to run inside of the cluster: it will + discover the API servers automatically and use the Pod's CA certificate + and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. + properties: + authorization: + description: |- + Authorization section for the API server. + + Cannot be set at the same time as `basicAuth`, `bearerToken`, or + `bearerTokenFile`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth configuration for the API server. + + Cannot be set at the same time as `authorization`, `bearerToken`, or + `bearerTokenFile`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File to read bearer token for accessing apiserver. + + Cannot be set at the same time as `basicAuth`, `authorization`, or `bearerToken`. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + host: + description: |- + Kubernetes API address consisting of a hostname or IP address followed + by an optional port number. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + tlsConfig: + description: TLS Config to use for the API server. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - host + type: object + arbitraryFSAccessThroughSMs: + description: |- + When true, ServiceMonitor, PodMonitor and Probe object are forbidden to + reference arbitrary files on the file system of the 'prometheus' + container. + When a ServiceMonitor's endpoint specifies a `bearerTokenFile` value + (e.g. '/var/run/secrets/kubernetes.io/serviceaccount/token'), a + malicious target can get access to the Prometheus service account's + token in the Prometheus' scrape request. Setting + `spec.arbitraryFSAccessThroughSM` to 'true' would prevent the attack. + Users should instead provide the credentials using the + `spec.bearerTokenSecret` field. + properties: + deny: + type: boolean + type: object + automountServiceAccountToken: + description: |- + AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod. + If the field isn't set, the operator mounts the service account token by default. + + **Warning:** be aware that by default, Prometheus requires the service account token for Kubernetes service discovery. + It is possible to use strategic merge patch to project the service account token into the 'prometheus' container. + type: boolean + bodySizeLimit: + description: |- + BodySizeLimit defines per-scrape on response body size. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedBodySizeLimit. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + configMaps: + description: |- + ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus + object, which shall be mounted into the Prometheus Pods. + Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-`. + The ConfigMaps are mounted into /etc/prometheus/configmaps/ in the 'prometheus' container. + items: + type: string + type: array + containers: + description: |- + Containers allows injecting additional containers or modifying operator + generated containers. This can be used to allow adding an authentication + proxy to the Pods or to change the behavior of an operator generated + container. Containers described here modify an operator generated + container if they share the same name and modifications are done via a + strategic merge patch. + + The names of containers managed by the operator are: + * `prometheus` + * `config-reloader` + * `thanos-sidecar` + + Overriding containers is entirely outside the scope of what the + maintainers will support and by doing so, you accept that this behaviour + may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native + histogram with custom buckets. + + It requires Prometheus >= v3.4.0. + type: boolean + dnsConfig: + description: Defines the DNS configuration for the pods. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Name is required and must be unique. + minLength: 1 + type: string + value: + description: Value is optional. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + type: object + dnsPolicy: + description: Defines the DNS policy for the pods. + enum: + - ClusterFirstWithHostNet + - ClusterFirst + - Default + - None + type: string + enableFeatures: + description: |- + Enable access to Prometheus feature flags. By default, no features are enabled. + + Enabling features which are disabled by default is entirely outside the + scope of what the maintainers will support and by doing so, you accept + that this behaviour may break at any time without notice. + + For more information see https://prometheus.io/docs/prometheus/latest/feature_flags/ + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + enableOTLPReceiver: + description: |- + Enable Prometheus to be used as a receiver for the OTLP Metrics protocol. + + Note that the OTLP receiver endpoint is automatically enabled if `.spec.otlpConfig` is defined. + + It requires Prometheus >= v2.47.0. + type: boolean + enableRemoteWriteReceiver: + description: |- + Enable Prometheus to be used as a receiver for the Prometheus remote + write protocol. + + WARNING: This is not considered an efficient way of ingesting samples. + Use it with caution for specific low-volume use cases. + It is not suitable for replacing the ingestion via scraping and turning + Prometheus into a push-based metrics collection system. + For more information see https://prometheus.io/docs/prometheus/latest/querying/api/#remote-write-receiver + + It requires Prometheus >= v2.33.0. + type: boolean + enableServiceLinks: + description: Indicates whether information about services should be injected into pod's environment variables + type: boolean + enforcedBodySizeLimit: + description: |- + When defined, enforcedBodySizeLimit specifies a global limit on the size + of uncompressed response body that will be accepted by Prometheus. + Targets responding with a body larger than this many bytes will cause + the scrape to fail. + + It requires Prometheus >= v2.28.0. + + When both `enforcedBodySizeLimit` and `bodySizeLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined bodySizeLimit value will inherit the global bodySizeLimit value (Prometheus >= 2.45.0) or the enforcedBodySizeLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedBodySizeLimit` is greater than the `bodySizeLimit`, the `bodySizeLimit` will be set to `enforcedBodySizeLimit`. + * Scrape objects with a bodySizeLimit value less than or equal to enforcedBodySizeLimit keep their specific value. + * Scrape objects with a bodySizeLimit value greater than enforcedBodySizeLimit are set to enforcedBodySizeLimit. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + enforcedKeepDroppedTargets: + description: |- + When defined, enforcedKeepDroppedTargets specifies a global limit on the number of targets + dropped by relabeling that will be kept in memory. The value overrides + any `spec.keepDroppedTargets` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.keepDroppedTargets` is + greater than zero and less than `spec.enforcedKeepDroppedTargets`. + + It requires Prometheus >= v2.47.0. + + When both `enforcedKeepDroppedTargets` and `keepDroppedTargets` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined keepDroppedTargets value will inherit the global keepDroppedTargets value (Prometheus >= 2.45.0) or the enforcedKeepDroppedTargets value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedKeepDroppedTargets` is greater than the `keepDroppedTargets`, the `keepDroppedTargets` will be set to `enforcedKeepDroppedTargets`. + * Scrape objects with a keepDroppedTargets value less than or equal to enforcedKeepDroppedTargets keep their specific value. + * Scrape objects with a keepDroppedTargets value greater than enforcedKeepDroppedTargets are set to enforcedKeepDroppedTargets. + format: int64 + type: integer + enforcedLabelLimit: + description: |- + When defined, enforcedLabelLimit specifies a global limit on the number + of labels per sample. The value overrides any `spec.labelLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelLimit` is + greater than zero and less than `spec.enforcedLabelLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelLimit` and `labelLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelLimit value will inherit the global labelLimit value (Prometheus >= 2.45.0) or the enforcedLabelLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelLimit` is greater than the `labelLimit`, the `labelLimit` will be set to `enforcedLabelLimit`. + * Scrape objects with a labelLimit value less than or equal to enforcedLabelLimit keep their specific value. + * Scrape objects with a labelLimit value greater than enforcedLabelLimit are set to enforcedLabelLimit. + format: int64 + type: integer + enforcedLabelNameLengthLimit: + description: |- + When defined, enforcedLabelNameLengthLimit specifies a global limit on the length + of labels name per sample. The value overrides any `spec.labelNameLengthLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelNameLengthLimit` is + greater than zero and less than `spec.enforcedLabelNameLengthLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelNameLengthLimit` and `labelNameLengthLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelNameLengthLimit value will inherit the global labelNameLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelNameLengthLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelNameLengthLimit` is greater than the `labelNameLengthLimit`, the `labelNameLengthLimit` will be set to `enforcedLabelNameLengthLimit`. + * Scrape objects with a labelNameLengthLimit value less than or equal to enforcedLabelNameLengthLimit keep their specific value. + * Scrape objects with a labelNameLengthLimit value greater than enforcedLabelNameLengthLimit are set to enforcedLabelNameLengthLimit. + format: int64 + type: integer + enforcedLabelValueLengthLimit: + description: |- + When not null, enforcedLabelValueLengthLimit defines a global limit on the length + of labels value per sample. The value overrides any `spec.labelValueLengthLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.labelValueLengthLimit` is + greater than zero and less than `spec.enforcedLabelValueLengthLimit`. + + It requires Prometheus >= v2.27.0. + + When both `enforcedLabelValueLengthLimit` and `labelValueLengthLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined labelValueLengthLimit value will inherit the global labelValueLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelValueLengthLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedLabelValueLengthLimit` is greater than the `labelValueLengthLimit`, the `labelValueLengthLimit` will be set to `enforcedLabelValueLengthLimit`. + * Scrape objects with a labelValueLengthLimit value less than or equal to enforcedLabelValueLengthLimit keep their specific value. + * Scrape objects with a labelValueLengthLimit value greater than enforcedLabelValueLengthLimit are set to enforcedLabelValueLengthLimit. + format: int64 + type: integer + enforcedNamespaceLabel: + description: |- + When not empty, a label will be added to: + + 1. All metrics scraped from `ServiceMonitor`, `PodMonitor`, `Probe` and `ScrapeConfig` objects. + 2. All metrics generated from recording rules defined in `PrometheusRule` objects. + 3. All alerts generated from alerting rules defined in `PrometheusRule` objects. + 4. All vector selectors of PromQL expressions defined in `PrometheusRule` objects. + + The label will not added for objects referenced in `spec.excludedFromEnforcement`. + + The label's name is this field's value. + The label's value is the namespace of the `ServiceMonitor`, + `PodMonitor`, `Probe`, `PrometheusRule` or `ScrapeConfig` object. + type: string + enforcedSampleLimit: + description: |- + When defined, enforcedSampleLimit specifies a global limit on the number + of scraped samples that will be accepted. This overrides any + `spec.sampleLimit` set by ServiceMonitor, PodMonitor, Probe objects + unless `spec.sampleLimit` is greater than zero and less than + `spec.enforcedSampleLimit`. + + It is meant to be used by admins to keep the overall number of + samples/series under a desired limit. + + When both `enforcedSampleLimit` and `sampleLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined sampleLimit value will inherit the global sampleLimit value (Prometheus >= 2.45.0) or the enforcedSampleLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedSampleLimit` is greater than the `sampleLimit`, the `sampleLimit` will be set to `enforcedSampleLimit`. + * Scrape objects with a sampleLimit value less than or equal to enforcedSampleLimit keep their specific value. + * Scrape objects with a sampleLimit value greater than enforcedSampleLimit are set to enforcedSampleLimit. + format: int64 + type: integer + enforcedTargetLimit: + description: |- + When defined, enforcedTargetLimit specifies a global limit on the number + of scraped targets. The value overrides any `spec.targetLimit` set by + ServiceMonitor, PodMonitor, Probe objects unless `spec.targetLimit` is + greater than zero and less than `spec.enforcedTargetLimit`. + + It is meant to be used by admins to to keep the overall number of + targets under a desired limit. + + When both `enforcedTargetLimit` and `targetLimit` are defined and greater than zero, the following rules apply: + * Scrape objects without a defined targetLimit value will inherit the global targetLimit value (Prometheus >= 2.45.0) or the enforcedTargetLimit value (Prometheus < v2.45.0). + If Prometheus version is >= 2.45.0 and the `enforcedTargetLimit` is greater than the `targetLimit`, the `targetLimit` will be set to `enforcedTargetLimit`. + * Scrape objects with a targetLimit value less than or equal to enforcedTargetLimit keep their specific value. + * Scrape objects with a targetLimit value greater than enforcedTargetLimit are set to enforcedTargetLimit. + format: int64 + type: integer + excludedFromEnforcement: + description: |- + List of references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects + to be excluded from enforcing a namespace label of origin. + + It is only applicable if `spec.enforcedNamespaceLabel` set to true. + items: + description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object. + properties: + group: + default: monitoring.coreos.com + description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com` + enum: + - monitoring.coreos.com + type: string + name: + description: Name of the referent. When not set, all resources in the namespace are matched. + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + minLength: 1 + type: string + resource: + description: Resource of the referent. + enum: + - prometheusrules + - servicemonitors + - podmonitors + - probes + - scrapeconfigs + type: string + required: + - namespace + - resource + type: object + type: array + externalLabels: + additionalProperties: + type: string + description: |- + The labels to add to any time series or alerts when communicating with + external systems (federation, remote storage, Alertmanager). + Labels defined by `spec.replicaExternalLabelName` and + `spec.prometheusExternalLabelName` take precedence over this list. + type: object + externalUrl: + description: |- + The external URL under which the Prometheus service is externally + available. This is necessary to generate correct URLs (for instance if + Prometheus is accessible behind an Ingress resource). + type: string + hostAliases: + description: |- + Optional list of hosts and IPs that will be injected into the Pod's + hosts file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + required: + - hostnames + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostNetwork: + description: |- + Use the host's network namespace if true. + + Make sure to understand the security implications if you want to enable + it (https://kubernetes.io/docs/concepts/configuration/overview/ ). + + When hostNetwork is enabled, this will set the DNS policy to + `ClusterFirstWithHostNet` automatically (unless `.spec.DNSPolicy` is set + to a different value). + type: boolean + hostUsers: + description: |- + HostUsers supports the user space in Kubernetes. + + More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/ + + The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled. + Starting Kubernetes 1.33, the feature is enabled by default. + type: boolean + ignoreNamespaceSelectors: + description: |- + When true, `spec.namespaceSelector` from all PodMonitor, ServiceMonitor + and Probe objects will be ignored. They will only discover targets + within the namespace of the PodMonitor, ServiceMonitor and Probe + object. + type: boolean + image: + description: |- + Container image name for Prometheus. If specified, it takes precedence + over the `spec.baseImage`, `spec.tag` and `spec.sha` fields. + + Specifying `spec.version` is still necessary to ensure the Prometheus + Operator knows which version of Prometheus is being configured. + + If neither `spec.image` nor `spec.baseImage` are defined, the operator + will use the latest upstream version of Prometheus available at the time + when the operator was released. + type: string + imagePullPolicy: + description: |- + Image pull policy for the 'prometheus', 'init-config-reloader' and 'config-reloader' containers. + See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details. + enum: + - "" + - Always + - Never + - IfNotPresent + type: string + imagePullSecrets: + description: |- + An optional list of references to Secrets in the same namespace + to use for pulling images from registries. + See http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + InitContainers allows injecting initContainers to the Pod definition. Those + can be used to e.g. fetch secrets for injection into the Prometheus + configuration from external sources. Any errors during the execution of + an initContainer will lead to a restart of the Pod. More info: + https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + InitContainers described here modify an operator generated init + containers if they share the same name and modifications are done via a + strategic merge patch. + + The names of init container name managed by the operator are: + * `init-config-reloader`. + + Overriding init containers is entirely outside the scope of what the + maintainers will support and by doing so, you accept that this behaviour + may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedKeepDroppedTargets. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelLimit. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelNameLengthLimit. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelValueLengthLimit. + format: int64 + type: integer + listenLocal: + description: |- + When true, the Prometheus server listens on the loopback address + instead of the Pod IP's address. + type: boolean + logFormat: + description: Log format for Log level for Prometheus and the config-reloader sidecar. + enum: + - "" + - logfmt + - json + type: string + logLevel: + description: Log level for Prometheus and the config-reloader sidecar. + enum: + - "" + - debug + - info + - warn + - error + type: string + maximumStartupDurationSeconds: + description: |- + Defines the maximum time that the `prometheus` container's startup probe will wait before being considered failed. The startup probe will return success after the WAL replay is complete. + If set, the value should be greater than 60 (seconds). Otherwise it will be equal to 600 seconds (15 minutes). + format: int32 + minimum: 60 + type: integer + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created Pod should be ready + without any of its container crashing for it to be considered available. + + If unset, pods will be considered available as soon as they are ready. + format: int32 + minimum: 0 + type: integer + mode: + description: |- + Mode defines how the Prometheus operator deploys the PrometheusAgent pod(s). + + (Alpha) Using this field requires the `PrometheusAgentDaemonSet` feature gate to be enabled. + enum: + - StatefulSet + - DaemonSet + type: string + nameEscapingScheme: + description: |- + Specifies the character escaping scheme that will be requested when scraping + for metric and label names that do not conform to the legacy Prometheus + character set. + + It requires Prometheus >= v3.4.0. + enum: + - AllowUTF8 + - Underscores + - Dots + - Values + type: string + nameValidationScheme: + description: |- + Specifies the validation scheme for metric and label names. + + It requires Prometheus >= v2.55.0. + enum: + - UTF8 + - Legacy + type: string + nodeSelector: + additionalProperties: + type: string + description: Defines on which Nodes the Pods are scheduled. + type: object + otlp: + description: |- + Settings related to the OTLP receiver feature. + It requires Prometheus >= v2.55.0. + properties: + convertHistogramsToNHCB: + description: |- + Configures optional translation of OTLP explicit bucket histograms into native histograms with custom buckets. + It requires Prometheus >= v3.4.0. + type: boolean + ignoreResourceAttributes: + description: |- + List of OpenTelemetry resource attributes to ignore when `promoteAllResourceAttributes` is true. + + It requires `promoteAllResourceAttributes` to be true. + It requires Prometheus >= v3.5.0. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + keepIdentifyingResourceAttributes: + description: |- + Enables adding `service.name`, `service.namespace` and `service.instance.id` + resource attributes to the `target_info` metric, on top of converting them into the `instance` and `job` labels. + + It requires Prometheus >= v3.1.0. + type: boolean + promoteAllResourceAttributes: + description: |- + Promote all resource attributes to metric labels except the ones defined in `ignoreResourceAttributes`. + + Cannot be true when `promoteResourceAttributes` is defined. + It requires Prometheus >= v3.5.0. + type: boolean + promoteResourceAttributes: + description: |- + List of OpenTelemetry Attributes that should be promoted to metric labels, defaults to none. + Cannot be defined when `promoteAllResourceAttributes` is true. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + translationStrategy: + description: |- + Configures how the OTLP receiver endpoint translates the incoming metrics. + + It requires Prometheus >= v3.0.0. + enum: + - NoUTF8EscapingWithSuffixes + - UnderscoreEscapingWithSuffixes + - NoTranslation + type: string + type: object + overrideHonorLabels: + description: |- + When true, Prometheus resolves label conflicts by renaming the labels in the scraped data + to “exported_” for all targets created from ServiceMonitor, PodMonitor and + ScrapeConfig objects. Otherwise the HonorLabels field of the service or pod monitor applies. + In practice,`overrideHonorLaels:true` enforces `honorLabels:false` + for all ServiceMonitor, PodMonitor and ScrapeConfig objects. + type: boolean + overrideHonorTimestamps: + description: |- + When true, Prometheus ignores the timestamps for all the targets created + from service and pod monitors. + Otherwise the HonorTimestamps field of the service or pod monitor applies. + type: boolean + paused: + description: |- + When a Prometheus deployment is paused, no actions except for deletion + will be performed on the underlying objects. + type: boolean + persistentVolumeClaimRetentionPolicy: + description: |- + The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet. + The default behavior is all PVCs are retained. + This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26. + It requires enabling the StatefulSetAutoDeletePVC feature gate. + properties: + whenDeleted: + description: |- + WhenDeleted specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is deleted. The default policy + of `Retain` causes PVCs to not be affected by StatefulSet deletion. The + `Delete` policy causes those PVCs to be deleted. + type: string + whenScaled: + description: |- + WhenScaled specifies what happens to PVCs created from StatefulSet + VolumeClaimTemplates when the StatefulSet is scaled down. The default + policy of `Retain` causes PVCs to not be affected by a scaledown. The + `Delete` policy causes the associated PVCs for any excess pods above + the replica count to be deleted. + type: string + type: object + podMetadata: + description: |- + PodMetadata configures labels and annotations which are propagated to the Prometheus pods. + + The following items are reserved and cannot be overridden: + * "prometheus" label, set to the name of the Prometheus object. + * "app.kubernetes.io/instance" label, set to the name of the Prometheus object. + * "app.kubernetes.io/managed-by" label, set to "prometheus-operator". + * "app.kubernetes.io/name" label, set to "prometheus". + * "app.kubernetes.io/version" label, set to the Prometheus version. + * "operator.prometheus.io/name" label, set to the name of the Prometheus object. + * "operator.prometheus.io/shard" label, set to the shard number of the Prometheus object. + * "kubectl.kubernetes.io/default-container" annotation, set to "prometheus". + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + podMonitorNamespaceSelector: + description: |- + Namespaces to match for PodMonitors discovery. An empty label selector + matches all namespaces. A null label selector (default value) matches the current + namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podMonitorSelector: + description: |- + PodMonitors to be selected for target discovery. An empty label selector + matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podTargetLabels: + description: |- + PodTargetLabels are appended to the `spec.podTargetLabels` field of all + PodMonitor and ServiceMonitor objects. + items: + type: string + type: array + portName: + default: web + description: |- + Port name used for the pods and governing service. + Default: "web" + type: string + priorityClassName: + description: Priority class assigned to the Pods. + type: string + probeNamespaceSelector: + description: |- + Namespaces to match for Probe discovery. An empty label + selector matches all namespaces. A null label selector matches the + current namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + probeSelector: + description: |- + Probes to be selected for target discovery. An empty label selector + matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + prometheusExternalLabelName: + description: |- + Name of Prometheus external label used to denote the Prometheus instance + name. The external label will _not_ be added when the field is set to + the empty string (`""`). + + Default: "prometheus" + type: string + reloadStrategy: + description: |- + Defines the strategy used to reload the Prometheus configuration. + If not specified, the configuration is reloaded using the /-/reload HTTP endpoint. + enum: + - HTTP + - ProcessSignal + type: string + remoteWrite: + description: Defines the list of remote write configurations. + items: + description: |- + RemoteWriteSpec defines the configuration to write samples from Prometheus + to a remote endpoint. + properties: + authorization: + description: |- + Authorization section for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + azureAd: + description: |- + AzureAD for the URL. + + It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`. + properties: + cloud: + description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'. + enum: + - AzureChina + - AzureGovernment + - AzurePublic + type: string + managedIdentity: + description: |- + ManagedIdentity defines the Azure User-assigned Managed identity. + Cannot be set at the same time as `oauth` or `sdk`. + properties: + clientId: + description: The client id + type: string + required: + - clientId + type: object + oauth: + description: |- + OAuth defines the oauth config that is being used to authenticate. + Cannot be set at the same time as `managedIdentity` or `sdk`. + + It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0. + properties: + clientId: + description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + type: string + clientSecret: + description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.' + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tenantId: + description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + pattern: ^[0-9a-zA-Z-.]+$ + type: string + required: + - clientId + - clientSecret + - tenantId + type: object + sdk: + description: |- + SDK defines the Azure SDK config that is being used to authenticate. + See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication + Cannot be set at the same time as `oauth` or `managedIdentity`. + + It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0. + properties: + tenantId: + description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.' + pattern: ^[0-9a-zA-Z-.]+$ + type: string + type: object + type: object + basicAuth: + description: |- + BasicAuth configuration for the URL. + + Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File from which to read bearer token for the URL. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + type: boolean + headers: + additionalProperties: + type: string + description: |- + Custom HTTP headers to be sent along with each remote write request. + Be aware that headers that are set by Prometheus itself can't be overwritten. + + It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0. + type: object + messageVersion: + description: |- + The Remote Write message's version to use when writing to the endpoint. + + `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0. + `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0. + + When `Version2.0` is selected, Prometheus will automatically be + configured to append the metadata of scraped metrics to the WAL. + + Before setting this field, consult with your remote storage provider + what message version it supports. + + It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0. + enum: + - V1.0 + - V2.0 + type: string + metadataConfig: + description: MetadataConfig configures the sending of series metadata to the remote storage. + properties: + maxSamplesPerSend: + description: |- + MaxSamplesPerSend is the maximum number of metadata samples per send. + + It requires Prometheus >= v2.29.0. + format: int32 + minimum: -1 + type: integer + send: + description: Defines whether metric metadata is sent to the remote storage or not. + type: boolean + sendInterval: + description: Defines how frequently metric metadata is sent to the remote storage. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + name: + description: |- + The name of the remote write queue, it must be unique if specified. The + name is used in metrics and logging in order to differentiate queues. + + It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + OAuth2 configuration for the URL. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + queueConfig: + description: QueueConfig allows tuning of the remote write queue parameters. + properties: + batchSendDeadline: + description: BatchSendDeadline is the maximum time a sample will wait in buffer. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + capacity: + description: |- + Capacity is the number of samples to buffer per shard before we start + dropping them. + type: integer + maxBackoff: + description: MaxBackoff is the maximum retry delay. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + maxRetries: + description: MaxRetries is the maximum number of times to retry a batch on recoverable errors. + type: integer + maxSamplesPerSend: + description: MaxSamplesPerSend is the maximum number of samples per send. + type: integer + maxShards: + description: MaxShards is the maximum number of shards, i.e. amount of concurrency. + type: integer + minBackoff: + description: MinBackoff is the initial retry delay. Gets doubled for every retry. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + minShards: + description: MinShards is the minimum number of shards, i.e. amount of concurrency. + type: integer + retryOnRateLimit: + description: |- + Retry upon receiving a 429 status code from the remote-write storage. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + type: boolean + sampleAgeLimit: + description: |- + SampleAgeLimit drops samples older than the limit. + It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + remoteTimeout: + description: Timeout for requests to the remote write endpoint. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + roundRobinDNS: + description: |- + When enabled: + - The remote-write mechanism will resolve the hostname via DNS. + - It will randomly select one of the resolved IP addresses and connect to it. + + When disabled (default behavior): + - The Go standard library will handle hostname resolution. + - It will attempt connections to each resolved IP address sequentially. + + Note: The connection timeout applies to the entire resolution and connection process. + If disabled, the timeout is distributed across all connection attempts. + + It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0. + type: boolean + sendExemplars: + description: |- + Enables sending of exemplars over remote write. Note that + exemplar-storage itself must be enabled using the `spec.enableFeatures` + option for exemplars to be scraped in the first place. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + type: boolean + sendNativeHistograms: + description: |- + Enables sending of native histograms, also known as sparse histograms + over remote write. + + It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0. + type: boolean + sigv4: + description: |- + Sigv4 allows to configures AWS's Signature Verification 4 for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + accessKey: + description: |- + AccessKey is the AWS API key. If not specified, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: |- + SecretKey is the AWS API secret. If not specified, the environment + variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + description: TLS Config to use for the URL. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: The URL of the endpoint to send samples to. + minLength: 1 + type: string + writeRelabelConfigs: + description: The list of remote write relabel configurations. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + required: + - url + type: object + type: array + remoteWriteReceiverMessageVersions: + description: |- + List of the protobuf message versions to accept when receiving the + remote writes. + + It requires Prometheus >= v2.54.0. + items: + enum: + - V1.0 + - V2.0 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + replicaExternalLabelName: + description: |- + Name of Prometheus external label used to denote the replica name. + The external label will _not_ be added when the field is set to the + empty string (`""`). + + Default: "prometheus_replica" + type: string + replicas: + description: |- + Number of replicas of each shard to deploy for a Prometheus deployment. + `spec.replicas` multiplied by `spec.shards` is the total number of Pods + created. + + Default: 1 + format: int32 + type: integer + resources: + description: Defines the resources requests and limits of the 'prometheus' container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + routePrefix: + description: |- + The route prefix Prometheus registers HTTP handlers for. + + This is useful when using `spec.externalURL`, and a proxy is rewriting + HTTP routes of a request, and the actual ExternalURL is still true, but + the server serves requests under a different route prefix. For example + for use with `kubectl proxy`. + type: string + runtime: + description: RuntimeConfig configures the values for the Prometheus process behavior + properties: + goGC: + description: |- + The Go garbage collection target percentage. Lowering this number may increase the CPU usage. + See: https://tip.golang.org/doc/gc-guide#GOGC + format: int32 + minimum: -1 + type: integer + type: object + sampleLimit: + description: |- + SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedSampleLimit. + format: int64 + type: integer + scrapeClasses: + description: |- + List of scrape classes to expose to scraping objects such as + PodMonitors, ServiceMonitors, Probes and ScrapeConfigs. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + items: + properties: + attachMetadata: + description: |- + AttachMetadata configures additional metadata to the discovered targets. + When the scrape object defines its own configuration, it takes + precedence over the scrape class configuration. + properties: + node: + description: |- + When set to true, Prometheus attaches node metadata to the discovered + targets. + + The Prometheus service account must have the `list` and `watch` + permissions on the `Nodes` objects. + type: boolean + type: object + authorization: + description: |- + Authorization section for the ScrapeClass. + It will only apply if the scrape resource doesn't specify any Authorization. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + default: + description: |- + Default indicates that the scrape applies to all scrape objects that + don't configure an explicit scrape class name. + + Only one scrape class can be set as the default. + type: boolean + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + It will only apply if the scrape resource doesn't specify any FallbackScrapeProtocol + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + metricRelabelings: + description: |- + MetricRelabelings configures the relabeling rules to apply to all samples before ingestion. + + The Operator adds the scrape class metric relabelings defined here. + Then the Operator adds the target-specific metric relabelings defined in ServiceMonitors, PodMonitors, Probes and ScrapeConfigs. + Then the Operator adds namespace enforcement relabeling rule, specified in '.spec.enforcedNamespaceLabel'. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + name: + description: Name of the scrape class. + minLength: 1 + type: string + relabelings: + description: |- + Relabelings configures the relabeling rules to apply to all scrape targets. + + The Operator automatically adds relabelings for a few standard Kubernetes fields + like `__meta_kubernetes_namespace` and `__meta_kubernetes_service_name`. + Then the Operator adds the scrape class relabelings defined here. + Then the Operator adds the target-specific relabelings defined in the scrape object. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + tlsConfig: + description: |- + TLSConfig defines the TLS settings to use for the scrape. When the + scrape objects define their own CA, certificate and/or key, they take + precedence over the corresponding scrape class fields. + + For now only the `caFile`, `certFile` and `keyFile` fields are supported. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + + It requires Prometheus >= v3.5.0. + type: boolean + scrapeConfigNamespaceSelector: + description: |- + Namespaces to match for ScrapeConfig discovery. An empty label selector + matches all namespaces. A null label selector matches the current + namespace only. + + Note that the ScrapeConfig custom resource definition is currently at Alpha level. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + scrapeConfigSelector: + description: |- + ScrapeConfigs to be selected for target discovery. An empty label + selector matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + + Note that the ScrapeConfig custom resource definition is currently at Alpha level. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + scrapeFailureLogFile: + description: |- + File to which scrape failures are logged. + Reloading the configuration will reopen the file. + + If the filename has an empty path, e.g. 'file.log', The Prometheus Pods + will mount the file into an emptyDir volume at `/var/log/prometheus`. + If a full path is provided, e.g. '/var/log/prometheus/file.log', you + must mount a volume in the specified directory and it must be writable. + It requires Prometheus >= v2.55.0. + minLength: 1 + type: string + scrapeInterval: + default: 30s + description: |- + Interval between consecutive scrapes. + + Default: "30s" + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + scrapeProtocols: + description: |- + The protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + + `PrometheusText1.0.0` requires Prometheus >= v3.0.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + type: array + x-kubernetes-list-type: set + scrapeTimeout: + description: |- + Number of seconds to wait until a scrape request times out. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + secrets: + description: |- + Secrets is a list of Secrets in the same namespace as the Prometheus + object, which shall be mounted into the Prometheus Pods. + Each Secret is added to the StatefulSet definition as a volume named `secret-`. + The Secrets are mounted into /etc/prometheus/secrets/ in the 'prometheus' container. + items: + type: string + type: array + x-kubernetes-list-type: set + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + This defaults to the default PodSecurityContext. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run the + Prometheus Pods. + type: string + serviceDiscoveryRole: + description: |- + Defines the service discovery role used to discover targets from + `ServiceMonitor` objects and Alertmanager endpoints. + + If set, the value should be either "Endpoints" or "EndpointSlice". + If unset, the operator assumes the "Endpoints" role. + enum: + - Endpoints + - EndpointSlice + type: string + serviceMonitorNamespaceSelector: + description: |- + Namespaces to match for ServicedMonitors discovery. An empty label selector + matches all namespaces. A null label selector (default value) matches the current + namespace only. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceMonitorSelector: + description: |- + ServiceMonitors to be selected for target discovery. An empty label + selector matches all objects. A null label selector matches no objects. + + If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector` + and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged. + The Prometheus operator will ensure that the Prometheus configuration's + Secret exists, but it is the responsibility of the user to provide the raw + gzipped Prometheus configuration under the `prometheus.yaml.gz` key. + This behavior is *deprecated* and will be removed in the next major version + of the custom resource definition. It is recommended to use + `spec.additionalScrapeConfigs` instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceName: + description: |- + The name of the service name used by the underlying StatefulSet(s) as the governing service. + If defined, the Service must be created before the Prometheus/PrometheusAgent resource in the same namespace and it must define a selector that matches the pod labels. + If empty, the operator will create and manage a headless service named `prometheus-operated` for Prometheus resources, + or `prometheus-agent-operated` for PrometheusAgent resources. + When deploying multiple Prometheus/PrometheusAgent resources in the same namespace, it is recommended to specify a different value for each. + See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details. + minLength: 1 + type: string + shards: + description: |- + Number of shards to distribute the scraped targets onto. + + `spec.replicas` multiplied by `spec.shards` is the total number of Pods + being created. + + When not defined, the operator assumes only one shard. + + Note that scaling down shards will not reshard data onto the remaining + instances, it must be manually moved. Increasing shards will not reshard + data either but it will continue to be available from the same + instances. To query globally, use either + * Thanos sidecar + querier for query federation and Thanos Ruler for rules. + * Remote-write to send metrics to a central location. + + By default, the sharding of targets is performed on: + * The `__address__` target's metadata label for PodMonitor, + ServiceMonitor and ScrapeConfig resources. + * The `__param_target__` label for Probe resources. + + Users can define their own sharding implementation by setting the + `__tmp_hash` label during the target discovery with relabeling + configuration (either in the monitoring resources or via scrape class). + + You can also disable sharding on a specific target by setting the + `__tmp_disable_sharding` label with relabeling configuration. When + the label value isn't empty, all Prometheus shards will scrape the target. + format: int32 + type: integer + storage: + description: Storage defines the storage used by Prometheus. + properties: + disableMountSubPath: + description: 'Deprecated: subPath usage will be removed in a future release.' + type: boolean + emptyDir: + description: |- + EmptyDirVolumeSource to be used by the StatefulSet. + If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + EphemeralVolumeSource to be used by the StatefulSet. + This is a beta field in k8s 1.21 and GA in 1.15. + For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate. + More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + description: |- + Defines the PVC spec to be used by the Prometheus StatefulSets. + The easiest way to use a volume that cannot be automatically provisioned + is to use a label selector alongside manually created PersistentVolumes. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + spec: + description: |- + Defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + status: + description: 'Deprecated: this field is never set.' + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume operation. It can be in any of following states:\n - Pending\n Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\n the specified VolumeAttributesClass not existing.\n - InProgress\n InProgress indicates that the volume is being modified.\n - Infeasible\n Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass needs to be specified.\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: object + targetLimit: + description: |- + TargetLimit defines a limit on the number of scraped targets that will be accepted. + Only valid in Prometheus versions 2.45.0 and newer. + + Note that the global limit only applies to scrape objects that don't specify an explicit limit value. + If you want to enforce a maximum limit for all scrape objects, refer to enforcedTargetLimit. + format: int64 + type: integer + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down) which may lead to data corruption. + + Defaults to 600 seconds. + format: int64 + minimum: 0 + type: integer + tolerations: + description: Defines the Pods' tolerations if specified. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: Defines the pod's topology spread constraints if specified. + items: + properties: + additionalLabelSelectors: + description: Defines what Prometheus Operator managed labels should be added to labelSelector on the topologySpreadConstraint. + enum: + - OnResource + - OnShard + type: string + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + tracingConfig: + description: |- + TracingConfig configures tracing in Prometheus. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + properties: + clientType: + description: Client used to export the traces. Supported values are `http` or `grpc`. + enum: + - http + - grpc + type: string + compression: + description: Compression key for supported compression types. The only supported value is `gzip`. + enum: + - gzip + type: string + endpoint: + description: Endpoint to send the traces to. Should be provided in format :. + minLength: 1 + type: string + headers: + additionalProperties: + type: string + description: Key-value pairs to be used as headers associated with gRPC or HTTP requests. + type: object + insecure: + description: If disabled, the client will use a secure connection. + type: boolean + samplingFraction: + anyOf: + - type: integer + - type: string + description: Sets the probability a given trace will be sampled. Must be a float from 0 through 1. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + timeout: + description: Maximum time the exporter will wait for each batch export. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS Config to use when sending traces. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - endpoint + type: object + tsdb: + description: |- + Defines the runtime reloadable configuration of the timeseries database(TSDB). + It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0. + properties: + outOfOrderTimeWindow: + description: |- + Configures how old an out-of-order/out-of-bounds sample can be with + respect to the TSDB max time. + + An out-of-order/out-of-bounds sample is ingested into the TSDB as long as + the timestamp of the sample is >= (TSDB.MaxTime - outOfOrderTimeWindow). + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + + It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + version: + description: |- + Version of Prometheus being deployed. The operator uses this information + to generate the Prometheus StatefulSet + configuration files. + + If not specified, the operator assumes the latest upstream version of + Prometheus available at the time when the version of the operator was + released. + type: string + volumeMounts: + description: |- + VolumeMounts allows the configuration of additional VolumeMounts. + + VolumeMounts will be appended to other VolumeMounts in the 'prometheus' + container, that are generated as a result of StorageSpec objects. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Volumes allows the configuration of additional volumes on the output + StatefulSet definition. Volumes specified will be appended to other + volumes that are generated as a result of StorageSpec objects. + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + walCompression: + description: |- + Configures compression of the write-ahead log (WAL) using Snappy. + + WAL compression is enabled by default for Prometheus >= 2.20.0 + + Requires Prometheus v2.11.0 and above. + type: boolean + web: + description: Defines the configuration of the Prometheus web server. + properties: + httpConfig: + description: Defines HTTP parameters for web server. + properties: + headers: + description: List of headers that can be added to HTTP responses. + properties: + contentSecurityPolicy: + description: |- + Set the Content-Security-Policy header to HTTP responses. + Unset if blank. + type: string + strictTransportSecurity: + description: |- + Set the Strict-Transport-Security header to HTTP responses. + Unset if blank. + Please make sure that you use this with care as this header might force + browsers to load Prometheus and the other applications hosted on the same + domain and subdomains over HTTPS. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + type: string + xContentTypeOptions: + description: |- + Set the X-Content-Type-Options header to HTTP responses. + Unset if blank. Accepted value is nosniff. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + enum: + - "" + - NoSniff + type: string + xFrameOptions: + description: |- + Set the X-Frame-Options header to HTTP responses. + Unset if blank. Accepted values are deny and sameorigin. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + enum: + - "" + - Deny + - SameOrigin + type: string + xXSSProtection: + description: |- + Set the X-XSS-Protection header to all responses. + Unset if blank. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + type: string + type: object + http2: + description: |- + Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS. + When TLSConfig is not configured, HTTP/2 will be disabled. + Whenever the value of the field changes, a rolling update will be triggered. + type: boolean + type: object + maxConnections: + description: |- + Defines the maximum number of simultaneous connections + A zero value means that Prometheus doesn't accept any incoming connection. + format: int32 + minimum: 0 + type: integer + pageTitle: + description: The prometheus web page title. + type: string + tlsConfig: + description: Defines the TLS parameters for HTTPS. + properties: + cert: + description: |- + Secret or ConfigMap containing the TLS certificate for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `certFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: |- + Path to the TLS certificate file in the container for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `cert`. + type: string + cipherSuites: + description: |- + List of supported cipher suites for TLS versions up to TLS 1.2. + + If not defined, the Go default cipher suites are used. + Available cipher suites are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#pkg-constants + items: + type: string + type: array + client_ca: + description: |- + Secret or ConfigMap containing the CA certificate for client certificate + authentication to the server. + + It is mutually exclusive with `clientCAFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientAuthType: + description: |- + The server policy for client TLS authentication. + + For more detail on clientAuth options: + https://golang.org/pkg/crypto/tls/#ClientAuthType + type: string + clientCAFile: + description: |- + Path to the CA certificate file for client certificate authentication to + the server. + + It is mutually exclusive with `client_ca`. + type: string + curvePreferences: + description: |- + Elliptic curves that will be used in an ECDHE handshake, in preference + order. + + Available curves are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#CurveID + items: + type: string + type: array + keyFile: + description: |- + Path to the TLS private key file in the container for the web server. + + If defined, either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keySecret`. + type: string + keySecret: + description: |- + Secret containing the TLS private key for the web server. + + Either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keyFile`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: Maximum TLS version that is acceptable. + type: string + minVersion: + description: Minimum TLS version that is acceptable. + type: string + preferServerCipherSuites: + description: |- + Controls whether the server selects the client's most preferred cipher + suite, or the server's most preferred cipher suite. + + If true then the server's preference, as expressed in + the order of elements in cipherSuites, is used. + type: boolean + type: object + type: object + type: object + x-kubernetes-validations: + - message: replicas cannot be set when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.replicas))' + - message: storage cannot be set when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.storage))' + - message: shards cannot be greater than 1 when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.shards) && self.shards > 1)' + - message: persistentVolumeClaimRetentionPolicy cannot be set when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.persistentVolumeClaimRetentionPolicy))' + - message: scrapeConfigSelector cannot be set when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.scrapeConfigSelector))' + - message: probeSelector cannot be set when mode is DaemonSet + rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.probeSelector))' + status: + description: |- + Most recent observed status of the Prometheus cluster. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this Prometheus deployment. + format: int32 + type: integer + conditions: + description: The current state of the Prometheus deployment. + items: + description: |- + Condition represents the state of the resources associated with the + Prometheus, Alertmanager or ThanosRuler resource. + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: Human-readable message indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the + instance. + format: int64 + type: integer + reason: + description: Reason for the condition's last transition. + type: string + status: + description: Status of the condition. + minLength: 1 + type: string + type: + description: Type of the condition being reported. + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + paused: + description: |- + Represents whether any actions on the underlying managed objects are + being performed. Only delete actions will be performed. + type: boolean + replicas: + description: |- + Total number of non-terminated pods targeted by this Prometheus deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: The selector used to match the pods targeted by this Prometheus resource. + type: string + shardStatuses: + description: The list has one entry per shard. Each entry provides a summary of the shard status. + items: + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this shard. + format: int32 + type: integer + replicas: + description: Total number of pods targeted by this shard. + format: int32 + type: integer + shardID: + description: Identifier of the shard. + type: string + unavailableReplicas: + description: Total number of unavailable pods targeted by this shard. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this shard + that have the desired spec. + format: int32 + type: integer + required: + - availableReplicas + - replicas + - shardID + - unavailableReplicas + - updatedReplicas + type: object + type: array + x-kubernetes-list-map-keys: + - shardID + x-kubernetes-list-type: map + shards: + description: Shards is the most recently observed number of shards. + format: int32 + type: integer + unavailableReplicas: + description: Total number of unavailable pods targeted by this Prometheus deployment. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this Prometheus deployment + that have the desired version spec. + format: int32 + type: integer + required: + - availableReplicas + - paused + - replicas + - unavailableReplicas + - updatedReplicas + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.shards + statusReplicasPath: .status.shards + status: {} diff --git a/release/kubernetes/monitoring/setup/0prometheusruleCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0prometheusruleCustomResourceDefinition.yaml new file mode 100644 index 000000000..7da6fea29 --- /dev/null +++ b/release/kubernetes/monitoring/setup/0prometheusruleCustomResourceDefinition.yaml @@ -0,0 +1,168 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: prometheusrules.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PrometheusRule + listKind: PrometheusRuleList + plural: prometheusrules + shortNames: + - promrule + singular: prometheusrule + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + The `PrometheusRule` custom resource definition (CRD) defines [alerting](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) and [recording](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) rules to be evaluated by `Prometheus` or `ThanosRuler` objects. + + `Prometheus` and `ThanosRuler` objects select `PrometheusRule` objects using label and namespace selectors. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of desired alerting rule definitions for Prometheus. + properties: + groups: + description: Content of Prometheus rule file + items: + description: RuleGroup is a list of sequentially evaluated recording and alerting rules. + properties: + interval: + description: Interval determines how often rules in the group are evaluated. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + labels: + additionalProperties: + type: string + description: |- + Labels to add or overwrite before storing the result for its rules. + The labels defined at the rule level take precedence. + + It requires Prometheus >= 3.0.0. + The field is ignored for Thanos Ruler. + type: object + limit: + description: |- + Limit the number of alerts an alerting rule and series a recording + rule can produce. + Limit is supported starting with Prometheus >= 2.31 and Thanos Ruler >= 0.24. + type: integer + name: + description: Name of the rule group. + minLength: 1 + type: string + partial_response_strategy: + description: |- + PartialResponseStrategy is only used by ThanosRuler and will + be ignored by Prometheus instances. + More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response + pattern: ^(?i)(abort|warn)?$ + type: string + query_offset: + description: |- + Defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past. + + It requires Prometheus >= v2.53.0. + It is not supported for ThanosRuler. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + rules: + description: List of alerting and recording rules. + items: + description: |- + Rule describes an alerting or recording rule + See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) rule + properties: + alert: + description: |- + Name of the alert. Must be a valid label value. + Only one of `record` and `alert` must be set. + type: string + annotations: + additionalProperties: + type: string + description: |- + Annotations to add to each alert. + Only valid for alerting rules. + type: object + expr: + anyOf: + - type: integer + - type: string + description: PromQL expression to evaluate. + x-kubernetes-int-or-string: true + for: + description: Alerts are considered firing once they have been returned for this long. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + keep_firing_for: + description: KeepFiringFor defines how long an alert will continue firing after the condition that triggered it has cleared. + minLength: 1 + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + labels: + additionalProperties: + type: string + description: Labels to add or overwrite. + type: object + record: + description: |- + Name of the time series to output to. Must be a valid metric name. + Only one of `record` and `alert` must be set. + type: string + required: + - expr + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/release/kubernetes/monitoring/setup/0scrapeconfigCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0scrapeconfigCustomResourceDefinition.yaml new file mode 100644 index 000000000..add8846ba --- /dev/null +++ b/release/kubernetes/monitoring/setup/0scrapeconfigCustomResourceDefinition.yaml @@ -0,0 +1,11689 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: scrapeconfigs.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ScrapeConfig + listKind: ScrapeConfigList + plural: scrapeconfigs + shortNames: + - scfg + singular: scrapeconfig + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ScrapeConfig defines a namespaced Prometheus scrape_config to be aggregated across + multiple namespaces into the Prometheus configuration. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ScrapeConfigSpec is a specification of the desired configuration for a scrape configuration. + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + azureSDConfigs: + description: AzureSDConfigs defines a list of Azure service discovery configurations. + items: + description: |- + AzureSDConfig allow retrieving scrape targets from Azure VMs. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#azure_sd_config + properties: + authenticationMethod: + description: |- + # The authentication method, either `OAuth` or `ManagedIdentity` or `SDK`. + See https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview + SDK authentication method uses environment variables by default. + See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication + enum: + - OAuth + - ManagedIdentity + - SDK + type: string + authorization: + description: |- + Authorization header configuration to authenticate against the target HTTP endpoint. + Cannot be set at the same time as `oAuth2`, or `basicAuth`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth information to authenticate against the target HTTP endpoint. + More info: https://prometheus.io/docs/operating/configuration/#endpoints + Cannot be set at the same time as `authorization`, or `oAuth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientID: + description: Optional client ID. Only required with the OAuth authentication method. + minLength: 1 + type: string + clientSecret: + description: Optional client secret. Only required with the OAuth authentication method. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + environment: + description: The Azure environment. + minLength: 1 + type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration to authenticate against the target HTTP endpoint. + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + resourceGroup: + description: |- + Optional resource group name. Limits discovery to this resource group. + Requires Prometheus v2.35.0 and above + minLength: 1 + type: string + subscriptionID: + description: The subscription ID. Always required. + minLength: 1 + type: string + tenantID: + description: Optional tenant ID. Only required with the OAuth authentication method. + minLength: 1 + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - subscriptionID + type: object + type: array + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + consulSDConfigs: + description: ConsulSDConfigs defines a list of Consul service discovery configurations. + items: + description: |- + ConsulSDConfig defines a Consul service discovery configuration + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#consul_sd_config + properties: + allowStale: + description: |- + Allow stale Consul results (see https://www.consul.io/api/features/consistency.html). Will reduce load on Consul. + If unset, Prometheus uses its default value. + type: boolean + authorization: + description: |- + Optional Authorization header configuration to authenticate against the Consul Server. + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + Optional BasicAuth information to authenticate against the Consul Server. + More info: https://prometheus.io/docs/operating/configuration/#endpoints + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + datacenter: + description: Consul Datacenter name, if not provided it will use the local Consul Agent Datacenter. + minLength: 1 + type: string + enableHTTP2: + description: |- + Whether to enable HTTP2. + If unset, Prometheus uses its default value. + type: boolean + filter: + description: |- + Filter expression used to filter the catalog results. + See https://www.consul.io/api-docs/catalog#list-services + It requires Prometheus >= 3.0.0. + minLength: 1 + type: string + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + If unset, Prometheus uses its default value. + type: boolean + namespace: + description: |- + Namespaces are only supported in Consul Enterprise. + + It requires Prometheus >= 2.28.0. + minLength: 1 + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + nodeMeta: + additionalProperties: + type: string + description: |- + Node metadata key/value pairs to filter nodes for a given service. + Starting with Consul 1.14, it is recommended to use `filter` with the `NodeMeta` selector instead. + type: object + x-kubernetes-map-type: atomic + oauth2: + description: |- + Optional OAuth2.0 configuration. + Cannot be set at the same time as `basicAuth`, or `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + partition: + description: Admin Partitions are only supported in Consul Enterprise. + minLength: 1 + type: string + pathPrefix: + description: |- + Prefix for URIs for when consul is behind an API gateway (reverse proxy). + + It requires Prometheus >= 2.45.0. + minLength: 1 + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: |- + The time after which the provided names are refreshed. + On large setup it might be a good idea to increase this value because the catalog will change all the time. + If unset, Prometheus uses its default value. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + scheme: + description: HTTP Scheme default "http" + enum: + - HTTP + - HTTPS + type: string + server: + description: Consul server address. A valid string consisting of a hostname or IP followed by an optional port number. + minLength: 1 + type: string + services: + description: A list of services for which targets are retrieved. If omitted, all services are scraped. + items: + type: string + type: array + x-kubernetes-list-type: set + tagSeparator: + description: |- + The string by which Consul tags are joined into the tag label. + If unset, Prometheus uses its default value. + minLength: 1 + type: string + tags: + description: |- + An optional list of tags used to filter nodes for a given service. Services must contain all tags in the list. + Starting with Consul 1.14, it is recommended to use `filter` with the `ServiceTags` selector instead. + items: + type: string + type: array + x-kubernetes-list-type: set + tlsConfig: + description: TLS configuration to connect to the Consul API. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenRef: + description: Consul ACL TokenRef, if not provided it will use the ACL from the local Consul Agent. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - server + type: object + type: array + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean + digitalOceanSDConfigs: + description: DigitalOceanSDConfigs defines a list of DigitalOcean service discovery configurations. + items: + description: |- + DigitalOceanSDConfig allow retrieving scrape targets from DigitalOcean's Droplets API. + This service discovery uses the public IPv4 address by default, by that can be changed with relabeling + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#digitalocean_sd_config + properties: + authorization: + description: |- + Authorization header configuration to authenticate against the DigitalOcean API. + Cannot be set at the same time as `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: The port to scrape metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Refresh interval to re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + dnsSDConfigs: + description: DNSSDConfigs defines a list of DNS service discovery configurations. + items: + description: |- + DNSSDConfig allows specifying a set of DNS domain names which are periodically queried to discover a list of targets. + The DNS servers to be contacted are read from /etc/resolv.conf. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dns_sd_config + properties: + names: + description: A list of DNS domain names to be queried. + items: + minLength: 1 + type: string + minItems: 1 + type: array + port: + description: |- + The port number used if the query type is not SRV + Ignored for SRV records + format: int32 + maximum: 65535 + minimum: 0 + type: integer + refreshInterval: + description: |- + RefreshInterval configures the time after which the provided names are refreshed. + If not set, Prometheus uses its default value. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: + description: |- + The type of DNS query to perform. One of SRV, A, AAAA, MX or NS. + If not set, Prometheus uses its default value. + + When set to NS, it requires Prometheus >= v2.49.0. + When set to MX, it requires Prometheus >= v2.38.0 + enum: + - A + - AAAA + - MX + - NS + - SRV + type: string + required: + - names + type: object + type: array + dockerSDConfigs: + description: DockerSDConfigs defines a list of Docker service discovery configurations. + items: + description: |- + Docker SD configurations allow retrieving scrape targets from Docker Engine hosts. + This SD discovers "containers" and will create a target for each network IP and + port the container is configured to expose. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#docker_sd_config + properties: + authorization: + description: |- + Authorization header configuration to authenticate against the Docker API. + Cannot be set at the same time as `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + filters: + description: Optional filters to limit the discovery process to a subset of the available resources. + items: + description: Filter name and value pairs to limit the discovery process to a subset of available resources. + properties: + name: + description: Name of the Filter. + type: string + values: + description: Value to filter on. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + required: + - name + - values + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + host: + description: Address of the docker daemon + minLength: 1 + type: string + hostNetworkingHost: + description: The host to use if the container is in host networking mode. + minLength: 1 + type: string + matchFirstNetwork: + description: |- + Configure whether to match the first network if the container has multiple networks defined. + If unset, Prometheus uses true by default. + It requires Prometheus >= v2.54.1. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: The port to scrape metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Time after which the container is refreshed. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - host + type: object + type: array + dockerSwarmSDConfigs: + description: DockerswarmSDConfigs defines a list of Dockerswarm service discovery configurations. + items: + description: |- + DockerSwarmSDConfig configurations allow retrieving scrape targets from Docker Swarm engine. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config + properties: + authorization: + description: Authorization header configuration to authenticate against the target HTTP endpoint. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: Optional HTTP basic authentication information. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + filters: + description: |- + Optional filters to limit the discovery process to a subset of available + resources. + The available filters are listed in the upstream documentation: + Services: https://docs.docker.com/engine/api/v1.40/#operation/ServiceList + Tasks: https://docs.docker.com/engine/api/v1.40/#operation/TaskList + Nodes: https://docs.docker.com/engine/api/v1.40/#operation/NodeList + items: + description: Filter name and value pairs to limit the discovery process to a subset of available resources. + properties: + name: + description: Name of the Filter. + type: string + values: + description: Value to filter on. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + required: + - name + - values + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + host: + description: Address of the Docker daemon + pattern: ^[a-zA-Z][a-zA-Z0-9+.-]*://.+$ + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: |- + The port to scrape metrics from, when `role` is nodes, and for discovered + tasks and services that don't have published ports. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: The time after which the service discovery data is refreshed. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + role: + description: Role of the targets to retrieve. Must be `Services`, `Tasks`, or `Nodes`. + enum: + - Services + - Tasks + - Nodes + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - host + - role + type: object + type: array + ec2SDConfigs: + description: EC2SDConfigs defines a list of EC2 service discovery configurations. + items: + description: |- + EC2SDConfig allow retrieving scrape targets from AWS EC2 instances. + The private IP address is used by default, but may be changed to the public IP address with relabeling. + The IAM credentials used must have the ec2:DescribeInstances permission to discover scrape targets + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ec2_sd_config + + The EC2 service discovery requires AWS API keys or role ARN for authentication. + BasicAuth, Authorization and OAuth2 fields are not present on purpose. + properties: + accessKey: + description: AccessKey is the AWS API key. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHTTP2: + description: |- + Whether to enable HTTP2. + It requires Prometheus >= v2.41.0 + type: boolean + filters: + description: |- + Filters can be used optionally to filter the instance list by other criteria. + Available filter criteria can be found here: + https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html + Filter API documentation: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Filter.html + It requires Prometheus >= v2.3.0 + items: + description: Filter name and value pairs to limit the discovery process to a subset of available resources. + properties: + name: + description: Name of the Filter. + type: string + values: + description: Value to filter on. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + required: + - name + - values + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + It requires Prometheus >= v2.41.0 + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + region: + description: The AWS region. + minLength: 1 + type: string + roleARN: + description: AWS Role ARN, an alternative to using AWS API keys. + minLength: 1 + type: string + secretKey: + description: SecretKey is the AWS API secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tlsConfig: + description: |- + TLS configuration to connect to the AWS EC2 API. + It requires Prometheus >= v2.41.0 + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + enableCompression: + description: |- + When false, Prometheus will request uncompressed response from the scraped target. + + It requires Prometheus >= v2.49.0. + + If unset, Prometheus uses true by default. + type: boolean + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + eurekaSDConfigs: + description: EurekaSDConfigs defines a list of Eureka service discovery configurations. + items: + description: |- + Eureka SD configurations allow retrieving scrape targets using the Eureka REST API. + Prometheus will periodically check the REST endpoint and create a target for every app instance. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#eureka_sd_config + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization` or `basic_auth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Refresh interval to re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + server: + description: The URL to connect to the Eureka server. + minLength: 1 + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - server + type: object + type: array + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + fileSDConfigs: + description: FileSDConfigs defines a list of file service discovery configurations. + items: + description: |- + FileSDConfig defines a Prometheus file service discovery configuration + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#file_sd_config + properties: + files: + description: |- + List of files to be used for file discovery. Recommendation: use absolute paths. While relative paths work, the + prometheus-operator project makes no guarantees about the working directory where the configuration file is + stored. + Files must be mounted using Prometheus.ConfigMaps or Prometheus.Secrets. + items: + description: SDFile represents a file used for service discovery + pattern: ^[^*]*(\*[^/]*)?\.(json|yml|yaml|JSON|YML|YAML)$ + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + refreshInterval: + description: RefreshInterval configures the refresh interval at which Prometheus will reload the content of the files. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + required: + - files + type: object + type: array + gceSDConfigs: + description: GCESDConfigs defines a list of GCE service discovery configurations. + items: + description: |- + GCESDConfig configures scrape targets from GCP GCE instances. + The private IP address is used by default, but may be changed to + the public IP address with relabeling. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#gce_sd_config + + The GCE service discovery will load the Google Cloud credentials + from the file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable. + See https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform + + A pre-requisite for using GCESDConfig is that a Secret containing valid + Google Cloud credentials is mounted into the Prometheus or PrometheusAgent + pod via the `.spec.secrets` field and that the GOOGLE_APPLICATION_CREDENTIALS + environment variable is set to /etc/prometheus/secrets//. + properties: + filter: + description: |- + Filter can be used optionally to filter the instance list by other criteria + Syntax of this filter is described in the filter query parameter section: + https://cloud.google.com/compute/docs/reference/latest/instances/list + minLength: 1 + type: string + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + project: + description: The Google Cloud Project ID + minLength: 1 + type: string + refreshInterval: + description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tagSeparator: + description: The tag separator is used to separate the tags on concatenation + minLength: 1 + type: string + zone: + description: The zone of the scrape targets. If you need multiple zones use multiple GCESDConfigs. + minLength: 1 + type: string + required: + - project + - zone + type: object + type: array + hetznerSDConfigs: + description: HetznerSDConfigs defines a list of Hetzner service discovery configurations. + items: + description: |- + HetznerSDConfig allow retrieving scrape targets from Hetzner Cloud API and Robot API. + This service discovery uses the public IPv4 address by default, but that can be changed with relabeling + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#hetzner_sd_config + properties: + authorization: + description: |- + Authorization header configuration, required when role is hcloud. + Role robot does not support bearer token authentication. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth information to use on every scrape request, required when role is robot. + Role hcloud does not support basic auth. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + labelSelector: + description: |- + Label selector used to filter the servers when fetching them from the API. + It requires Prometheus >= v3.5.0. + minLength: 1 + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be used at the same time as `basic_auth` or `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: The port to scrape metrics from. + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: The time after which the servers are refreshed. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + role: + description: The Hetzner role of entities that should be discovered. + enum: + - hcloud + - Hcloud + - robot + - Robot + type: string + tlsConfig: + description: TLS configuration to use on every scrape request. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - role + type: object + type: array + honorLabels: + description: HonorLabels chooses the metric's labels on collisions with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. + type: boolean + httpSDConfigs: + description: HTTPSDConfigs defines a list of HTTP service discovery configurations. + items: + description: |- + HTTPSDConfig defines a prometheus HTTP service discovery configuration + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config + properties: + authorization: + description: |- + Authorization header configuration to authenticate against the target HTTP endpoint. + Cannot be set at the same time as `oAuth2`, or `basicAuth`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth information to authenticate against the target HTTP endpoint. + More info: https://prometheus.io/docs/operating/configuration/#endpoints + Cannot be set at the same time as `authorization`, or `oAuth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration to authenticate against the target HTTP endpoint. + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: |- + RefreshInterval configures the refresh interval at which Prometheus will re-query the + endpoint to update the target list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: URL from which the targets are fetched. + minLength: 1 + pattern: ^http(s)?://.+$ + type: string + required: + - url + type: object + type: array + ionosSDConfigs: + description: IonosSDConfigs defines a list of IONOS service discovery configurations. + items: + description: |- + IonosSDConfig configurations allow retrieving scrape targets from IONOS resources. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ionos_sd_config + properties: + authorization: + description: Authorization` header configuration, required when using IONOS. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + datacenterID: + description: The unique ID of the IONOS data center. + minLength: 1 + type: string + enableHTTP2: + description: Configure whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether the HTTP requests should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: Configure whether to enable OAuth2. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: Port to scrape the metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Refresh interval to re-read the list of resources. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS configuration to use when connecting to the IONOS API. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - authorization + - datacenterID + type: object + type: array + jobName: + description: |- + The value of the `job` label assigned to the scraped metrics by default. + + The `job_name` field in the rendered scrape configuration is always controlled by the + operator to prevent duplicate job names, which Prometheus does not allow. Instead the + `job` label is set by means of relabeling configs. + minLength: 1 + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + kubernetesSDConfigs: + description: KubernetesSDConfigs defines a list of Kubernetes service discovery configurations. + items: + description: |- + KubernetesSDConfig allows retrieving scrape targets from Kubernetes' REST API. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config + properties: + apiServer: + description: |- + The API server address consisting of a hostname or IP address followed + by an optional port number. + If left empty, Prometheus is assumed to run inside + of the cluster. It will discover API servers automatically and use the pod's + CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. + minLength: 1 + type: string + attachMetadata: + description: |- + Optional metadata to attach to discovered targets. + It requires Prometheus >= v2.35.0 when using the `Pod` role and + Prometheus >= v2.37.0 for `Endpoints` and `Endpointslice` roles. + properties: + node: + description: |- + Attaches node metadata to discovered targets. + When set to true, Prometheus must have the `get` permission on the + `Nodes` objects. + Only valid for Pod, Endpoint and Endpointslice roles. + type: boolean + type: object + authorization: + description: |- + Authorization header to use on every scrape request. + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + BasicAuth information to use on every scrape request. + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + namespaces: + description: Optional namespace discovery. If omitted, Prometheus discovers targets across all namespaces. + properties: + names: + description: |- + List of namespaces where to watch for resources. + If empty and `ownNamespace` isn't true, Prometheus watches for resources in all namespaces. + items: + type: string + type: array + x-kubernetes-list-type: set + ownNamespace: + description: Includes the namespace in which the Prometheus pod runs to the list of watched namespaces. + type: boolean + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + role: + description: |- + Role of the Kubernetes entities that should be discovered. + Role `Endpointslice` requires Prometheus >= v2.21.0 + enum: + - Pod + - Endpoints + - Ingress + - Service + - Node + - EndpointSlice + type: string + selectors: + description: |- + Selector to select objects. + It requires Prometheus >= v2.17.0 + items: + description: K8SSelectorConfig is Kubernetes Selector Config + properties: + field: + description: |- + An optional field selector to limit the service discovery to resources which have fields with specific values. + e.g: `metadata.name=foobar` + minLength: 1 + type: string + label: + description: |- + An optional label selector to limit the service discovery to resources with specific labels and label values. + e.g: `node.kubernetes.io/instance-type=master` + minLength: 1 + type: string + role: + description: |- + Role specifies the type of Kubernetes resource to limit the service discovery to. + Accepted values are: Node, Pod, Endpoints, EndpointSlice, Service, Ingress. + enum: + - Pod + - Endpoints + - Ingress + - Service + - Node + - EndpointSlice + type: string + required: + - role + type: object + type: array + x-kubernetes-list-map-keys: + - role + x-kubernetes-list-type: map + tlsConfig: + description: TLS configuration to connect to the Kubernetes API. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - role + type: object + type: array + kumaSDConfigs: + description: KumaSDConfigs defines a list of Kuma service discovery configurations. + items: + description: |- + KumaSDConfig allow retrieving scrape targets from Kuma's control plane. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kuma_sd_config + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientID: + description: Client id is used by Kuma Control Plane to compute Monitoring Assignment for specific Prometheus backend. + type: string + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + fetchTimeout: + description: The time after which the monitoring assignments are refreshed. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: The time to wait between polling update requests. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + server: + description: Address of the Kuma Control Plane's MADS xDS server. + minLength: 1 + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - server + type: object + type: array + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + lightSailSDConfigs: + description: LightsailSDConfigs defines a list of Lightsail service discovery configurations. + items: + description: |- + LightSailSDConfig configurations allow retrieving scrape targets from AWS Lightsail instances. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#lightsail_sd_config + properties: + accessKey: + description: AccessKey is the AWS API key. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authorization: + description: |- + Optional `authorization` HTTP header configuration. + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + Optional HTTP basic authentication information. + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Configure whether to enable HTTP2. + type: boolean + endpoint: + description: Custom endpoint to be used. + minLength: 1 + type: string + followRedirects: + description: Configure whether the HTTP requests should follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth2.0 configuration. + Cannot be set at the same time as `basicAuth`, or `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: |- + Port to scrape the metrics from. + If using the public IP address, this must instead be specified in the relabeling rule. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Refresh interval to re-read the list of instances. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + region: + description: The AWS region. + minLength: 1 + type: string + roleARN: + description: AWS Role ARN, an alternative to using AWS API keys. + type: string + secretKey: + description: SecretKey is the AWS API secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tlsConfig: + description: TLS configuration to connect to the Puppet DB. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + linodeSDConfigs: + description: LinodeSDConfigs defines a list of Linode service discovery configurations. + items: + description: |- + LinodeSDConfig configurations allow retrieving scrape targets from Linode's Linode APIv4. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#linode_sd_config + properties: + authorization: + description: Authorization header configuration. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be used at the same time as `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: Default port to scrape metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Time after which the linode instances are refreshed. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + region: + description: Optional region to filter on. + minLength: 1 + type: string + tagSeparator: + description: The string by which Linode Instance tags are joined into the tag label. + minLength: 1 + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + metricRelabelings: + description: MetricRelabelConfigs to apply to samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + minItems: 1 + type: array + metricsPath: + description: MetricsPath HTTP path to scrape for metrics. If empty, Prometheus uses the default value (e.g. /metrics). + minLength: 1 + type: string + nameEscapingScheme: + description: |- + Metric name escaping mode to request through content negotiation. + + It requires Prometheus >= v3.4.0. + enum: + - AllowUTF8 + - Underscores + - Dots + - Values + type: string + nameValidationScheme: + description: |- + Specifies the validation scheme for metric and label names. + + It requires Prometheus >= v3.0.0. + enum: + - UTF8 + - Legacy + type: string + nativeHistogramBucketLimit: + description: |- + If there are more than this many buckets in a native histogram, + buckets will be merged to stay within the limit. + It requires Prometheus >= v2.45.0. + format: int64 + type: integer + nativeHistogramMinBucketFactor: + anyOf: + - type: integer + - type: string + description: |- + If the growth factor of one bucket to the next is smaller than this, + buckets will be merged to increase the factor sufficiently. + It requires Prometheus >= v2.50.0. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + nomadSDConfigs: + description: NomadSDConfigs defines a list of Nomad service discovery configurations. + items: + description: |- + NomadSDConfig configurations allow retrieving scrape targets from Nomad's Service API. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#nomad_sd_config + properties: + allowStale: + description: |- + The information to access the Nomad API. It is to be defined + as the Nomad documentation requires. + type: boolean + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + namespace: + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth 2.0 configuration. + Cannot be set at the same time as `authorization` or `basic_auth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: |- + Duration is a valid time duration that can be parsed by Prometheus model.ParseDuration() function. + Supported units: y, w, d, h, m, s, ms + Examples: `30s`, `1m`, `1h20m15s`, `15d` + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + region: + type: string + server: + minLength: 1 + type: string + tagSeparator: + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - server + type: object + type: array + oauth2: + description: OAuth2 configuration to use on every scrape request. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + openstackSDConfigs: + description: OpenStackSDConfigs defines a list of OpenStack service discovery configurations. + items: + description: |- + OpenStackSDConfig allow retrieving scrape targets from OpenStack Nova instances. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#openstack_sd_config + properties: + allTenants: + description: |- + Whether the service discovery should list all instances for all projects. + It is only relevant for the 'instance' role and usually requires admin permissions. + type: boolean + applicationCredentialId: + description: ApplicationCredentialID + type: string + applicationCredentialName: + description: |- + The ApplicationCredentialID or ApplicationCredentialName fields are + required if using an application credential to authenticate. Some providers + allow you to create an application credential to authenticate rather than a + password. + minLength: 1 + type: string + applicationCredentialSecret: + description: |- + The applicationCredentialSecret field is required if using an application + credential to authenticate. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + availability: + description: Availability of the endpoint to connect to. + enum: + - Public + - public + - Admin + - admin + - Internal + - internal + type: string + domainID: + description: DomainID + minLength: 1 + type: string + domainName: + description: |- + At most one of domainId and domainName must be provided if using username + with Identity V3. Otherwise, either are optional. + minLength: 1 + type: string + identityEndpoint: + description: |- + IdentityEndpoint specifies the HTTP endpoint that is required to work with + the Identity API of the appropriate version. + pattern: ^http(s)?:\/\/.+$ + type: string + password: + description: |- + Password for the Identity V2 and V3 APIs. Consult with your provider's + control panel to discover your account's preferred method of authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + projectID: + description: ' ProjectID' + minLength: 1 + type: string + projectName: + description: |- + The ProjectId and ProjectName fields are optional for the Identity V2 API. + Some providers allow you to specify a ProjectName instead of the ProjectId. + Some require both. Your provider's authentication policies will determine + how these fields influence authentication. + minLength: 1 + type: string + refreshInterval: + description: Refresh interval to re-read the instance list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + region: + description: The OpenStack Region. + minLength: 1 + type: string + role: + description: |- + The OpenStack role of entities that should be discovered. + + Note: The `LoadBalancer` role requires Prometheus >= v3.2.0. + enum: + - Instance + - Hypervisor + - LoadBalancer + type: string + tlsConfig: + description: TLS configuration applying to the target HTTP endpoint. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + userid: + description: UserID + minLength: 1 + type: string + username: + description: |- + Username is required if using Identity V2 API. Consult with your provider's + control panel to discover your account's username. + In Identity V3, either userid or a combination of username + and domainId or domainName are needed + minLength: 1 + type: string + required: + - region + - role + type: object + type: array + ovhcloudSDConfigs: + description: OVHCloudSDConfigs defines a list of OVHcloud service discovery configurations. + items: + description: |- + OVHCloudSDConfig configurations allow retrieving scrape targets from OVHcloud's dedicated servers and VPS using their API. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ovhcloud_sd_config + properties: + applicationKey: + description: Access key to use. https://api.ovh.com. + minLength: 1 + type: string + applicationSecret: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + consumerKey: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpoint: + description: Custom endpoint to be used. + minLength: 1 + type: string + refreshInterval: + description: Refresh interval to re-read the resources list. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + service: + allOf: + - enum: + - VPS + - DedicatedServer + - enum: + - VPS + - DedicatedServer + description: Service of the targets to retrieve. Must be `VPS` or `DedicatedServer`. + type: string + required: + - applicationKey + - applicationSecret + - consumerKey + - service + type: object + type: array + params: + additionalProperties: + items: + type: string + type: array + description: Optional HTTP URL parameters + type: object + x-kubernetes-map-type: atomic + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + puppetDBSDConfigs: + description: PuppetDBSDConfigs defines a list of PuppetDB service discovery configurations. + items: + description: |- + PuppetDBSDConfig configurations allow retrieving scrape targets from PuppetDB resources. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#puppetdb_sd_config + properties: + authorization: + description: |- + Optional `authorization` HTTP header configuration. + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + Optional HTTP basic authentication information. + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + enableHTTP2: + description: Configure whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether the HTTP requests should follow HTTP 3xx redirects. + type: boolean + includeParameters: + description: |- + Whether to include the parameters as meta labels. + Note: Enabling this exposes parameters in the Prometheus UI and API. Make sure + that you don't have secrets exposed as parameters if you enable this. + type: boolean + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + Optional OAuth2.0 configuration. + Cannot be set at the same time as `basicAuth`, or `authorization`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + port: + description: Port to scrape the metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + query: + description: |- + Puppet Query Language (PQL) query. Only resources are supported. + https://puppet.com/docs/puppetdb/latest/api/query/v4/pql.html + minLength: 1 + type: string + refreshInterval: + description: Refresh interval to re-read the list of resources. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + tlsConfig: + description: TLS configuration to connect to the Puppet DB. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: The URL of the PuppetDB root query endpoint. + minLength: 1 + pattern: ^http(s)?://.+$ + type: string + required: + - query + - url + type: object + type: array + relabelings: + description: |- + RelabelConfigs defines how to rewrite the target's labels before scraping. + Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields. + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + minItems: 1 + type: array + sampleLimit: + description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + format: int64 + type: integer + scalewaySDConfigs: + description: ScalewaySDConfigs defines a list of Scaleway instances and baremetal service discovery configurations. + items: + description: |- + ScalewaySDConfig configurations allow retrieving scrape targets from Scaleway instances and baremetal services. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scaleway_sd_config + properties: + accessKey: + description: Access key to use. https://console.scaleway.com/project/credentials + minLength: 1 + type: string + apiURL: + description: API URL to use when doing the server listing requests. + pattern: ^http(s)?://.+$ + type: string + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx redirects. + type: boolean + nameFilter: + description: NameFilter specify a name filter (works as a LIKE) to apply on the server listing request. + minLength: 1 + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + port: + description: The port to scrape metrics from. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + projectID: + description: Project ID of the targets. + minLength: 1 + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + refreshInterval: + description: Refresh interval to re-read the list of instances. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + role: + description: Service of the targets to retrieve. Must be `Instance` or `Baremetal`. + enum: + - Instance + - Baremetal + type: string + secretKey: + description: Secret key to use when listing targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tagsFilter: + description: TagsFilter specify a tag filter (a server needs to have all defined tags to be listed) to apply on the server listing request. + items: + minLength: 1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + zone: + description: Zone is the availability zone of your targets (e.g. fr-par-1). + minLength: 1 + type: string + required: + - accessKey + - projectID + - role + - secretKey + type: object + type: array + scheme: + description: |- + Configures the protocol scheme used for requests. + If empty, Prometheus uses HTTP by default. + enum: + - HTTP + - HTTPS + type: string + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + type: boolean + scrapeInterval: + description: ScrapeInterval is the interval between consecutive scrapes. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + scrapeProtocols: + description: |- + The protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + scrapeTimeout: + description: |- + ScrapeTimeout is the number of seconds to wait until a scrape request times out. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + staticConfigs: + description: StaticConfigs defines a list of static targets with a common label set. + items: + description: |- + StaticConfig defines a Prometheus static configuration. + See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config + properties: + labels: + additionalProperties: + type: string + description: Labels assigned to all metrics scraped from the targets. + type: object + x-kubernetes-map-type: atomic + targets: + description: List of targets for this static configuration. + items: + description: |- + Target represents a target for Prometheus to scrape + kubebuilder:validation:MinLength:=1 + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + required: + - targets + type: object + type: array + targetLimit: + description: TargetLimit defines a limit on the number of scraped targets that will be accepted. + format: int64 + type: integer + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + trackTimestampsStaleness: + description: |- + TrackTimestampsStaleness whether Prometheus tracks staleness of + the metrics that have an explicit timestamp present in scraped data. + Has no effect if `honorTimestamps` is false. + It requires Prometheus >= v2.48.0. + type: boolean + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/release/kubernetes/monitoring/setup/0servicemonitorCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0servicemonitorCustomResourceDefinition.yaml new file mode 100644 index 000000000..323844abe --- /dev/null +++ b/release/kubernetes/monitoring/setup/0servicemonitorCustomResourceDefinition.yaml @@ -0,0 +1,1324 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: servicemonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ServiceMonitor + listKind: ServiceMonitorList + plural: servicemonitors + shortNames: + - smon + singular: servicemonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + The `ServiceMonitor` custom resource definition (CRD) defines how `Prometheus` and `PrometheusAgent` can scrape metrics from a group of services. + Among other things, it allows to specify: + * The services to scrape via label selectors. + * The container ports to scrape. + * Authentication credentials to use. + * Target and metric relabeling. + + `Prometheus` and `PrometheusAgent` objects select `ServiceMonitor` objects using label and namespace selectors. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of desired Service selection for target discovery by + Prometheus. + properties: + attachMetadata: + description: |- + `attachMetadata` defines additional metadata which is added to the + discovered targets. + + It requires Prometheus >= v2.37.0. + properties: + node: + description: |- + When set to true, Prometheus attaches node metadata to the discovered + targets. + + The Prometheus service account must have the `list` and `watch` + permissions on the `Nodes` objects. + type: boolean + type: object + bodySizeLimit: + description: |- + When defined, bodySizeLimit specifies a job level limit on the size + of uncompressed response body that will be accepted by Prometheus. + + It requires Prometheus >= v2.28.0. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + convertClassicHistogramsToNHCB: + description: |- + Whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean + endpoints: + description: |- + List of endpoints part of this ServiceMonitor. + Defines how to scrape metrics from Kubernetes [Endpoints](https://kubernetes.io/docs/concepts/services-networking/service/#endpoints) objects. + In most cases, an Endpoints object is backed by a Kubernetes [Service](https://kubernetes.io/docs/concepts/services-networking/service/) object with the same name and labels. + items: + description: |- + Endpoint defines an endpoint serving Prometheus metrics to be scraped by + Prometheus. + properties: + authorization: + description: |- + `authorization` configures the Authorization header credentials to use when + scraping the target. + + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + `basicAuth` configures the Basic Authentication credentials to use when + scraping the target. + + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + description: |- + File to read bearer token for scraping the target. + + Deprecated: use `authorization` instead. + type: string + bearerTokenSecret: + description: |- + `bearerTokenSecret` specifies a key of a Secret containing the bearer + token for scraping targets. The secret needs to be in the same namespace + as the ServiceMonitor object and readable by the Prometheus Operator. + + Deprecated: use `authorization` instead. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: '`enableHttp2` can be used to disable HTTP2 when scraping the target.' + type: boolean + filterRunning: + description: |- + When true, the pods which are not running (e.g. either in Failed or + Succeeded state) are dropped during the target discovery. + + If unset, the filtering is enabled. + + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + type: boolean + followRedirects: + description: |- + `followRedirects` defines whether the scrape requests should follow HTTP + 3xx redirects. + type: boolean + honorLabels: + description: |- + When true, `honorLabels` preserves the metric's labels when they collide + with the target's labels. + type: boolean + honorTimestamps: + description: |- + `honorTimestamps` controls whether Prometheus preserves the timestamps + when exposed by the target. + type: boolean + interval: + description: |- + Interval at which Prometheus scrapes the metrics from the target. + + If empty, Prometheus uses the global scrape interval. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: |- + `metricRelabelings` configures the relabeling rules to apply to the + samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + `oauth2` configures the OAuth2 settings to use when scraping the target. + + It requires Prometheus >= 2.27.0. + + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: params define optional HTTP URL parameters. + type: object + path: + description: |- + HTTP path from which to scrape for metrics. + + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + port: + description: |- + Name of the Service port which this endpoint refers to. + + It takes precedence over `targetPort`. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + relabelings: + description: |- + `relabelings` configures the relabeling rules to apply the target's + metadata labels. + + The Operator automatically adds relabelings for a few standard Kubernetes fields. + + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: |- + HTTP scheme to use for scraping. + + `http` and `https` are the expected values unless you rewrite the + `__scheme__` label via relabeling. + + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: |- + Timeout after which Prometheus considers the scrape to be failed. + + If empty, Prometheus uses the global scrape timeout unless it is less + than the target's scrape interval value in which the latter is used. + The value cannot be greater than the scrape interval otherwise the operator will reject the resource. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the target port of the `Pod` object behind the + Service. The port must be specified with the container's port property. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the target. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + trackTimestampsStaleness: + description: |- + `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + the metrics that have an explicit timestamp present in scraped data. + Has no effect if `honorTimestamps` is false. + + It requires Prometheus >= v2.48.0. + type: boolean + type: object + type: array + fallbackScrapeProtocol: + description: |- + The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + + It requires Prometheus >= v3.0.0. + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + jobLabel: + description: |- + `jobLabel` selects the label from the associated Kubernetes `Service` + object which will be used as the `job` label for all metrics. + + For example if `jobLabel` is set to `foo` and the Kubernetes `Service` + object is labeled with `foo: bar`, then Prometheus adds the `job="bar"` + label to all ingested metrics. + + If the value of this field is empty or if the label doesn't exist for + the given Service, the `job` label of the metrics defaults to the name + of the associated Kubernetes `Service`. + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + namespaceSelector: + description: |- + `namespaceSelector` defines in which namespace(s) Prometheus should discover the services. + By default, the services are discovered in the same namespace as the `ServiceMonitor` object but it is possible to select pods across different/all namespaces. + properties: + any: + description: |- + Boolean describing whether all namespaces are selected in contrast to a + list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + nativeHistogramBucketLimit: + description: |- + If there are more than this many buckets in a native histogram, + buckets will be merged to stay within the limit. + It requires Prometheus >= v2.45.0. + format: int64 + type: integer + nativeHistogramMinBucketFactor: + anyOf: + - type: integer + - type: string + description: |- + If the growth factor of one bucket to the next is smaller than this, + buckets will be merged to increase the factor sufficiently. + It requires Prometheus >= v2.50.0. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + podTargetLabels: + description: |- + `podTargetLabels` defines the labels which are transferred from the + associated Kubernetes `Pod` object onto the ingested metrics. + items: + type: string + type: array + sampleLimit: + description: |- + `sampleLimit` defines a per-scrape limit on the number of scraped samples + that will be accepted. + format: int64 + type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeClassicHistograms: + description: |- + Whether to scrape a classic histogram that is also exposed as a native histogram. + It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. + type: boolean + scrapeProtocols: + description: |- + `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + If unset, Prometheus uses its default value. + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + * `PrometheusText1.0.0` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + - PrometheusText1.0.0 + type: string + type: array + x-kubernetes-list-type: set + selector: + description: Label selector to select the Kubernetes `Endpoints` objects to scrape metrics from. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + selectorMechanism: + description: |- + Mechanism used to select the endpoints to scrape. + By default, the selection process relies on relabel configurations to filter the discovered targets. + Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters. + Which strategy is best for your use case needs to be carefully evaluated. + + It requires Prometheus >= v2.17.0. + enum: + - RelabelConfig + - RoleSelector + type: string + targetLabels: + description: |- + `targetLabels` defines the labels which are transferred from the + associated Kubernetes `Service` object onto the ingested metrics. + items: + type: string + type: array + targetLimit: + description: |- + `targetLimit` defines a limit on the number of scraped targets that will + be accepted. + format: int64 + type: integer + required: + - endpoints + - selector + type: object + status: + description: |- + This Status subresource is under active development and is updated only when the + "StatusForConfigurationResources" feature gate is enabled. + + Most recent observed status of the ServiceMonitor. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bindings: + description: The list of workload resources (Prometheus or PrometheusAgent) which select the configuration resource. + items: + description: WorkloadBinding is a link between a configuration resource and a workload resource. + properties: + conditions: + description: The current state of the configuration resource when bound to the referenced Prometheus object. + items: + description: ConfigResourceCondition describes the status of configuration resources linked to Prometheus, PrometheusAgent, Alertmanager, or ThanosRuler. + properties: + lastTransitionTime: + description: LastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: Human-readable message indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the object. + format: int64 + type: integer + reason: + description: Reason for the condition's last transition. + type: string + status: + description: Status of the condition. + minLength: 1 + type: string + type: + description: |- + Type of the condition being reported. + Currently, only "Accepted" is supported. + enum: + - Accepted + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + group: + description: The group of the referenced resource. + enum: + - monitoring.coreos.com + type: string + name: + description: The name of the referenced object. + minLength: 1 + type: string + namespace: + description: The namespace of the referenced object. + minLength: 1 + type: string + resource: + description: The type of resource being referenced (e.g. Prometheus or PrometheusAgent). + enum: + - prometheuses + - prometheusagents + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/release/kubernetes/monitoring/setup/0thanosrulerCustomResourceDefinition.yaml b/release/kubernetes/monitoring/setup/0thanosrulerCustomResourceDefinition.yaml new file mode 100644 index 000000000..b31658ca9 --- /dev/null +++ b/release/kubernetes/monitoring/setup/0thanosrulerCustomResourceDefinition.yaml @@ -0,0 +1,8878 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + operator.prometheus.io/version: 0.85.0 + name: thanosrulers.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ThanosRuler + listKind: ThanosRulerList + plural: thanosrulers + shortNames: + - ruler + singular: thanosruler + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The version of Thanos Ruler + jsonPath: .spec.version + name: Version + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Replicas + type: integer + - description: The number of ready replicas + jsonPath: .status.availableReplicas + name: Ready + type: integer + - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status + name: Reconciled + type: string + - jsonPath: .status.conditions[?(@.type == 'Available')].status + name: Available + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Whether the resource reconciliation is paused or not + jsonPath: .status.paused + name: Paused + priority: 1 + type: boolean + name: v1 + schema: + openAPIV3Schema: + description: |- + The `ThanosRuler` custom resource definition (CRD) defines a desired [Thanos Ruler](https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md) setup to run in a Kubernetes cluster. + + A `ThanosRuler` instance requires at least one compatible Prometheus API endpoint (either Thanos Querier or Prometheus services). + + The resource defines via label and namespace selectors which `PrometheusRule` objects should be associated to the deployed Thanos Ruler instances. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the ThanosRuler cluster. More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + additionalArgs: + description: |- + AdditionalArgs allows setting additional arguments for the ThanosRuler container. + It is intended for e.g. activating hidden flags which are not supported by + the dedicated configuration options yet. The arguments are passed as-is to the + ThanosRuler container which may cause issues if they are invalid or not supported + by the given ThanosRuler version. + In case of an argument conflict (e.g. an argument which is already set by the + operator itself) or when providing an invalid argument the reconciliation will + fail and an error will be logged. + items: + description: Argument as part of the AdditionalArgs list. + properties: + name: + description: Name of the argument, e.g. "scrape.discovery-reload-interval". + minLength: 1 + type: string + value: + description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile) + type: string + required: + - name + type: object + type: array + affinity: + description: If specified, the pod's scheduling constraints. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + alertDropLabels: + description: |- + Configures the label names which should be dropped in Thanos Ruler + alerts. + + The replica label `thanos_ruler_replica` will always be dropped from the alerts. + items: + type: string + type: array + alertQueryUrl: + description: |- + The external Query URL the Thanos Ruler will set in the 'Source' field + of all alerts. + Maps to the '--alert.query-url' CLI arg. + type: string + alertRelabelConfigFile: + description: |- + Configures the path to the alert relabeling configuration file. + + Alert relabel configuration must have the form as specified in the + official Prometheus documentation: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs + + The operator performs no validation of the configuration file. + + This field takes precedence over `alertRelabelConfig`. + type: string + alertRelabelConfigs: + description: |- + Configures alert relabeling in Thanos Ruler. + + Alert relabel configuration must have the form as specified in the + official Prometheus documentation: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs + + The operator performs no validation of the configuration. + + `alertRelabelConfigFile` takes precedence over this field. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + alertmanagersConfig: + description: |- + Configures the list of Alertmanager endpoints to send alerts to. + + The configuration format is defined at https://thanos.io/tip/components/rule.md/#alertmanager. + + It requires Thanos >= v0.10.0. + + The operator performs no validation of the configuration. + + This field takes precedence over `alertmanagersUrl`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + alertmanagersUrl: + description: |- + Configures the list of Alertmanager endpoints to send alerts to. + + For Thanos >= v0.10.0, it is recommended to use `alertmanagersConfig` instead. + + `alertmanagersConfig` takes precedence over this field. + items: + type: string + type: array + containers: + description: |- + Containers allows injecting additional containers or modifying operator generated + containers. This can be used to allow adding an authentication proxy to a ThanosRuler pod or + to change the behavior of an operator generated container. Containers described here modify + an operator generated container if they share the same name and modifications are done via a + strategic merge patch. The current container names are: `thanos-ruler` and `config-reloader`. + Overriding containers is entirely outside the scope of what the maintainers will support and by doing + so, you accept that this behaviour may break at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Defines the DNS configuration for the pods. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Name is required and must be unique. + minLength: 1 + type: string + value: + description: Value is optional. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + type: object + dnsPolicy: + description: Defines the DNS policy for the pods. + enum: + - ClusterFirstWithHostNet + - ClusterFirst + - Default + - None + type: string + enableFeatures: + description: |- + Enable access to Thanos Ruler feature flags. By default, no features are enabled. + + Enabling features which are disabled by default is entirely outside the + scope of what the maintainers will support and by doing so, you accept + that this behaviour may break at any time without notice. + + For more information see https://thanos.io/tip/components/rule.md/ + + It requires Thanos >= 0.39.0. + items: + minLength: 1 + type: string + type: array + x-kubernetes-list-type: set + enableServiceLinks: + description: Indicates whether information about services should be injected into pod's environment variables + type: boolean + enforcedNamespaceLabel: + description: |- + EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert + and metric that is user created. The label value will always be the namespace of the object that is + being created. + type: string + evaluationInterval: + default: 15s + description: Interval between consecutive evaluations. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + excludedFromEnforcement: + description: |- + List of references to PrometheusRule objects + to be excluded from enforcing a namespace label of origin. + Applies only if enforcedNamespaceLabel set to true. + items: + description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object. + properties: + group: + default: monitoring.coreos.com + description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com` + enum: + - monitoring.coreos.com + type: string + name: + description: Name of the referent. When not set, all resources in the namespace are matched. + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + minLength: 1 + type: string + resource: + description: Resource of the referent. + enum: + - prometheusrules + - servicemonitors + - podmonitors + - probes + - scrapeconfigs + type: string + required: + - namespace + - resource + type: object + type: array + externalPrefix: + description: |- + The external URL the Thanos Ruler instances will be available under. This is + necessary to generate correct URLs. This is necessary if Thanos Ruler is not + served from root of a DNS name. + type: string + grpcServerTlsConfig: + description: |- + GRPCServerTLSConfig configures the gRPC server from which Thanos Querier reads + recorded rule data. + Note: Currently only the CAFile, CertFile, and KeyFile fields are supported. + Maps to the '--grpc-server-tls-*' CLI args. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + hostAliases: + description: Pods' hostAliases configuration + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + required: + - hostnames + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostUsers: + description: |- + HostUsers supports the user space in Kubernetes. + + More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/ + + The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled. + Starting Kubernetes 1.33, the feature is enabled by default. + type: boolean + image: + description: Thanos container image URL. + type: string + imagePullPolicy: + description: |- + Image pull policy for the 'thanos', 'init-config-reloader' and 'config-reloader' containers. + See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details. + enum: + - "" + - Always + - Never + - IfNotPresent + type: string + imagePullSecrets: + description: |- + An optional list of references to secrets in the same namespace + to use for pulling thanos images from registries + see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + InitContainers allows adding initContainers to the pod definition. Those can be used to e.g. + fetch secrets for injection into the ThanosRuler configuration from external sources. Any + errors during the execution of an initContainer will lead to a restart of the Pod. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + Using initContainers for any use case other then secret fetching is entirely outside the scope + of what the maintainers will support and by doing so, you accept that this behaviour may break + at any time without notice. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + Configures the external label pairs of the ThanosRuler resource. + + A default replica label `thanos_ruler_replica` will be always added as a + label with the value of the pod's name. + type: object + listenLocal: + description: |- + ListenLocal makes the Thanos ruler listen on loopback, so that it + does not bind against the Pod IP. + type: boolean + logFormat: + description: Log format for ThanosRuler to be configured with. + enum: + - "" + - logfmt + - json + type: string + logLevel: + description: Log level for ThanosRuler to be configured with. + enum: + - "" + - debug + - info + - warn + - error + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created pod should be ready + without any of its container crashing for it to be considered available. + + If unset, pods will be considered available as soon as they are ready. + format: int32 + minimum: 0 + type: integer + nodeSelector: + additionalProperties: + type: string + description: Define which Nodes the Pods are scheduled on. + type: object + objectStorageConfig: + description: |- + Configures object storage. + + The configuration format is defined at https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage + + The operator performs no validation of the configuration. + + `objectStorageConfigFile` takes precedence over this field. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + objectStorageConfigFile: + description: |- + Configures the path of the object storage configuration file. + + The configuration format is defined at https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage + + The operator performs no validation of the configuration file. + + This field takes precedence over `objectStorageConfig`. + type: string + paused: + description: |- + When a ThanosRuler deployment is paused, no actions except for deletion + will be performed on the underlying objects. + type: boolean + podMetadata: + description: |- + PodMetadata configures labels and annotations which are propagated to the ThanosRuler pods. + + The following items are reserved and cannot be overridden: + * "app.kubernetes.io/name" label, set to "thanos-ruler". + * "app.kubernetes.io/managed-by" label, set to "prometheus-operator". + * "app.kubernetes.io/instance" label, set to the name of the ThanosRuler instance. + * "thanos-ruler" label, set to the name of the ThanosRuler instance. + * "kubectl.kubernetes.io/default-container" annotation, set to "thanos-ruler". + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + portName: + default: web + description: |- + Port name used for the pods and governing service. + Defaults to `web`. + type: string + priorityClassName: + description: Priority class assigned to the Pods + type: string + prometheusRulesExcludedFromEnforce: + description: |- + PrometheusRulesExcludedFromEnforce - list of Prometheus rules to be excluded from enforcing + of adding namespace labels. Works only if enforcedNamespaceLabel set to true. + Make sure both ruleNamespace and ruleName are set for each pair + Deprecated: use excludedFromEnforcement instead. + items: + description: |- + PrometheusRuleExcludeConfig enables users to configure excluded + PrometheusRule names and their namespaces to be ignored while enforcing + namespace label for alerts and metrics. + properties: + ruleName: + description: Name of the excluded PrometheusRule object. + type: string + ruleNamespace: + description: Namespace of the excluded PrometheusRule object. + type: string + required: + - ruleName + - ruleNamespace + type: object + type: array + queryConfig: + description: |- + Configures the list of Thanos Query endpoints from which to query metrics. + + The configuration format is defined at https://thanos.io/tip/components/rule.md/#query-api + + It requires Thanos >= v0.11.0. + + The operator performs no validation of the configuration. + + This field takes precedence over `queryEndpoints`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + queryEndpoints: + description: |- + Configures the list of Thanos Query endpoints from which to query metrics. + + For Thanos >= v0.11.0, it is recommended to use `queryConfig` instead. + + `queryConfig` takes precedence over this field. + items: + type: string + type: array + remoteWrite: + description: |- + Defines the list of remote write configurations. + + When the list isn't empty, the ruler is configured with stateless mode. + + It requires Thanos >= 0.24.0. + items: + description: |- + RemoteWriteSpec defines the configuration to write samples from Prometheus + to a remote endpoint. + properties: + authorization: + description: |- + Authorization section for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + credentials: + description: Selects a key of a Secret in the namespace that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive with `credentials`. + type: string + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + "Basic" is not a supported value. + + Default: "Bearer" + type: string + type: object + azureAd: + description: |- + AzureAD for the URL. + + It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`. + properties: + cloud: + description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'. + enum: + - AzureChina + - AzureGovernment + - AzurePublic + type: string + managedIdentity: + description: |- + ManagedIdentity defines the Azure User-assigned Managed identity. + Cannot be set at the same time as `oauth` or `sdk`. + properties: + clientId: + description: The client id + type: string + required: + - clientId + type: object + oauth: + description: |- + OAuth defines the oauth config that is being used to authenticate. + Cannot be set at the same time as `managedIdentity` or `sdk`. + + It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0. + properties: + clientId: + description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + type: string + clientSecret: + description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.' + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tenantId: + description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.' + minLength: 1 + pattern: ^[0-9a-zA-Z-.]+$ + type: string + required: + - clientId + - clientSecret + - tenantId + type: object + sdk: + description: |- + SDK defines the Azure SDK config that is being used to authenticate. + See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication + Cannot be set at the same time as `oauth` or `managedIdentity`. + + It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0. + properties: + tenantId: + description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.' + pattern: ^[0-9a-zA-Z-.]+$ + type: string + type: object + type: object + basicAuth: + description: |- + BasicAuth configuration for the URL. + + Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: |- + *Warning: this field shouldn't be used because the token value appears + in clear-text. Prefer using `authorization`.* + + Deprecated: this will be removed in a future release. + type: string + bearerTokenFile: + description: |- + File from which to read bearer token for the URL. + + Deprecated: this will be removed in a future release. Prefer using `authorization`. + type: string + enableHTTP2: + description: Whether to enable HTTP2. + type: boolean + followRedirects: + description: |- + Configure whether HTTP requests follow HTTP 3xx redirects. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + type: boolean + headers: + additionalProperties: + type: string + description: |- + Custom HTTP headers to be sent along with each remote write request. + Be aware that headers that are set by Prometheus itself can't be overwritten. + + It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0. + type: object + messageVersion: + description: |- + The Remote Write message's version to use when writing to the endpoint. + + `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0. + `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0. + + When `Version2.0` is selected, Prometheus will automatically be + configured to append the metadata of scraped metrics to the WAL. + + Before setting this field, consult with your remote storage provider + what message version it supports. + + It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0. + enum: + - V1.0 + - V2.0 + type: string + metadataConfig: + description: MetadataConfig configures the sending of series metadata to the remote storage. + properties: + maxSamplesPerSend: + description: |- + MaxSamplesPerSend is the maximum number of metadata samples per send. + + It requires Prometheus >= v2.29.0. + format: int32 + minimum: -1 + type: integer + send: + description: Defines whether metric metadata is sent to the remote storage or not. + type: boolean + sendInterval: + description: Defines how frequently metric metadata is sent to the remote storage. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + name: + description: |- + The name of the remote write queue, it must be unique if specified. The + name is used in metrics and logging in order to differentiate queues. + + It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0. + type: string + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + oauth2: + description: |- + OAuth2 configuration for the URL. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + noProxy: + description: |- + `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + scopes: + description: '`scopes` defines the OAuth2 scopes used for the token request.' + items: + type: string + type: array + tlsConfig: + description: |- + TLS configuration to use when connecting to the OAuth2 server. + It requires Prometheus >= v2.43.0. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + tokenUrl: + description: '`tokenURL` configures the URL to fetch the token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + ProxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: '`proxyURL` defines the HTTP proxy server to use.' + pattern: ^(http|https|socks5)://.+$ + type: string + queueConfig: + description: QueueConfig allows tuning of the remote write queue parameters. + properties: + batchSendDeadline: + description: BatchSendDeadline is the maximum time a sample will wait in buffer. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + capacity: + description: |- + Capacity is the number of samples to buffer per shard before we start + dropping them. + type: integer + maxBackoff: + description: MaxBackoff is the maximum retry delay. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + maxRetries: + description: MaxRetries is the maximum number of times to retry a batch on recoverable errors. + type: integer + maxSamplesPerSend: + description: MaxSamplesPerSend is the maximum number of samples per send. + type: integer + maxShards: + description: MaxShards is the maximum number of shards, i.e. amount of concurrency. + type: integer + minBackoff: + description: MinBackoff is the initial retry delay. Gets doubled for every retry. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + minShards: + description: MinShards is the minimum number of shards, i.e. amount of concurrency. + type: integer + retryOnRateLimit: + description: |- + Retry upon receiving a 429 status code from the remote-write storage. + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + type: boolean + sampleAgeLimit: + description: |- + SampleAgeLimit drops samples older than the limit. + It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + type: object + remoteTimeout: + description: Timeout for requests to the remote write endpoint. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + roundRobinDNS: + description: |- + When enabled: + - The remote-write mechanism will resolve the hostname via DNS. + - It will randomly select one of the resolved IP addresses and connect to it. + + When disabled (default behavior): + - The Go standard library will handle hostname resolution. + - It will attempt connections to each resolved IP address sequentially. + + Note: The connection timeout applies to the entire resolution and connection process. + If disabled, the timeout is distributed across all connection attempts. + + It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0. + type: boolean + sendExemplars: + description: |- + Enables sending of exemplars over remote write. Note that + exemplar-storage itself must be enabled using the `spec.enableFeatures` + option for exemplars to be scraped in the first place. + + It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0. + type: boolean + sendNativeHistograms: + description: |- + Enables sending of native histograms, also known as sparse histograms + over remote write. + + It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0. + type: boolean + sigv4: + description: |- + Sigv4 allows to configures AWS's Signature Verification 4 for the URL. + + It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0. + + Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`. + properties: + accessKey: + description: |- + AccessKey is the AWS API key. If not specified, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: |- + SecretKey is the AWS API secret. If not specified, the environment + variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + description: TLS Config to use for the URL. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: |- + Maximum acceptable TLS version. + + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + minVersion: + description: |- + Minimum acceptable TLS version. + + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. + enum: + - TLS10 + - TLS11 + - TLS12 + - TLS13 + type: string + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: The URL of the endpoint to send samples to. + minLength: 1 + type: string + writeRelabelConfigs: + description: The list of remote write relabel configurations. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + Regex capture groups are available. + type: string + type: object + type: array + required: + - url + type: object + type: array + replicas: + description: Number of thanos ruler instances to deploy. + format: int32 + type: integer + resendDelay: + description: Minimum amount of time to wait before resending an alert to Alertmanager. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + resources: + description: |- + Resources defines the resource requirements for single Pods. + If not provided, no requests/limits will be set + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + retention: + default: 24h + description: |- + Time duration ThanosRuler shall retain data for. Default is '24h', and + must match the regular expression `[0-9]+(ms|s|m|h|d|w|y)` (milliseconds + seconds minutes hours days weeks years). + + The field has no effect when remote-write is configured since the Ruler + operates in stateless mode. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + routePrefix: + description: The route prefix ThanosRuler registers HTTP handlers for. This allows thanos UI to be served on a sub-path. + type: string + ruleConcurrentEval: + description: |- + How many rules can be evaluated concurrently. + It requires Thanos >= v0.37.0. + format: int32 + minimum: 1 + type: integer + ruleGracePeriod: + description: |- + Minimum duration between alert and restored "for" state. + This is maintained only for alerts with configured "for" time greater than grace period. + It requires Thanos >= v0.30.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + ruleNamespaceSelector: + description: |- + Namespaces to be selected for Rules discovery. If unspecified, only + the same namespace as the ThanosRuler object is in is used. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + ruleOutageTolerance: + description: |- + Max time to tolerate prometheus outage for restoring "for" state of alert. + It requires Thanos >= v0.30.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + ruleQueryOffset: + description: |- + The default rule group's query offset duration to use. + It requires Thanos >= v0.38.0. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + ruleSelector: + description: |- + PrometheusRule objects to be selected for rule evaluation. An empty + label selector matches all objects. A null label selector matches no + objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + This defaults to the default PodSecurityContext. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run the + Thanos Ruler Pods. + type: string + serviceName: + description: |- + The name of the service name used by the underlying StatefulSet(s) as the governing service. + If defined, the Service must be created before the ThanosRuler resource in the same namespace and it must define a selector that matches the pod labels. + If empty, the operator will create and manage a headless service named `thanos-ruler-operated` for ThanosRuler resources. + When deploying multiple ThanosRuler resources in the same namespace, it is recommended to specify a different value for each. + See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details. + minLength: 1 + type: string + storage: + description: Storage spec to specify how storage shall be used. + properties: + disableMountSubPath: + description: 'Deprecated: subPath usage will be removed in a future release.' + type: boolean + emptyDir: + description: |- + EmptyDirVolumeSource to be used by the StatefulSet. + If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + EphemeralVolumeSource to be used by the StatefulSet. + This is a beta field in k8s 1.21 and GA in 1.15. + For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate. + More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + description: |- + Defines the PVC spec to be used by the Prometheus StatefulSets. + The easiest way to use a volume that cannot be automatically provisioned + is to use a label selector alongside manually created PersistentVolumes. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ + type: string + type: object + spec: + description: |- + Defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + status: + description: 'Deprecated: this field is never set.' + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'Resizing'. + items: + description: PersistentVolumeClaimCondition contains details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "Resizing" that means the underlying + persistent volume is being resized. + type: string + status: + description: |- + Status is the status of the condition. + Can be True, False, Unknown. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required + type: string + type: + description: |- + Type is the type of the condition. + More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is a beta field and requires enabling VolumeAttributesClass feature (off by default). + properties: + status: + description: "status is the status of the ControllerModifyVolume operation. It can be in any of following states:\n - Pending\n Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\n the specified VolumeAttributesClass not existing.\n - InProgress\n InProgress indicates that the volume is being modified.\n - Infeasible\n Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass needs to be specified.\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down) which may lead to data corruption. + + Defaults to 120 seconds. + format: int64 + minimum: 0 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: If specified, the pod's topology spread constraints. + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + tracingConfig: + description: |- + Configures tracing. + + The configuration format is defined at https://thanos.io/tip/thanos/tracing.md/#configuration + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + + The operator performs no validation of the configuration. + + `tracingConfigFile` takes precedence over this field. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + tracingConfigFile: + description: |- + Configures the path of the tracing configuration file. + + The configuration format is defined at https://thanos.io/tip/thanos/tracing.md/#configuration + + This is an *experimental feature*, it may change in any upcoming release + in a breaking way. + + The operator performs no validation of the configuration file. + + This field takes precedence over `tracingConfig`. + type: string + version: + description: Version of Thanos to be deployed. + type: string + volumeMounts: + description: |- + VolumeMounts allows configuration of additional VolumeMounts on the output StatefulSet definition. + VolumeMounts specified will be appended to other VolumeMounts in the ruler container, + that are generated as a result of StorageSpec objects. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Volumes allows configuration of additional volumes on the output StatefulSet definition. Volumes specified will + be appended to other volumes that are generated as a result of StorageSpec objects. + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + web: + description: Defines the configuration of the ThanosRuler web server. + properties: + httpConfig: + description: Defines HTTP parameters for web server. + properties: + headers: + description: List of headers that can be added to HTTP responses. + properties: + contentSecurityPolicy: + description: |- + Set the Content-Security-Policy header to HTTP responses. + Unset if blank. + type: string + strictTransportSecurity: + description: |- + Set the Strict-Transport-Security header to HTTP responses. + Unset if blank. + Please make sure that you use this with care as this header might force + browsers to load Prometheus and the other applications hosted on the same + domain and subdomains over HTTPS. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + type: string + xContentTypeOptions: + description: |- + Set the X-Content-Type-Options header to HTTP responses. + Unset if blank. Accepted value is nosniff. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + enum: + - "" + - NoSniff + type: string + xFrameOptions: + description: |- + Set the X-Frame-Options header to HTTP responses. + Unset if blank. Accepted values are deny and sameorigin. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + enum: + - "" + - Deny + - SameOrigin + type: string + xXSSProtection: + description: |- + Set the X-XSS-Protection header to all responses. + Unset if blank. + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + type: string + type: object + http2: + description: |- + Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS. + When TLSConfig is not configured, HTTP/2 will be disabled. + Whenever the value of the field changes, a rolling update will be triggered. + type: boolean + type: object + tlsConfig: + description: Defines the TLS parameters for HTTPS. + properties: + cert: + description: |- + Secret or ConfigMap containing the TLS certificate for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `certFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: |- + Path to the TLS certificate file in the container for the web server. + + Either `keySecret` or `keyFile` must be defined. + + It is mutually exclusive with `cert`. + type: string + cipherSuites: + description: |- + List of supported cipher suites for TLS versions up to TLS 1.2. + + If not defined, the Go default cipher suites are used. + Available cipher suites are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#pkg-constants + items: + type: string + type: array + client_ca: + description: |- + Secret or ConfigMap containing the CA certificate for client certificate + authentication to the server. + + It is mutually exclusive with `clientCAFile`. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientAuthType: + description: |- + The server policy for client TLS authentication. + + For more detail on clientAuth options: + https://golang.org/pkg/crypto/tls/#ClientAuthType + type: string + clientCAFile: + description: |- + Path to the CA certificate file for client certificate authentication to + the server. + + It is mutually exclusive with `client_ca`. + type: string + curvePreferences: + description: |- + Elliptic curves that will be used in an ECDHE handshake, in preference + order. + + Available curves are documented in the Go documentation: + https://golang.org/pkg/crypto/tls/#CurveID + items: + type: string + type: array + keyFile: + description: |- + Path to the TLS private key file in the container for the web server. + + If defined, either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keySecret`. + type: string + keySecret: + description: |- + Secret containing the TLS private key for the web server. + + Either `cert` or `certFile` must be defined. + + It is mutually exclusive with `keyFile`. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxVersion: + description: Maximum TLS version that is acceptable. + type: string + minVersion: + description: Minimum TLS version that is acceptable. + type: string + preferServerCipherSuites: + description: |- + Controls whether the server selects the client's most preferred cipher + suite, or the server's most preferred cipher suite. + + If true then the server's preference, as expressed in + the order of elements in cipherSuites, is used. + type: boolean + type: object + type: object + type: object + status: + description: |- + Most recent observed status of the ThanosRuler cluster. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + availableReplicas: + description: |- + Total number of available pods (ready for at least minReadySeconds) + targeted by this ThanosRuler deployment. + format: int32 + type: integer + conditions: + description: The current state of the ThanosRuler object. + items: + description: |- + Condition represents the state of the resources associated with the + Prometheus, Alertmanager or ThanosRuler resource. + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: Human-readable message indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the + instance. + format: int64 + type: integer + reason: + description: Reason for the condition's last transition. + type: string + status: + description: Status of the condition. + minLength: 1 + type: string + type: + description: Type of the condition being reported. + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + paused: + description: |- + Represents whether any actions on the underlying managed objects are + being performed. Only delete actions will be performed. + type: boolean + replicas: + description: |- + Total number of non-terminated pods targeted by this ThanosRuler deployment + (their labels match the selector). + format: int32 + type: integer + unavailableReplicas: + description: Total number of unavailable pods targeted by this ThanosRuler deployment. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated pods targeted by this ThanosRuler deployment + that have the desired version spec. + format: int32 + type: integer + required: + - availableReplicas + - paused + - replicas + - unavailableReplicas + - updatedReplicas + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/release/kubernetes/monitoring/setup/namespace.yaml b/release/kubernetes/monitoring/setup/namespace.yaml new file mode 100644 index 000000000..a426afd68 --- /dev/null +++ b/release/kubernetes/monitoring/setup/namespace.yaml @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Namespace +metadata: + labels: + pod-security.kubernetes.io/warn: privileged + pod-security.kubernetes.io/warn-version: latest + name: monitoring diff --git a/scripts/resourcegen/gen.go b/scripts/resourcegen/gen.go new file mode 100644 index 000000000..0c3e25cfc --- /dev/null +++ b/scripts/resourcegen/gen.go @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "log" + "os" + "path/filepath" + "sort" + "strings" + "text/template" + + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + _ "github.com/apache/dubbo-admin/api/mesh/v1alpha1" +) + +// resourceTemplate for creating a Dubbo Resource. +var resourceTemplate = template.Must(template.New("dubbo-resource").Parse(` +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Generated by tools/resourcegen +// Run "make generate" to update this file. + +{{ $pkg := printf "%sproto" .Package }} +{{ $tk := "` + "`" + `" }} + +// nolint:whitespace +package v1alpha1 + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + {{ $pkg }} "github.com/apache/dubbo-admin/api/{{ .Package }}/v1alpha1" + "github.com/apache/dubbo-admin/pkg/core/logger" + coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" +) +{{range .Resources}} + +const {{.Name}}Kind coremodel.ResourceKind = "{{.Name}}" + +func init() { + coremodel.RegisterResourceSchema({{.Name}}Kind, New{{.Name}}Resource, New{{.Name}}ResourceList) +} + +type {{.Name}}Resource struct { + + metav1.TypeMeta {{ $tk }}json:",inline"{{ $tk }} + + metav1.ObjectMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }} + + // Mesh is the name of the dubbo mesh this resource belongs to. + // It may be omitted for cluster-scoped resources. + Mesh string {{ $tk }}json:"mesh,omitempty"{{ $tk }} + + // Spec is the specification of the Dubbo {{ .ProtoType }} resource. + Spec *{{$pkg}}.{{.Name}} {{ $tk }}json:"spec,omitempty"{{ $tk }} + + // Status is the status of the Dubbo {{.Name}} resource. + Status {{.Name}}ResourceStatus {{ $tk }}json:"status,omitempty"{{ $tk }} +} + +type {{.Name}}ResourceStatus struct { + // define resource-specific status here +} + +func (r *{{.Name}}Resource) ResourceKind() coremodel.ResourceKind { + return {{.Name}}Kind +} + +func (r *{{.Name}}Resource) ResourceMesh() string { + return r.Mesh +} + +func (r *{{.Name}}Resource) ResourceKey() string { + return coremodel.BuildResourceKey(r.Mesh, r.Name) +} + +func (r *{{.Name}}Resource) ResourceMeta() metav1.ObjectMeta { + return r.ObjectMeta +} + +func (r *{{.Name}}Resource) ResourceSpec() coremodel.ResourceSpec { + return r.Spec +} + +func (r *{{.Name}}Resource) DeepCopyObject() k8sruntime.Object { + out := &{{.Name}}Resource{ + TypeMeta: r.TypeMeta, + Mesh: r.Mesh, + Status: r.Status, + } + + r.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + + if r.Spec != nil { + spec, ok := proto.Clone(r.Spec).(*{{ $pkg }}.{{.Name}}) + if !ok { + logger.Warnf("failed to clone spec %v, spec is not conformed to %s", r.Spec, r.ResourceKind()) + return out + } + out.Spec = spec + } + + return out +} + +func (r *{{.Name}}Resource) String() string { + jsonStr, err := json.Marshal(r) + if err != nil { + logger.Errorf("failed to encode {{.Name}}Resource: %s to json, err: %v", r.ResourceKey(), err) + return "" + } + return string(jsonStr) +} + +func New{{.Name}}ResourceWithAttributes(name string, mesh string) *{{.Name}}Resource{ + return &{{.Name}}Resource{ + TypeMeta: metav1.TypeMeta{ + Kind: string({{.Name}}Kind), + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{}, + }, + Mesh: mesh, + Spec: &meshproto.{{.Name}}{}, + } +} + +func New{{.Name}}Resource() coremodel.Resource { + return &{{.Name}}Resource{ + TypeMeta: metav1.TypeMeta{ + Kind: string({{.Name}}Kind), + APIVersion: "v1alpha1", + }, + Spec: &meshproto.{{.Name}}{}, + } +} + +type {{.Name}}ResourceList struct { + metav1.TypeMeta {{ $tk }}json:",inline"{{ $tk }} + metav1.ListMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }} + Items []*{{.Name}}Resource {{ $tk }}json:"items"{{ $tk }} +} + +func (r *{{.Name}}ResourceList) DeepCopyObject() k8sruntime.Object { + out := &{{.Name}}ResourceList{ + TypeMeta: r.TypeMeta, + } + r.ListMeta.DeepCopyInto(&out.ListMeta) + + if len(r.Items) == 0 { + return out + } + out.Items = make([]*{{.Name}}Resource, len(r.Items)) + for i := range r.Items { + out.Items[i] = r.Items[i].DeepCopyObject().(*{{.Name}}Resource) + } + return out +} + +func New{{.Name}}ResourceList() coremodel.ResourceList { + return &{{.Name}}ResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string({{.Name}}Kind), + APIVersion: "v1alpha1", + }, + Items: make([]*{{.Name}}Resource, 0), + } +} + +func (r *{{.Name}}ResourceList) SetItems(items []coremodel.Resource) { + r.Items = make([]*{{.Name}}Resource, len(items)) + for i := range items { + res, ok := items[i].(*{{.Name}}Resource) + if !ok{ + logger.Errorf("unexpected resource type, expected: %s, get %s", {{.Name}}Kind, res.ResourceKind()) + continue + } + r.Items[i] = res + } +} + +func New{{.Name}}ResourceListWithItems(items ...*{{.Name}}Resource) *{{.Name}}ResourceList { + return &{{.Name}}ResourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: string({{.Name}}Kind), + APIVersion: "v1alpha1", + }, + Items: items, + } +} + +{{- end }} {{/* Resources */}} +`)) + +// ProtoMessageFunc ... +type ProtoMessageFunc func(protoreflect.MessageType) bool + +// OnDubboResourceMessage ... +func OnDubboResourceMessage(pkg string, f ProtoMessageFunc) ProtoMessageFunc { + return func(m protoreflect.MessageType) bool { + r := DubboResourceForMessage(m.Descriptor()) + if r == nil { + return true + } + + fullname := string(m.Descriptor().FullName()) + if strings.Contains(fullname, "legacy") { + log.Printf("Skipping message: %s", fullname) + return true + } + if r.Package == pkg { + return f(m) + } + + return true + } +} + +func main() { + var pkg string + var outputDir string + + flag.StringVar(&pkg, "package", "", "the name of the package to generate: (mesh, system)") + flag.StringVar(&outputDir, "output", "", "the directory to write generated files") + flag.Parse() + + switch pkg { + case "mesh", "system": + default: + log.Fatalf("package %s is not supported", pkg) + } + + if err := os.MkdirAll(outputDir, 0755); err != nil { + log.Fatalf("failed to create output dir: %v", err) + } + + var types []protoreflect.MessageType + protoregistry.GlobalTypes.RangeMessages( + OnDubboResourceMessage(pkg, func(m protoreflect.MessageType) bool { + types = append(types, m) + return true + })) + + // Sort by name so the output is deterministic. + sort.Slice(types, func(i, j int) bool { + return types[i].Descriptor().FullName() < types[j].Descriptor().FullName() + }) + + var resources []ResourceInfo + for _, t := range types { + resourceInfo := ToResourceInfo(t.Descriptor()) + resources = append(resources, resourceInfo) + } + + for _, resource := range resources { + var buf bytes.Buffer + if err := resourceTemplate.Execute(&buf, struct { + Package string + Resources []ResourceInfo + }{ + Package: pkg, + Resources: []ResourceInfo{resource}, + }); err != nil { + log.Fatalf("template error for %s: %s", resource.Name, err) + } + + out, err := format.Source(buf.Bytes()) + if err != nil { + log.Fatalf("format error for %s: %s", resource.Name, err) + } + + filename := filepath.Join(outputDir, fmt.Sprintf("%s_types.go", strings.ToLower(resource.Name))) + if err := os.WriteFile(filename, out, 0644); err != nil { + log.Fatalf("write file error for %s: %s", filename, err) + } + + log.Printf("Generated: %s", filename) + } +} diff --git a/scripts/resourcegen/util.go b/scripts/resourcegen/util.go new file mode 100644 index 000000000..d1fe6f25e --- /dev/null +++ b/scripts/resourcegen/util.go @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "fmt" + + "golang.org/x/text/cases" + "golang.org/x/text/language" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/apache/dubbo-admin/api/mesh" +) + +// DubboResourceForMessage fetches the Dubbo resource option out of a message. +func DubboResourceForMessage(desc protoreflect.MessageDescriptor) *mesh.DubboResourceOptions { + ext := proto.GetExtension(desc.Options(), mesh.E_Resource) + var resOption *mesh.DubboResourceOptions + if r, ok := ext.(*mesh.DubboResourceOptions); ok { + resOption = r + } + + return resOption +} + +// SelectorsForMessage finds all the top-level fields in the message are +// repeated selectors. We want to generate convenience accessors for these. +func SelectorsForMessage(m protoreflect.MessageDescriptor) []string { + var selectors []string + fields := m.Fields() + + for i := 0; i < fields.Len(); i++ { + field := fields.Get(i) + m := field.Message() + if m != nil && m.FullName() == "dubbo.mesh.v1alpha1.Selector" { + fieldName := string(field.Name()) + caser := cases.Title(language.English) + selectors = append(selectors, caser.String(fieldName)) + } + } + + return selectors +} + +type ResourceInfo struct { + Name string + PluralName string + ProtoType string + Selectors []string + IsExperimental bool +} + +func ToResourceInfo(desc protoreflect.MessageDescriptor) ResourceInfo { + r := DubboResourceForMessage(desc) + + out := ResourceInfo{ + Name: r.Name, + PluralName: r.PluralName, + ProtoType: string(desc.Name()), + Selectors: SelectorsForMessage(desc), + IsExperimental: r.IsExperimental, + } + + if p := desc.Parent(); p != nil { + if _, ok := p.(protoreflect.MessageDescriptor); ok { + out.ProtoType = fmt.Sprintf("%s_%s", p.Name(), desc.Name()) + } + } + return out +} diff --git a/tools/resourcegen/main.go b/tools/resourcegen/main.go deleted file mode 100644 index 25915da37..000000000 --- a/tools/resourcegen/main.go +++ /dev/null @@ -1,237 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "go/format" - "log" - "os" - "path/filepath" - "sort" - "strings" - "text/template" - - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - _ "github.com/apache/dubbo-admin/api/mesh/v1alpha1" - _ "github.com/apache/dubbo-admin/api/system/v1alpha1" - - util "github.com/apache/dubbo-admin/tools/resourcegen/util" -) - -// resourceTemplate for creating a Dubbo Resource. -var resourceTemplate = template.Must(template.New("dubbo-resource").Parse(` -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Generated by tools/resourcegen -// Run "make generate" to update this file. - -{{ $pkg := printf "%sproto" .Package }} -{{ $tk := "` + "`" + `" }} - -// nolint:whitespace -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - {{ $pkg }} "github.com/apache/dubbo-admin/api/{{ .Package }}/v1alpha1" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -{{range .Resources}} - -// +kubebuilder:object:root=true -{{- if .ScopeNamespace }} -// +kubebuilder:resource:categories=dubbo,scope=Namespaced -{{- else }} -// +kubebuilder:resource:categories=dubbo,scope=Cluster -{{- end}} -{{- range .AdditionalPrinterColumns }} -// +kubebuilder:printcolumn:{{ . }} -{{- end}} - -const {{.ResourceType}}Kind coremodel.ResourceKind = "{{.ResourceType}}" - -func init() { - coremodel.RegisterResourceKind({{.ResourceType}}Kind) -} - -type {{.ResourceType}}Resource struct { - metav1.TypeMeta {{ $tk }}json:",inline"{{ $tk }} - metav1.ObjectMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }} - - // Mesh is the name of the dubbo mesh this resource belongs to. - // It may be omitted for cluster-scoped resources. - // - // +kubebuilder:validation:Optional - Mesh string {{ $tk }}json:"mesh,omitempty"{{ $tk }} - -{{- if eq .ResourceType "DataplaneInsight" }} - // Status is the status the dubbo resource. - // +kubebuilder:validation:Optional - Status *apiextensionsv1.JSON {{ $tk }}json:"status,omitempty"{{ $tk }} -{{- else}} - // Spec is the specification of the Dubbo {{ .ProtoType }} resource. - // +kubebuilder:validation:Optional - Spec *{{$pkg}}.{{.ResourceType}} {{ $tk }}json:"spec,omitempty"{{ $tk }} -{{- end}} - // Status is the status of the Dubbo {{.ResourceType}} resource. - Status {{.ResourceType}}ResourceStatus {{ $tk }}json:"status,omitempty"{{ $tk }} -} - -type {{.ResourceType}}ResourceStatus struct { - // define resource-specific status here -} - -// +kubebuilder:object:root=true -{{- if .ScopeNamespace }} -// +kubebuilder:resource:scope=Cluster -{{- else }} -// +kubebuilder:resource:scope=Namespaced -{{- end}} -type {{.ResourceType}}ResourceList struct { - metav1.TypeMeta {{ $tk }}json:",inline"{{ $tk }} - metav1.ListMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }} - Items []{{.ResourceType}}Resource {{ $tk }}json:"items"{{ $tk }} -} - -func (r *{{.ResourceType}}Resource) ResourceKind() coremodel.ResourceKind { - return {{.ResourceType}}Kind -} - -func (r *{{.ResourceType}}Resource) MeshName() string { - return r.Mesh -} - -func (r *{{.ResourceType}}Resource) ResourceKey() string { - return coremodel.BuildResourceKey(r.Mesh, r.Name) -} - -func (r *{{.ResourceType}}Resource) ResourceMeta() metav1.ObjectMeta { - return r.ObjectMeta -} - -func (r *{{.ResourceType}}Resource) ResourceSpec() coremodel.ResourceSpec { - return r.Spec -} - -func New{{.ResourceType}}Resource(name string, mesh string, apiVersion string) *{{.ResourceType}}Resource{ - return &{{.ResourceType}}Resource{ - TypeMeta: metav1.TypeMeta{ - Kind: string({{.ResourceType}}Kind), - APIVersion: apiVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{}, - }, - Mesh: mesh, - } -} - -{{- end }} {{/* Resources */}} -`)) - -// ProtoMessageFunc ... -type ProtoMessageFunc func(protoreflect.MessageType) bool - -// OnDubboResourceMessage ... -func OnDubboResourceMessage(pkg string, f ProtoMessageFunc) ProtoMessageFunc { - return func(m protoreflect.MessageType) bool { - r := util.DubboResourceForMessage(m.Descriptor()) - if r == nil { - return true - } - - fullname := string(m.Descriptor().FullName()) - if strings.Contains(fullname, "legacy") { - log.Printf("Skipping message: %s", fullname) - return true - } - if r.Package == pkg { - return f(m) - } - - return true - } -} - -func main() { - var pkg string - var outputDir string - - flag.StringVar(&pkg, "package", "", "the name of the package to generate: (mesh, system)") - flag.StringVar(&outputDir, "output", "", "the directory to write generated files") - flag.Parse() - - switch pkg { - case "mesh", "system": - default: - log.Fatalf("package %s is not supported", pkg) - } - - if err := os.MkdirAll(outputDir, 0755); err != nil { - log.Fatalf("failed to create output dir: %v", err) - } - - var types []protoreflect.MessageType - protoregistry.GlobalTypes.RangeMessages( - OnDubboResourceMessage(pkg, func(m protoreflect.MessageType) bool { - types = append(types, m) - return true - })) - - // Sort by name so the output is deterministic. - sort.Slice(types, func(i, j int) bool { - return types[i].Descriptor().FullName() < types[j].Descriptor().FullName() - }) - - var resources []util.ResourceInfo - for _, t := range types { - resourceInfo := util.ToResourceInfo(t.Descriptor()) - resources = append(resources, resourceInfo) - } - - for _, resource := range resources { - // 每次只传一个资源到模板中 - var buf bytes.Buffer - if err := resourceTemplate.Execute(&buf, struct { - Package string - Resources []util.ResourceInfo - }{ - Package: pkg, - Resources: []util.ResourceInfo{resource}, // 只放一个资源 - }); err != nil { - log.Fatalf("template error for %s: %s", resource.ResourceType, err) - } - - out, err := format.Source(buf.Bytes()) - if err != nil { - log.Fatalf("format error for %s: %s", resource.ResourceType, err) - } - - filename := filepath.Join(outputDir, fmt.Sprintf("%s_types.go", strings.ToLower(resource.ResourceType))) - if err := os.WriteFile(filename, out, 0644); err != nil { - log.Fatalf("write file error for %s: %s", filename, err) - } - - log.Printf("Generated: %s", filename) - } -} diff --git a/tools/resourcegen/util/util.go b/tools/resourcegen/util/util.go deleted file mode 100644 index 397229ac4..000000000 --- a/tools/resourcegen/util/util.go +++ /dev/null @@ -1,135 +0,0 @@ -package util - -import ( - "fmt" - - "golang.org/x/text/cases" - "golang.org/x/text/language" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - - "github.com/apache/dubbo-admin/api/mesh" - coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model" -) - -// DubboResourceForMessage fetches the Dubbo resource option out of a message. -func DubboResourceForMessage(desc protoreflect.MessageDescriptor) *mesh.DubboResourceOptions { - ext := proto.GetExtension(desc.Options(), mesh.E_Resource) - var resOption *mesh.DubboResourceOptions - if r, ok := ext.(*mesh.DubboResourceOptions); ok { - resOption = r - } - - return resOption -} - -// SelectorsForMessage finds all the top-level fields in the message are -// repeated selectors. We want to generate convenience accessors for these. -func SelectorsForMessage(m protoreflect.MessageDescriptor) []string { - var selectors []string - fields := m.Fields() - - for i := 0; i < fields.Len(); i++ { - field := fields.Get(i) - m := field.Message() - if m != nil && m.FullName() == "dubbo.mesh.v1alpha1.Selector" { - fieldName := string(field.Name()) - caser := cases.Title(language.English) - selectors = append(selectors, caser.String(fieldName)) - } - } - - return selectors -} - -type ResourceInfo struct { - ResourceName string - ResourceType string - ProtoType string - Selectors []string - SkipRegistration bool - SkipKubernetesWrappers bool - ScopeNamespace bool - Global bool - DubboctlSingular string - DubboctlPlural string - WsReadOnly bool - WsAdminOnly bool - WsPath string - DdsDirection string - AllowToInspect bool - StorageVersion bool - IsPolicy bool - SingularDisplayName string - PluralDisplayName string - IsExperimental bool - AdditionalPrinterColumns []string - HasInsights bool -} - -func ToResourceInfo(desc protoreflect.MessageDescriptor) ResourceInfo { - r := DubboResourceForMessage(desc) - - out := ResourceInfo{ - ResourceType: r.Type, - ResourceName: r.Name, - ProtoType: string(desc.Name()), - Selectors: SelectorsForMessage(desc), - SkipRegistration: r.SkipRegistration, - SkipKubernetesWrappers: r.SkipKubernetesWrappers, - Global: r.Global, - ScopeNamespace: r.ScopeNamespace, - AllowToInspect: r.AllowToInspect, - StorageVersion: r.StorageVersion, - SingularDisplayName: coremodel.DisplayName(r.Type), - PluralDisplayName: r.PluralDisplayName, - IsExperimental: r.IsExperimental, - AdditionalPrinterColumns: r.AdditionalPrinterColumns, - HasInsights: r.HasInsights, - } - if r.Ws != nil { - pluralResourceName := r.Ws.Plural - if pluralResourceName == "" { - pluralResourceName = r.Ws.Name + "s" - } - out.WsReadOnly = r.Ws.ReadOnly - out.WsAdminOnly = r.Ws.AdminOnly - out.WsPath = pluralResourceName - if !r.Ws.ReadOnly { - out.DubboctlSingular = r.Ws.Name - out.DubboctlPlural = pluralResourceName - // Keep the typo to preserve backward compatibility - if out.DubboctlSingular == "health-check" { - out.DubboctlSingular = "healthcheck" - out.DubboctlPlural = "healthchecks" - } - } - } - if out.PluralDisplayName == "" { - out.PluralDisplayName = coremodel.PluralType(coremodel.DisplayName(r.Type)) - } - // Working around the fact we don't really differentiate policies from the rest of resources: - // Anything global can't be a policy as it need to be on a mesh. Anything with locked Ws config is something internal and therefore not a policy - out.IsPolicy = !out.SkipRegistration && !out.Global && !out.WsAdminOnly && !out.WsReadOnly && out.ResourceType != "Dataplane" && out.ResourceType != "ExternalService" - switch { - case r.Dds == nil || (!r.Dds.SendToZone && !r.Dds.SendToGlobal): - out.DdsDirection = "" - case r.Dds.SendToGlobal && r.Dds.SendToZone: - out.DdsDirection = "model.ZoneToGlobalFlag | model.GlobalToAllButOriginalZoneFlag" - case r.Dds.SendToGlobal: - out.DdsDirection = "model.ZoneToGlobalFlag" - case r.Dds.SendToZone: - out.DdsDirection = "model.GlobalToAllZonesFlag" - } - - if out.ResourceType == "MeshGateway" { - out.DdsDirection = "model.ZoneToGlobalFlag | model.GlobalToAllZonesFlag" - } - - if p := desc.Parent(); p != nil { - if _, ok := p.(protoreflect.MessageDescriptor); ok { - out.ProtoType = fmt.Sprintf("%s_%s", p.Name(), desc.Name()) - } - } - return out -} diff --git a/ui-vue3/.env.mock b/ui-vue3/.env.mock new file mode 100644 index 000000000..673b4b23c --- /dev/null +++ b/ui-vue3/.env.mock @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +VITE_MOCK_ENABLED=true diff --git a/ui-vue3/package.json b/ui-vue3/package.json index d330ef448..70b06d7c1 100644 --- a/ui-vue3/package.json +++ b/ui-vue3/package.json @@ -5,6 +5,7 @@ "type": "module", "scripts": { "dev": "vite", + "dev:mock": "vite --mode mock", "check:i18n": "node --loader ts-node/esm src/base/i18n/sortI18n.ts", "preview": "vite preview", "test:unit": "vitest", @@ -22,24 +23,25 @@ }, "dependencies": { "@antv/g2": "^5.1.12", + "@antv/g6": "^5.0.51", "@iconify/json": "^2.2.157", "@iconify/vue": "^4.1.1", - "@types/highlight.js": "^9.12.4", "@types/lodash": "^4.14.202", "@types/lodash-es": "^4.17.12", "@types/nprogress": "^0.2.3", "ant-design-vue": "4.x", + "axios": "^1.13.6", "dayjs": "^1.11.13", + "g6-extension-vue": "^0.1.0", "gsap": "^3.12.7", - "highlight.js": "^11.11.1", "js-cookie": "^3.0.5", "js-yaml": "^4.1.0", "less": "^4.2.0", "lodash": "^4.17.21", - "mockjs": "^1.1.0", "monaco-editor": "^0.52.2", "nprogress": "^0.2.0", "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^4.7.1", "pinyin-pro": "^3.19.3", "ts-node": "^10.9.2", "tslib": "^2.6.2", @@ -53,8 +55,6 @@ "@rushstack/eslint-patch": "^1.3.3", "@tsconfig/node18": "^18.2.2", "@types/jsdom": "^21.1.6", - "@types/markdown-it": "^14.1.2", - "@types/mockjs": "^1.0.10", "@types/node": "^20.10.6", "@vitejs/plugin-vue": "^4.5.1", "@vitejs/plugin-vue-jsx": "^3.1.0", @@ -62,22 +62,24 @@ "@vue/eslint-config-typescript": "^12.0.0", "@vue/test-utils": "^2.4.3", "@vue/tsconfig": "^0.4.0", - "autoprefixer": "^10.4.21", "cypress": "^13.6.1", "eslint": "^8.49.0", "eslint-plugin-cypress": "^2.15.1", "eslint-plugin-vue": "^9.17.0", "husky": "^9.0.6", "jsdom": "^23.0.1", - "markdown-it": "^14.1.0", + "msw": "2.11.6", "npm-run-all2": "^6.1.1", - "postcss": "^8.5.6", "prettier": "^3.0.3", "start-server-and-test": "^2.0.3", - "tailwindcss": "3", "typescript": "~5.2.0", "vite": "^5.0.5", "vitest": "^1.0.1", "vue-tsc": "^1.8.25" + }, + "msw": { + "workerDirectory": [ + "public" + ] } } diff --git a/ui-vue3/public/mockServiceWorker.js b/ui-vue3/public/mockServiceWorker.js new file mode 100644 index 000000000..2f658e919 --- /dev/null +++ b/ui-vue3/public/mockServiceWorker.js @@ -0,0 +1,349 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + */ + +const PACKAGE_VERSION = '2.11.6' +const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82' +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') +const activeClientIds = new Set() + +addEventListener('install', function () { + self.skipWaiting() +}) + +addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) + +addEventListener('message', async function (event) { + const clientId = Reflect.get(event.source || {}, 'id') + + if (!clientId || !self.clients) { + return + } + + const client = await self.clients.get(clientId) + + if (!client) { + return + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }) + break + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }) + break + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }) + break + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +addEventListener('fetch', function (event) { + const requestInterceptedAt = Date.now() + + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if ( + event.request.cache === 'only-if-cached' && + event.request.mode !== 'same-origin' + ) { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been terminated (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + const requestId = crypto.randomUUID() + event.respondWith(handleRequest(event, requestId, requestInterceptedAt)) +}) + +/** + * @param {FetchEvent} event + * @param {string} requestId + * @param {number} requestInterceptedAt + */ +async function handleRequest(event, requestId, requestInterceptedAt) { + const client = await resolveMainClient(event) + const requestCloneForEvents = event.request.clone() + const response = await getResponse( + event, + client, + requestId, + requestInterceptedAt, + ) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents) + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone() + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ) + } + + return response +} + +/** + * Resolve the main client for the given event. + * Client that issues a request doesn't necessarily equal the client + * that registered the worker. It's with the latter the worker should + * communicate with during the response resolving phase. + * @param {FetchEvent} event + * @returns {Promise} + */ +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (activeClientIds.has(event.clientId)) { + return client + } + + if (client?.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +/** + * @param {FetchEvent} event + * @param {Client | undefined} client + * @param {string} requestId + * @param {number} requestInterceptedAt + * @returns {Promise} + */ +async function getResponse(event, client, requestId, requestInterceptedAt) { + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone() + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers) + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept') + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()) + const filteredValues = values.filter( + (value) => value !== 'msw/passthrough', + ) + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')) + } else { + headers.delete('accept') + } + } + + return fetch(requestClone, { headers }) + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough() + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request) + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + interceptedAt: requestInterceptedAt, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ) + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) + } + + case 'PASSTHROUGH': { + return passthrough() + } + } + + return passthrough() +} + +/** + * @param {Client} client + * @param {any} message + * @param {Array} transferrables + * @returns {Promise} + */ +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage(message, [ + channel.port2, + ...transferrables.filter(Boolean), + ]) + }) +} + +/** + * @param {Response} response + * @returns {Response} + */ +function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error() + } + + const mockedResponse = new Response(response.body, response) + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }) + + return mockedResponse +} + +/** + * @param {Request} request + */ +async function serializeRequest(request) { + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + } +} diff --git a/ui-vue3/src/App.vue b/ui-vue3/src/App.vue index a56ecc7dc..07827a6ba 100644 --- a/ui-vue3/src/App.vue +++ b/ui-vue3/src/App.vue @@ -14,7 +14,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - diff --git a/ui-vue3/src/views/resources/applications/tabs/config.vue b/ui-vue3/src/views/resources/applications/tabs/config.vue index cc636850a..0fd29b539 100644 --- a/ui-vue3/src/views/resources/applications/tabs/config.vue +++ b/ui-vue3/src/views/resources/applications/tabs/config.vue @@ -23,7 +23,12 @@